sfscanner 0.0.0-stage → 0.1.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.
@@ -0,0 +1,86 @@
1
+ import { type ScanConfigV2, type ScanSeverityV2 } from './contracts';
2
+ import type { V2CommandName } from './help';
3
+ export type CliFormatV2 = 'json' | 'ndjson' | 'sarif' | 'table';
4
+ export type CliProfileV2 = 'beta-default' | 'beta-hardened';
5
+ export type CliTargetEnumV2 = 'UNKNOWN' | 'COMMUNITY' | 'ENTERPRISE' | 'CLOUD' | 'SELF_HOSTED' | 'OWNER' | 'ADMIN' | 'MEMBER' | 'LEGACY' | 'NATIVE';
6
+ export type CliParseErrorCodeV2 = 'NO_COMMAND' | 'UNKNOWN_COMMAND' | 'UNKNOWN_OPTION' | 'MISSING_VALUE' | 'INVALID_VALUE' | 'DUPLICATE_OPTION' | 'UNEXPECTED_ARGUMENT' | 'REMOTE_PATH' | 'RULE_PACK_INVALID' | 'SEMANTIC_CATALOGUE_INVALID' | 'PROFILE_NOT_ADMITTED';
7
+ export type CliParseErrorV2 = Readonly<{
8
+ code: CliParseErrorCodeV2;
9
+ message: string;
10
+ argument?: string;
11
+ }>;
12
+ type ScanCommandV2 = Readonly<{
13
+ kind: 'scan';
14
+ schema: 'v2';
15
+ inputs: readonly string[];
16
+ format: CliFormatV2;
17
+ profile: CliProfileV2;
18
+ failOn: ScanSeverityV2;
19
+ requireComplete: boolean;
20
+ concurrency: number;
21
+ timeoutMs?: number;
22
+ output?: string;
23
+ configPath?: string;
24
+ rules: 'builtin';
25
+ catalogue: 'builtin';
26
+ limits: string;
27
+ target?: string;
28
+ n8nVersion?: string;
29
+ edition: 'COMMUNITY' | 'ENTERPRISE' | 'CLOUD' | 'UNKNOWN';
30
+ deployment: 'SELF_HOSTED' | 'CLOUD' | 'UNKNOWN';
31
+ role: 'OWNER' | 'ADMIN' | 'MEMBER' | 'UNKNOWN';
32
+ taskRunner: 'LEGACY' | 'NATIVE' | 'UNKNOWN';
33
+ communityPackages: readonly string[];
34
+ configuration: readonly string[];
35
+ include: readonly string[];
36
+ exclude: readonly string[];
37
+ allowUnsignedDevelopmentRules: boolean;
38
+ noColor: boolean;
39
+ cliOverrides: Readonly<Partial<ScanConfigV2>>;
40
+ }>;
41
+ export type CliHelpCommandV2 = Readonly<{
42
+ kind: 'help';
43
+ schema: 'v2';
44
+ command?: V2CommandName;
45
+ }>;
46
+ export type CliCommandV2 = ScanCommandV2 | Readonly<{
47
+ kind: 'rules';
48
+ schema: 'v2';
49
+ format: 'json' | 'table';
50
+ }> | Readonly<{
51
+ kind: 'explain';
52
+ schema: 'v2';
53
+ format: 'json' | 'table';
54
+ ruleId: string;
55
+ }> | Readonly<{
56
+ kind: 'profiles';
57
+ schema: 'v2';
58
+ format: 'json' | 'table';
59
+ }> | Readonly<{
60
+ kind: 'validate-config';
61
+ schema: 'v2';
62
+ format: 'json' | 'table';
63
+ path: string;
64
+ }> | Readonly<{
65
+ kind: 'version';
66
+ schema: 'v2';
67
+ format: 'json' | 'table';
68
+ }>;
69
+ type ParsedCommandV2 = CliCommandV2 | CliHelpCommandV2;
70
+ export type CliParseResultV2 = Readonly<{
71
+ ok: true;
72
+ command: ParsedCommandV2;
73
+ } | {
74
+ ok: false;
75
+ error: CliParseErrorV2;
76
+ }>;
77
+ export type CliArgumentDispatch = Readonly<{
78
+ mode: 'v1';
79
+ argv: readonly string[];
80
+ } | {
81
+ mode: 'v2';
82
+ result: CliParseResultV2;
83
+ }>;
84
+ export declare function parseArgumentsV2(argv: readonly string[]): CliParseResultV2;
85
+ export declare function parseCliArguments(argv: readonly string[]): CliArgumentDispatch;
86
+ export {};
@@ -0,0 +1,294 @@
1
+ // src/v2/contracts.ts
2
+ var SCAN_CONFIG_SCHEMA_V2 = "n8n-scan-config-v2";
3
+ var ADMITTED_PROFILE_V2 = Object.freeze({ id: "beta-default", version: "2.0.0", digest: "3ca5d69db2554383e22c44afe507cc98e381ea58a7e42aaac0ee8f7497fb4f44" });
4
+ var ADMITTED_PROFILE_SPECIFIERS_V2 = Object.freeze([
5
+ ADMITTED_PROFILE_V2.id,
6
+ `${ADMITTED_PROFILE_V2.id}@${ADMITTED_PROFILE_V2.version}`
7
+ ]);
8
+ function isAdmittedProfileSpecifierV2(value) {
9
+ return typeof value === "string" && ADMITTED_PROFILE_SPECIFIERS_V2.includes(value);
10
+ }
11
+ var BUILTIN_AUTHORITIES_V2 = Object.freeze({
12
+ profile: ADMITTED_PROFILE_V2,
13
+ rules: Object.freeze({ id: "scanner-core-builtins", version: "2.0.0", digest: "a36d00564bbf8e8c38f05820480782cdc53fdbd3712558850066c4e3f5c3413d", signatureStatus: "VERIFIED" }),
14
+ semantics: Object.freeze({ id: "scanner-core-builtins", version: "2.0.0", digest: "1bb11f63269d427cb28e141dfe0a6a1512e53c298abdb4d6450545ceb56d11c4" }),
15
+ limits: Object.freeze({ schemaVersion: "scanner-limits-v2", digest: "fca787753ca88f71cf0d174427f4ac730a7aef1c823aaf73aa1ea72af92b4077" })
16
+ });
17
+ var PROFILE_MANIFEST_DIGEST_V2 = ADMITTED_PROFILE_V2.digest;
18
+ var BUILTIN_RULESET_AUTHORITY_V2 = BUILTIN_AUTHORITIES_V2.rules;
19
+ var BUILTIN_SEMANTICS_AUTHORITY_V2 = BUILTIN_AUTHORITIES_V2.semantics;
20
+ var BUILTIN_LIMITS_AUTHORITY_V2 = BUILTIN_AUTHORITIES_V2.limits;
21
+ var RULE_PACK_DIGEST_V2 = BUILTIN_RULESET_AUTHORITY_V2.digest;
22
+ var SEMANTIC_CATALOGUE_DIGEST_V2 = BUILTIN_SEMANTICS_AUTHORITY_V2.digest;
23
+ var DEFAULT_SCAN_CONFIG_V2 = Object.freeze({
24
+ schemaVersion: SCAN_CONFIG_SCHEMA_V2,
25
+ format: "json",
26
+ profile: ADMITTED_PROFILE_V2.id,
27
+ failOn: "INFO",
28
+ requireComplete: false,
29
+ concurrency: 1,
30
+ rules: "builtin",
31
+ catalogue: "builtin",
32
+ limits: "builtin",
33
+ include: Object.freeze(["**/*.json"]),
34
+ exclude: Object.freeze([".git/**", "node_modules/**"]),
35
+ allowUnsignedDevelopmentRules: false,
36
+ noColor: false
37
+ });
38
+ var SCAN_CONFIG_V2_FIELDS = Object.freeze([
39
+ "schemaVersion",
40
+ "format",
41
+ "profile",
42
+ "output",
43
+ "inputs",
44
+ "configPath",
45
+ "failOn",
46
+ "requireComplete",
47
+ "concurrency",
48
+ "rules",
49
+ "catalogue",
50
+ "limits",
51
+ "target",
52
+ "include",
53
+ "exclude",
54
+ "allowUnsignedDevelopmentRules",
55
+ "noColor"
56
+ ]);
57
+
58
+ // src/v2/arguments.ts
59
+ var severities = ["CRITICAL", "HIGH", "MEDIUM", "LOW", "INFO"];
60
+ var commands = Object.freeze({ scan: true, rules: true, explain: true, profiles: true, "validate-config": true, version: true, "--version": true });
61
+ var implicitV2Commands = Object.freeze({ rules: true, explain: true, profiles: true, "validate-config": true, version: true });
62
+ var scalarOptions = Object.freeze({ "--format": true, "--profile": true, "--fail-on": true, "--max-concurrency": true, "--concurrency": true, "--timeout": true, "--output": true, "--config": true, "--rules": true, "--catalogue": true, "--limits": true, "--target": true, "--n8n-version": true, "--edition": true, "--deployment": true, "--role": true, "--task-runner": true });
63
+ var repeatableOptions = Object.freeze({ "--community-package": true, "--configuration": true, "--include": true, "--exclude": true });
64
+ var configFields = Object.freeze({ "--format": "format", "--profile": "profile", "--fail-on": "failOn", "--max-concurrency": "concurrency", "--concurrency": "concurrency", "--output": "output", "--config": "configPath", "--rules": "rules", "--catalogue": "catalogue", "--limits": "limits", "--target": "target", "--include": "include", "--exclude": "exclude", "inputs": "inputs", "--require-complete": "requireComplete", "--allow-unsigned-development-rules": "allowUnsignedDevelopmentRules", "--no-color": "noColor" });
65
+ var overrideOrder = ["format", "profile", "output", "inputs", "configPath", "failOn", "requireComplete", "concurrency", "rules", "catalogue", "limits", "target", "include", "exclude", "allowUnsignedDevelopmentRules", "noColor"];
66
+ function parseArgumentsV2(argv) {
67
+ const stripped = stripSchema(argv);
68
+ if (!stripped.ok) return stripped.result;
69
+ const args = stripped.args;
70
+ const raw = args[0];
71
+ if (!raw) return failure("NO_COMMAND", "A v2 command is required.");
72
+ if (raw === "--help") return success({ kind: "help", schema: "v2" });
73
+ if (commands[raw] !== true) return failure("UNKNOWN_COMMAND", "Unknown v2 command.");
74
+ const kind = raw === "--version" ? "version" : raw;
75
+ if (kind !== "scan") return parseMetadata(kind, args.slice(1));
76
+ if (args.length === 2 && args[1] === "--help") return success({ kind: "help", schema: "v2", command: "scan" });
77
+ const value = {
78
+ kind: "scan",
79
+ schema: "v2",
80
+ inputs: [],
81
+ format: "json",
82
+ profile: "beta-default",
83
+ failOn: "INFO",
84
+ requireComplete: false,
85
+ concurrency: 1,
86
+ rules: "builtin",
87
+ catalogue: "builtin",
88
+ limits: "builtin",
89
+ edition: "UNKNOWN",
90
+ deployment: "UNKNOWN",
91
+ role: "UNKNOWN",
92
+ taskRunner: "UNKNOWN",
93
+ communityPackages: [],
94
+ configuration: [],
95
+ include: ["**/*.json"],
96
+ exclude: [".git/**", "node_modules/**"],
97
+ allowUnsignedDevelopmentRules: false,
98
+ noColor: false
99
+ };
100
+ const overrides = {};
101
+ const inputs = [];
102
+ const repeatable = { "--community-package": [], "--configuration": [], "--include": [], "--exclude": [] };
103
+ const seen = /* @__PURE__ */ new Set();
104
+ for (let index = 1; index < args.length; index += 1) {
105
+ const token = args[index];
106
+ if (token === "--") {
107
+ inputs.push(...args.slice(index + 1));
108
+ break;
109
+ }
110
+ if (token === "-" || !token.startsWith("-")) {
111
+ if (!local(token)) return failure("REMOTE_PATH", "Input path is not admitted.");
112
+ inputs.push(token);
113
+ continue;
114
+ }
115
+ const [name, inline] = splitOption(token);
116
+ if (name === "--require-complete" || name === "--allow-unsigned-development-rules" || name === "--no-color") {
117
+ if (inline !== void 0 || seen.has(name)) return failure("DUPLICATE_OPTION", "Option supplied more than once.", name);
118
+ seen.add(name);
119
+ value[name === "--require-complete" ? "requireComplete" : name === "--no-color" ? "noColor" : "allowUnsignedDevelopmentRules"] = true;
120
+ overrides[configFields[name]] = true;
121
+ continue;
122
+ }
123
+ if (scalarOptions[name] !== true && repeatableOptions[name] !== true) return failure("UNKNOWN_OPTION", "Unknown option.", name);
124
+ const duplicateKey = name === "--max-concurrency" ? "--concurrency" : name;
125
+ if (seen.has(duplicateKey) && scalarOptions[name] === true) return failure("DUPLICATE_OPTION", "Option supplied more than once.", name);
126
+ const read = inline === void 0 ? args[index + 1] : inline;
127
+ if (read === void 0 || read.length === 0 || inline === void 0 && read.startsWith("-") && !(name === "--output" && read === "-")) return failure("MISSING_VALUE", "Option requires a value.", name);
128
+ if (inline === void 0) index += 1;
129
+ if (repeatableOptions[name] === true) {
130
+ if (!local(read)) return failure("REMOTE_PATH", "Option value is not admitted.", name);
131
+ repeatable[name].push(read);
132
+ if (configFields[name]) overrides[configFields[name]] = Object.freeze([...repeatable[name]]);
133
+ continue;
134
+ }
135
+ if (name === "--format" && !["json", "ndjson", "sarif", "table"].includes(read)) return failure("INVALID_VALUE", "Format is invalid.", name);
136
+ if (name === "--profile" && !isAdmittedProfileSpecifierV2(read)) return failure("PROFILE_NOT_ADMITTED", "Profile is not admitted.", name);
137
+ if (name === "--fail-on" && !severities.includes(read)) return failure("INVALID_VALUE", "Fail threshold is invalid.", name);
138
+ if ((name === "--max-concurrency" || name === "--concurrency" || name === "--timeout") && !positiveInteger(read, name === "--timeout" ? 2 ** 31 - 1 : 16)) return failure("INVALID_VALUE", "Numeric option is invalid.", name);
139
+ if (name === "--n8n-version" && !/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/.test(read)) return failure("INVALID_VALUE", "n8n version is invalid.", name);
140
+ if (name === "--edition" && !["COMMUNITY", "ENTERPRISE", "CLOUD", "UNKNOWN"].includes(read)) return failure("INVALID_VALUE", "Edition is invalid.", name);
141
+ if (name === "--deployment" && !["SELF_HOSTED", "CLOUD", "UNKNOWN"].includes(read)) return failure("INVALID_VALUE", "Deployment is invalid.", name);
142
+ if (name === "--role" && !["OWNER", "ADMIN", "MEMBER", "UNKNOWN"].includes(read)) return failure("INVALID_VALUE", "Role is invalid.", name);
143
+ if (name === "--task-runner" && !["LEGACY", "NATIVE", "UNKNOWN"].includes(read)) return failure("INVALID_VALUE", "Task runner is invalid.", name);
144
+ if (name === "--rules" || name === "--catalogue") {
145
+ if (read !== "builtin") return failure(name === "--rules" ? "RULE_PACK_INVALID" : "SEMANTIC_CATALOGUE_INVALID", "Only built-in authority is available.", name);
146
+ } else if (["--limits", "--target", "--config"].includes(name) && (read === "-" || !local(read))) return failure("REMOTE_PATH", "Option value is not admitted.", name);
147
+ else if (name === "--output" && read !== "-" && !local(read)) return failure("REMOTE_PATH", "Option value is not admitted.", name);
148
+ else if (["--n8n-version", "--edition", "--deployment", "--role", "--task-runner"].includes(name) && !safeText(read)) return failure("INVALID_VALUE", "Option value is not admitted.", name);
149
+ seen.add(duplicateKey);
150
+ assign(value, name, read);
151
+ if (configFields[name]) overrides[configFields[name]] = ["--max-concurrency", "--concurrency"].includes(name) ? Number(read) : read;
152
+ }
153
+ if (value.allowUnsignedDevelopmentRules === true) return failure("RULE_PACK_INVALID", "External rule packs are not admitted in this release.", "--allow-unsigned-development-rules");
154
+ if (inputs.length === 0) return failure("UNEXPECTED_ARGUMENT", "At least one workflow input is required.");
155
+ if (inputs.some((input) => !local(input))) return failure("REMOTE_PATH", "Input path is not admitted.");
156
+ if (inputs.includes("-") && inputs.length > 1) return failure("UNEXPECTED_ARGUMENT", "Standard input cannot be combined with file inputs.");
157
+ overrides.inputs = Object.freeze([...inputs]);
158
+ const cliOverrides = {};
159
+ const sparse = cliOverrides;
160
+ for (const field of overrideOrder) if (Object.prototype.hasOwnProperty.call(overrides, field)) sparse[field] = overrides[field];
161
+ const command = {
162
+ kind: "scan",
163
+ schema: "v2",
164
+ inputs: Object.freeze([...inputs]),
165
+ format: value.format,
166
+ profile: value.profile,
167
+ failOn: value.failOn,
168
+ requireComplete: value.requireComplete,
169
+ concurrency: value.concurrency,
170
+ ...typeof value.timeoutMs === "number" ? { timeoutMs: value.timeoutMs } : {},
171
+ ...typeof value.output === "string" ? { output: value.output } : {},
172
+ ...typeof value.configPath === "string" ? { configPath: value.configPath } : {},
173
+ rules: value.rules,
174
+ catalogue: value.catalogue,
175
+ limits: value.limits,
176
+ ...typeof value.target === "string" ? { target: value.target } : {},
177
+ ...typeof value.n8nVersion === "string" ? { n8nVersion: value.n8nVersion } : {},
178
+ edition: value.edition,
179
+ deployment: value.deployment,
180
+ role: value.role,
181
+ taskRunner: value.taskRunner,
182
+ communityPackages: arrayFor(repeatable["--community-package"]),
183
+ configuration: arrayFor(repeatable["--configuration"]),
184
+ include: repeatable["--include"].length > 0 ? arrayFor(repeatable["--include"]) : Object.freeze(["**/*.json"]),
185
+ exclude: repeatable["--exclude"].length > 0 ? arrayFor(repeatable["--exclude"]) : Object.freeze([".git/**", "node_modules/**"]),
186
+ allowUnsignedDevelopmentRules: value.allowUnsignedDevelopmentRules,
187
+ noColor: value.noColor,
188
+ cliOverrides
189
+ };
190
+ return success(command);
191
+ }
192
+ function arrayFor(values) {
193
+ return Object.freeze([...values ?? []]);
194
+ }
195
+ function parseCliArguments(argv) {
196
+ const hasSchema = hasSchemaMarker(argv);
197
+ const implicit = argv[0] !== void 0 && implicitV2Commands[argv[0]] === true;
198
+ return hasSchema || implicit ? freeze({ mode: "v2", result: parseArgumentsV2(argv) }) : freeze({ mode: "v1", argv: Object.freeze([...argv]) });
199
+ }
200
+ function parseMetadata(kind, args) {
201
+ if (args.length === 1 && args[0] === "--help") return success({ kind: "help", schema: "v2", command: kind });
202
+ let format = "json";
203
+ const rest = [];
204
+ let seen = false;
205
+ for (let index = 0; index < args.length; index += 1) {
206
+ const token = args[index];
207
+ if (token.startsWith("-")) {
208
+ const [name, inline] = splitOption(token);
209
+ if (name !== "--format" || seen) return failure(seen ? "DUPLICATE_OPTION" : "UNKNOWN_OPTION", seen ? "Option supplied more than once." : "Unknown option.", name);
210
+ const value = inline ?? args[++index];
211
+ if (!value) return failure("MISSING_VALUE", "Option requires a value.", name);
212
+ if (value !== "json" && value !== "table") return failure("INVALID_VALUE", "Format is invalid.", name);
213
+ format = value;
214
+ seen = true;
215
+ } else rest.push(token);
216
+ }
217
+ if (kind === "rules" || kind === "profiles" || kind === "version") {
218
+ if (rest.length > 0) return failure("UNEXPECTED_ARGUMENT", "Command does not accept positional arguments.");
219
+ return success({ kind, schema: "v2", format });
220
+ }
221
+ if (kind === "explain") return rest.length === 1 && safeText(rest[0]) ? success({ kind, schema: "v2", format, ruleId: rest[0] }) : failure("UNEXPECTED_ARGUMENT", "explain requires one rule ID.");
222
+ if (rest.length !== 1 || !local(rest[0])) return failure("UNEXPECTED_ARGUMENT", "validate-config requires one local file.");
223
+ return success({ kind, schema: "v2", format, path: rest[0] });
224
+ }
225
+ function assign(value, name, read) {
226
+ const fields = { "--format": "format", "--profile": "profile", "--fail-on": "failOn", "--max-concurrency": "concurrency", "--concurrency": "concurrency", "--timeout": "timeoutMs", "--output": "output", "--config": "configPath", "--rules": "rules", "--catalogue": "catalogue", "--limits": "limits", "--target": "target", "--n8n-version": "n8nVersion", "--edition": "edition", "--deployment": "deployment", "--role": "role", "--task-runner": "taskRunner" };
227
+ value[fields[name]] = ["--max-concurrency", "--concurrency", "--timeout"].includes(name) ? Number(read) : read;
228
+ }
229
+ function splitOption(token) {
230
+ const at = token.indexOf("=");
231
+ return at < 0 ? [token, void 0] : [token.slice(0, at), token.slice(at + 1)];
232
+ }
233
+ function positiveInteger(value, maximum) {
234
+ if (!/^\d+$/.test(value)) return false;
235
+ const number = Number(value);
236
+ return Number.isSafeInteger(number) && number > 0 && number <= maximum;
237
+ }
238
+ function safeText(value) {
239
+ return value.length > 0 && value.length <= 4096 && !/[\u0000-\u001f\u007f]/.test(value) && !/^(?:[a-z][a-z\d+.-]*:|\/|[a-z]:|\\\\)/i.test(value);
240
+ }
241
+ function local(value) {
242
+ return safeText(value) && !/^(?:[a-z][a-z\d+.-]*:|\/|[a-z]:|\\\\)/i.test(value);
243
+ }
244
+ function hasSchemaMarker(argv) {
245
+ for (const token of argv) {
246
+ if (token === "--") break;
247
+ if (token === "--schema" || token.startsWith("--schema=")) return true;
248
+ }
249
+ return false;
250
+ }
251
+ function stripSchema(argv) {
252
+ const args = [];
253
+ let seen = false;
254
+ for (let index = 0; index < argv.length; index += 1) {
255
+ const token = argv[index];
256
+ if (token === "--") {
257
+ args.push(...argv.slice(index));
258
+ break;
259
+ }
260
+ if (token === "--schema") {
261
+ if (seen || argv[index + 1] !== "v2") return { ok: false, result: failure(seen ? "DUPLICATE_OPTION" : "INVALID_VALUE", seen ? "Option supplied more than once." : "Schema must be v2.", "--schema") };
262
+ seen = true;
263
+ index += 1;
264
+ continue;
265
+ }
266
+ if (token.startsWith("--schema=")) {
267
+ if (seen || token.slice(9) !== "v2") return { ok: false, result: failure(seen ? "DUPLICATE_OPTION" : "INVALID_VALUE", seen ? "Option supplied more than once." : "Schema must be v2.", "--schema") };
268
+ seen = true;
269
+ continue;
270
+ }
271
+ args.push(token);
272
+ }
273
+ return { ok: true, args };
274
+ }
275
+ function success(command) {
276
+ return freeze({ ok: true, command });
277
+ }
278
+ function failure(code, message, argument) {
279
+ const safe = argument !== void 0 && /^--[A-Za-z0-9][A-Za-z0-9-]{0,63}$/.test(argument) ? argument : void 0;
280
+ return freeze({ ok: false, error: { code, message, ...safe === void 0 ? {} : { argument: safe } } });
281
+ }
282
+ function freeze(value, seen = /* @__PURE__ */ new WeakSet()) {
283
+ if (value && typeof value === "object") {
284
+ if (seen.has(value)) return value;
285
+ seen.add(value);
286
+ for (const name of Object.getOwnPropertyNames(value)) freeze(value[name], seen);
287
+ Object.freeze(value);
288
+ }
289
+ return value;
290
+ }
291
+ export {
292
+ parseArgumentsV2,
293
+ parseCliArguments
294
+ };
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/v2/contracts.ts", "../../src/v2/arguments.ts"],
4
+ "sourcesContent": ["export const SCAN_CONFIG_SCHEMA_V2 = 'n8n-scan-config-v2' as const;\nexport type ScanFormatV2 = 'json' | 'ndjson' | 'sarif' | 'table';\nexport type ScanSeverityV2 = 'CRITICAL' | 'HIGH' | 'MEDIUM' | 'LOW' | 'INFO';\n\nexport type ScanConfigV2 = Readonly<{\n schemaVersion: typeof SCAN_CONFIG_SCHEMA_V2;\n format?: ScanFormatV2;\n profile?: string;\n output?: string;\n inputs?: readonly string[];\n configPath?: string;\n failOn?: ScanSeverityV2;\n requireComplete?: boolean;\n concurrency?: number;\n rules?: string;\n catalogue?: string;\n limits?: string;\n target?: string;\n include?: readonly string[];\n exclude?: readonly string[];\n allowUnsignedDevelopmentRules?: boolean;\n noColor?: boolean;\n}>;\n\nexport const ADMITTED_PROFILE_V2 = Object.freeze({ id: 'beta-default', version: '2.0.0', digest: '3ca5d69db2554383e22c44afe507cc98e381ea58a7e42aaac0ee8f7497fb4f44' });\n\n/**\n * The profile spellings a caller may write, and the one place they are listed. Both the\n * config loader and the MCP tool read this, so a profile cannot be admitted on one\n * surface and refused on the other; the bare id and its `id@version` pin are the same\n * admission, and both canonicalize to `ADMITTED_PROFILE_V2.id`.\n */\nexport const ADMITTED_PROFILE_SPECIFIERS_V2: readonly string[] = Object.freeze([\n ADMITTED_PROFILE_V2.id,\n `${ADMITTED_PROFILE_V2.id}@${ADMITTED_PROFILE_V2.version}`,\n]);\n\nexport function isAdmittedProfileSpecifierV2(value: unknown): value is string {\n return typeof value === 'string' && ADMITTED_PROFILE_SPECIFIERS_V2.includes(value);\n}\nexport const BUILTIN_AUTHORITIES_V2 = Object.freeze({\n profile: ADMITTED_PROFILE_V2,\n rules: Object.freeze({ id: 'scanner-core-builtins', version: '2.0.0', digest: 'a36d00564bbf8e8c38f05820480782cdc53fdbd3712558850066c4e3f5c3413d', signatureStatus: 'VERIFIED' as const }),\n semantics: Object.freeze({ id: 'scanner-core-builtins', version: '2.0.0', digest: '1bb11f63269d427cb28e141dfe0a6a1512e53c298abdb4d6450545ceb56d11c4' }),\n limits: Object.freeze({ schemaVersion: 'scanner-limits-v2' as const, digest: 'fca787753ca88f71cf0d174427f4ac730a7aef1c823aaf73aa1ea72af92b4077' }),\n});\nexport const PROFILE_MANIFEST_DIGEST_V2 = ADMITTED_PROFILE_V2.digest;\nexport const BUILTIN_RULESET_AUTHORITY_V2 = BUILTIN_AUTHORITIES_V2.rules;\nexport const BUILTIN_SEMANTICS_AUTHORITY_V2 = BUILTIN_AUTHORITIES_V2.semantics;\nexport const BUILTIN_LIMITS_AUTHORITY_V2 = BUILTIN_AUTHORITIES_V2.limits;\nexport const RULE_PACK_DIGEST_V2 = BUILTIN_RULESET_AUTHORITY_V2.digest;\nexport const SEMANTIC_CATALOGUE_DIGEST_V2 = BUILTIN_SEMANTICS_AUTHORITY_V2.digest;\n\nexport const DEFAULT_SCAN_CONFIG_V2: ScanConfigV2 = Object.freeze({\n schemaVersion: SCAN_CONFIG_SCHEMA_V2,\n format: 'json', profile: ADMITTED_PROFILE_V2.id, failOn: 'INFO', requireComplete: false, concurrency: 1,\n rules: 'builtin', catalogue: 'builtin', limits: 'builtin',\n include: Object.freeze(['**/*.json']), exclude: Object.freeze(['.git/**', 'node_modules/**']),\n allowUnsignedDevelopmentRules: false, noColor: false,\n});\n\nexport const SCAN_CONFIG_V2_FIELDS = Object.freeze([\n 'schemaVersion', 'format', 'profile', 'output', 'inputs', 'configPath', 'failOn', 'requireComplete', 'concurrency',\n 'rules', 'catalogue', 'limits', 'target', 'include', 'exclude', 'allowUnsignedDevelopmentRules', 'noColor',\n] as const);\nexport const SCAN_CONFIG_V2_MAX_STRING = 4096;\nexport const SCAN_CONFIG_V2_MAX_PATTERNS = 1024;\nexport const SCAN_CONFIG_V2_MAX_CONCURRENCY = 16;\n", "import { isAdmittedProfileSpecifierV2, type ScanConfigV2, type ScanSeverityV2 } from './contracts';\nimport type { V2CommandName } from './help';\n\nexport type CliFormatV2 = 'json' | 'ndjson' | 'sarif' | 'table';\nexport type CliProfileV2 = 'beta-default' | 'beta-hardened';\nexport type CliTargetEnumV2 = 'UNKNOWN' | 'COMMUNITY' | 'ENTERPRISE' | 'CLOUD' | 'SELF_HOSTED' | 'OWNER' | 'ADMIN' | 'MEMBER' | 'LEGACY' | 'NATIVE';\nexport type CliParseErrorCodeV2 = 'NO_COMMAND' | 'UNKNOWN_COMMAND' | 'UNKNOWN_OPTION' | 'MISSING_VALUE' | 'INVALID_VALUE' | 'DUPLICATE_OPTION' | 'UNEXPECTED_ARGUMENT' | 'REMOTE_PATH' | 'RULE_PACK_INVALID' | 'SEMANTIC_CATALOGUE_INVALID' | 'PROFILE_NOT_ADMITTED';\nexport type CliParseErrorV2 = Readonly<{ code: CliParseErrorCodeV2; message: string; argument?: string }>;\n\ntype ScanCommandV2 = Readonly<{\n kind: 'scan'; schema: 'v2'; inputs: readonly string[]; format: CliFormatV2; profile: CliProfileV2; failOn: ScanSeverityV2;\n requireComplete: boolean; concurrency: number; timeoutMs?: number; output?: string; configPath?: string;\n rules: 'builtin'; catalogue: 'builtin'; limits: string; target?: string; n8nVersion?: string;\n edition: 'COMMUNITY' | 'ENTERPRISE' | 'CLOUD' | 'UNKNOWN'; deployment: 'SELF_HOSTED' | 'CLOUD' | 'UNKNOWN';\n role: 'OWNER' | 'ADMIN' | 'MEMBER' | 'UNKNOWN'; taskRunner: 'LEGACY' | 'NATIVE' | 'UNKNOWN';\n communityPackages: readonly string[]; configuration: readonly string[]; include: readonly string[]; exclude: readonly string[];\n allowUnsignedDevelopmentRules: boolean; noColor: boolean; cliOverrides: Readonly<Partial<ScanConfigV2>>;\n}>;\nexport type CliHelpCommandV2 = Readonly<{ kind: 'help'; schema: 'v2'; command?: V2CommandName }>;\nexport type CliCommandV2 = ScanCommandV2\n | Readonly<{ kind: 'rules'; schema: 'v2'; format: 'json' | 'table' }>\n | Readonly<{ kind: 'explain'; schema: 'v2'; format: 'json' | 'table'; ruleId: string }>\n | Readonly<{ kind: 'profiles'; schema: 'v2'; format: 'json' | 'table' }>\n | Readonly<{ kind: 'validate-config'; schema: 'v2'; format: 'json' | 'table'; path: string }>\n | Readonly<{ kind: 'version'; schema: 'v2'; format: 'json' | 'table' }>;\ntype ParsedCommandV2 = CliCommandV2 | CliHelpCommandV2;\nexport type CliParseResultV2 = Readonly<{ ok: true; command: ParsedCommandV2 } | { ok: false; error: CliParseErrorV2 }>;\nexport type CliArgumentDispatch = Readonly<{ mode: 'v1'; argv: readonly string[] } | { mode: 'v2'; result: CliParseResultV2 }>;\n\nconst severities: readonly ScanSeverityV2[] = ['CRITICAL', 'HIGH', 'MEDIUM', 'LOW', 'INFO'];\nconst commands: Record<string, true> = Object.freeze({ scan: true, rules: true, explain: true, profiles: true, 'validate-config': true, version: true, '--version': true });\nconst implicitV2Commands: Record<string, true> = Object.freeze({ rules: true, explain: true, profiles: true, 'validate-config': true, version: true });\nconst scalarOptions: Record<string, true> = Object.freeze({ '--format': true, '--profile': true, '--fail-on': true, '--max-concurrency': true, '--concurrency': true, '--timeout': true, '--output': true, '--config': true, '--rules': true, '--catalogue': true, '--limits': true, '--target': true, '--n8n-version': true, '--edition': true, '--deployment': true, '--role': true, '--task-runner': true });\nconst repeatableOptions: Record<string, true> = Object.freeze({ '--community-package': true, '--configuration': true, '--include': true, '--exclude': true });\nconst configFields: Record<string, keyof ScanConfigV2> = Object.freeze({ '--format': 'format', '--profile': 'profile', '--fail-on': 'failOn', '--max-concurrency': 'concurrency', '--concurrency': 'concurrency', '--output': 'output', '--config': 'configPath', '--rules': 'rules', '--catalogue': 'catalogue', '--limits': 'limits', '--target': 'target', '--include': 'include', '--exclude': 'exclude', 'inputs': 'inputs', '--require-complete': 'requireComplete', '--allow-unsigned-development-rules': 'allowUnsignedDevelopmentRules', '--no-color': 'noColor' });\nconst overrideOrder: readonly (keyof ScanConfigV2)[] = ['format', 'profile', 'output', 'inputs', 'configPath', 'failOn', 'requireComplete', 'concurrency', 'rules', 'catalogue', 'limits', 'target', 'include', 'exclude', 'allowUnsignedDevelopmentRules', 'noColor'];\n\nexport function parseArgumentsV2(argv: readonly string[]): CliParseResultV2 {\n const stripped = stripSchema(argv); if (!stripped.ok) return stripped.result;\n const args = stripped.args; const raw = args[0];\n if (!raw) return failure('NO_COMMAND', 'A v2 command is required.');\n if (raw === '--help') return success({ kind: 'help', schema: 'v2' });\n if (commands[raw] !== true) return failure('UNKNOWN_COMMAND', 'Unknown v2 command.');\n const kind = raw === '--version' ? 'version' : raw;\n if (kind !== 'scan') return parseMetadata(kind as Exclude<CliCommandV2['kind'], 'scan' | 'help'>, args.slice(1));\n if (args.length === 2 && args[1] === '--help') return success({ kind: 'help', schema: 'v2', command: 'scan' });\n const value: Record<string, unknown> = {\n kind: 'scan', schema: 'v2', inputs: [], format: 'json', profile: 'beta-default', failOn: 'INFO', requireComplete: false,\n concurrency: 1, rules: 'builtin', catalogue: 'builtin', limits: 'builtin', edition: 'UNKNOWN', deployment: 'UNKNOWN',\n role: 'UNKNOWN', taskRunner: 'UNKNOWN', communityPackages: [], configuration: [], include: ['**/*.json'],\n exclude: ['.git/**', 'node_modules/**'], allowUnsignedDevelopmentRules: false, noColor: false,\n };\n const overrides: Record<string, unknown> = {}; const inputs: string[] = []; const repeatable: Record<string, string[]> = { '--community-package': [], '--configuration': [], '--include': [], '--exclude': [] }; const seen = new Set<string>();\n for (let index = 1; index < args.length; index += 1) {\n const token = args[index]!;\n if (token === '--') { inputs.push(...args.slice(index + 1)); break; }\n if (token === '-' || !token.startsWith('-')) { if (!local(token)) return failure('REMOTE_PATH', 'Input path is not admitted.'); inputs.push(token); continue; }\n const [name, inline] = splitOption(token);\n if (name === '--require-complete' || name === '--allow-unsigned-development-rules' || name === '--no-color') {\n if (inline !== undefined || seen.has(name)) return failure('DUPLICATE_OPTION', 'Option supplied more than once.', name);\n seen.add(name); value[name === '--require-complete' ? 'requireComplete' : name === '--no-color' ? 'noColor' : 'allowUnsignedDevelopmentRules'] = true; overrides[configFields[name]!] = true; continue;\n }\n if (scalarOptions[name] !== true && repeatableOptions[name] !== true) return failure('UNKNOWN_OPTION', 'Unknown option.', name);\n const duplicateKey = name === '--max-concurrency' ? '--concurrency' : name;\n if (seen.has(duplicateKey) && scalarOptions[name] === true) return failure('DUPLICATE_OPTION', 'Option supplied more than once.', name);\n const read = inline === undefined ? args[index + 1] : inline;\n if (read === undefined || read.length === 0 || (inline === undefined && read.startsWith('-') && !(name === '--output' && read === '-'))) return failure('MISSING_VALUE', 'Option requires a value.', name);\n if (inline === undefined) index += 1;\n if (repeatableOptions[name] === true) { if (!local(read)) return failure('REMOTE_PATH', 'Option value is not admitted.', name); repeatable[name]!.push(read); if (configFields[name]) overrides[configFields[name]!] = Object.freeze([...repeatable[name]!]); continue; }\n if (name === '--format' && !['json', 'ndjson', 'sarif', 'table'].includes(read)) return failure('INVALID_VALUE', 'Format is invalid.', name);\n if (name === '--profile' && !isAdmittedProfileSpecifierV2(read)) return failure('PROFILE_NOT_ADMITTED', 'Profile is not admitted.', name);\n if (name === '--fail-on' && !severities.includes(read as ScanSeverityV2)) return failure('INVALID_VALUE', 'Fail threshold is invalid.', name);\n if ((name === '--max-concurrency' || name === '--concurrency' || name === '--timeout') && !positiveInteger(read, name === '--timeout' ? 2 ** 31 - 1 : 16)) return failure('INVALID_VALUE', 'Numeric option is invalid.', name);\n if (name === '--n8n-version' && !/^\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?(?:\\+[0-9A-Za-z.-]+)?$/.test(read)) return failure('INVALID_VALUE', 'n8n version is invalid.', name);\n if (name === '--edition' && !['COMMUNITY', 'ENTERPRISE', 'CLOUD', 'UNKNOWN'].includes(read)) return failure('INVALID_VALUE', 'Edition is invalid.', name);\n if (name === '--deployment' && !['SELF_HOSTED', 'CLOUD', 'UNKNOWN'].includes(read)) return failure('INVALID_VALUE', 'Deployment is invalid.', name);\n if (name === '--role' && !['OWNER', 'ADMIN', 'MEMBER', 'UNKNOWN'].includes(read)) return failure('INVALID_VALUE', 'Role is invalid.', name);\n if (name === '--task-runner' && !['LEGACY', 'NATIVE', 'UNKNOWN'].includes(read)) return failure('INVALID_VALUE', 'Task runner is invalid.', name);\n if (name === '--rules' || name === '--catalogue') { if (read !== 'builtin') return failure(name === '--rules' ? 'RULE_PACK_INVALID' : 'SEMANTIC_CATALOGUE_INVALID', 'Only built-in authority is available.', name); }\n else if (['--limits', '--target', '--config'].includes(name) && (read === '-' || !local(read))) return failure('REMOTE_PATH', 'Option value is not admitted.', name);\n else if (name === '--output' && read !== '-' && !local(read)) return failure('REMOTE_PATH', 'Option value is not admitted.', name);\n else if (['--n8n-version', '--edition', '--deployment', '--role', '--task-runner'].includes(name) && !safeText(read)) return failure('INVALID_VALUE', 'Option value is not admitted.', name);\n seen.add(duplicateKey); assign(value, name, read); if (configFields[name]) overrides[configFields[name]!] = ['--max-concurrency', '--concurrency'].includes(name) ? Number(read) : read;\n }\n // No external rule pack is admittable: `--rules`/`--catalogue` accept only the built-in authority,\n // so the unsigned development escape hatch has nothing it could admit. It is refused as a usage\n // error instead of being left to imply that a local pack would be loaded.\n if (value.allowUnsignedDevelopmentRules === true) return failure('RULE_PACK_INVALID', 'External rule packs are not admitted in this release.', '--allow-unsigned-development-rules');\n if (inputs.length === 0) return failure('UNEXPECTED_ARGUMENT', 'At least one workflow input is required.');\n if (inputs.some((input) => !local(input))) return failure('REMOTE_PATH', 'Input path is not admitted.');\n if (inputs.includes('-') && inputs.length > 1) return failure('UNEXPECTED_ARGUMENT', 'Standard input cannot be combined with file inputs.');\n overrides.inputs = Object.freeze([...inputs]);\n const cliOverrides: Partial<ScanConfigV2> = {}; const sparse = cliOverrides as Record<string, unknown>; for (const field of overrideOrder) if (Object.prototype.hasOwnProperty.call(overrides, field)) sparse[field] = overrides[field];\n const command: ScanCommandV2 = {\n kind: 'scan', schema: 'v2', inputs: Object.freeze([...inputs]), format: value.format as CliFormatV2, profile: value.profile as CliProfileV2, failOn: value.failOn as ScanSeverityV2, requireComplete: value.requireComplete as boolean, concurrency: value.concurrency as number,\n ...(typeof value.timeoutMs === 'number' ? { timeoutMs: value.timeoutMs } : {}), ...(typeof value.output === 'string' ? { output: value.output } : {}), ...(typeof value.configPath === 'string' ? { configPath: value.configPath } : {}), rules: value.rules as 'builtin', catalogue: value.catalogue as 'builtin', limits: value.limits as string,\n ...(typeof value.target === 'string' ? { target: value.target } : {}), ...(typeof value.n8nVersion === 'string' ? { n8nVersion: value.n8nVersion } : {}), edition: value.edition as ScanCommandV2['edition'], deployment: value.deployment as ScanCommandV2['deployment'], role: value.role as ScanCommandV2['role'], taskRunner: value.taskRunner as ScanCommandV2['taskRunner'], communityPackages: arrayFor(repeatable['--community-package']), configuration: arrayFor(repeatable['--configuration']), include: repeatable['--include']!.length > 0 ? arrayFor(repeatable['--include']) : Object.freeze(['**/*.json']), exclude: repeatable['--exclude']!.length > 0 ? arrayFor(repeatable['--exclude']) : Object.freeze(['.git/**', 'node_modules/**']), allowUnsignedDevelopmentRules: value.allowUnsignedDevelopmentRules as boolean, noColor: value.noColor as boolean, cliOverrides,\n };\n return success(command);\n}\n\nfunction arrayFor(values: readonly string[] | undefined): readonly string[] { return Object.freeze([...(values ?? [])]); }\nexport function parseCliArguments(argv: readonly string[]): CliArgumentDispatch { const hasSchema = hasSchemaMarker(argv); const implicit = argv[0] !== undefined && implicitV2Commands[argv[0]!] === true; return hasSchema || implicit ? freeze({ mode: 'v2', result: parseArgumentsV2(argv) }) : freeze({ mode: 'v1', argv: Object.freeze([...argv]) }); }\nfunction parseMetadata(kind: Exclude<CliCommandV2['kind'], 'scan' | 'help'>, args: readonly string[]): CliParseResultV2 {\n if (args.length === 1 && args[0] === '--help') return success({ kind: 'help', schema: 'v2', command: kind });\n let format: 'json' | 'table' = 'json';\n const rest: string[] = [];\n let seen = false;\n for (let index = 0; index < args.length; index += 1) {\n const token = args[index]!;\n if (token.startsWith('-')) {\n const [name, inline] = splitOption(token);\n if (name !== '--format' || seen) return failure(seen ? 'DUPLICATE_OPTION' : 'UNKNOWN_OPTION', seen ? 'Option supplied more than once.' : 'Unknown option.', name);\n const value = inline ?? args[++index];\n if (!value) return failure('MISSING_VALUE', 'Option requires a value.', name);\n if (value !== 'json' && value !== 'table') return failure('INVALID_VALUE', 'Format is invalid.', name);\n format = value;\n seen = true;\n } else rest.push(token);\n }\n if (kind === 'rules' || kind === 'profiles' || kind === 'version') {\n if (rest.length > 0) return failure('UNEXPECTED_ARGUMENT', 'Command does not accept positional arguments.');\n return success({ kind, schema: 'v2', format });\n }\n if (kind === 'explain') return rest.length === 1 && safeText(rest[0]!) ? success({ kind, schema: 'v2', format, ruleId: rest[0]! }) : failure('UNEXPECTED_ARGUMENT', 'explain requires one rule ID.');\n if (rest.length !== 1 || !local(rest[0]!)) return failure('UNEXPECTED_ARGUMENT', 'validate-config requires one local file.');\n return success({ kind, schema: 'v2', format, path: rest[0]! });\n}\nfunction assign(value: Record<string, unknown>, name: string, read: string): void { const fields: Record<string, string> = { '--format': 'format', '--profile': 'profile', '--fail-on': 'failOn', '--max-concurrency': 'concurrency', '--concurrency': 'concurrency', '--timeout': 'timeoutMs', '--output': 'output', '--config': 'configPath', '--rules': 'rules', '--catalogue': 'catalogue', '--limits': 'limits', '--target': 'target', '--n8n-version': 'n8nVersion', '--edition': 'edition', '--deployment': 'deployment', '--role': 'role', '--task-runner': 'taskRunner' }; value[fields[name]!] = ['--max-concurrency', '--concurrency', '--timeout'].includes(name) ? Number(read) : read; }\nfunction splitOption(token: string): [string, string | undefined] { const at = token.indexOf('='); return at < 0 ? [token, undefined] : [token.slice(0, at), token.slice(at + 1)]; }\nfunction positiveInteger(value: string, maximum: number): boolean { if (!/^\\d+$/.test(value)) return false; const number = Number(value); return Number.isSafeInteger(number) && number > 0 && number <= maximum; }\nfunction safeText(value: string): boolean { return value.length > 0 && value.length <= 4096 && !/[\\u0000-\\u001f\\u007f]/.test(value) && !/^(?:[a-z][a-z\\d+.-]*:|\\/|[a-z]:|\\\\\\\\)/i.test(value); }\nfunction local(value: string): boolean { return safeText(value) && !/^(?:[a-z][a-z\\d+.-]*:|\\/|[a-z]:|\\\\\\\\)/i.test(value); }\nfunction hasSchemaMarker(argv: readonly string[]): boolean { for (const token of argv) { if (token === '--') break; if (token === '--schema' || token.startsWith('--schema=')) return true; } return false; }\nfunction stripSchema(argv: readonly string[]): { ok: true; args: readonly string[] } | { ok: false; result: CliParseResultV2 } { const args: string[] = []; let seen = false; for (let index = 0; index < argv.length; index += 1) { const token = argv[index]!; if (token === '--') { args.push(...argv.slice(index)); break; } if (token === '--schema') { if (seen || argv[index + 1] !== 'v2') return { ok: false, result: failure(seen ? 'DUPLICATE_OPTION' : 'INVALID_VALUE', seen ? 'Option supplied more than once.' : 'Schema must be v2.', '--schema') }; seen = true; index += 1; continue; } if (token.startsWith('--schema=')) { if (seen || token.slice(9) !== 'v2') return { ok: false, result: failure(seen ? 'DUPLICATE_OPTION' : 'INVALID_VALUE', seen ? 'Option supplied more than once.' : 'Schema must be v2.', '--schema') }; seen = true; continue; } args.push(token); } return { ok: true, args }; }\nfunction success(command: ParsedCommandV2): CliParseResultV2 { return freeze({ ok: true as const, command }); }\nfunction failure(code: CliParseErrorCodeV2, message: string, argument?: string): CliParseResultV2 { const safe = argument !== undefined && /^--[A-Za-z0-9][A-Za-z0-9-]{0,63}$/.test(argument) ? argument : undefined; return freeze({ ok: false as const, error: { code, message, ...(safe === undefined ? {} : { argument: safe }) } }); }\nfunction freeze<T>(value: T, seen = new WeakSet<object>()): T { if (value && typeof value === 'object') { if (seen.has(value as object)) return value; seen.add(value as object); for (const name of Object.getOwnPropertyNames(value as object)) freeze((value as Record<string, unknown>)[name], seen); Object.freeze(value); } return value; }\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,34 @@
1
+ import type { Stats } from 'node:fs';
2
+ export type AtomicOutputFailureCodeV2 = 'INVALID_CONFIG' | 'SERIALIZATION_FAILED' | 'OUTPUT_WRITE_FAILED' | 'CANCELLED';
3
+ export type AtomicOutputResultV2 = Readonly<{
4
+ ok: true;
5
+ } | {
6
+ ok: false;
7
+ code: AtomicOutputFailureCodeV2;
8
+ message: string;
9
+ }>;
10
+ export type AtomicOutputHandleV2 = Readonly<{
11
+ write: (bytes: Uint8Array) => Promise<void>;
12
+ sync: () => Promise<void>;
13
+ close: () => Promise<void>;
14
+ }>;
15
+ export type AtomicOutputStatV2 = Pick<Stats, 'isFile' | 'isDirectory' | 'isSymbolicLink'>;
16
+ export type AtomicOutputHostV2 = Readonly<{
17
+ lstat?: (path: string) => Promise<AtomicOutputStatV2>;
18
+ realpath?: (path: string) => Promise<string>;
19
+ open?: (path: string) => Promise<AtomicOutputHandleV2>;
20
+ write?: (path: string, bytes: Uint8Array) => Promise<void>;
21
+ sync?: (path: string) => Promise<void>;
22
+ rename?: (from: string, to: string) => Promise<void>;
23
+ unlink?: (path: string) => Promise<void>;
24
+ }>;
25
+ export type AtomicOutputOptionsV2 = Readonly<{
26
+ baseDirectory?: string;
27
+ inputPaths?: readonly string[];
28
+ signal?: AbortSignal;
29
+ maxTempAttempts?: number;
30
+ host?: AtomicOutputHostV2;
31
+ }>;
32
+ export declare function writeAtomicUtf8V2(target: string, text: string, options?: AtomicOutputOptionsV2): Promise<AtomicOutputResultV2>;
33
+ export declare function writeAtomicBytesV2(target: string, bytes: Uint8Array, options?: AtomicOutputOptionsV2): Promise<AtomicOutputResultV2>;
34
+ export declare function writeAtomicOutputV2(target: string, content: string | Uint8Array, options?: AtomicOutputOptionsV2): Promise<AtomicOutputResultV2>;
@@ -0,0 +1,44 @@
1
+ import { type ScanWorkflowV2FailureCode, type ScanWorkflowV2Result } from '@hub/scanner-core/v2';
2
+ import { type ScanConfigV2 } from './config';
3
+ import { type CliStdin, type InputReadHost, type ReadInputResult } from './input-read';
4
+ import type { SelectedInputV2 } from './input-selection';
5
+ import { type SigintSource } from './worker-host';
6
+ export type BatchErrorCodeV2 = ScanWorkflowV2FailureCode | 'INPUT_READ_FAILED';
7
+ export type BatchItemStatusV2 = 'COMPLETED' | 'FAILED' | 'CANCELLED' | 'TIMEOUT';
8
+ export type BatchItemV2 = Readonly<{
9
+ label: string;
10
+ status: BatchItemStatusV2;
11
+ result?: ScanWorkflowV2Result;
12
+ error?: Readonly<{
13
+ code: BatchErrorCodeV2;
14
+ }>;
15
+ }>;
16
+ export type BatchResultV2 = Readonly<{
17
+ ok: true;
18
+ items: readonly BatchItemV2[];
19
+ cancelled: boolean;
20
+ completed: number;
21
+ failed: number;
22
+ concurrency: number;
23
+ }> | Readonly<{
24
+ ok: false;
25
+ code: 'INVALID_CONFIG' | 'CANCELLED';
26
+ message: string;
27
+ }>;
28
+ export type BatchScanV2 = (bytes: Uint8Array, item: SelectedInputV2) => ScanWorkflowV2Result | PromiseLike<ScanWorkflowV2Result>;
29
+ export type BatchReadV2 = (item: SelectedInputV2) => Uint8Array | ReadInputResult | PromiseLike<Uint8Array | ReadInputResult>;
30
+ export type BatchRunnerInput = Readonly<{
31
+ items: readonly SelectedInputV2[];
32
+ config: ScanConfigV2;
33
+ scan?: BatchScanV2;
34
+ read?: BatchReadV2;
35
+ stdin?: CliStdin;
36
+ readHost?: InputReadHost;
37
+ baseDirectory?: string;
38
+ maxInputBytes?: number;
39
+ timeoutMs?: number;
40
+ signal?: AbortSignal;
41
+ sigint?: SigintSource;
42
+ now?: () => number;
43
+ }>;
44
+ export declare function runBatchV2(input: BatchRunnerInput): Promise<BatchResultV2>;
@@ -0,0 +1,28 @@
1
+ import type { CliStdin, InputReadHost } from './input-read';
2
+ import { type InputSelectionHost } from './input-selection';
3
+ import type { CliCommandV2 } from './arguments';
4
+ import { type BatchReadV2, type BatchScanV2 } from './batch-runner';
5
+ import { type CliEnvelopeV2 } from './json-output';
6
+ import { type ExitCodeV2 } from './exit-reducer';
7
+ import type { SigintSource } from './worker-host';
8
+ export type V2CliRunOptions = Readonly<{
9
+ cwd?: string;
10
+ stdin?: CliStdin;
11
+ signal?: AbortSignal;
12
+ read?: BatchReadV2;
13
+ scan?: BatchScanV2;
14
+ readHost?: InputReadHost;
15
+ selectionHost?: InputSelectionHost;
16
+ sigint?: SigintSource;
17
+ }>;
18
+ export type V2CliRunResult = Readonly<{
19
+ exitCode: ExitCodeV2;
20
+ stdout: string;
21
+ stderr: string;
22
+ document?: CliEnvelopeV2 | string;
23
+ }>;
24
+ type ScanCommand = Extract<CliCommandV2, {
25
+ kind: 'scan';
26
+ }>;
27
+ export declare function runCliV2(command: ScanCommand, options?: V2CliRunOptions): Promise<V2CliRunResult>;
28
+ export {};