@loomweaver/cli 0.7.5 → 0.7.6
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/dist/main.mjs +131 -58
- package/package.json +1 -1
package/dist/main.mjs
CHANGED
|
@@ -6,7 +6,7 @@ function isUnsafePath(path) {
|
|
|
6
6
|
}
|
|
7
7
|
function generate(recipe, input) {
|
|
8
8
|
const files = recipe.build(input);
|
|
9
|
-
const unsafe = Object.keys(files).find(isUnsafePath);
|
|
9
|
+
const unsafe = Object.keys(files).find((path) => isUnsafePath(path));
|
|
10
10
|
if (unsafe !== void 0) {
|
|
11
11
|
throw new Error(`Recipe "${recipe.id}" produced an unsafe path: "${unsafe}".`);
|
|
12
12
|
}
|
|
@@ -17,8 +17,16 @@ function amendments(recipe, input) {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
// ../devkit/src/lib/amend/merge.ts
|
|
20
|
+
function normalizeProjectRoot(value) {
|
|
21
|
+
const rooted = value.replace(/^\.?\/*/, "");
|
|
22
|
+
let end = rooted.length;
|
|
23
|
+
while (end > 0 && rooted[end - 1] === "/") {
|
|
24
|
+
end -= 1;
|
|
25
|
+
}
|
|
26
|
+
return rooted.slice(0, end);
|
|
27
|
+
}
|
|
20
28
|
function joinProjectPath(projectRoot, path) {
|
|
21
|
-
const root = projectRoot
|
|
29
|
+
const root = normalizeProjectRoot(projectRoot);
|
|
22
30
|
return root ? `${root}/${path}` : path;
|
|
23
31
|
}
|
|
24
32
|
function resolveAssetInput(glob, projectRoot) {
|
|
@@ -34,8 +42,8 @@ function ensurePostcssPlugin(existing, amendment) {
|
|
|
34
42
|
declined: [`${amendment.file}: "plugins" is not an object`]
|
|
35
43
|
};
|
|
36
44
|
}
|
|
37
|
-
const next = { ...plugins
|
|
38
|
-
if (amendment.plugin
|
|
45
|
+
const next = { ...plugins };
|
|
46
|
+
if (Object.hasOwn(next, amendment.plugin)) {
|
|
39
47
|
return { value: root, added: [], declined: [] };
|
|
40
48
|
}
|
|
41
49
|
next[amendment.plugin] = {};
|
|
@@ -46,10 +54,10 @@ function ensurePostcssPlugin(existing, amendment) {
|
|
|
46
54
|
};
|
|
47
55
|
}
|
|
48
56
|
function ensureBuildTarget(target, amendment, projectRoot) {
|
|
49
|
-
const next = { ...asObject(target)
|
|
57
|
+
const next = { ...asObject(target) };
|
|
50
58
|
const added = [];
|
|
51
59
|
const declined = [];
|
|
52
|
-
const options = { ...asObject(next["options"])
|
|
60
|
+
const options = { ...asObject(next["options"]) };
|
|
53
61
|
const styles = ensureStrings(
|
|
54
62
|
options["styles"],
|
|
55
63
|
amendment.styles.map((style) => joinProjectPath(projectRoot, style))
|
|
@@ -65,8 +73,8 @@ function ensureBuildTarget(target, amendment, projectRoot) {
|
|
|
65
73
|
}
|
|
66
74
|
next["options"] = options;
|
|
67
75
|
if (amendment.inlineCritical !== void 0 || amendment.serviceWorker) {
|
|
68
|
-
const configurations = { ...asObject(next["configurations"])
|
|
69
|
-
const production = { ...asObject(configurations["production"])
|
|
76
|
+
const configurations = { ...asObject(next["configurations"]) };
|
|
77
|
+
const production = { ...asObject(configurations["production"]) };
|
|
70
78
|
if (amendment.serviceWorker && production["serviceWorker"] === void 0) {
|
|
71
79
|
production["serviceWorker"] = joinProjectPath(
|
|
72
80
|
projectRoot,
|
|
@@ -96,8 +104,8 @@ function ensureBuildTarget(target, amendment, projectRoot) {
|
|
|
96
104
|
return { value: next, added, declined };
|
|
97
105
|
}
|
|
98
106
|
function ensureStylesheetSource(css, source) {
|
|
99
|
-
const quoted = source.
|
|
100
|
-
if (new RegExp(`@source
|
|
107
|
+
const quoted = source.replaceAll(/[.*+?^${}()|[\]\\]/g, String.raw`\$&`);
|
|
108
|
+
if (new RegExp(String.raw`@source\s+['"]${quoted}/?['"]`).test(css)) {
|
|
101
109
|
return css;
|
|
102
110
|
}
|
|
103
111
|
return `${css.trimEnd()}
|
|
@@ -109,7 +117,7 @@ function ensureInlineCritical(optimization, inlineCritical) {
|
|
|
109
117
|
if (typeof optimization === "boolean") {
|
|
110
118
|
return { value: optimization, changed: false, declined: true };
|
|
111
119
|
}
|
|
112
|
-
const root = { ...asObject(optimization)
|
|
120
|
+
const root = { ...asObject(optimization) };
|
|
113
121
|
const styles = asObject(root["styles"]);
|
|
114
122
|
if (styles === void 0 && root["styles"] !== void 0) {
|
|
115
123
|
return { value: optimization, changed: false, declined: true };
|
|
@@ -118,7 +126,7 @@ function ensureInlineCritical(optimization, inlineCritical) {
|
|
|
118
126
|
return { value: optimization, changed: false, declined: false };
|
|
119
127
|
}
|
|
120
128
|
return {
|
|
121
|
-
value: { ...root, styles: { ...styles
|
|
129
|
+
value: { ...root, styles: { ...styles, inlineCritical } },
|
|
122
130
|
changed: true,
|
|
123
131
|
declined: false
|
|
124
132
|
};
|
|
@@ -127,10 +135,11 @@ function ensureStrings(existing, wanted) {
|
|
|
127
135
|
const list2 = Array.isArray(existing) ? [...existing] : [];
|
|
128
136
|
const added = [];
|
|
129
137
|
for (const entry of wanted) {
|
|
130
|
-
if (
|
|
131
|
-
|
|
132
|
-
added.push(entry);
|
|
138
|
+
if (list2.includes(entry)) {
|
|
139
|
+
continue;
|
|
133
140
|
}
|
|
141
|
+
list2.push(entry);
|
|
142
|
+
added.push(entry);
|
|
134
143
|
}
|
|
135
144
|
return { value: list2, added };
|
|
136
145
|
}
|
|
@@ -145,7 +154,7 @@ function ensureAssets(existing, wanted, projectRoot) {
|
|
|
145
154
|
list2.push({
|
|
146
155
|
glob: glob.glob,
|
|
147
156
|
input,
|
|
148
|
-
...glob.output
|
|
157
|
+
...glob.output !== void 0 && { output: glob.output }
|
|
149
158
|
});
|
|
150
159
|
added.push(input);
|
|
151
160
|
}
|
|
@@ -163,34 +172,60 @@ function asObject(value) {
|
|
|
163
172
|
}
|
|
164
173
|
|
|
165
174
|
// ../devkit/src/lib/amend/compose.ts
|
|
166
|
-
var
|
|
175
|
+
var APP_CONFIG = /export\s+const\s+appConfig\s*:[^=]*=\s*\{/;
|
|
176
|
+
var PROVIDERS_OPEN = /providers\s*:\s*\[/g;
|
|
167
177
|
var SHELL_IMPORT = /import\s*\{([^}]*)\}\s*from\s*'@loomweaver\/shell';/;
|
|
178
|
+
function closingLine(source, from) {
|
|
179
|
+
let close = source.indexOf("],", from);
|
|
180
|
+
while (close !== -1) {
|
|
181
|
+
let start = close;
|
|
182
|
+
while (start > from && source.charAt(start - 1).trim() === "") {
|
|
183
|
+
start -= 1;
|
|
184
|
+
}
|
|
185
|
+
const gap = source.slice(start, close);
|
|
186
|
+
const newline = gap.indexOf("\n");
|
|
187
|
+
if (newline !== -1) {
|
|
188
|
+
return { insertAt: start + newline, indent: gap.slice(newline + 1) };
|
|
189
|
+
}
|
|
190
|
+
close = source.indexOf("],", close + 2);
|
|
191
|
+
}
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
function providersBlock(source) {
|
|
195
|
+
const declaration = APP_CONFIG.exec(source);
|
|
196
|
+
if (!declaration) {
|
|
197
|
+
return null;
|
|
198
|
+
}
|
|
199
|
+
PROVIDERS_OPEN.lastIndex = declaration.index + declaration[0].length;
|
|
200
|
+
const open = PROVIDERS_OPEN.exec(source);
|
|
201
|
+
return open ? closingLine(source, open.index + open[0].length) : null;
|
|
202
|
+
}
|
|
168
203
|
function composePlugin(source, amendment, importPath) {
|
|
169
204
|
if (source.includes(amendment.symbol)) {
|
|
170
205
|
return { source, composed: true };
|
|
171
206
|
}
|
|
172
|
-
const providers = PROVIDERS.exec(source);
|
|
173
207
|
const shellImport = SHELL_IMPORT.exec(source);
|
|
174
|
-
if (!
|
|
208
|
+
if (!shellImport || !providersBlock(source)) {
|
|
175
209
|
return { source, composed: false };
|
|
176
210
|
}
|
|
177
211
|
const withImports = source.replace(
|
|
178
212
|
SHELL_IMPORT,
|
|
179
|
-
`import {${withShellSymbols(shellImport[1])}} from '@loomweaver/shell';
|
|
213
|
+
() => `import {${withShellSymbols(shellImport[1])}} from '@loomweaver/shell';
|
|
180
214
|
import { ${amendment.symbol} } from '${importPath}';`
|
|
181
215
|
);
|
|
182
|
-
const
|
|
216
|
+
const block = providersBlock(withImports);
|
|
217
|
+
if (!block) {
|
|
218
|
+
return { source, composed: false };
|
|
219
|
+
}
|
|
220
|
+
const indent = `${block.indent} `;
|
|
183
221
|
const lines = [
|
|
184
222
|
`${indent}provideTranslationNamespaces('${amendment.id}'),`,
|
|
185
223
|
`${indent}provideCapabilityGrants({ ${amendment.id}: [${amendment.capabilities.map((capability) => `'${capability}'`).join(", ")}] }),`,
|
|
186
224
|
`${indent}...providePlugins(${amendment.symbol}),`
|
|
187
225
|
].join("\n");
|
|
188
226
|
return {
|
|
189
|
-
source: withImports.
|
|
190
|
-
|
|
191
|
-
(_all, head, body, tail) => `${head}${body}
|
|
192
|
-
${lines}${tail}`
|
|
193
|
-
),
|
|
227
|
+
source: `${withImports.slice(0, block.insertAt)}
|
|
228
|
+
${lines}${withImports.slice(block.insertAt)}`,
|
|
194
229
|
composed: true
|
|
195
230
|
};
|
|
196
231
|
}
|
|
@@ -211,13 +246,13 @@ function withShellSymbols(existing) {
|
|
|
211
246
|
];
|
|
212
247
|
const present = existing.split(",").map((symbol) => symbol.trim()).filter(Boolean);
|
|
213
248
|
const missing = wanted.filter(
|
|
214
|
-
(symbol) =>
|
|
249
|
+
(symbol) => present.every((entry) => entry.replace(/^type\s+/, "") !== symbol)
|
|
215
250
|
);
|
|
216
251
|
if (missing.length === 0) {
|
|
217
252
|
return existing;
|
|
218
253
|
}
|
|
219
254
|
const multiline = existing.includes("\n");
|
|
220
|
-
const all = [...present, ...missing].
|
|
255
|
+
const all = [...present, ...missing].toSorted((a, b) => a.localeCompare(b));
|
|
221
256
|
return multiline ? `
|
|
222
257
|
${all.join(",\n ")},
|
|
223
258
|
` : ` ${all.join(", ")} `;
|
|
@@ -384,17 +419,17 @@ function resolveMenuSlot(menu) {
|
|
|
384
419
|
}
|
|
385
420
|
return typeof menu === "string" && menu.length ? menu : void 0;
|
|
386
421
|
}
|
|
387
|
-
var PLATFORM_BOUND_CHORD_TOKENS = [
|
|
422
|
+
var PLATFORM_BOUND_CHORD_TOKENS = /* @__PURE__ */ new Set([
|
|
388
423
|
"cmd",
|
|
389
424
|
"command",
|
|
390
425
|
"ctrl",
|
|
391
426
|
"control",
|
|
392
427
|
"meta"
|
|
393
|
-
];
|
|
428
|
+
]);
|
|
394
429
|
function assertPlatformNeutralChord(shortcut) {
|
|
395
430
|
const tokens = shortcut.toLowerCase().split("+").map((token) => token.trim());
|
|
396
431
|
const bound = tokens.find(
|
|
397
|
-
(token) => PLATFORM_BOUND_CHORD_TOKENS.
|
|
432
|
+
(token) => PLATFORM_BOUND_CHORD_TOKENS.has(token)
|
|
398
433
|
);
|
|
399
434
|
if (bound) {
|
|
400
435
|
throw new Error(
|
|
@@ -1384,7 +1419,7 @@ import { provideProductIdentity } from '@loomweaver/plugin-sdk';
|
|
|
1384
1419
|
'status-bar' (bar) are what the scaffolded weaver targets. */
|
|
1385
1420
|
export const layout: ShellLayout = {
|
|
1386
1421
|
regions: [
|
|
1387
|
-
${renderRegions("
|
|
1422
|
+
${renderRegions(" ".repeat(4))}
|
|
1388
1423
|
],
|
|
1389
1424
|
};
|
|
1390
1425
|
|
|
@@ -1569,7 +1604,7 @@ var angularDistribution = {
|
|
|
1569
1604
|
return {
|
|
1570
1605
|
"src/main.ts": mainTs(),
|
|
1571
1606
|
"src/app/app.config.ts": appConfigTs(d),
|
|
1572
|
-
...d.withTests
|
|
1607
|
+
...d.withTests && { "src/app/app.config.spec.ts": appConfigSpec() },
|
|
1573
1608
|
"src/app/app.ts": appTs(),
|
|
1574
1609
|
"src/app/app.html": appHtml(),
|
|
1575
1610
|
"src/index.html": indexHtml(d),
|
|
@@ -1841,7 +1876,7 @@ import { ShellLayout } from '@loomweaver/shell';
|
|
|
1841
1876
|
|
|
1842
1877
|
export const ${l.propertyName}Layout: ShellLayout = {
|
|
1843
1878
|
regions: [
|
|
1844
|
-
${renderRegions("
|
|
1879
|
+
${renderRegions(" ".repeat(4))}
|
|
1845
1880
|
],
|
|
1846
1881
|
};
|
|
1847
1882
|
`;
|
|
@@ -1857,7 +1892,7 @@ var layout = {
|
|
|
1857
1892
|
// ../devkit/src/recipes/angular-weaver/amendments.ts
|
|
1858
1893
|
function weaverAmendments(input, where) {
|
|
1859
1894
|
const w = resolveWeaverInput(input);
|
|
1860
|
-
const directory = (where ?? "")
|
|
1895
|
+
const directory = normalizeProjectRoot(where ?? "");
|
|
1861
1896
|
if (!directory) {
|
|
1862
1897
|
return [];
|
|
1863
1898
|
}
|
|
@@ -1925,7 +1960,7 @@ function bool(values, name) {
|
|
|
1925
1960
|
return typeof value === "boolean" ? value : void 0;
|
|
1926
1961
|
}
|
|
1927
1962
|
function kebabCase(name) {
|
|
1928
|
-
return name.
|
|
1963
|
+
return name.replaceAll(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);
|
|
1929
1964
|
}
|
|
1930
1965
|
var ID_PATTERN = "^[a-z][a-z0-9]*(-[a-z0-9]+)*$";
|
|
1931
1966
|
var PLACEMENT_OPTIONS = [
|
|
@@ -2338,6 +2373,14 @@ function validateEntry(raw, index, known) {
|
|
|
2338
2373
|
}
|
|
2339
2374
|
];
|
|
2340
2375
|
}
|
|
2376
|
+
return [
|
|
2377
|
+
...validateEntryIdentity(raw, index),
|
|
2378
|
+
...validateCapabilities2(raw["capabilities"], index, known),
|
|
2379
|
+
...validateEntryMetadata(raw, index),
|
|
2380
|
+
...validateEntryKeys(raw, index)
|
|
2381
|
+
];
|
|
2382
|
+
}
|
|
2383
|
+
function validateEntryIdentity(raw, index) {
|
|
2341
2384
|
const findings = [];
|
|
2342
2385
|
if (typeof raw["id"] !== "string" || raw["id"].length === 0) {
|
|
2343
2386
|
findings.push({
|
|
@@ -2379,7 +2422,10 @@ function validateEntry(raw, index, known) {
|
|
|
2379
2422
|
path: at(index, "version")
|
|
2380
2423
|
});
|
|
2381
2424
|
}
|
|
2382
|
-
findings
|
|
2425
|
+
return findings;
|
|
2426
|
+
}
|
|
2427
|
+
function validateEntryMetadata(raw, index) {
|
|
2428
|
+
const findings = [];
|
|
2383
2429
|
if (raw["downloads"] !== void 0 && (typeof raw["downloads"] !== "number" || raw["downloads"] < 0)) {
|
|
2384
2430
|
findings.push({
|
|
2385
2431
|
level: "warning",
|
|
@@ -2404,6 +2450,10 @@ function validateEntry(raw, index, known) {
|
|
|
2404
2450
|
path: at(index, "repository")
|
|
2405
2451
|
});
|
|
2406
2452
|
}
|
|
2453
|
+
return findings;
|
|
2454
|
+
}
|
|
2455
|
+
function validateEntryKeys(raw, index) {
|
|
2456
|
+
const findings = [];
|
|
2407
2457
|
for (const key of Object.keys(raw)) {
|
|
2408
2458
|
if (!CATALOG_ENTRY_KEYS.includes(key)) {
|
|
2409
2459
|
findings.push({
|
|
@@ -2443,7 +2493,7 @@ function validateCatalog(catalog, known = KNOWN_CAPABILITIES) {
|
|
|
2443
2493
|
}
|
|
2444
2494
|
const findings = [];
|
|
2445
2495
|
const seen = /* @__PURE__ */ new Set();
|
|
2446
|
-
catalog.
|
|
2496
|
+
for (const [index, entry] of catalog.entries()) {
|
|
2447
2497
|
findings.push(...validateEntry(entry, index, known));
|
|
2448
2498
|
const id = isPlainObject(entry) ? entry["id"] : void 0;
|
|
2449
2499
|
if (typeof id === "string" && id.length > 0) {
|
|
@@ -2457,7 +2507,7 @@ function validateCatalog(catalog, known = KNOWN_CAPABILITIES) {
|
|
|
2457
2507
|
}
|
|
2458
2508
|
seen.add(id);
|
|
2459
2509
|
}
|
|
2460
|
-
}
|
|
2510
|
+
}
|
|
2461
2511
|
return findings;
|
|
2462
2512
|
}
|
|
2463
2513
|
|
|
@@ -2489,8 +2539,8 @@ function assign(flags, token, next) {
|
|
|
2489
2539
|
function parseArgs(argv) {
|
|
2490
2540
|
const flags = {};
|
|
2491
2541
|
let command = "";
|
|
2492
|
-
for (let
|
|
2493
|
-
const token = argv[
|
|
2542
|
+
for (let index = 0; index < argv.length; index++) {
|
|
2543
|
+
const token = argv[index];
|
|
2494
2544
|
if (token === "-h" || token === "--help") {
|
|
2495
2545
|
flags["help"] = true;
|
|
2496
2546
|
continue;
|
|
@@ -2500,8 +2550,8 @@ function parseArgs(argv) {
|
|
|
2500
2550
|
continue;
|
|
2501
2551
|
}
|
|
2502
2552
|
if (token.startsWith("--")) {
|
|
2503
|
-
if (assign(flags, token, argv[
|
|
2504
|
-
|
|
2553
|
+
if (assign(flags, token, argv[index + 1])) {
|
|
2554
|
+
index++;
|
|
2505
2555
|
}
|
|
2506
2556
|
continue;
|
|
2507
2557
|
}
|
|
@@ -2581,7 +2631,7 @@ function resolveBuildProject(workspace, target) {
|
|
|
2581
2631
|
`No project with a build target found in ${workspace.configFile ?? workspace.root}.`
|
|
2582
2632
|
);
|
|
2583
2633
|
}
|
|
2584
|
-
const inside = projects.filter((project) => contains(project.root, relativeTo(workspace.root, target))).
|
|
2634
|
+
const inside = projects.filter((project) => contains(project.root, relativeTo(workspace.root, target))).toSorted((a, b) => b.root.length - a.root.length);
|
|
2585
2635
|
if (inside.length > 0) {
|
|
2586
2636
|
return inside[0];
|
|
2587
2637
|
}
|
|
@@ -2633,8 +2683,15 @@ function contains(projectRoot, target) {
|
|
|
2633
2683
|
function relativeTo(root, target) {
|
|
2634
2684
|
return relative(root, resolve(target)).split(sep).join("/");
|
|
2635
2685
|
}
|
|
2686
|
+
function withoutTrailingSlashes(path) {
|
|
2687
|
+
let end = path.length;
|
|
2688
|
+
while (end > 0 && path[end - 1] === "/") {
|
|
2689
|
+
end -= 1;
|
|
2690
|
+
}
|
|
2691
|
+
return path.slice(0, end);
|
|
2692
|
+
}
|
|
2636
2693
|
function normalise(value) {
|
|
2637
|
-
return typeof value === "string" ? value.replace(/^\.?\/*/, "")
|
|
2694
|
+
return typeof value === "string" ? withoutTrailingSlashes(value.replace(/^\.?\/*/, "")) : "";
|
|
2638
2695
|
}
|
|
2639
2696
|
function asObject2(value) {
|
|
2640
2697
|
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
|
|
@@ -2656,7 +2713,7 @@ function planAmend(amendments2, target) {
|
|
|
2656
2713
|
return {
|
|
2657
2714
|
amendments: [],
|
|
2658
2715
|
remaining: [
|
|
2659
|
-
`No workspace was found above the target directory, so nothing could be wired here. Add it by hand, or generate inside the workspace: ${amendments2.map(describeAmendment).join(" \xB7 ")}`
|
|
2716
|
+
`No workspace was found above the target directory, so nothing could be wired here. Add it by hand, or generate inside the workspace: ${amendments2.map((amendment) => describeAmendment(amendment)).join(" \xB7 ")}`
|
|
2660
2717
|
]
|
|
2661
2718
|
};
|
|
2662
2719
|
}
|
|
@@ -2671,10 +2728,14 @@ var Amender = class {
|
|
|
2671
2728
|
constructor(workspace, target) {
|
|
2672
2729
|
this.workspace = workspace;
|
|
2673
2730
|
this.target = target;
|
|
2674
|
-
this.planned = [];
|
|
2675
|
-
this.remaining = [];
|
|
2676
|
-
this.configAdded = [];
|
|
2677
2731
|
}
|
|
2732
|
+
workspace;
|
|
2733
|
+
target;
|
|
2734
|
+
planned = [];
|
|
2735
|
+
remaining = [];
|
|
2736
|
+
configAdded = [];
|
|
2737
|
+
config;
|
|
2738
|
+
project;
|
|
2678
2739
|
plan(amendments2) {
|
|
2679
2740
|
for (const amendment of amendments2) {
|
|
2680
2741
|
this.planOne(amendment);
|
|
@@ -2972,7 +3033,7 @@ function planWrite(files, root) {
|
|
|
2972
3033
|
const absoluteRoot = resolve4(root);
|
|
2973
3034
|
const planned = [];
|
|
2974
3035
|
const conflicts = [];
|
|
2975
|
-
for (const path of Object.keys(files).
|
|
3036
|
+
for (const path of Object.keys(files).toSorted((a, b) => a.localeCompare(b))) {
|
|
2976
3037
|
const absolute = resolve4(absoluteRoot, path);
|
|
2977
3038
|
const inside = relative4(absoluteRoot, absolute);
|
|
2978
3039
|
if (inside.startsWith("..") || isAbsolute(inside)) {
|
|
@@ -3016,7 +3077,7 @@ function replaceSymlinkEntry(absolute) {
|
|
|
3016
3077
|
}
|
|
3017
3078
|
|
|
3018
3079
|
// src/lib/run.ts
|
|
3019
|
-
var VERSION = "0.7.
|
|
3080
|
+
var VERSION = "0.7.6";
|
|
3020
3081
|
function help() {
|
|
3021
3082
|
const commands = SCAFFOLDS.map((s) => ` ${s.name.padEnd(16)}${s.summary}`);
|
|
3022
3083
|
return [
|
|
@@ -3061,7 +3122,7 @@ function reportFindings(io, findings, strict) {
|
|
|
3061
3122
|
io.out("No findings.");
|
|
3062
3123
|
return 0;
|
|
3063
3124
|
}
|
|
3064
|
-
|
|
3125
|
+
for (const f of findings) io.err(`${f.level}: ${f.message}`);
|
|
3065
3126
|
if (findings.some((f) => f.level === "error")) {
|
|
3066
3127
|
return 1;
|
|
3067
3128
|
}
|
|
@@ -3134,12 +3195,16 @@ function reportAmendments(io, amend, done) {
|
|
|
3134
3195
|
);
|
|
3135
3196
|
for (const amendment of amend.amendments) {
|
|
3136
3197
|
io.out(` ${amendment.display}`);
|
|
3137
|
-
|
|
3198
|
+
for (const entry of amendment.added) {
|
|
3199
|
+
io.out(` + ${entry}`);
|
|
3200
|
+
}
|
|
3138
3201
|
}
|
|
3139
3202
|
}
|
|
3140
3203
|
if (amend.remaining.length > 0) {
|
|
3141
3204
|
io.out("Still to do by hand:");
|
|
3142
|
-
|
|
3205
|
+
for (const entry of amend.remaining) {
|
|
3206
|
+
io.out(` - ${entry}`);
|
|
3207
|
+
}
|
|
3143
3208
|
}
|
|
3144
3209
|
}
|
|
3145
3210
|
function scaffold(args, io) {
|
|
@@ -3157,12 +3222,16 @@ function scaffold(args, io) {
|
|
|
3157
3222
|
const amend = planAmend(amendmentsFor(descriptor, args), out);
|
|
3158
3223
|
if (boolFlag(args, "dry-run")) {
|
|
3159
3224
|
io.out(`Would write ${paths.length} file(s) into ${plan.root}:`);
|
|
3160
|
-
|
|
3225
|
+
for (const path of paths) {
|
|
3226
|
+
io.out(` ${path}`);
|
|
3227
|
+
}
|
|
3161
3228
|
if (plan.conflicts.length > 0) {
|
|
3162
3229
|
io.out(
|
|
3163
3230
|
`${plan.conflicts.length} of them already exist and would need --force:`
|
|
3164
3231
|
);
|
|
3165
|
-
plan.conflicts
|
|
3232
|
+
for (const path of plan.conflicts) {
|
|
3233
|
+
io.out(` ${path}`);
|
|
3234
|
+
}
|
|
3166
3235
|
}
|
|
3167
3236
|
reportAmendments(io, amend, false);
|
|
3168
3237
|
return 0;
|
|
@@ -3171,13 +3240,17 @@ function scaffold(args, io) {
|
|
|
3171
3240
|
io.err(
|
|
3172
3241
|
`${plan.conflicts.length} file(s) already exist; pass --force to overwrite:`
|
|
3173
3242
|
);
|
|
3174
|
-
plan.conflicts
|
|
3243
|
+
for (const path of plan.conflicts) {
|
|
3244
|
+
io.err(` ${path}`);
|
|
3245
|
+
}
|
|
3175
3246
|
return 1;
|
|
3176
3247
|
}
|
|
3177
3248
|
applyWrite(files, plan);
|
|
3178
3249
|
applyAmend(amend);
|
|
3179
3250
|
io.out(`Wrote ${paths.length} file(s) into ${plan.root}:`);
|
|
3180
|
-
|
|
3251
|
+
for (const path of paths) {
|
|
3252
|
+
io.out(` ${path}`);
|
|
3253
|
+
}
|
|
3181
3254
|
reportAmendments(io, amend, true);
|
|
3182
3255
|
return 0;
|
|
3183
3256
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@loomweaver/cli",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.6",
|
|
4
4
|
"description": "LoomWeaver scaffolding CLI: generates weavers, distributions and integrations into any project — no Nx workspace, no LoomWeaver checkout and no AI assistant required.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"loomweaver",
|