@svgforge/svgforge-cli 2.0.0 → 2.0.2-unstable.202609132246.c961c8e
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +0 -1
- package/README.md +1 -0
- package/bin/svgforge.js +66 -12
- package/package.json +11 -12
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -103,6 +103,7 @@ The test suite spawns the CLI as a child process against fixtures in `test/fixtu
|
|
|
103
103
|
## License
|
|
104
104
|
|
|
105
105
|
[MIT](LICENSE) © Felix Müller
|
|
106
|
+
|
|
106
107
|
[npm-url]: https://www.npmjs.com/package/@svgforge/svgforge-cli
|
|
107
108
|
|
|
108
109
|
[npm-image]: https://img.shields.io/npm/v/@svgforge/svgforge-cli?logo=npm&logoColor=fff
|
package/bin/svgforge.js
CHANGED
|
@@ -3,15 +3,13 @@
|
|
|
3
3
|
/**
|
|
4
4
|
Svgforge is a Node.js module for creating SVG sprites
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
Some code based on the command line interface originally written for svg-sprite
|
|
7
7
|
by Joschi Kuphal — this is a standalone fork/package of that CLI.
|
|
8
8
|
|
|
9
|
-
@see https://github.com/
|
|
10
|
-
@author
|
|
11
|
-
@author Felix Müller
|
|
12
|
-
@copyright © 2018 Joschi Kuphal
|
|
9
|
+
@see https://github.com/svgforge/svgforge-cli
|
|
10
|
+
@author Felix Müller (https://github.com/joeda1)
|
|
13
11
|
@copyright © 2026 Felix Müller
|
|
14
|
-
@license MIT https://github.com/
|
|
12
|
+
@license MIT https://github.com/svgforge/svgforge-cli/blob/main/LICENSE
|
|
15
13
|
*/
|
|
16
14
|
|
|
17
15
|
import fs from 'node:fs';
|
|
@@ -471,6 +469,40 @@ function loadVariables(cfg) {
|
|
|
471
469
|
}
|
|
472
470
|
}
|
|
473
471
|
|
|
472
|
+
/**
|
|
473
|
+
Resolve the output directories that must not be re-ingested as source files
|
|
474
|
+
|
|
475
|
+
Generated artifacts (sprites, stylesheets, examples) live inside the configured
|
|
476
|
+
destination tree. When an input glob covers that tree (e.g. a recursive
|
|
477
|
+
SVG glob), a sprite written by a previous run would otherwise be fed back
|
|
478
|
+
in as a shape with an id derived from its output path (e.g.
|
|
479
|
+
"assets--OUT--stack--svg--sprite").
|
|
480
|
+
|
|
481
|
+
@param {SpriterConfig} cfg Spriter configuration
|
|
482
|
+
@returns {string[]} Absolute output root directories to exclude from the input
|
|
483
|
+
*/
|
|
484
|
+
function getExcludedInputRoots(cfg) {
|
|
485
|
+
const destRoot = path.resolve(cfg.dest || '.');
|
|
486
|
+
const roots = new Set([destRoot]);
|
|
487
|
+
|
|
488
|
+
// When the destination defaults to the current directory every glob would
|
|
489
|
+
// land inside it, so restrict the exclusion to the mode specific output
|
|
490
|
+
// directories instead.
|
|
491
|
+
if (destRoot === process.cwd()) {
|
|
492
|
+
roots.clear();
|
|
493
|
+
|
|
494
|
+
for (const mode of MODES) {
|
|
495
|
+
const modeDest = cfg.mode?.[mode]?.dest;
|
|
496
|
+
|
|
497
|
+
if (modeDest) {
|
|
498
|
+
roots.add(path.resolve(destRoot, modeDest));
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
return [...roots];
|
|
504
|
+
}
|
|
505
|
+
|
|
474
506
|
/**
|
|
475
507
|
Run the command line interface
|
|
476
508
|
|
|
@@ -493,19 +525,41 @@ async function main() {
|
|
|
493
525
|
loadVariables(config);
|
|
494
526
|
|
|
495
527
|
const spriter = new SVGSpriter(config);
|
|
496
|
-
const files = argv._.flatMap(filePattern => fs.globSync(filePattern).toSorted((a, b) => b.localeCompare(a)));
|
|
497
528
|
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
529
|
+
// Glob (>= 9, incl. fs.globSync) returns paths without the "./" segment, so
|
|
530
|
+
// the base directory marker has to be detected on the original pattern. A
|
|
531
|
+
// literal "/./" segment marks the directory from which shape ID traversal
|
|
532
|
+
// should start (e.g. "assets/./**/*.svg" yields "path--to--source" instead
|
|
533
|
+
// of "assets--path--to--source").
|
|
534
|
+
const matchedFiles = argv._.flatMap(pattern => {
|
|
535
|
+
const marker = pattern.lastIndexOf('./');
|
|
536
|
+
const baseDepth = marker === -1 ? 0 : pattern.slice(0, marker).split('/').filter(Boolean).length;
|
|
537
|
+
return fs.globSync(pattern)
|
|
538
|
+
.toSorted((a, b) => b.localeCompare(a))
|
|
539
|
+
.map(file => ({baseDepth, file}));
|
|
540
|
+
});
|
|
541
|
+
const excludedInputRoots = getExcludedInputRoots(config);
|
|
542
|
+
|
|
543
|
+
for (const {baseDepth, file: filePattern} of matchedFiles) {
|
|
503
544
|
const file = path.resolve(filePattern);
|
|
545
|
+
|
|
546
|
+
// Skip files inside the output tree so previously generated artifacts are
|
|
547
|
+
// not processed as source shapes again
|
|
548
|
+
if (excludedInputRoots.some(root => file === root || file.startsWith(root + path.sep))) {
|
|
549
|
+
continue;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
// Detect relative patterns to preserve directory structure in the shape
|
|
553
|
+
// identifiers (e.g. "nested/leaf.svg" -> "nested--leaf")
|
|
554
|
+
const isRelative = !path.isAbsolute(filePattern) && !filePattern.startsWith('../');
|
|
504
555
|
const stat = fs.lstatSync(file);
|
|
505
556
|
let basename;
|
|
506
557
|
|
|
507
558
|
if (stat.isSymbolicLink()) {
|
|
508
559
|
basename = path.basename(fs.readlinkSync(file));
|
|
560
|
+
} else if (baseDepth > 0) {
|
|
561
|
+
// Strip the base directory marked by "/./" from the shape identifier
|
|
562
|
+
basename = filePattern.split('/').filter(Boolean).slice(baseDepth).join('/');
|
|
509
563
|
} else {
|
|
510
564
|
basename = isRelative ? filePattern : path.basename(file);
|
|
511
565
|
}
|
package/package.json
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@svgforge/svgforge-cli",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2-unstable.202609132246.c961c8e",
|
|
4
4
|
"author": "Felix Müller (https://github.com/joeda1)",
|
|
5
|
-
"contributors": [
|
|
6
|
-
"Joschi Kuphal <joschi@kuphal.net> (https://github.com/jkphl)"
|
|
7
|
-
],
|
|
8
5
|
"description": "Command line interface for svgforge — create SVG sprites & stacks with stylesheet resources (CSS, Sass, etc.)",
|
|
9
6
|
"homepage": "https://github.com/svgforge/svgforge-cli",
|
|
10
7
|
"repository": {
|
|
@@ -33,20 +30,22 @@
|
|
|
33
30
|
"files": [
|
|
34
31
|
"bin"
|
|
35
32
|
],
|
|
33
|
+
"scripts": {
|
|
34
|
+
"prepare": "husky",
|
|
35
|
+
"lint": "xo",
|
|
36
|
+
"fix": "xo --fix",
|
|
37
|
+
"test": "node --test test/*.test.js",
|
|
38
|
+
"test:coverage": "mkdir -p coverage && node --test --experimental-test-coverage --test-reporter=spec --test-reporter-destination=stdout --test-reporter=lcov --test-reporter-destination=coverage/lcov.info"
|
|
39
|
+
},
|
|
36
40
|
"dependencies": {
|
|
41
|
+
"@svgforge/svgforge": "^2.0.2-unstable.0",
|
|
37
42
|
"js-yaml": "^5.4.1",
|
|
38
|
-
"@svgforge/svgforge": "^2.0.0",
|
|
39
43
|
"vinyl": "^3.0.1",
|
|
40
44
|
"yargs": "^18.1.0"
|
|
41
45
|
},
|
|
42
46
|
"devDependencies": {
|
|
43
47
|
"eslint-plugin-jsdoc": "^64.3.2",
|
|
48
|
+
"husky": "^9.1.7",
|
|
44
49
|
"xo": "^4.0.0"
|
|
45
|
-
},
|
|
46
|
-
"scripts": {
|
|
47
|
-
"lint": "xo",
|
|
48
|
-
"fix": "xo --fix",
|
|
49
|
-
"test": "node --test test/*.test.js",
|
|
50
|
-
"test:coverage": "mkdir -p coverage && node --test --experimental-test-coverage --test-reporter=spec --test-reporter-destination=stdout --test-reporter=lcov --test-reporter-destination=coverage/lcov.info"
|
|
51
50
|
}
|
|
52
|
-
}
|
|
51
|
+
}
|