outfitter 0.3.4 → 0.4.0
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/actions/add.d.ts +1 -1
- package/dist/actions/add.js +6 -5
- package/dist/actions/check-automation.d.ts +4 -2
- package/dist/actions/check-automation.js +13 -9
- package/dist/actions/check.d.ts +2 -2
- package/dist/actions/check.js +6 -6
- package/dist/actions/demo.d.ts +1 -1
- package/dist/actions/demo.js +3 -4
- package/dist/actions/docs.d.ts +7 -7
- package/dist/actions/docs.js +12 -13
- package/dist/actions/doctor.d.ts +1 -1
- package/dist/actions/doctor.js +8 -7
- package/dist/actions/init.d.ts +9 -7
- package/dist/actions/init.js +12 -10
- package/dist/actions/scaffold.d.ts +1 -1
- package/dist/actions/scaffold.js +14 -12
- package/dist/actions/shared.d.ts +1 -20
- package/dist/actions/shared.js +1 -5
- package/dist/actions/upgrade.d.ts +10 -2
- package/dist/actions/upgrade.js +15 -8
- package/dist/actions.js +51 -48
- package/dist/cli.js +51 -48
- package/dist/commands/add.js +4 -3
- package/dist/commands/check-action-ceremony.d.ts +1 -1
- package/dist/commands/check-action-ceremony.js +2 -2
- package/dist/commands/check-action-registry.d.ts +52 -0
- package/dist/commands/check-action-registry.js +13 -0
- package/dist/commands/check-docs-sentinel.d.ts +1 -1
- package/dist/commands/check-docs-sentinel.js +2 -2
- package/dist/commands/check-orchestrator.d.ts +1 -1
- package/dist/commands/check-orchestrator.js +2 -2
- package/dist/commands/check-preset-versions.d.ts +4 -2
- package/dist/commands/check-preset-versions.js +8 -3
- package/dist/commands/check-publish-guardrails.d.ts +1 -1
- package/dist/commands/check-publish-guardrails.js +2 -2
- package/dist/commands/check-surface-map-format.d.ts +1 -1
- package/dist/commands/check-surface-map-format.js +2 -2
- package/dist/commands/check-surface-map.d.ts +1 -1
- package/dist/commands/check-surface-map.js +2 -2
- package/dist/commands/check-tsdoc.d.ts +2 -2
- package/dist/commands/check.js +3 -3
- package/dist/commands/demo.d.ts +1 -1
- package/dist/commands/demo.js +1 -1
- package/dist/commands/docs-api.d.ts +3 -3
- package/dist/commands/docs-api.js +2 -2
- package/dist/commands/docs-export.d.ts +2 -2
- package/dist/commands/docs-export.js +2 -2
- package/dist/commands/docs-list.d.ts +2 -2
- package/dist/commands/docs-list.js +2 -2
- package/dist/commands/docs-search.d.ts +2 -2
- package/dist/commands/docs-search.js +2 -2
- package/dist/commands/docs-show.d.ts +2 -2
- package/dist/commands/docs-show.js +2 -2
- package/dist/commands/doctor.js +6 -5
- package/dist/commands/init-execution.d.ts +5 -5
- package/dist/commands/init-execution.js +6 -4
- package/dist/commands/init-option-resolution.d.ts +3 -3
- package/dist/commands/init-option-resolution.js +1 -1
- package/dist/commands/init-output.d.ts +5 -5
- package/dist/commands/init-output.js +3 -3
- package/dist/commands/init.d.ts +5 -5
- package/dist/commands/init.js +9 -9
- package/dist/commands/scaffold-output.js +3 -3
- package/dist/commands/scaffold-planning.d.ts +9 -10
- package/dist/commands/scaffold-planning.js +6 -4
- package/dist/commands/scaffold.js +12 -10
- package/dist/commands/shared-deps.js +2 -2
- package/dist/commands/upgrade-codemod-builder.d.ts +45 -0
- package/dist/commands/upgrade-codemod-builder.js +14 -0
- package/dist/commands/upgrade-output.js +2 -2
- package/dist/commands/upgrade-workspace.js +5 -1
- package/dist/commands/upgrade.js +9 -5
- package/dist/create/index.d.ts +1 -1
- package/dist/create/planner.js +1 -1
- package/dist/engine/blocks.d.ts +2 -2
- package/dist/engine/blocks.js +5 -4
- package/dist/engine/config.d.ts +2 -2
- package/dist/engine/config.js +6 -5
- package/dist/engine/dependency-versions.d.ts +11 -3
- package/dist/engine/dependency-versions.js +6 -2
- package/dist/engine/executor.d.ts +2 -2
- package/dist/engine/executor.js +23 -10
- package/dist/engine/index.d.ts +8 -9
- package/dist/engine/index.js +1 -5
- package/dist/engine/package-json.d.ts +3 -0
- package/dist/engine/package-json.js +10 -0
- package/dist/engine/post-scaffold.js +1 -1
- package/dist/engine/preset.d.ts +3 -3
- package/dist/engine/preset.js +4 -2
- package/dist/engine/render-plan.js +2 -2
- package/dist/engine/types.d.ts +1 -1
- package/dist/engine/workspace.d.ts +2 -2
- package/dist/engine/workspace.js +3 -2
- package/dist/index.d.ts +7 -7
- package/dist/manifest.js +1 -1
- package/dist/output-mode.d.ts +2 -2
- package/dist/output-mode.js +2 -4
- package/dist/scaffold-e2e/cli.d.ts +19 -0
- package/dist/scaffold-e2e/cli.js +14 -0
- package/dist/scaffold-e2e/config.d.ts +6 -0
- package/dist/scaffold-e2e/config.js +14 -0
- package/dist/scaffold-e2e/runner.d.ts +29 -0
- package/dist/scaffold-e2e/runner.js +17 -0
- package/dist/scaffold-e2e/template-guardrails.d.ts +25 -0
- package/dist/scaffold-e2e/template-guardrails.js +183 -0
- package/dist/scaffold-e2e/workspace.d.ts +27 -0
- package/dist/scaffold-e2e/workspace.js +18 -0
- package/dist/scripts/scaffold-e2e.js +78 -0
- package/dist/shared/{outfitter-qsrx7m4w.js → outfitter-00wxeg2g.js} +8 -8
- package/dist/shared/{outfitter-ex8gn945.js → outfitter-0cspz333.js} +4 -6
- package/dist/shared/{outfitter-rp89dafm.js → outfitter-0xp447gf.js} +55 -8
- package/dist/shared/outfitter-0zs8makw.js +94 -0
- package/dist/shared/{outfitter-5d9wbzhh.d.ts → outfitter-11r5ny73.d.ts} +2 -2
- package/dist/shared/{outfitter-gyayfx5r.js → outfitter-18s82np1.js} +1 -1
- package/dist/shared/{outfitter-954y4mzx.d.ts → outfitter-1dekqnaw.d.ts} +1 -1
- package/dist/shared/{outfitter-6t7xeyg1.js → outfitter-1t8gjzw6.js} +91 -3
- package/dist/shared/{outfitter-tqznjgbm.js → outfitter-23159bef.js} +6 -3
- package/dist/shared/{outfitter-y6ee0k45.d.ts → outfitter-232ean4v.d.ts} +1 -1
- package/dist/shared/{outfitter-3rcrvva8.js → outfitter-247et71q.js} +8 -8
- package/dist/shared/{outfitter-xs94pkfe.js → outfitter-3f261xh0.js} +5 -7
- package/dist/shared/outfitter-4bs5a2n4.js +31 -0
- package/dist/shared/{outfitter-76k25svs.js → outfitter-4c4q091c.js} +6 -28
- package/dist/shared/{outfitter-738z4c37.js → outfitter-4t818mq5.js} +21 -9
- package/dist/shared/{outfitter-4s9meh3j.js → outfitter-4w9sc6bw.js} +24 -0
- package/dist/shared/outfitter-5gaptj9b.js +83 -0
- package/dist/shared/{outfitter-2ysjerp6.d.ts → outfitter-5rc4hxdn.d.ts} +2 -2
- package/dist/shared/{outfitter-ttjr95y9.js → outfitter-7krhbg3b.js} +3 -3
- package/dist/shared/{outfitter-7n7vsz95.js → outfitter-7t7ces1x.js} +1 -42
- package/dist/shared/{outfitter-gdc7b7de.d.ts → outfitter-8231g70k.d.ts} +1 -1
- package/dist/shared/{outfitter-yhb23pjc.js → outfitter-8jd1sak0.js} +4 -4
- package/dist/shared/{outfitter-wkt0a0ra.js → outfitter-93e1shd4.js} +4 -6
- package/dist/shared/{outfitter-wyg1tpp5.d.ts → outfitter-a93yanw6.d.ts} +1 -1
- package/dist/shared/{outfitter-mstr60zz.js → outfitter-aa5nzw14.js} +47 -22
- package/dist/shared/{outfitter-fxry5n58.js → outfitter-b05mvbmx.js} +4 -4
- package/dist/shared/{outfitter-1fy7byz5.js → outfitter-bsjq8gkk.js} +6 -4
- package/dist/shared/{outfitter-ssrtakh3.js → outfitter-c50y6yr3.js} +4 -4
- package/dist/shared/{outfitter-cyvr4r8d.d.ts → outfitter-crxe5gth.d.ts} +4 -0
- package/dist/shared/{outfitter-fj2v5ffz.js → outfitter-d5kz9x7g.js} +1 -1
- package/dist/shared/{outfitter-dmfac1w9.js → outfitter-dna8exj2.js} +19 -10
- package/dist/shared/{outfitter-940h0x7b.js → outfitter-e44qcs0w.js} +3 -3
- package/dist/shared/{outfitter-r2awqszh.d.ts → outfitter-e5x0ybqt.d.ts} +12 -3
- package/dist/shared/{outfitter-3tx3adgj.js → outfitter-ez7qffv5.js} +8 -6
- package/dist/shared/outfitter-fgrqt6aq.js +179 -0
- package/dist/shared/outfitter-fhahf9f3.d.ts +14 -0
- package/dist/shared/{outfitter-c7sbs7es.js → outfitter-g6r9avgz.js} +3 -3
- package/dist/shared/{outfitter-ssynegbs.js → outfitter-ga59fa45.js} +1 -1
- package/dist/shared/{outfitter-tavatb5p.js → outfitter-gna739c3.js} +86 -31
- package/dist/shared/{outfitter-nxvjxrmw.d.ts → outfitter-grt5ngqq.d.ts} +1 -1
- package/dist/shared/{outfitter-58rn1sj1.d.ts → outfitter-gsjbcta2.d.ts} +1 -1
- package/dist/shared/{outfitter-q1g58t85.js → outfitter-gvpwpqnc.js} +0 -1
- package/dist/shared/{outfitter-x39awx8g.js → outfitter-hr4cvmjy.js} +47 -25
- package/dist/shared/{outfitter-xwzjgswj.js → outfitter-hw9f0zq9.js} +57 -21
- package/dist/shared/{outfitter-ksyvwmb5.js → outfitter-jhpcjeg1.js} +5 -5
- package/dist/shared/outfitter-kc46jq69.d.ts +12 -0
- package/dist/shared/{outfitter-px5sv5gn.js → outfitter-ksg34wka.js} +5 -5
- package/dist/shared/{outfitter-wrcqq29p.js → outfitter-n63ygpv3.js} +30 -23
- package/dist/shared/{outfitter-qsd5638j.js → outfitter-n9jp1abt.js} +16 -40
- package/dist/shared/{outfitter-d0kqashd.d.ts → outfitter-nhft74pe.d.ts} +4 -2
- package/dist/shared/{outfitter-8kmak0wc.d.ts → outfitter-nx1sywpb.d.ts} +1 -1
- package/dist/shared/{outfitter-5r6q2749.d.ts → outfitter-pw74st5t.d.ts} +1 -1
- package/dist/shared/{outfitter-h0wmtxw8.d.ts → outfitter-qka1skyw.d.ts} +1 -1
- package/dist/shared/{outfitter-6mpkh3zn.js → outfitter-qps83547.js} +30 -23
- package/dist/shared/outfitter-qzd5djgx.js +88 -0
- package/dist/shared/{outfitter-hf5bj2gq.js → outfitter-sh015v8k.js} +4 -4
- package/dist/shared/{outfitter-ypcvwg1s.js → outfitter-srznx3hj.js} +1 -1
- package/dist/shared/{outfitter-n0ed012k.js → outfitter-ssq33ym3.js} +8 -8
- package/dist/shared/outfitter-sxf8jjjn.js +7 -0
- package/dist/shared/{outfitter-p2wn07b7.js → outfitter-t535h0mw.js} +1 -1
- package/dist/shared/{outfitter-znbqe5zy.d.ts → outfitter-t8dg4tg5.d.ts} +1 -1
- package/dist/shared/{outfitter-ydw7x6bh.js → outfitter-t8mvabed.js} +1 -1
- package/dist/shared/{outfitter-6ddf91vh.js → outfitter-t9xkn37g.js} +11 -12
- package/dist/shared/{outfitter-x4cc5xsq.js → outfitter-wmgzyymq.js} +4 -4
- package/dist/shared/outfitter-wna6gp2t.js +56 -0
- package/dist/shared/outfitter-x0r7mfvy.js +142 -0
- package/dist/shared/{outfitter-b9cpnr7e.js → outfitter-x4f8v5vf.js} +1 -1
- package/dist/shared/{outfitter-x8w5sjnd.d.ts → outfitter-x6322tjp.d.ts} +1 -1
- package/dist/shared/{outfitter-6rtcemk7.d.ts → outfitter-xa4915yp.d.ts} +3 -2
- package/dist/shared/{outfitter-2z61gp5w.js → outfitter-xg5yryp2.js} +1 -1
- package/dist/shared/{outfitter-rdpw2sbp.d.ts → outfitter-xn5km042.d.ts} +6 -0
- package/dist/shared/{outfitter-cyhzstz0.js → outfitter-xqr4fp1n.js} +4 -4
- package/dist/shared/outfitter-z6tg0swx.js +87 -0
- package/dist/shared/{outfitter-1gmrtapz.js → outfitter-zmzrsvcn.js} +17 -21
- package/dist/shared/{outfitter-8ggmja91.js → outfitter-zqj1nte1.js} +66 -67
- package/dist/targets/index.d.ts +2 -2
- package/dist/targets/registry.d.ts +2 -2
- package/dist/targets/registry.js +13 -1
- package/dist/targets/types.d.ts +1 -1
- package/package.json +85 -39
- package/dist/actions/docs-output-mode.d.ts +0 -4
- package/dist/actions/docs-output-mode.js +0 -8
- package/dist/engine/template.d.ts +0 -4
- package/dist/engine/template.js +0 -34
- package/dist/shared/outfitter-7r12fj7f.js +0 -30
- package/dist/shared/outfitter-a79xrm12.d.ts +0 -17
- package/dist/shared/outfitter-ec83h4v2.js +0 -17
- package/dist/shared/outfitter-fbvfd5zq.d.ts +0 -13
- package/dist/shared/outfitter-yywcypw8.js +0 -53
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
resolveStructuredOutputMode
|
|
4
|
+
} from "./outfitter-sxf8jjjn.js";
|
|
5
|
+
|
|
6
|
+
// apps/outfitter/src/commands/check-action-registry.ts
|
|
7
|
+
import { existsSync, readdirSync, readFileSync } from "fs";
|
|
8
|
+
import { join, relative, resolve } from "path";
|
|
9
|
+
import { Result } from "@outfitter/contracts";
|
|
10
|
+
var COMMANDS_RELATIVE_DIR = "apps/outfitter/src/commands";
|
|
11
|
+
var ACTIONS_RELATIVE_DIR = "apps/outfitter/src/actions";
|
|
12
|
+
var REGISTRY_RELATIVE_PATH = "apps/outfitter/src/actions.ts";
|
|
13
|
+
var LOCAL_REGISTRY_RELATIVE_PATH = "src/actions.ts";
|
|
14
|
+
var LOCAL_COMMANDS_RELATIVE_DIR = "src/commands";
|
|
15
|
+
|
|
16
|
+
class CheckActionRegistryError extends Error {
|
|
17
|
+
_tag = "CheckActionRegistryError";
|
|
18
|
+
constructor(message, options) {
|
|
19
|
+
super(message, options);
|
|
20
|
+
this.name = "CheckActionRegistryError";
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function extractCommandImports(content) {
|
|
24
|
+
const imports = new Set;
|
|
25
|
+
const importPattern = /from\s+["']\.\.\/commands\/([^"']+)\.(js|ts)["']/g;
|
|
26
|
+
let match;
|
|
27
|
+
while ((match = importPattern.exec(content)) !== null) {
|
|
28
|
+
const basename = match[1];
|
|
29
|
+
if (basename) {
|
|
30
|
+
imports.add(`${basename}.ts`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return imports;
|
|
34
|
+
}
|
|
35
|
+
function parseNamedImportSymbols(namedImports) {
|
|
36
|
+
const withoutComments = namedImports.replace(/\/\*[\s\S]*?\*\//g, "").replace(/\/\/.*$/gm, "");
|
|
37
|
+
return withoutComments.split(",").map((raw) => raw.trim()).filter((raw) => raw.length > 0).map((raw) => {
|
|
38
|
+
const withoutType = raw.replace(/^type\s+/, "").trim();
|
|
39
|
+
if (!withoutType) {
|
|
40
|
+
return "";
|
|
41
|
+
}
|
|
42
|
+
const aliased = withoutType.match(/^([A-Za-z_$][A-Za-z0-9_$]*)\s+as\s+([A-Za-z_$][A-Za-z0-9_$]*)$/);
|
|
43
|
+
return aliased?.[2] ?? withoutType;
|
|
44
|
+
}).filter((symbol) => symbol.length > 0);
|
|
45
|
+
}
|
|
46
|
+
function extractRegisteredActionFiles(registryContent) {
|
|
47
|
+
const importMap = new Map;
|
|
48
|
+
const importPattern = /import\s+\{([^}]+)\}\s+from\s+["']\.\/actions\/([^"']+)\.(js|ts)["']/g;
|
|
49
|
+
let match;
|
|
50
|
+
while ((match = importPattern.exec(registryContent)) !== null) {
|
|
51
|
+
const symbols = parseNamedImportSymbols(match[1]);
|
|
52
|
+
const file = `${match[2]}.ts`;
|
|
53
|
+
for (const sym of symbols) {
|
|
54
|
+
importMap.set(sym, file);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
const addPattern = /\.add\((\w+)\)/g;
|
|
58
|
+
const registeredFiles = new Set;
|
|
59
|
+
while ((match = addPattern.exec(registryContent)) !== null) {
|
|
60
|
+
const symbol = match[1];
|
|
61
|
+
const file = importMap.get(symbol);
|
|
62
|
+
if (file) {
|
|
63
|
+
registeredFiles.add(file);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return registeredFiles;
|
|
67
|
+
}
|
|
68
|
+
function listTsFiles(dir, rootDir = dir) {
|
|
69
|
+
const files = [];
|
|
70
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
71
|
+
if (entry.name.startsWith("__")) {
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
const entryPath = resolve(dir, entry.name);
|
|
75
|
+
if (entry.isDirectory()) {
|
|
76
|
+
files.push(...listTsFiles(entryPath, rootDir));
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
if (!entry.isFile()) {
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
if (entry.name.endsWith(".ts") && !entry.name.endsWith(".test.ts")) {
|
|
83
|
+
files.push(relative(rootDir, entryPath).replaceAll("\\", "/"));
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return files.toSorted();
|
|
87
|
+
}
|
|
88
|
+
function resolveWorkspaceRoot(cwd) {
|
|
89
|
+
const resolved = resolve(cwd);
|
|
90
|
+
if (existsSync(resolve(resolved, REGISTRY_RELATIVE_PATH))) {
|
|
91
|
+
return resolved;
|
|
92
|
+
}
|
|
93
|
+
if (existsSync(resolve(resolved, LOCAL_REGISTRY_RELATIVE_PATH)) && existsSync(resolve(resolved, LOCAL_COMMANDS_RELATIVE_DIR))) {
|
|
94
|
+
const parentWorkspace = resolve(resolved, "../..");
|
|
95
|
+
if (existsSync(resolve(parentWorkspace, REGISTRY_RELATIVE_PATH))) {
|
|
96
|
+
return parentWorkspace;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
let current = resolved;
|
|
100
|
+
while (true) {
|
|
101
|
+
if (existsSync(resolve(current, REGISTRY_RELATIVE_PATH))) {
|
|
102
|
+
return current;
|
|
103
|
+
}
|
|
104
|
+
const parent = resolve(current, "..");
|
|
105
|
+
if (parent === current) {
|
|
106
|
+
return resolved;
|
|
107
|
+
}
|
|
108
|
+
current = parent;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
async function runCheckActionRegistry(options) {
|
|
112
|
+
try {
|
|
113
|
+
const workspaceRoot = resolveWorkspaceRoot(options.cwd);
|
|
114
|
+
const commandsDir = resolve(workspaceRoot, COMMANDS_RELATIVE_DIR);
|
|
115
|
+
const actionsDir = resolve(workspaceRoot, ACTIONS_RELATIVE_DIR);
|
|
116
|
+
const registryPath = resolve(workspaceRoot, REGISTRY_RELATIVE_PATH);
|
|
117
|
+
const registryContent = readFileSync(registryPath, "utf-8");
|
|
118
|
+
const registeredActionFiles = extractRegisteredActionFiles(registryContent);
|
|
119
|
+
const referencedCommands = new Set;
|
|
120
|
+
for (const actionFile of registeredActionFiles) {
|
|
121
|
+
const filePath = resolve(actionsDir, actionFile);
|
|
122
|
+
const content = readFileSync(filePath, "utf-8");
|
|
123
|
+
const imports = extractCommandImports(content);
|
|
124
|
+
for (const imp of imports) {
|
|
125
|
+
referencedCommands.add(imp);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
const commandFiles = listTsFiles(commandsDir);
|
|
129
|
+
const registered = [];
|
|
130
|
+
const unregistered = [];
|
|
131
|
+
for (const file of commandFiles) {
|
|
132
|
+
const relativePath = join(COMMANDS_RELATIVE_DIR, file);
|
|
133
|
+
if (referencedCommands.has(file)) {
|
|
134
|
+
registered.push(relativePath);
|
|
135
|
+
} else {
|
|
136
|
+
unregistered.push(relativePath);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return Result.ok({
|
|
140
|
+
actionsDir,
|
|
141
|
+
commandsDir,
|
|
142
|
+
ok: unregistered.length === 0,
|
|
143
|
+
registered,
|
|
144
|
+
registeredCount: registered.length,
|
|
145
|
+
totalCommands: commandFiles.length,
|
|
146
|
+
unregistered,
|
|
147
|
+
unregisteredCount: unregistered.length
|
|
148
|
+
});
|
|
149
|
+
} catch (error) {
|
|
150
|
+
const message = error instanceof Error ? error.message : "Failed to scan action registry";
|
|
151
|
+
return Result.err(new CheckActionRegistryError(message, { cause: error }));
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
async function printCheckActionRegistryResult(result, options) {
|
|
155
|
+
const structuredMode = resolveStructuredOutputMode(options?.mode);
|
|
156
|
+
if (structuredMode) {
|
|
157
|
+
const serialized = structuredMode === "json" ? JSON.stringify(result, null, 2) : JSON.stringify(result);
|
|
158
|
+
process.stdout.write(`${serialized}
|
|
159
|
+
`);
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
process.stdout.write(`[action-registry] scanned ${result.totalCommands} command files in ${result.commandsDir}
|
|
163
|
+
`);
|
|
164
|
+
process.stdout.write(`[action-registry] ${result.registeredCount} registered, ${result.unregisteredCount} unregistered
|
|
165
|
+
`);
|
|
166
|
+
if (result.unregistered.length === 0) {
|
|
167
|
+
process.stdout.write(`[action-registry] all command files are referenced by action definitions
|
|
168
|
+
`);
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
process.stderr.write(`[action-registry] unregistered command files:
|
|
172
|
+
`);
|
|
173
|
+
for (const file of result.unregistered) {
|
|
174
|
+
process.stderr.write(` - ${file}
|
|
175
|
+
`);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export { CheckActionRegistryError, runCheckActionRegistry, printCheckActionRegistryResult };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { OutputMode } from "@outfitter/cli/types";
|
|
2
|
+
type StructuredOutputMode = Extract<OutputMode, "json" | "jsonl">;
|
|
3
|
+
/** Output modes resolvable from CLI flags and env vars. */
|
|
4
|
+
type CliOutputMode = "human" | "json" | "jsonl";
|
|
5
|
+
/**
|
|
6
|
+
* Narrow an output mode to its structured subset (`"json"` | `"jsonl"`).
|
|
7
|
+
*
|
|
8
|
+
* Returns `undefined` when the mode is not machine-readable (e.g., `"human"`,
|
|
9
|
+
* `"tree"`, `"table"`) or when `mode` is `undefined`.
|
|
10
|
+
* This is a pure type-narrowing helper — it does NOT check env vars.
|
|
11
|
+
* Use `resolveOutputMode()` from `@outfitter/cli/query` for full resolution.
|
|
12
|
+
*/
|
|
13
|
+
declare function resolveStructuredOutputMode(mode?: OutputMode): StructuredOutputMode | undefined;
|
|
14
|
+
export { StructuredOutputMode, CliOutputMode, resolveStructuredOutputMode };
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
} from "./outfitter-svts4wk2.js";
|
|
8
8
|
import {
|
|
9
9
|
resolveStructuredOutputMode
|
|
10
|
-
} from "./outfitter-
|
|
10
|
+
} from "./outfitter-sxf8jjjn.js";
|
|
11
11
|
|
|
12
12
|
// apps/outfitter/src/commands/docs-show.ts
|
|
13
13
|
import { readFile } from "fs/promises";
|
|
@@ -63,7 +63,7 @@ async function printDocsShowResults(result, options) {
|
|
|
63
63
|
});
|
|
64
64
|
process.stdout.write(filtered);
|
|
65
65
|
} else {
|
|
66
|
-
await output(result,
|
|
66
|
+
await output(result, structuredMode);
|
|
67
67
|
}
|
|
68
68
|
return;
|
|
69
69
|
}
|
|
@@ -86,7 +86,7 @@ async function printDocsShowResults(result, options) {
|
|
|
86
86
|
lines.push("-".repeat(60));
|
|
87
87
|
lines.push("");
|
|
88
88
|
lines.push(result.content);
|
|
89
|
-
await output(lines,
|
|
89
|
+
await output(lines, "human");
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
export { runDocsShow, printDocsShowResults };
|
|
@@ -3,23 +3,63 @@ import {
|
|
|
3
3
|
deriveBinName,
|
|
4
4
|
deriveProjectName,
|
|
5
5
|
executePlan,
|
|
6
|
+
getPresetsBaseDir,
|
|
6
7
|
isPathWithin,
|
|
7
8
|
resolveAuthor,
|
|
8
9
|
resolveYear,
|
|
9
10
|
scaffoldWorkspaceRoot,
|
|
10
11
|
validateProjectDirectoryName
|
|
11
|
-
} from "./outfitter-
|
|
12
|
-
import {
|
|
13
|
-
runPostScaffold
|
|
14
|
-
} from "./outfitter-4s9meh3j.js";
|
|
12
|
+
} from "./outfitter-gvpwpqnc.js";
|
|
15
13
|
import {
|
|
16
14
|
OperationCollector
|
|
17
15
|
} from "./outfitter-1h7k8xxt.js";
|
|
16
|
+
import {
|
|
17
|
+
runPostScaffold
|
|
18
|
+
} from "./outfitter-4w9sc6bw.js";
|
|
18
19
|
|
|
19
20
|
// apps/outfitter/src/commands/init-execution.ts
|
|
20
|
-
import { existsSync } from "fs";
|
|
21
|
+
import { existsSync, readdirSync } from "fs";
|
|
21
22
|
import { basename, join, resolve } from "path";
|
|
22
23
|
import { Result } from "@outfitter/contracts";
|
|
24
|
+
function discoverPresetExamples() {
|
|
25
|
+
const examplesRoot = join(getPresetsBaseDir(), "_examples");
|
|
26
|
+
if (!existsSync(examplesRoot)) {
|
|
27
|
+
return new Map;
|
|
28
|
+
}
|
|
29
|
+
const examplesByPreset = new Map;
|
|
30
|
+
for (const entry of readdirSync(examplesRoot, { withFileTypes: true })) {
|
|
31
|
+
if (!entry.isDirectory()) {
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
const separatorIndex = entry.name.indexOf("-");
|
|
35
|
+
if (separatorIndex <= 0 || separatorIndex >= entry.name.length - 1) {
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
const preset = entry.name.slice(0, separatorIndex);
|
|
39
|
+
const example = entry.name.slice(separatorIndex + 1);
|
|
40
|
+
const existing = examplesByPreset.get(preset) ?? [];
|
|
41
|
+
existing.push(example);
|
|
42
|
+
examplesByPreset.set(preset, existing);
|
|
43
|
+
}
|
|
44
|
+
return new Map([...examplesByPreset.entries()].map(([preset, examples]) => [
|
|
45
|
+
preset,
|
|
46
|
+
[...new Set(examples)].toSorted()
|
|
47
|
+
]));
|
|
48
|
+
}
|
|
49
|
+
function getPresetExamples() {
|
|
50
|
+
return discoverPresetExamples();
|
|
51
|
+
}
|
|
52
|
+
function validateExample(preset, example) {
|
|
53
|
+
const presetExamples = getPresetExamples();
|
|
54
|
+
const available = presetExamples.get(preset);
|
|
55
|
+
if (!available || available.length === 0) {
|
|
56
|
+
return Result.err(`Preset '${preset}' has no available examples. ` + `Only these presets support --example: ${[...presetExamples.keys()].join(", ")}`);
|
|
57
|
+
}
|
|
58
|
+
if (!available.includes(example)) {
|
|
59
|
+
return Result.err(`Unknown example '${example}' for preset '${preset}'. ` + `Available examples: ${available.join(", ")}`);
|
|
60
|
+
}
|
|
61
|
+
return Result.ok(`_examples/${preset}-${example}`);
|
|
62
|
+
}
|
|
23
63
|
function toExecutionErrorMessage(error) {
|
|
24
64
|
if (error instanceof Error) {
|
|
25
65
|
return error.message;
|
|
@@ -47,6 +87,13 @@ function buildInitPlan(target, input, projectDir, resolvedBinName) {
|
|
|
47
87
|
includeTooling: input.includeTooling,
|
|
48
88
|
overlayBaseTemplate: true
|
|
49
89
|
},
|
|
90
|
+
...input.exampleOverlayDir ? [
|
|
91
|
+
{
|
|
92
|
+
type: "copy-example-overlay",
|
|
93
|
+
preset: input.exampleOverlayDir,
|
|
94
|
+
targetDir: projectDir
|
|
95
|
+
}
|
|
96
|
+
] : [],
|
|
50
97
|
{ type: "inject-shared-config" },
|
|
51
98
|
...input.local ? [{ type: "rewrite-local-dependencies", mode: "workspace" }] : [],
|
|
52
99
|
...blocks.length > 0 ? [{ type: "add-blocks", blocks }] : []
|
|
@@ -54,38 +101,46 @@ function buildInitPlan(target, input, projectDir, resolvedBinName) {
|
|
|
54
101
|
};
|
|
55
102
|
}
|
|
56
103
|
async function executeInitPipeline(input, target, options) {
|
|
57
|
-
|
|
58
|
-
if (input.
|
|
104
|
+
let resolvedInput = input;
|
|
105
|
+
if (input.example) {
|
|
106
|
+
const exampleResult = validateExample(input.preset, input.example);
|
|
107
|
+
if (exampleResult.isErr()) {
|
|
108
|
+
return Result.err(exampleResult.error);
|
|
109
|
+
}
|
|
110
|
+
resolvedInput = { ...input, exampleOverlayDir: exampleResult.value };
|
|
111
|
+
}
|
|
112
|
+
const projectName = deriveProjectName(resolvedInput.packageName);
|
|
113
|
+
if (resolvedInput.structure === "workspace") {
|
|
59
114
|
const invalidProjectName = validateProjectDirectoryName(projectName);
|
|
60
115
|
if (invalidProjectName) {
|
|
61
116
|
return Result.err(`Invalid workspace project name '${projectName}': ${invalidProjectName}`);
|
|
62
117
|
}
|
|
63
118
|
}
|
|
64
119
|
const collector = options.dryRun ? new OperationCollector : undefined;
|
|
65
|
-
const projectBaseDir = resolve(
|
|
120
|
+
const projectBaseDir = resolve(resolvedInput.rootDir, target.placement);
|
|
66
121
|
const resolvedProjectDir = resolve(projectBaseDir, projectName);
|
|
67
|
-
if (
|
|
122
|
+
if (resolvedInput.structure === "workspace" && !isPathWithin(projectBaseDir, resolvedProjectDir)) {
|
|
68
123
|
return Result.err(`Invalid workspace project name '${projectName}': path escapes '${projectBaseDir}'`);
|
|
69
124
|
}
|
|
70
|
-
const projectDir =
|
|
71
|
-
if (
|
|
72
|
-
if (existsSync(join(
|
|
73
|
-
return Result.err(`Directory '${
|
|
125
|
+
const projectDir = resolvedInput.structure === "workspace" ? resolvedProjectDir : resolvedInput.rootDir;
|
|
126
|
+
if (resolvedInput.structure === "single") {
|
|
127
|
+
if (existsSync(join(resolvedInput.rootDir, "package.json")) && !options.force) {
|
|
128
|
+
return Result.err(`Directory '${resolvedInput.rootDir}' already has a package.json. Use --force to overwrite, or use 'outfitter add' for existing projects.`);
|
|
74
129
|
}
|
|
75
130
|
} else {
|
|
76
|
-
const workspaceName =
|
|
77
|
-
const workspacePackageJsonPath = join(
|
|
131
|
+
const workspaceName = resolvedInput.workspaceName ?? basename(resolvedInput.rootDir);
|
|
132
|
+
const workspacePackageJsonPath = join(resolvedInput.rootDir, "package.json");
|
|
78
133
|
if (options.dryRun) {
|
|
79
134
|
if (existsSync(workspacePackageJsonPath) && !options.force) {
|
|
80
|
-
return Result.err(`Directory '${
|
|
135
|
+
return Result.err(`Directory '${resolvedInput.rootDir}' already has a package.json. Use --force to overwrite.`);
|
|
81
136
|
}
|
|
82
137
|
collector?.add({
|
|
83
138
|
type: "dir-create",
|
|
84
|
-
path: join(
|
|
139
|
+
path: join(resolvedInput.rootDir, "apps")
|
|
85
140
|
});
|
|
86
141
|
collector?.add({
|
|
87
142
|
type: "dir-create",
|
|
88
|
-
path: join(
|
|
143
|
+
path: join(resolvedInput.rootDir, "packages")
|
|
89
144
|
});
|
|
90
145
|
collector?.add(existsSync(workspacePackageJsonPath) ? {
|
|
91
146
|
type: "file-overwrite",
|
|
@@ -96,7 +151,7 @@ async function executeInitPipeline(input, target, options) {
|
|
|
96
151
|
path: workspacePackageJsonPath,
|
|
97
152
|
source: "generated"
|
|
98
153
|
});
|
|
99
|
-
const readmePath = join(
|
|
154
|
+
const readmePath = join(resolvedInput.rootDir, "README.md");
|
|
100
155
|
if (options.force || !existsSync(readmePath)) {
|
|
101
156
|
collector?.add(existsSync(readmePath) ? {
|
|
102
157
|
type: "file-overwrite",
|
|
@@ -108,7 +163,7 @@ async function executeInitPipeline(input, target, options) {
|
|
|
108
163
|
source: "generated"
|
|
109
164
|
});
|
|
110
165
|
}
|
|
111
|
-
const gitignorePath = join(
|
|
166
|
+
const gitignorePath = join(resolvedInput.rootDir, ".gitignore");
|
|
112
167
|
if (options.force || !existsSync(gitignorePath)) {
|
|
113
168
|
collector?.add(existsSync(gitignorePath) ? {
|
|
114
169
|
type: "file-overwrite",
|
|
@@ -121,14 +176,14 @@ async function executeInitPipeline(input, target, options) {
|
|
|
121
176
|
});
|
|
122
177
|
}
|
|
123
178
|
} else {
|
|
124
|
-
const workspaceResult = scaffoldWorkspaceRoot(
|
|
179
|
+
const workspaceResult = scaffoldWorkspaceRoot(resolvedInput.rootDir, workspaceName, options.force);
|
|
125
180
|
if (workspaceResult.isErr()) {
|
|
126
181
|
return Result.err(workspaceResult.error.message);
|
|
127
182
|
}
|
|
128
183
|
}
|
|
129
184
|
}
|
|
130
|
-
const resolvedBinName =
|
|
131
|
-
const plan = buildInitPlan(target,
|
|
185
|
+
const resolvedBinName = resolvedInput.binName ?? deriveBinName(deriveProjectName(resolvedInput.packageName));
|
|
186
|
+
const plan = buildInitPlan(target, resolvedInput, projectDir, resolvedBinName);
|
|
132
187
|
const executeResult = await executePlan(plan, {
|
|
133
188
|
force: options.force,
|
|
134
189
|
...collector ? { collector } : {}
|
|
@@ -137,11 +192,11 @@ async function executeInitPipeline(input, target, options) {
|
|
|
137
192
|
return Result.err(toExecutionErrorMessage(executeResult.error));
|
|
138
193
|
}
|
|
139
194
|
const postScaffoldResult = await runPostScaffold({
|
|
140
|
-
rootDir:
|
|
195
|
+
rootDir: resolvedInput.rootDir,
|
|
141
196
|
projectDir,
|
|
142
197
|
origin: "init",
|
|
143
|
-
target:
|
|
144
|
-
structure:
|
|
198
|
+
target: resolvedInput.preset,
|
|
199
|
+
structure: resolvedInput.structure,
|
|
145
200
|
skipInstall: options.skipInstall,
|
|
146
201
|
skipGit: options.skipGit,
|
|
147
202
|
skipCommit: options.skipCommit,
|
|
@@ -152,15 +207,15 @@ async function executeInitPipeline(input, target, options) {
|
|
|
152
207
|
return Result.err("Post-scaffold step failed");
|
|
153
208
|
}
|
|
154
209
|
return Result.ok({
|
|
155
|
-
structure:
|
|
156
|
-
rootDir:
|
|
210
|
+
structure: resolvedInput.structure,
|
|
211
|
+
rootDir: resolvedInput.rootDir,
|
|
157
212
|
projectDir,
|
|
158
|
-
preset:
|
|
159
|
-
packageName:
|
|
213
|
+
preset: resolvedInput.preset,
|
|
214
|
+
packageName: resolvedInput.packageName,
|
|
160
215
|
blocksAdded: executeResult.value.blocksAdded,
|
|
161
216
|
postScaffold: postScaffoldResult.value,
|
|
162
217
|
...collector ? { dryRunPlan: collector.toJSON() } : {}
|
|
163
218
|
});
|
|
164
219
|
}
|
|
165
220
|
|
|
166
|
-
export { executeInitPipeline };
|
|
221
|
+
export { validateExample, executeInitPipeline };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Unique identifier for a scaffold target.
|
|
3
3
|
*/
|
|
4
|
-
type TargetId = "minimal" | "cli" | "mcp" | "daemon" | "library" | "full-stack" | "api" | "worker" | "web";
|
|
4
|
+
type TargetId = "minimal" | "basic" | "cli" | "mcp" | "daemon" | "library" | "full-stack" | "api" | "worker" | "web";
|
|
5
5
|
/**
|
|
6
6
|
* Whether the target produces a runnable application or a library package.
|
|
7
7
|
*/
|
|
@@ -3,6 +3,5 @@ export { injectSharedConfig, rewriteLocalDependencies } from "./config.js";
|
|
|
3
3
|
export { executePlan } from "./executor.js";
|
|
4
4
|
export { deriveBinName, deriveProjectName, isPathWithin, resolveAuthor, resolvePackageName, resolveYear, sanitizePackageName, validatePackageName, validateProjectDirectoryName } from "./names.js";
|
|
5
5
|
export { copyPresetFiles, getOutputFilename, getPresetsBaseDir, isBinaryFile, replacePlaceholders } from "./preset.js";
|
|
6
|
-
export { copyTemplateFiles, getTemplatesDir } from "./template.js";
|
|
7
6
|
export { ScaffoldError } from "./types.js";
|
|
8
7
|
export { buildWorkspaceRootPackageJson, detectWorkspaceRoot, scaffoldWorkspaceRoot } from "./workspace.js";
|
|
@@ -3,7 +3,10 @@
|
|
|
3
3
|
import { existsSync, readdirSync, readFileSync } from "fs";
|
|
4
4
|
import { dirname, join, resolve } from "path";
|
|
5
5
|
import { fileURLToPath } from "url";
|
|
6
|
+
import { extractMessage, InternalError, Result } from "@outfitter/contracts";
|
|
6
7
|
import { getResolvedVersions } from "@outfitter/presets";
|
|
8
|
+
import { isPlainObject } from "@outfitter/types";
|
|
9
|
+
var OUTFITTER_PACKAGE_NAME = "outfitter";
|
|
7
10
|
var DEPENDENCY_SECTIONS = [
|
|
8
11
|
"dependencies",
|
|
9
12
|
"devDependencies",
|
|
@@ -17,8 +20,13 @@ function clearResolvedVersionsCache() {
|
|
|
17
20
|
function readJsonFile(path) {
|
|
18
21
|
return JSON.parse(readFileSync(path, "utf-8"));
|
|
19
22
|
}
|
|
20
|
-
function
|
|
21
|
-
|
|
23
|
+
function normalizeVersionRange(version) {
|
|
24
|
+
const trimmed = version.trim();
|
|
25
|
+
const semverMatch = trimmed.match(/\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?/);
|
|
26
|
+
if (semverMatch) {
|
|
27
|
+
return semverMatch[0];
|
|
28
|
+
}
|
|
29
|
+
return trimmed.replace(/^[\^~>=<]+/, "");
|
|
22
30
|
}
|
|
23
31
|
function normalizeRange(value) {
|
|
24
32
|
const trimmed = value.trim();
|
|
@@ -37,20 +45,20 @@ function findOutfitterPackageRoot() {
|
|
|
37
45
|
if (existsSync(packageJsonPath)) {
|
|
38
46
|
try {
|
|
39
47
|
const parsed = readJsonFile(packageJsonPath);
|
|
40
|
-
if (
|
|
41
|
-
return currentDir;
|
|
48
|
+
if (isPlainObject(parsed) && typeof parsed["name"] === "string" && parsed["name"] === OUTFITTER_PACKAGE_NAME) {
|
|
49
|
+
return Result.ok(currentDir);
|
|
42
50
|
}
|
|
43
51
|
} catch {}
|
|
44
52
|
}
|
|
45
53
|
currentDir = dirname(currentDir);
|
|
46
54
|
}
|
|
47
|
-
|
|
55
|
+
return Result.err(InternalError.create(`Unable to find outfitter package root (walked 10 levels up from ${dirname(fileURLToPath(import.meta.url))}). ` + "Ensure this module is running from within the outfitter package tree."));
|
|
48
56
|
}
|
|
49
57
|
function collectOutfitterDepsFromPackageJson(packageJson) {
|
|
50
58
|
const collected = {};
|
|
51
59
|
for (const section of DEPENDENCY_SECTIONS) {
|
|
52
60
|
const sectionValue = packageJson[section];
|
|
53
|
-
if (!
|
|
61
|
+
if (!isPlainObject(sectionValue)) {
|
|
54
62
|
continue;
|
|
55
63
|
}
|
|
56
64
|
for (const [name, value] of Object.entries(sectionValue)) {
|
|
@@ -83,7 +91,7 @@ function collectWorkspacePackageRanges(packageRoot) {
|
|
|
83
91
|
}
|
|
84
92
|
try {
|
|
85
93
|
const parsed = readJsonFile(packageJsonPath);
|
|
86
|
-
if (!
|
|
94
|
+
if (!isPlainObject(parsed)) {
|
|
87
95
|
continue;
|
|
88
96
|
}
|
|
89
97
|
const name = parsed["name"];
|
|
@@ -100,28 +108,37 @@ function collectWorkspacePackageRanges(packageRoot) {
|
|
|
100
108
|
}
|
|
101
109
|
function resolvePresetDependencyVersions() {
|
|
102
110
|
if (cachedResolvedVersions) {
|
|
103
|
-
return cachedResolvedVersions;
|
|
111
|
+
return Result.ok(cachedResolvedVersions);
|
|
112
|
+
}
|
|
113
|
+
try {
|
|
114
|
+
const { all: presetsVersions } = getResolvedVersions();
|
|
115
|
+
const packageRootResult = findOutfitterPackageRoot();
|
|
116
|
+
if (packageRootResult.isErr()) {
|
|
117
|
+
return packageRootResult;
|
|
118
|
+
}
|
|
119
|
+
const packageRoot = packageRootResult.value;
|
|
120
|
+
const packageJsonPath = join(packageRoot, "package.json");
|
|
121
|
+
const raw = existsSync(packageJsonPath) ? readJsonFile(packageJsonPath) : undefined;
|
|
122
|
+
const fromOutfitterPackage = raw !== undefined && isPlainObject(raw) ? collectOutfitterDepsFromPackageJson(raw) : {};
|
|
123
|
+
const fromWorkspacePackages = collectWorkspacePackageRanges(packageRoot);
|
|
124
|
+
const internal = {
|
|
125
|
+
...fromOutfitterPackage,
|
|
126
|
+
...fromWorkspacePackages
|
|
127
|
+
};
|
|
128
|
+
cachedResolvedVersions = {
|
|
129
|
+
internal,
|
|
130
|
+
external: { ...presetsVersions }
|
|
131
|
+
};
|
|
132
|
+
return Result.ok(cachedResolvedVersions);
|
|
133
|
+
} catch (error) {
|
|
134
|
+
return Result.err(InternalError.create(`Failed to resolve preset dependency versions: ${extractMessage(error)}`));
|
|
104
135
|
}
|
|
105
|
-
const { all: presetsVersions } = getResolvedVersions();
|
|
106
|
-
const packageRoot = findOutfitterPackageRoot();
|
|
107
|
-
const packageJsonPath = join(packageRoot, "package.json");
|
|
108
|
-
const raw = existsSync(packageJsonPath) ? readJsonFile(packageJsonPath) : undefined;
|
|
109
|
-
const fromOutfitterPackage = raw !== undefined && isRecord(raw) ? collectOutfitterDepsFromPackageJson(raw) : {};
|
|
110
|
-
const fromWorkspacePackages = collectWorkspacePackageRanges(packageRoot);
|
|
111
|
-
const internal = {
|
|
112
|
-
...fromOutfitterPackage,
|
|
113
|
-
...fromWorkspacePackages
|
|
114
|
-
};
|
|
115
|
-
cachedResolvedVersions = {
|
|
116
|
-
internal,
|
|
117
|
-
external: { ...presetsVersions }
|
|
118
|
-
};
|
|
119
|
-
return cachedResolvedVersions;
|
|
120
136
|
}
|
|
121
137
|
function applyResolvedDependencyVersions(parsedPackageJson, versions) {
|
|
138
|
+
const unresolved = new Set;
|
|
122
139
|
for (const section of DEPENDENCY_SECTIONS) {
|
|
123
140
|
const sectionValue = parsedPackageJson[section];
|
|
124
|
-
if (!
|
|
141
|
+
if (!isPlainObject(sectionValue)) {
|
|
125
142
|
continue;
|
|
126
143
|
}
|
|
127
144
|
for (const [name, value] of Object.entries(sectionValue)) {
|
|
@@ -138,9 +155,14 @@ function applyResolvedDependencyVersions(parsedPackageJson, versions) {
|
|
|
138
155
|
const resolvedExternal = versions.external[name];
|
|
139
156
|
if (resolvedExternal) {
|
|
140
157
|
sectionValue[name] = resolvedExternal;
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
if (value === "catalog:") {
|
|
161
|
+
unresolved.add(name);
|
|
141
162
|
}
|
|
142
163
|
}
|
|
143
164
|
}
|
|
165
|
+
return [...unresolved].toSorted();
|
|
144
166
|
}
|
|
145
167
|
|
|
146
|
-
export { clearResolvedVersionsCache, resolvePresetDependencyVersions, applyResolvedDependencyVersions };
|
|
168
|
+
export { DEPENDENCY_SECTIONS, clearResolvedVersionsCache, normalizeVersionRange, resolvePresetDependencyVersions, applyResolvedDependencyVersions };
|