Skip to content

Commit

Permalink
Merge branch 'main' into develop/misc
Browse files Browse the repository at this point in the history
  • Loading branch information
zachleat authored Oct 17, 2024
2 parents 1debb0c + bb49365 commit 39f612a
Show file tree
Hide file tree
Showing 6 changed files with 408 additions and 15 deletions.
8 changes: 5 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
name: Node Unit Tests
on:
push:
branches-ignore:
Expand All @@ -8,14 +9,15 @@ jobs:
strategy:
matrix:
os: ["ubuntu-latest", "macos-latest", "windows-latest"]
node: ["16", "18", "20"]
node: ["16", "18", "20", "22"]
name: Node.js ${{ matrix.node }} on ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Setup node
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
# cache: npm
- run: npm install
- run: npm test
env:
Expand Down
4 changes: 4 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
const TemplatePath = require("./src/TemplatePath.js");
const isPlainObject = require("./src/IsPlainObject.js");
const Merge = require("./src/Merge.js");
const { DeepCopy } = Merge;

module.exports = {
TemplatePath,
isPlainObject,
Merge,
DeepCopy,
};
7 changes: 2 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@11ty/eleventy-utils",
"version": "1.0.2",
"version": "1.0.3",
"description": "Low level internal utilities to be shared amongst Eleventy projects",
"main": "index.js",
"files": [
Expand Down Expand Up @@ -38,10 +38,7 @@
},
"bugs": "https://github.com/11ty/eleventy-utils/issues",
"homepage": "https://github.com/11ty/eleventy-utils/",
"dependencies": {
"normalize-path": "^3.0.0"
},
"devDependencies": {
"ava": "^4.1.0"
"ava": "^6.1.3"
}
}
84 changes: 84 additions & 0 deletions src/Merge.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
"use strict";
// above is required for Object.freeze to fail correctly.

const isPlainObject = require("./IsPlainObject.js");

const OVERRIDE_PREFIX = "override:";

function cleanKey(key, prefix) {
if (prefix && key.startsWith(prefix)) {
return key.slice(prefix.length);
}
return key;
}

function getMergedItem(target, source, prefixes = {}) {
let { override } = prefixes;

// Shortcut for frozen source (if target does not exist)
if (!target && isPlainObject(source) && Object.isFrozen(source)) {
return source;
}

let sourcePlainObjectShortcut;
if (!target && isPlainObject(source)) {
// deep copy objects to avoid sharing and to effect key renaming
target = {};
sourcePlainObjectShortcut = true;
}

if (Array.isArray(target) && Array.isArray(source)) {
return target.concat(source);
} else if (isPlainObject(target)) {
if (sourcePlainObjectShortcut || isPlainObject(source)) {
for (let key in source) {
let overrideKey = cleanKey(key, override);

// An error happens here if the target is frozen
target[overrideKey] = getMergedItem(target[key], source[key], prefixes);
}
}
return target;
}
// number, string, class instance, etc
return source;
}

// The same as Merge but without override prefixes
function DeepCopy(targetObject, ...sources) {
for (let source of sources) {
if (!source) {
continue;
}

targetObject = getMergedItem(targetObject, source);
}
return targetObject;
}

function Merge(target, ...sources) {
// Remove override prefixes from root target.
if (isPlainObject(target)) {
for (let key in target) {
if (key.indexOf(OVERRIDE_PREFIX) === 0) {
target[key.slice(OVERRIDE_PREFIX.length)] = target[key];
delete target[key];
}
}
}

for (let source of sources) {
if (!source) {
continue;
}

target = getMergedItem(target, source, {
override: OVERRIDE_PREFIX,
});
}

return target;
}

module.exports = Merge;
module.exports.DeepCopy = DeepCopy;
16 changes: 9 additions & 7 deletions src/TemplatePath.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
const path = require("path");
const normalize = require("normalize-path");
const fs = require("fs");

function TemplatePath() {}
Expand Down Expand Up @@ -59,7 +58,7 @@ TemplatePath.getLastPathSegment = function (path) {
// Trim a trailing slash if there is one
path = path.replace(/\/$/, "");

return path.substring(path.lastIndexOf("/") + 1);
return path.slice(path.lastIndexOf("/") + 1);
};

/**
Expand Down Expand Up @@ -93,22 +92,25 @@ TemplatePath.getAllDirs = function (path) {
* @returns {String} the normalized path.
*/
TemplatePath.normalize = function (thePath) {
return normalize(path.normalize(thePath));
let filePath = path.normalize(thePath).split(path.sep).join("/");
if(filePath !== "/" && filePath.endsWith("/")) {
return filePath.slice(0, -1);
}
return filePath;
};

/**
* Joins all given path segments together.
*
* It uses Node.js’ [`path.join`][1] method and the [normalize-path][2] package.
* It uses Node.js’ [`path.join`][1] method.
*
* [1]: https://nodejs.org/api/path.html#path_path_join_paths
* [2]: https://www.npmjs.com/package/normalize-path
*
* @param {...String} paths - An arbitrary amount of path segments.
* @returns {String} the normalized and joined path.
*/
TemplatePath.join = function (...paths) {
return normalize(path.join(...paths));
return TemplatePath.normalize(path.join(...paths));
};

/**
Expand Down Expand Up @@ -236,7 +238,7 @@ TemplatePath.stripLeadingSubPath = function (path, subPath) {
subPath = TemplatePath.normalize(subPath);

if (subPath !== "." && path.startsWith(subPath)) {
return path.substring(subPath.length + 1);
return path.slice(subPath.length + 1);
}

return path;
Expand Down
Loading

0 comments on commit 39f612a

Please sign in to comment.