@stll/oxlint-config 1.3.0 → 1.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.
Files changed (65) hide show
  1. package/README.md +254 -17
  2. package/dist/cloud-setup-cli.cjs +18 -38
  3. package/dist/cloud-setup-cli.cjs.map +1 -1
  4. package/dist/cloud-setup-cli.mjs +21 -41
  5. package/dist/cloud-setup-cli.mjs.map +1 -1
  6. package/dist/consumer-compat-cli.cjs +50 -249
  7. package/dist/consumer-compat-cli.cjs.map +1 -1
  8. package/dist/consumer-compat-cli.mjs +6 -205
  9. package/dist/consumer-compat-cli.mjs.map +1 -1
  10. package/dist/consumer-node-support.cjs +497 -0
  11. package/dist/consumer-node-support.cjs.map +1 -0
  12. package/dist/consumer-node-support.mjs +381 -0
  13. package/dist/consumer-node-support.mjs.map +1 -0
  14. package/dist/dependabot-cli.cjs +67 -0
  15. package/dist/dependabot-cli.cjs.map +1 -0
  16. package/dist/dependabot-cli.d.cts +1 -0
  17. package/dist/dependabot-cli.d.mts +1 -0
  18. package/dist/dependabot-cli.mjs +67 -0
  19. package/dist/dependabot-cli.mjs.map +1 -0
  20. package/dist/dependabot.cjs +5 -0
  21. package/dist/dependabot.d.cts +108 -0
  22. package/dist/dependabot.d.mts +108 -0
  23. package/dist/dependabot.mjs +3 -0
  24. package/dist/generated-file.cjs +61 -0
  25. package/dist/generated-file.cjs.map +1 -0
  26. package/dist/generated-file.mjs +44 -0
  27. package/dist/generated-file.mjs.map +1 -0
  28. package/dist/publish-artifact-syntax.cjs +1309 -0
  29. package/dist/publish-artifact-syntax.cjs.map +1 -0
  30. package/dist/publish-artifact-syntax.mjs +1265 -0
  31. package/dist/publish-artifact-syntax.mjs.map +1 -0
  32. package/dist/publish-contract-cli.cjs +53 -12
  33. package/dist/publish-contract-cli.cjs.map +1 -1
  34. package/dist/publish-contract-cli.mjs +49 -8
  35. package/dist/publish-contract-cli.mjs.map +1 -1
  36. package/dist/toolchain-changed.cjs +5 -1
  37. package/dist/toolchain-changed.cjs.map +1 -1
  38. package/dist/toolchain-changed.mjs +6 -2
  39. package/dist/toolchain-changed.mjs.map +1 -1
  40. package/dist/toolchain-dependabot.cjs +455 -0
  41. package/dist/toolchain-dependabot.cjs.map +1 -0
  42. package/dist/toolchain-dependabot.mjs +423 -0
  43. package/dist/toolchain-dependabot.mjs.map +1 -0
  44. package/dist/toolchain-guard.cjs +1096 -424
  45. package/dist/toolchain-guard.cjs.map +1 -1
  46. package/dist/toolchain-guard.mjs +1085 -413
  47. package/dist/toolchain-guard.mjs.map +1 -1
  48. package/dist/toolchain-inputs.cjs +122 -22
  49. package/dist/toolchain-inputs.cjs.map +1 -1
  50. package/dist/toolchain-inputs.mjs +117 -23
  51. package/dist/toolchain-inputs.mjs.map +1 -1
  52. package/dist/toolchain-schema.cjs +0 -493
  53. package/dist/toolchain-schema.cjs.map +1 -1
  54. package/dist/toolchain-schema.mjs +3 -379
  55. package/dist/toolchain-schema.mjs.map +1 -1
  56. package/dist/typecheck-parity.cjs +1 -1
  57. package/dist/typecheck-probe-cli.cjs +1 -1
  58. package/dist/typecheck-probe-cli.cjs.map +1 -1
  59. package/dist/typecheck-probe-cli.mjs +1 -1
  60. package/dist/typecheck-probe-cli.mjs.map +1 -1
  61. package/package.json +13 -1
  62. package/dist/publish-contract.cjs +0 -431
  63. package/dist/publish-contract.cjs.map +0 -1
  64. package/dist/publish-contract.mjs +0 -396
  65. package/dist/publish-contract.mjs.map +0 -1
@@ -0,0 +1,381 @@
1
+ import { m as workspaceContains } from "./toolchain-inputs.mjs";
2
+ import path from "node:path";
3
+ import { satisfies, valid, validRange } from "semver";
4
+ import { isDeepStrictEqual } from "node:util";
5
+ import { parseDocument } from "yaml";
6
+ import picomatch from "picomatch";
7
+ //#region src/consumer-catalogs.ts
8
+ const record = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
9
+ const catalogMapping = (value, field) => {
10
+ if (!record(value)) throw new Error(`${field} must be a mapping`);
11
+ const entries = /* @__PURE__ */ new Map();
12
+ for (const [name, specifier] of Object.entries(value)) {
13
+ if (name === "" || typeof specifier !== "string" || specifier.trim() === "") throw new Error(`${field} must contain nonempty package specifiers`);
14
+ entries.set(name, specifier);
15
+ }
16
+ return Object.fromEntries(entries);
17
+ };
18
+ const catalogState = (source, file) => {
19
+ const result = {};
20
+ if (Object.hasOwn(source, "catalog")) result.catalog = catalogMapping(source["catalog"], `${file}: catalog`);
21
+ if (Object.hasOwn(source, "catalogs")) {
22
+ if (!record(source["catalogs"])) throw new Error(`${file}: catalogs must be a mapping`);
23
+ const named = /* @__PURE__ */ new Map();
24
+ for (const [name, entries] of Object.entries(source["catalogs"])) {
25
+ if (name === "") throw new Error(`${file}: catalog names must be nonempty`);
26
+ named.set(name, catalogMapping(entries, `${file}: catalogs.${name}`));
27
+ }
28
+ result.catalogs = Object.fromEntries(named);
29
+ }
30
+ return result;
31
+ };
32
+ const bunCatalogState = (manifest) => {
33
+ const sources = [manifest];
34
+ if (record(manifest["workspaces"])) sources.push(manifest["workspaces"]);
35
+ const merged = {};
36
+ for (const source of sources) {
37
+ const state = catalogState(source, "package.json");
38
+ for (const [field, value] of Object.entries(state)) {
39
+ if (Object.hasOwn(merged, field) && !isDeepStrictEqual(merged[field], value)) throw new Error(`conflicting Bun ${field} definitions in package.json`);
40
+ merged[field] = value;
41
+ }
42
+ }
43
+ return catalogState(merged, "package.json");
44
+ };
45
+ const pnpmWorkspaceState = (source, file) => {
46
+ const document = parseDocument(source, { uniqueKeys: true });
47
+ if (document.errors.length !== 0) throw new Error(`invalid pnpm workspace: ${file}`);
48
+ const workspace = document.toJS({ maxAliasCount: 100 });
49
+ if (!record(workspace)) throw new Error(`invalid pnpm workspace: ${file}`);
50
+ const packages = workspace["packages"];
51
+ if (packages !== void 0 && (!Array.isArray(packages) || !packages.every((entry) => typeof entry === "string"))) throw new Error(`invalid pnpm workspace packages: ${file}`);
52
+ return {
53
+ packages: packages ?? [],
54
+ ...catalogState(workspace, file)
55
+ };
56
+ };
57
+ const resolveConsumerCatalog = ({ directory: inputDirectory, name, specifier, files }) => {
58
+ let directory = inputDirectory;
59
+ while (true) {
60
+ const yamlFile = path.posix.join(directory, "pnpm-workspace.yaml");
61
+ const yaml = files[yamlFile];
62
+ const manifestFile = path.posix.join(directory, "package.json");
63
+ const json = files[manifestFile];
64
+ let state;
65
+ let patterns = [];
66
+ if (yaml !== void 0) {
67
+ const workspace = pnpmWorkspaceState(yaml, yamlFile);
68
+ state = catalogState(workspace, yamlFile);
69
+ patterns = workspace.packages;
70
+ } else if (json !== void 0) {
71
+ const manifest = JSON.parse(json);
72
+ if (!record(manifest)) throw new Error(`invalid catalog owner: ${manifestFile}`);
73
+ const declaration = manifest["workspaces"];
74
+ if (directory === "." || declaration !== void 0) {
75
+ state = bunCatalogState(manifest);
76
+ const packages = record(declaration) ? declaration["packages"] : declaration;
77
+ if (packages !== void 0 && (!Array.isArray(packages) || !packages.every((entry) => typeof entry === "string"))) throw new Error(`invalid catalog owner packages: ${manifestFile}`);
78
+ patterns = packages ?? [];
79
+ }
80
+ }
81
+ if (state !== void 0) {
82
+ if (!workspaceContains({
83
+ directory,
84
+ file: path.posix.join(inputDirectory, "package.json"),
85
+ patterns,
86
+ rootMembership: "implicit"
87
+ })) throw new Error(`catalog dependency ${name} is outside nearest workspace owner ${directory}`);
88
+ const catalogName = specifier.slice(8) || "default";
89
+ const named = state.catalogs;
90
+ const namedEntries = named !== void 0 && Object.hasOwn(named, catalogName) ? named[catalogName] : void 0;
91
+ const entries = catalogName === "default" ? state.catalog ?? namedEntries : namedEntries;
92
+ const resolved = entries !== void 0 && Object.hasOwn(entries, name) ? entries[name] : void 0;
93
+ if (resolved === void 0) throw new Error(`unresolved catalog dependency ${name} in workspace ${directory}`);
94
+ return resolved;
95
+ }
96
+ if (directory === ".") break;
97
+ directory = path.posix.dirname(directory);
98
+ }
99
+ throw new Error(`unresolved catalog dependency ${name}: no tracked workspace owner`);
100
+ };
101
+ //#endregion
102
+ //#region src/consumer-compat-config.ts
103
+ const consumerRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
104
+ const consumerRelativePath = (value, field) => {
105
+ if (typeof value !== "string" || value === "" || value.includes("\\") || value.includes("\0") || path.posix.isAbsolute(value) || value.split("/").some((part) => part === ".." || part === "")) throw new Error(`${field} must be a repository-relative path`);
106
+ return path.posix.normalize(value);
107
+ };
108
+ const command = (value, field) => {
109
+ if (!Array.isArray(value) || value.length === 0 || !value.every((part) => typeof part === "string" && part !== "" && !part.includes("\0"))) throw new Error(`${field} must be a nonempty command argument array`);
110
+ return value.map((part) => part);
111
+ };
112
+ const parseConsumerFixtures = (input) => {
113
+ if (!consumerRecord(input) || Object.keys(input).some((key) => key !== "packages") || !Array.isArray(input["packages"])) throw new Error("consumer fixtures must contain only a packages array");
114
+ const seen = /* @__PURE__ */ new Set();
115
+ return input["packages"].map((entry) => {
116
+ if (!consumerRecord(entry) || Object.keys(entry).some((key) => ![
117
+ "package",
118
+ "fixture",
119
+ "kind",
120
+ "build",
121
+ "smoke"
122
+ ].includes(key))) throw new Error("invalid consumer fixture declaration");
123
+ const packagePath = consumerRelativePath(entry["package"], "package");
124
+ const fixture = consumerRelativePath(entry["fixture"], "fixture");
125
+ const kind = entry["kind"];
126
+ if (kind !== "node" && kind !== "react") throw new Error("fixture kind must be node or react");
127
+ if (seen.has(packagePath)) throw new Error(`duplicate consumer fixture: ${packagePath}`);
128
+ seen.add(packagePath);
129
+ return {
130
+ package: packagePath,
131
+ fixture,
132
+ kind,
133
+ build: command(entry["build"], "build"),
134
+ smoke: command(entry["smoke"], "smoke")
135
+ };
136
+ });
137
+ };
138
+ const assertConsumerFixtureSelection = ({ selected, fixtures }) => {
139
+ const directories = selected.map((entry) => consumerRelativePath(entry, "selected package"));
140
+ const declared = new Set(fixtures.map((entry) => entry.package));
141
+ if (new Set(directories).size !== directories.length) throw new Error("duplicate selected consumer package");
142
+ if (directories.length !== declared.size || directories.some((entry) => !declared.has(entry))) throw new Error("selected consumer packages must exactly match declared fixtures");
143
+ };
144
+ const consumerBundledDependencyFields = ["bundleDependencies", "bundledDependencies"];
145
+ const consumerPackageNameValid = (value) => {
146
+ if (typeof value !== "string" || value.length === 0 || value.length > 214) return false;
147
+ const components = value.startsWith("@") ? value.slice(1).split("/") : [value];
148
+ if (value.startsWith("@") && components.length !== 2) return false;
149
+ if (!value.startsWith("@") && !/^[a-z0-9]/.test(value)) return false;
150
+ if (components.some((component) => !/^[a-z0-9._-]+$/.test(component) || component === "." || component === "..")) return false;
151
+ const packageName = components.at(-1);
152
+ return packageName !== "node_modules" && packageName !== "favicon.ico";
153
+ };
154
+ const assertConsumerPublishableManifest = ({ manifest, directory }) => {
155
+ const version = manifest["version"];
156
+ if (manifest["private"] !== true && (typeof version !== "string" || valid(version) === null)) throw new Error(`public consumer package requires a semver-valid version: ${directory}`);
157
+ if (manifest["private"] !== true && !consumerPackageNameValid(manifest["name"])) throw new Error(`public consumer package requires a valid npm name: ${directory}`);
158
+ for (const field of consumerBundledDependencyFields) if (Object.hasOwn(manifest, field)) throw new Error(`consumer packaging does not support ${field}: ${directory}`);
159
+ };
160
+ const assertConsumerFixtureKind = ({ fixture, pkg }) => {
161
+ const peers = pkg.manifest["peerDependencies"];
162
+ if (peers !== void 0 && !consumerRecord(peers)) throw new Error(`invalid published peerDependencies: ${pkg.name}`);
163
+ const react = consumerRecord(peers) ? peers["react"] : void 0;
164
+ if (react !== void 0 && (typeof react !== "string" || react.trim() === "" || validRange(react) === null)) throw new Error(`invalid published React peer: ${pkg.name}`);
165
+ const kind = react === void 0 ? "node" : "react";
166
+ if (fixture.kind !== kind) throw new Error(`${pkg.name} requires fixture kind ${kind} from its published peers`);
167
+ };
168
+ const consumerStagingPaths = (packages) => {
169
+ const paths = /* @__PURE__ */ new Map();
170
+ for (const [name, pkg] of packages) paths.set(name, consumerRelativePath(pkg.directory, "workspace package directory"));
171
+ return paths;
172
+ };
173
+ const consumerPackRootManifest = (packages, files) => {
174
+ const source = files["package.json"];
175
+ if (source !== void 0) {
176
+ const manifest = JSON.parse(source);
177
+ if (!consumerRecord(manifest)) throw new Error("root package manifest must be an object");
178
+ return manifest;
179
+ }
180
+ return [...packages.values()].find((pkg) => pkg.directory === ".")?.manifest ?? { private: true };
181
+ };
182
+ const consumerDependencyConfigFiles = [
183
+ ".npmrc",
184
+ ".pnpmfile.cjs",
185
+ "pnpm-workspace.yaml",
186
+ ".yarnrc",
187
+ ".yarnrc.yml"
188
+ ];
189
+ const assertConsumerFixtureManifest = (manifest) => {
190
+ for (const field of [
191
+ "pnpm",
192
+ "overrides",
193
+ "resolutions",
194
+ "workspaces",
195
+ "packageManager",
196
+ "allowScripts"
197
+ ]) if (manifest[field] !== void 0) throw new Error(`consumer fixture must not supply dependency-manager setting: ${field}`);
198
+ };
199
+ const bindConsumerManifest = ({ manifest, artifacts, typescript, react, manager }) => {
200
+ assertConsumerFixtureManifest(manifest);
201
+ const artifactBindings = Object.fromEntries([...artifacts].map(([name, file]) => [name, `file:${file}`]));
202
+ const owned = {
203
+ ...artifactBindings,
204
+ typescript,
205
+ ...react
206
+ };
207
+ const result = { ...manifest };
208
+ for (const field of [
209
+ "dependencies",
210
+ "devDependencies",
211
+ "optionalDependencies",
212
+ "peerDependencies"
213
+ ]) {
214
+ const entries = manifest[field];
215
+ if (entries === void 0) continue;
216
+ if (!consumerRecord(entries)) throw new Error(`fixture ${field} must be an object`);
217
+ for (const specifier of Object.values(entries)) if (typeof specifier !== "string" || /^(?:workspace:|file:|link:|\.\.?\/|\/)/.test(specifier)) throw new Error("fixture dependencies must resolve from registry or generated artifact bindings");
218
+ result[field] = Object.fromEntries(Object.entries(entries).filter(([name]) => !Object.hasOwn(owned, name)));
219
+ }
220
+ result["dependencies"] = {
221
+ ...consumerRecord(result["dependencies"]) ? result["dependencies"] : {},
222
+ ...artifactBindings,
223
+ ...react
224
+ };
225
+ result["devDependencies"] = {
226
+ ...consumerRecord(result["devDependencies"]) ? result["devDependencies"] : {},
227
+ typescript
228
+ };
229
+ if (manager === "npm") {
230
+ result["overrides"] = owned;
231
+ return {
232
+ manager,
233
+ manifest: result
234
+ };
235
+ }
236
+ return {
237
+ manager,
238
+ manifest: result,
239
+ workspace: {
240
+ packages: ["."],
241
+ overrides: owned
242
+ }
243
+ };
244
+ };
245
+ const workspacePatterns = (manifest) => {
246
+ const workspace = manifest["workspaces"];
247
+ const patterns = consumerRecord(workspace) ? workspace["packages"] : workspace;
248
+ if (patterns === void 0) return [];
249
+ if (!Array.isArray(patterns) || !patterns.every((entry) => typeof entry === "string")) throw new Error("package workspaces must be string patterns");
250
+ return patterns.map((entry) => entry);
251
+ };
252
+ const discoverConsumerManifests = (files) => {
253
+ const manifests = /* @__PURE__ */ new Map();
254
+ const manifestSources = /* @__PURE__ */ new Map();
255
+ const pnpmSources = /* @__PURE__ */ new Map();
256
+ const pnpmWorkspaces = /* @__PURE__ */ new Map();
257
+ for (const [file, content] of Object.entries(files)) if (path.posix.basename(file) === "pnpm-workspace.yaml") pnpmSources.set(path.posix.dirname(file), content);
258
+ else if (path.posix.basename(file) === "package.json") manifestSources.set(path.posix.dirname(file), content);
259
+ const assertWorkspaceOwner = (directory) => {
260
+ if (pnpmSources.has(directory) && !manifestSources.has(directory)) throw new Error(`consumer pnpm workspace requires an adjacent tracked package.json: ${path.posix.join(directory, "pnpm-workspace.yaml")}`);
261
+ };
262
+ const candidates = /* @__PURE__ */ new Set([...manifestSources.keys(), ...pnpmSources.keys()]);
263
+ const manifestAt = (directory) => {
264
+ const cached = manifests.get(directory);
265
+ if (cached) return cached;
266
+ const source = manifestSources.get(directory);
267
+ if (source === void 0) return void 0;
268
+ const json = JSON.parse(source);
269
+ if (!consumerRecord(json)) throw new Error(`invalid package manifest: ${directory}/package.json`);
270
+ manifests.set(directory, json);
271
+ return json;
272
+ };
273
+ const patternsAt = (directory, manifest) => {
274
+ const source = pnpmSources.get(directory);
275
+ if (source !== void 0 && !pnpmWorkspaces.has(directory)) {
276
+ const file = `${directory}/pnpm-workspace.yaml`;
277
+ const document = parseDocument(source, { uniqueKeys: true });
278
+ if (document.errors.length) throw new Error(`invalid pnpm workspace: ${file}`);
279
+ const json = document.toJS({ maxAliasCount: 100 });
280
+ if (!consumerRecord(json)) throw new Error(`invalid pnpm workspace: ${file}`);
281
+ const patterns = json["packages"] ?? [];
282
+ if (!Array.isArray(patterns) || !patterns.every((entry) => typeof entry === "string")) throw new Error(`invalid pnpm workspace packages: ${file}`);
283
+ pnpmWorkspaces.set(directory, patterns.map((entry) => entry));
284
+ }
285
+ return pnpmWorkspaces.get(directory) ?? workspacePatterns(manifest ?? {});
286
+ };
287
+ const roots = /* @__PURE__ */ new Set(["."]);
288
+ for (;;) {
289
+ const before = roots.size;
290
+ for (const directory of roots) {
291
+ assertWorkspaceOwner(directory);
292
+ const patterns = patternsAt(directory, manifestAt(directory));
293
+ for (const candidate of candidates) {
294
+ const relative = path.posix.relative(directory, candidate);
295
+ if (relative === "" || relative.startsWith("../")) continue;
296
+ const positives = patterns.filter((pattern) => !pattern.startsWith("!"));
297
+ const negatives = patterns.filter((pattern) => pattern.startsWith("!")).map((pattern) => pattern.slice(1));
298
+ if (positives.some((pattern) => picomatch.isMatch(relative, pattern)) && !negatives.some((pattern) => picomatch.isMatch(relative, pattern))) roots.add(candidate);
299
+ }
300
+ }
301
+ if (before === roots.size) break;
302
+ }
303
+ const discovered = /* @__PURE__ */ new Map();
304
+ for (const directory of roots) {
305
+ for (let owner = directory;; owner = path.posix.dirname(owner)) {
306
+ assertWorkspaceOwner(owner);
307
+ if (owner === ".") break;
308
+ }
309
+ const manifest = manifestAt(directory);
310
+ if (manifest) discovered.set(directory, manifest);
311
+ }
312
+ return discovered;
313
+ };
314
+ const discoverConsumerPackages = (files) => {
315
+ const packages = /* @__PURE__ */ new Map();
316
+ for (const [directory, manifest] of discoverConsumerManifests(files)) {
317
+ const name = manifest["name"];
318
+ if (typeof name !== "string" || name === "") continue;
319
+ if (packages.has(name)) throw new Error(`duplicate workspace package: ${name}`);
320
+ packages.set(name, {
321
+ directory,
322
+ name,
323
+ manifest
324
+ });
325
+ }
326
+ return packages;
327
+ };
328
+ const consumerPublishedDependencyFields = [
329
+ "dependencies",
330
+ "optionalDependencies",
331
+ "peerDependencies"
332
+ ];
333
+ const consumerPackageClosure = ({ selected, packages, files }) => {
334
+ const closure = /* @__PURE__ */ new Map();
335
+ const visit = (pkg) => {
336
+ if (closure.has(pkg.name)) return;
337
+ assertConsumerPublishableManifest(pkg);
338
+ closure.set(pkg.name, pkg);
339
+ for (const field of consumerPublishedDependencyFields) {
340
+ const dependencies = pkg.manifest[field];
341
+ if (!consumerRecord(dependencies)) continue;
342
+ for (const [name, specifier] of Object.entries(dependencies)) {
343
+ const local = packages.get(name);
344
+ if (typeof specifier !== "string") throw new Error(`invalid package dependency: ${pkg.name} -> ${name}`);
345
+ if (specifier.startsWith("catalog:") && local !== void 0) {
346
+ const resolved = resolveConsumerCatalog({
347
+ directory: pkg.directory,
348
+ name,
349
+ specifier,
350
+ files
351
+ });
352
+ const version = local.manifest["version"];
353
+ if (resolved.startsWith("workspace:") || typeof version === "string" && validRange(resolved) !== null && satisfies(version, resolved)) throw new Error(`catalog dependency ${name} resolves to workspace package ${local.name}; use workspace:`);
354
+ }
355
+ if (/^workspace:(?:@[^/@]+\/)?[^/@]+@/.test(specifier)) throw new Error(`workspace alias specifiers are not supported by consumer-compat: ${name} -> ${specifier}; use the package name as the dependency key`);
356
+ if (/^(?:file:|link:)/.test(specifier)) throw new Error(`published local dependencies must use workspace protocol: ${pkg.name} -> ${name}`);
357
+ if (local && (specifier.startsWith("workspace:") || typeof local.manifest["version"] === "string" && validRange(specifier) && satisfies(local.manifest["version"], specifier))) {
358
+ if (local.manifest["private"] === true) throw new Error(`published package depends on private workspace package: ${pkg.name} -> ${name}`);
359
+ visit(local);
360
+ } else if (typeof specifier === "string" && specifier.startsWith("workspace:")) throw new Error(`unresolved workspace dependency: ${pkg.name} -> ${name}`);
361
+ }
362
+ }
363
+ };
364
+ visit(selected);
365
+ return closure;
366
+ };
367
+ //#endregion
368
+ //#region src/consumer-node-support.ts
369
+ const consumerNodeSupportMatches = ({ range, node }) => range === void 0 || typeof range === "string" && range.trim() !== "" && validRange(range) !== null && satisfies(node, range);
370
+ const assertConsumerNodeSupport = ({ manifest, node, label }) => {
371
+ const engines = manifest["engines"];
372
+ const record = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
373
+ if (engines !== void 0 && !record(engines) || !consumerNodeSupportMatches({
374
+ range: record(engines) ? engines["node"] : void 0,
375
+ node
376
+ })) throw new Error(`${label} engines.node must support consumer Node ${node}`);
377
+ };
378
+ //#endregion
379
+ export { bunCatalogState as _, assertConsumerFixtureSelection as a, consumerDependencyConfigFiles as c, consumerRecord as d, consumerRelativePath as f, parseConsumerFixtures as g, discoverConsumerPackages as h, assertConsumerFixtureManifest as i, consumerPackRootManifest as l, discoverConsumerManifests as m, consumerNodeSupportMatches as n, assertConsumerPublishableManifest as o, consumerStagingPaths as p, assertConsumerFixtureKind as r, bindConsumerManifest as s, assertConsumerNodeSupport as t, consumerPackageClosure as u, catalogState as v, pnpmWorkspaceState as y };
380
+
381
+ //# sourceMappingURL=consumer-node-support.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consumer-node-support.mjs","names":[],"sources":["../src/consumer-catalogs.ts","../src/consumer-compat-config.ts","../src/consumer-node-support.ts"],"sourcesContent":["import path from \"node:path\";\nimport { isDeepStrictEqual } from \"node:util\";\nimport { parseDocument } from \"yaml\";\n\nimport { workspaceContains } from \"./toolchain-workspaces\";\n\nconst record = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst catalogMapping = (value: unknown, field: string) => {\n if (!record(value)) throw new Error(`${field} must be a mapping`);\n const entries = new Map<string, string>();\n for (const [name, specifier] of Object.entries(value)) {\n if (name === \"\" || typeof specifier !== \"string\" || specifier.trim() === \"\")\n throw new Error(`${field} must contain nonempty package specifiers`);\n entries.set(name, specifier);\n }\n return Object.fromEntries(entries);\n};\n\nexport const catalogState = (source: Record<string, unknown>, file: string) => {\n const result: {\n catalog?: Record<string, string>;\n catalogs?: Record<string, Record<string, string>>;\n } = {};\n if (Object.hasOwn(source, \"catalog\"))\n result.catalog = catalogMapping(source[\"catalog\"], `${file}: catalog`);\n if (Object.hasOwn(source, \"catalogs\")) {\n if (!record(source[\"catalogs\"]))\n throw new Error(`${file}: catalogs must be a mapping`);\n const named = new Map<string, Record<string, string>>();\n for (const [name, entries] of Object.entries(source[\"catalogs\"])) {\n if (name === \"\")\n throw new Error(`${file}: catalog names must be nonempty`);\n named.set(name, catalogMapping(entries, `${file}: catalogs.${name}`));\n }\n result.catalogs = Object.fromEntries(named);\n }\n return result;\n};\n\nexport const bunCatalogState = (manifest: Record<string, unknown>) => {\n const sources = [manifest];\n if (record(manifest[\"workspaces\"])) sources.push(manifest[\"workspaces\"]);\n const merged: Record<string, unknown> = {};\n for (const source of sources) {\n const state = catalogState(source, \"package.json\");\n for (const [field, value] of Object.entries(state)) {\n if (\n Object.hasOwn(merged, field) &&\n !isDeepStrictEqual(merged[field], value)\n )\n throw new Error(`conflicting Bun ${field} definitions in package.json`);\n merged[field] = value;\n }\n }\n return catalogState(merged, \"package.json\");\n};\n\nexport const pnpmWorkspaceState = (source: string, file: string) => {\n const document = parseDocument(source, { uniqueKeys: true });\n if (document.errors.length !== 0)\n throw new Error(`invalid pnpm workspace: ${file}`);\n const workspace: unknown = document.toJS({ maxAliasCount: 100 });\n if (!record(workspace)) throw new Error(`invalid pnpm workspace: ${file}`);\n const packages = workspace[\"packages\"];\n if (\n packages !== undefined &&\n (!Array.isArray(packages) ||\n !packages.every((entry: unknown) => typeof entry === \"string\"))\n )\n throw new Error(`invalid pnpm workspace packages: ${file}`);\n return { packages: packages ?? [], ...catalogState(workspace, file) };\n};\n\ntype ResolveConsumerCatalogOptions = {\n directory: string;\n name: string;\n specifier: string;\n files: Record<string, string>;\n};\nexport const resolveConsumerCatalog = ({\n directory: inputDirectory,\n name,\n specifier,\n files,\n}: ResolveConsumerCatalogOptions) => {\n let directory = inputDirectory;\n while (true) {\n const yamlFile = path.posix.join(directory, \"pnpm-workspace.yaml\");\n const yaml = files[yamlFile];\n const manifestFile = path.posix.join(directory, \"package.json\");\n const json = files[manifestFile];\n let state: ReturnType<typeof catalogState> | undefined;\n let patterns: string[] = [];\n if (yaml !== undefined) {\n const workspace = pnpmWorkspaceState(yaml, yamlFile);\n state = catalogState(workspace, yamlFile);\n patterns = workspace.packages;\n } else if (json !== undefined) {\n const manifest: unknown = JSON.parse(json);\n if (!record(manifest))\n throw new Error(`invalid catalog owner: ${manifestFile}`);\n const declaration = manifest[\"workspaces\"];\n if (directory === \".\" || declaration !== undefined) {\n state = bunCatalogState(manifest);\n const packages = record(declaration)\n ? declaration[\"packages\"]\n : declaration;\n if (\n packages !== undefined &&\n (!Array.isArray(packages) ||\n !packages.every((entry: unknown) => typeof entry === \"string\"))\n )\n throw new Error(`invalid catalog owner packages: ${manifestFile}`);\n patterns = packages ?? [];\n }\n }\n if (state !== undefined) {\n if (\n !workspaceContains({\n directory,\n file: path.posix.join(inputDirectory, \"package.json\"),\n patterns,\n rootMembership: \"implicit\",\n })\n )\n throw new Error(\n `catalog dependency ${name} is outside nearest workspace owner ${directory}`,\n );\n const catalogName = specifier.slice(\"catalog:\".length) || \"default\";\n const named = state.catalogs;\n const namedEntries =\n named !== undefined && Object.hasOwn(named, catalogName)\n ? named[catalogName]\n : undefined;\n const entries =\n catalogName === \"default\"\n ? (state.catalog ?? namedEntries)\n : namedEntries;\n const resolved =\n entries !== undefined && Object.hasOwn(entries, name)\n ? entries[name]\n : undefined;\n if (resolved === undefined)\n throw new Error(\n `unresolved catalog dependency ${name} in workspace ${directory}`,\n );\n return resolved;\n }\n if (directory === \".\") break;\n directory = path.posix.dirname(directory);\n }\n throw new Error(\n `unresolved catalog dependency ${name}: no tracked workspace owner`,\n );\n};\n","import path from \"node:path\";\nimport picomatch from \"picomatch\";\nimport { compare, satisfies, valid, validRange } from \"semver\";\nimport { parseDocument } from \"yaml\";\n\nimport { resolveConsumerCatalog } from \"./consumer-catalogs\";\n\nexport const consumerFixtureKinds = [\"node\", \"react\"] as const;\nexport type ConsumerFixture = {\n package: string;\n fixture: string;\n kind: (typeof consumerFixtureKinds)[number];\n build: string[];\n smoke: string[];\n};\n\nexport const consumerRecord = (\n value: unknown,\n): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nexport const consumerRelativePath = (value: unknown, field: string) => {\n if (\n typeof value !== \"string\" ||\n value === \"\" ||\n value.includes(\"\\\\\") ||\n value.includes(\"\\0\") ||\n path.posix.isAbsolute(value) ||\n value.split(\"/\").some((part) => part === \"..\" || part === \"\")\n )\n throw new Error(`${field} must be a repository-relative path`);\n return path.posix.normalize(value);\n};\n\nconst command = (value: unknown, field: string) => {\n if (\n !Array.isArray(value) ||\n value.length === 0 ||\n !value.every(\n (part: unknown) =>\n typeof part === \"string\" && part !== \"\" && !part.includes(\"\\0\"),\n )\n )\n throw new Error(`${field} must be a nonempty command argument array`);\n return value.map((part: string) => part);\n};\n\nexport const parseConsumerFixtures = (input: unknown): ConsumerFixture[] => {\n if (\n !consumerRecord(input) ||\n Object.keys(input).some((key) => key !== \"packages\") ||\n !Array.isArray(input[\"packages\"])\n )\n throw new Error(\"consumer fixtures must contain only a packages array\");\n const seen = new Set<string>();\n return input[\"packages\"].map((entry: unknown) => {\n if (\n !consumerRecord(entry) ||\n Object.keys(entry).some(\n (key) =>\n ![\"package\", \"fixture\", \"kind\", \"build\", \"smoke\"].includes(key),\n )\n )\n throw new Error(\"invalid consumer fixture declaration\");\n const packagePath = consumerRelativePath(entry[\"package\"], \"package\");\n const fixture = consumerRelativePath(entry[\"fixture\"], \"fixture\");\n const kind = entry[\"kind\"];\n if (kind !== \"node\" && kind !== \"react\")\n throw new Error(\"fixture kind must be node or react\");\n if (seen.has(packagePath))\n throw new Error(`duplicate consumer fixture: ${packagePath}`);\n seen.add(packagePath);\n return {\n package: packagePath,\n fixture,\n kind,\n build: command(entry[\"build\"], \"build\"),\n smoke: command(entry[\"smoke\"], \"smoke\"),\n };\n });\n};\n\ntype ConsumerFixtureSelectionOptions = {\n selected: readonly string[];\n fixtures: readonly ConsumerFixture[];\n};\nexport const assertConsumerFixtureSelection = ({\n selected,\n fixtures,\n}: ConsumerFixtureSelectionOptions) => {\n const directories = selected.map((entry) =>\n consumerRelativePath(entry, \"selected package\"),\n );\n const declared = new Set(fixtures.map((entry) => entry.package));\n if (new Set(directories).size !== directories.length)\n throw new Error(\"duplicate selected consumer package\");\n if (\n directories.length !== declared.size ||\n directories.some((entry) => !declared.has(entry))\n )\n throw new Error(\n \"selected consumer packages must exactly match declared fixtures\",\n );\n};\n\nexport type ConsumerPackage = {\n directory: string;\n name: string;\n manifest: Record<string, unknown>;\n};\n\nexport const consumerBundledDependencyFields = [\n \"bundleDependencies\",\n \"bundledDependencies\",\n] as const;\n\nconst consumerPackageNameValid = (value: unknown) => {\n if (typeof value !== \"string\" || value.length === 0 || value.length > 214)\n return false;\n const components = value.startsWith(\"@\")\n ? value.slice(1).split(\"/\")\n : [value];\n if (value.startsWith(\"@\") && components.length !== 2) return false;\n if (!value.startsWith(\"@\") && !/^[a-z0-9]/.test(value)) return false;\n if (\n components.some(\n (component) =>\n !/^[a-z0-9._-]+$/.test(component) ||\n component === \".\" ||\n component === \"..\",\n )\n )\n return false;\n const packageName = components.at(-1);\n return packageName !== \"node_modules\" && packageName !== \"favicon.ico\";\n};\n\nexport const assertConsumerPublishableManifest = ({\n manifest,\n directory,\n}: Pick<ConsumerPackage, \"manifest\" | \"directory\">) => {\n const version = manifest[\"version\"];\n if (\n manifest[\"private\"] !== true &&\n (typeof version !== \"string\" || valid(version) === null)\n )\n throw new Error(\n `public consumer package requires a semver-valid version: ${directory}`,\n );\n if (\n manifest[\"private\"] !== true &&\n !consumerPackageNameValid(manifest[\"name\"])\n )\n throw new Error(\n `public consumer package requires a valid npm name: ${directory}`,\n );\n for (const field of consumerBundledDependencyFields)\n if (Object.hasOwn(manifest, field))\n throw new Error(\n `consumer packaging does not support ${field}: ${directory}`,\n );\n};\n\ntype ConsumerFixtureKindOptions = {\n fixture: ConsumerFixture;\n pkg: ConsumerPackage;\n};\n\nexport const assertConsumerFixtureKind = ({\n fixture,\n pkg,\n}: ConsumerFixtureKindOptions) => {\n const peers = pkg.manifest[\"peerDependencies\"];\n if (peers !== undefined && !consumerRecord(peers))\n throw new Error(`invalid published peerDependencies: ${pkg.name}`);\n const react = consumerRecord(peers) ? peers[\"react\"] : undefined;\n if (\n react !== undefined &&\n (typeof react !== \"string\" ||\n react.trim() === \"\" ||\n validRange(react) === null)\n )\n throw new Error(`invalid published React peer: ${pkg.name}`);\n const kind = react === undefined ? \"node\" : \"react\";\n if (fixture.kind !== kind)\n throw new Error(\n `${pkg.name} requires fixture kind ${kind} from its published peers`,\n );\n};\n\nexport const consumerStagingPaths = (\n packages: Map<string, ConsumerPackage>,\n) => {\n const paths = new Map<string, string>();\n for (const [name, pkg] of packages)\n paths.set(\n name,\n consumerRelativePath(pkg.directory, \"workspace package directory\"),\n );\n return paths;\n};\n\nexport const consumerPackRootManifest = (\n packages: Map<string, ConsumerPackage>,\n files: Record<string, string>,\n) => {\n const source = files[\"package.json\"];\n if (source !== undefined) {\n const manifest: unknown = JSON.parse(source);\n if (!consumerRecord(manifest))\n throw new Error(\"root package manifest must be an object\");\n return manifest;\n }\n const root = [...packages.values()].find((pkg) => pkg.directory === \".\");\n return root?.manifest ?? { private: true };\n};\n\nexport const consumerDependencyConfigFiles = [\n \".npmrc\",\n \".pnpmfile.cjs\",\n \"pnpm-workspace.yaml\",\n \".yarnrc\",\n \".yarnrc.yml\",\n] as const;\n\nexport const assertConsumerFixtureManifest = (\n manifest: Record<string, unknown>,\n) => {\n for (const field of [\n \"pnpm\",\n \"overrides\",\n \"resolutions\",\n \"workspaces\",\n \"packageManager\",\n \"allowScripts\",\n ])\n if (manifest[field] !== undefined)\n throw new Error(\n `consumer fixture must not supply dependency-manager setting: ${field}`,\n );\n};\n\ntype BindConsumerManifestOptions = {\n manifest: Record<string, unknown>;\n artifacts: Map<string, string>;\n typescript: string;\n react: Record<string, string>;\n manager: \"npm\" | \"pnpm\";\n};\nexport const bindConsumerManifest = ({\n manifest,\n artifacts,\n typescript,\n react,\n manager,\n}: BindConsumerManifestOptions) => {\n assertConsumerFixtureManifest(manifest);\n const artifactBindings = Object.fromEntries(\n [...artifacts].map(([name, file]) => [name, `file:${file}`]),\n );\n const owned = { ...artifactBindings, typescript, ...react };\n const result = { ...manifest };\n for (const field of [\n \"dependencies\",\n \"devDependencies\",\n \"optionalDependencies\",\n \"peerDependencies\",\n ]) {\n const entries = manifest[field];\n if (entries === undefined) continue;\n if (!consumerRecord(entries))\n throw new Error(`fixture ${field} must be an object`);\n for (const specifier of Object.values(entries))\n if (\n typeof specifier !== \"string\" ||\n /^(?:workspace:|file:|link:|\\.\\.?\\/|\\/)/.test(specifier)\n )\n throw new Error(\n \"fixture dependencies must resolve from registry or generated artifact bindings\",\n );\n result[field] = Object.fromEntries(\n Object.entries(entries).filter(([name]) => !Object.hasOwn(owned, name)),\n );\n }\n result[\"dependencies\"] = {\n ...(consumerRecord(result[\"dependencies\"]) ? result[\"dependencies\"] : {}),\n ...artifactBindings,\n ...react,\n };\n result[\"devDependencies\"] = {\n ...(consumerRecord(result[\"devDependencies\"])\n ? result[\"devDependencies\"]\n : {}),\n typescript,\n };\n if (manager === \"npm\") {\n result[\"overrides\"] = owned;\n return { manager, manifest: result };\n }\n return {\n manager,\n manifest: result,\n workspace: { packages: [\".\"], overrides: owned },\n };\n};\n\nconst workspacePatterns = (manifest: Record<string, unknown>) => {\n const workspace = manifest[\"workspaces\"];\n const patterns = consumerRecord(workspace)\n ? workspace[\"packages\"]\n : workspace;\n if (patterns === undefined) return [];\n if (\n !Array.isArray(patterns) ||\n !patterns.every((entry: unknown) => typeof entry === \"string\")\n )\n throw new Error(\"package workspaces must be string patterns\");\n return patterns.map((entry: string) => entry);\n};\n\nexport const discoverConsumerManifests = (files: Record<string, string>) => {\n const manifests = new Map<string, Record<string, unknown>>();\n const manifestSources = new Map<string, string>();\n const pnpmSources = new Map<string, string>();\n const pnpmWorkspaces = new Map<string, string[]>();\n for (const [file, content] of Object.entries(files)) {\n if (path.posix.basename(file) === \"pnpm-workspace.yaml\") {\n pnpmSources.set(path.posix.dirname(file), content);\n } else if (path.posix.basename(file) === \"package.json\")\n manifestSources.set(path.posix.dirname(file), content);\n }\n const assertWorkspaceOwner = (directory: string) => {\n if (pnpmSources.has(directory) && !manifestSources.has(directory))\n throw new Error(\n `consumer pnpm workspace requires an adjacent tracked package.json: ${path.posix.join(directory, \"pnpm-workspace.yaml\")}`,\n );\n };\n const candidates = new Set([\n ...manifestSources.keys(),\n ...pnpmSources.keys(),\n ]);\n const manifestAt = (directory: string) => {\n const cached = manifests.get(directory);\n if (cached) return cached;\n const source = manifestSources.get(directory);\n if (source === undefined) return undefined;\n const json: unknown = JSON.parse(source);\n if (!consumerRecord(json))\n throw new Error(`invalid package manifest: ${directory}/package.json`);\n manifests.set(directory, json);\n return json;\n };\n const patternsAt = (\n directory: string,\n manifest: Record<string, unknown> | undefined,\n ) => {\n const source = pnpmSources.get(directory);\n if (source !== undefined && !pnpmWorkspaces.has(directory)) {\n const file = `${directory}/pnpm-workspace.yaml`;\n const document = parseDocument(source, { uniqueKeys: true });\n if (document.errors.length)\n throw new Error(`invalid pnpm workspace: ${file}`);\n const json: unknown = document.toJS({ maxAliasCount: 100 });\n if (!consumerRecord(json))\n throw new Error(`invalid pnpm workspace: ${file}`);\n const patterns = json[\"packages\"] ?? [];\n if (\n !Array.isArray(patterns) ||\n !patterns.every((entry: unknown) => typeof entry === \"string\")\n )\n throw new Error(`invalid pnpm workspace packages: ${file}`);\n pnpmWorkspaces.set(\n directory,\n patterns.map((entry: string) => entry),\n );\n }\n return pnpmWorkspaces.get(directory) ?? workspacePatterns(manifest ?? {});\n };\n const roots = new Set([\".\"]);\n for (;;) {\n const before = roots.size;\n for (const directory of roots) {\n assertWorkspaceOwner(directory);\n const manifest = manifestAt(directory);\n const patterns = patternsAt(directory, manifest);\n for (const candidate of candidates) {\n const relative = path.posix.relative(directory, candidate);\n if (relative === \"\" || relative.startsWith(\"../\")) continue;\n const positives = patterns.filter(\n (pattern) => !pattern.startsWith(\"!\"),\n );\n const negatives = patterns\n .filter((pattern) => pattern.startsWith(\"!\"))\n .map((pattern) => pattern.slice(1));\n if (\n positives.some((pattern) => picomatch.isMatch(relative, pattern)) &&\n !negatives.some((pattern) => picomatch.isMatch(relative, pattern))\n )\n roots.add(candidate);\n }\n }\n if (before === roots.size) break;\n }\n const discovered = new Map<string, Record<string, unknown>>();\n for (const directory of roots) {\n for (let owner = directory; ; owner = path.posix.dirname(owner)) {\n assertWorkspaceOwner(owner);\n if (owner === \".\") break;\n }\n const manifest = manifestAt(directory);\n if (manifest) discovered.set(directory, manifest);\n }\n return discovered;\n};\n\nexport const discoverConsumerPackages = (files: Record<string, string>) => {\n const packages = new Map<string, ConsumerPackage>();\n for (const [directory, manifest] of discoverConsumerManifests(files)) {\n const name = manifest[\"name\"];\n if (typeof name !== \"string\" || name === \"\") continue;\n if (packages.has(name))\n throw new Error(`duplicate workspace package: ${name}`);\n packages.set(name, { directory, name, manifest });\n }\n return packages;\n};\n\nexport const consumerPublishedDependencyFields = [\n \"dependencies\",\n \"optionalDependencies\",\n \"peerDependencies\",\n] as const;\n\ntype ConsumerPackageClosureOptions = {\n selected: ConsumerPackage;\n packages: Map<string, ConsumerPackage>;\n files: Record<string, string>;\n};\nexport const consumerPackageClosure = ({\n selected,\n packages,\n files,\n}: ConsumerPackageClosureOptions) => {\n const closure = new Map<string, ConsumerPackage>();\n const visit = (pkg: ConsumerPackage) => {\n if (closure.has(pkg.name)) return;\n assertConsumerPublishableManifest(pkg);\n closure.set(pkg.name, pkg);\n for (const field of consumerPublishedDependencyFields) {\n const dependencies = pkg.manifest[field];\n if (!consumerRecord(dependencies)) continue;\n for (const [name, specifier] of Object.entries(dependencies)) {\n const local = packages.get(name);\n if (typeof specifier !== \"string\")\n throw new Error(`invalid package dependency: ${pkg.name} -> ${name}`);\n if (specifier.startsWith(\"catalog:\") && local !== undefined) {\n const resolved = resolveConsumerCatalog({\n directory: pkg.directory,\n name,\n specifier,\n files,\n });\n const version = local.manifest[\"version\"];\n if (\n resolved.startsWith(\"workspace:\") ||\n (typeof version === \"string\" &&\n validRange(resolved) !== null &&\n satisfies(version, resolved))\n )\n throw new Error(\n `catalog dependency ${name} resolves to workspace package ${local.name}; use workspace:`,\n );\n }\n if (/^workspace:(?:@[^/@]+\\/)?[^/@]+@/.test(specifier))\n throw new Error(\n `workspace alias specifiers are not supported by consumer-compat: ${name} -> ${specifier}; use the package name as the dependency key`,\n );\n if (/^(?:file:|link:)/.test(specifier))\n throw new Error(\n `published local dependencies must use workspace protocol: ${pkg.name} -> ${name}`,\n );\n if (\n local &&\n (specifier.startsWith(\"workspace:\") ||\n (typeof local.manifest[\"version\"] === \"string\" &&\n validRange(specifier) &&\n satisfies(local.manifest[\"version\"], specifier)))\n ) {\n if (local.manifest[\"private\"] === true)\n throw new Error(\n `published package depends on private workspace package: ${pkg.name} -> ${name}`,\n );\n visit(local);\n } else if (\n typeof specifier === \"string\" &&\n specifier.startsWith(\"workspace:\")\n )\n throw new Error(\n `unresolved workspace dependency: ${pkg.name} -> ${name}`,\n );\n }\n }\n };\n visit(selected);\n return closure;\n};\n\nexport const oldestPublishedConsumerVersion = (\n versions: readonly string[],\n range: string,\n) => {\n if (!validRange(range))\n throw new Error(`invalid consumer peer range: ${range}`);\n const candidates = versions\n .filter((version) => satisfies(version, range))\n .sort(compare);\n const version = candidates.at(0);\n if (!version)\n throw new Error(`no published consumer version satisfies ${range}`);\n return version;\n};\n","import { satisfies, validRange } from \"semver\";\n\ntype ConsumerNodeSupportOptions = { range: unknown; node: string };\n\nexport const consumerNodeSupportMatches = ({\n range,\n node,\n}: ConsumerNodeSupportOptions) =>\n range === undefined ||\n (typeof range === \"string\" &&\n range.trim() !== \"\" &&\n validRange(range) !== null &&\n satisfies(node, range));\n\ntype AssertConsumerNodeSupportOptions = {\n manifest: Record<string, unknown>;\n node: string;\n label: string;\n};\nexport const assertConsumerNodeSupport = ({\n manifest,\n node,\n label,\n}: AssertConsumerNodeSupportOptions) => {\n const engines = manifest[\"engines\"];\n const record = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n if (\n (engines !== undefined && !record(engines)) ||\n !consumerNodeSupportMatches({\n range: record(engines) ? engines[\"node\"] : undefined,\n node,\n })\n )\n throw new Error(`${label} engines.node must support consumer Node ${node}`);\n};\n"],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/env node
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const require_toolchain_guard = require("./toolchain-guard.cjs");
4
+ const require_toolchain_dependabot = require("./toolchain-dependabot.cjs");
5
+ const require_toolchain_schema = require("./toolchain-schema.cjs");
6
+ require("./dependabot.cjs");
7
+ const require_generated_file = require("./generated-file.cjs");
8
+ let node_path = require("node:path");
9
+ let node_fs_promises = require("node:fs/promises");
10
+ //#region src/dependabot-cli.ts
11
+ const usage = "Usage: stll-dependabot (run from repository root)\n stll-dependabot --help";
12
+ const main = async () => {
13
+ const args = process.argv.slice(2);
14
+ if (args.length === 1 && args.at(0) === "--help") {
15
+ process.stdout.write(`${usage}\n`);
16
+ return;
17
+ }
18
+ if (args.length !== 0) throw new Error(usage);
19
+ const root = await (0, node_fs_promises.realpath)(process.cwd());
20
+ const { files, trackedFiles, diagnostics } = require_toolchain_guard.readToolchainInputs(root);
21
+ const policy = require_toolchain_schema.parseToolchainPolicy(JSON.parse(await (0, node_fs_promises.readFile)(new URL("../toolchain.json", require("url").pathToFileURL(__filename).href), "utf8")));
22
+ const yaml = (0, node_path.join)(root, ".github/dependabot.yaml");
23
+ const yml = (0, node_path.join)(root, ".github/dependabot.yml");
24
+ const yamlStat = await require_generated_file.checkGeneratedOutput(yaml);
25
+ const ymlStat = await require_generated_file.checkGeneratedOutput(yml);
26
+ const candidates = [{
27
+ relative: ".github/dependabot.yaml",
28
+ path: yaml,
29
+ stat: yamlStat
30
+ }, {
31
+ relative: ".github/dependabot.yml",
32
+ path: yml,
33
+ stat: ymlStat
34
+ }].filter(({ relative, stat }) => stat !== void 0 || trackedFiles.has(relative));
35
+ if (candidates.length > 1) throw new Error("keep exactly one Dependabot configuration: .yml or .yaml");
36
+ const selected = candidates.at(0) ?? {
37
+ relative: ".github/dependabot.yml",
38
+ path: yml,
39
+ stat: ymlStat
40
+ };
41
+ const remainingDiagnostics = await require_generated_file.generationDiagnostics({
42
+ diagnostics,
43
+ outputs: [{
44
+ relative: selected.relative,
45
+ destination: selected.path
46
+ }]
47
+ });
48
+ if (remainingDiagnostics.length !== 0) throw new Error(remainingDiagnostics.map(({ path, message }) => `${path}: ${message}`).join("\n"));
49
+ const destination = selected.path;
50
+ const mode = selected.stat?.mode;
51
+ await require_generated_file.writeGeneratedFile({
52
+ destination,
53
+ text: require_toolchain_dependabot.generateDependabotConfig({
54
+ files,
55
+ policy: policy.dependabot
56
+ }),
57
+ mode: mode === void 0 ? 420 : mode & 511
58
+ });
59
+ process.stdout.write(`Generated ${selected.relative}\n`);
60
+ };
61
+ main().catch((error) => {
62
+ process.stderr.write(`dependabot: ${error instanceof Error ? error.message : String(error)}\n`);
63
+ process.exitCode = 1;
64
+ });
65
+ //#endregion
66
+
67
+ //# sourceMappingURL=dependabot-cli.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependabot-cli.cjs","names":["realpath","readToolchainInputs","parseToolchainPolicy","readFile","join","checkGeneratedOutput","generationDiagnostics","writeGeneratedFile","generateDependabotConfig"],"sources":["../src/dependabot-cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { readFile, realpath } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { generateDependabotConfig, parseToolchainPolicy } from \"./dependabot\";\nimport {\n checkGeneratedOutput,\n generationDiagnostics,\n writeGeneratedFile,\n} from \"./generated-file\";\nimport { readToolchainInputs } from \"./toolchain-guard\";\n\nconst usage =\n \"Usage: stll-dependabot (run from repository root)\\n stll-dependabot --help\";\nconst main = async () => {\n const args = process.argv.slice(2);\n if (args.length === 1 && args.at(0) === \"--help\") {\n process.stdout.write(`${usage}\\n`);\n return;\n }\n if (args.length !== 0) throw new Error(usage);\n const root = await realpath(process.cwd());\n const { files, trackedFiles, diagnostics } = readToolchainInputs(root);\n const policy = parseToolchainPolicy(\n JSON.parse(\n await readFile(new URL(\"../toolchain.json\", import.meta.url), \"utf8\"),\n ),\n );\n const yaml = join(root, \".github/dependabot.yaml\");\n const yml = join(root, \".github/dependabot.yml\");\n const yamlStat = await checkGeneratedOutput(yaml);\n const ymlStat = await checkGeneratedOutput(yml);\n const candidates = [\n { relative: \".github/dependabot.yaml\", path: yaml, stat: yamlStat },\n { relative: \".github/dependabot.yml\", path: yml, stat: ymlStat },\n ].filter(\n ({ relative, stat }) => stat !== undefined || trackedFiles.has(relative),\n );\n if (candidates.length > 1)\n throw new Error(\"keep exactly one Dependabot configuration: .yml or .yaml\");\n const selected = candidates.at(0) ?? {\n relative: \".github/dependabot.yml\",\n path: yml,\n stat: ymlStat,\n };\n const remainingDiagnostics = await generationDiagnostics({\n diagnostics,\n outputs: [{ relative: selected.relative, destination: selected.path }],\n });\n if (remainingDiagnostics.length !== 0)\n throw new Error(\n remainingDiagnostics\n .map(({ path, message }) => `${path}: ${message}`)\n .join(\"\\n\"),\n );\n const destination = selected.path;\n const mode = selected.stat?.mode;\n await writeGeneratedFile({\n destination,\n text: generateDependabotConfig({ files, policy: policy.dependabot }),\n mode: mode === undefined ? 0o644 : mode & 0o777,\n });\n process.stdout.write(`Generated ${selected.relative}\\n`);\n};\n\nmain().catch((error: unknown) => {\n process.stderr.write(\n `dependabot: ${error instanceof Error ? error.message : String(error)}\\n`,\n );\n process.exitCode = 1;\n});\n"],"mappings":";;;;;;;;;;AAYA,MAAM,QACJ;AACF,MAAM,OAAO,YAAY;CACvB,MAAM,OAAO,QAAQ,KAAK,MAAM,CAAC;CACjC,IAAI,KAAK,WAAW,KAAK,KAAK,GAAG,CAAC,MAAM,UAAU;EAChD,QAAQ,OAAO,MAAM,GAAG,MAAM,GAAG;EACjC;CACF;CACA,IAAI,KAAK,WAAW,GAAG,MAAM,IAAI,MAAM,KAAK;CAC5C,MAAM,OAAO,OAAA,GAAMA,iBAAAA,SAAAA,CAAS,QAAQ,IAAI,CAAC;CACzC,MAAM,EAAE,OAAO,cAAc,gBAAgBC,wBAAAA,oBAAoB,IAAI;CACrE,MAAM,SAASC,yBAAAA,qBACb,KAAK,MACH,OAAA,GAAMC,iBAAAA,SAAAA,CAAS,IAAI,IAAI,qBAAA,QAAA,KAAA,CAAA,CAAA,cAAA,UAAA,CAAA,CAAA,IAAoC,GAAG,MAAM,CACtE,CACF;CACA,MAAM,QAAA,GAAOC,UAAAA,KAAAA,CAAK,MAAM,yBAAyB;CACjD,MAAM,OAAA,GAAMA,UAAAA,KAAAA,CAAK,MAAM,wBAAwB;CAC/C,MAAM,WAAW,MAAMC,uBAAAA,qBAAqB,IAAI;CAChD,MAAM,UAAU,MAAMA,uBAAAA,qBAAqB,GAAG;CAC9C,MAAM,aAAa,CACjB;EAAE,UAAU;EAA2B,MAAM;EAAM,MAAM;CAAS,GAClE;EAAE,UAAU;EAA0B,MAAM;EAAK,MAAM;CAAQ,CACjE,CAAC,CAAC,QACC,EAAE,UAAU,WAAW,SAAS,KAAA,KAAa,aAAa,IAAI,QAAQ,CACzE;CACA,IAAI,WAAW,SAAS,GACtB,MAAM,IAAI,MAAM,0DAA0D;CAC5E,MAAM,WAAW,WAAW,GAAG,CAAC,KAAK;EACnC,UAAU;EACV,MAAM;EACN,MAAM;CACR;CACA,MAAM,uBAAuB,MAAMC,uBAAAA,sBAAsB;EACvD;EACA,SAAS,CAAC;GAAE,UAAU,SAAS;GAAU,aAAa,SAAS;EAAK,CAAC;CACvE,CAAC;CACD,IAAI,qBAAqB,WAAW,GAClC,MAAM,IAAI,MACR,qBACG,KAAK,EAAE,MAAM,cAAc,GAAG,KAAK,IAAI,SAAS,CAAC,CACjD,KAAK,IAAI,CACd;CACF,MAAM,cAAc,SAAS;CAC7B,MAAM,OAAO,SAAS,MAAM;CAC5B,MAAMC,uBAAAA,mBAAmB;EACvB;EACA,MAAMC,6BAAAA,yBAAyB;GAAE;GAAO,QAAQ,OAAO;EAAW,CAAC;EACnE,MAAM,SAAS,KAAA,IAAY,MAAQ,OAAO;CAC5C,CAAC;CACD,QAAQ,OAAO,MAAM,aAAa,SAAS,SAAS,GAAG;AACzD;AAEA,KAAK,CAAC,CAAC,OAAO,UAAmB;CAC/B,QAAQ,OAAO,MACb,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAAE,GACxE;CACA,QAAQ,WAAW;AACrB,CAAC"}
@@ -0,0 +1 @@
1
+ export {}
@@ -0,0 +1 @@
1
+ export {}
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/env node
2
+ import { r as readToolchainInputs } from "./toolchain-guard.mjs";
3
+ import { r as generateDependabotConfig } from "./toolchain-dependabot.mjs";
4
+ import { t as parseToolchainPolicy } from "./toolchain-schema.mjs";
5
+ import "./dependabot.mjs";
6
+ import { n as generationDiagnostics, r as writeGeneratedFile, t as checkGeneratedOutput } from "./generated-file.mjs";
7
+ import { join } from "node:path";
8
+ import { readFile, realpath } from "node:fs/promises";
9
+ //#region src/dependabot-cli.ts
10
+ const usage = "Usage: stll-dependabot (run from repository root)\n stll-dependabot --help";
11
+ const main = async () => {
12
+ const args = process.argv.slice(2);
13
+ if (args.length === 1 && args.at(0) === "--help") {
14
+ process.stdout.write(`${usage}\n`);
15
+ return;
16
+ }
17
+ if (args.length !== 0) throw new Error(usage);
18
+ const root = await realpath(process.cwd());
19
+ const { files, trackedFiles, diagnostics } = readToolchainInputs(root);
20
+ const policy = parseToolchainPolicy(JSON.parse(await readFile(new URL("../toolchain.json", import.meta.url), "utf8")));
21
+ const yaml = join(root, ".github/dependabot.yaml");
22
+ const yml = join(root, ".github/dependabot.yml");
23
+ const yamlStat = await checkGeneratedOutput(yaml);
24
+ const ymlStat = await checkGeneratedOutput(yml);
25
+ const candidates = [{
26
+ relative: ".github/dependabot.yaml",
27
+ path: yaml,
28
+ stat: yamlStat
29
+ }, {
30
+ relative: ".github/dependabot.yml",
31
+ path: yml,
32
+ stat: ymlStat
33
+ }].filter(({ relative, stat }) => stat !== void 0 || trackedFiles.has(relative));
34
+ if (candidates.length > 1) throw new Error("keep exactly one Dependabot configuration: .yml or .yaml");
35
+ const selected = candidates.at(0) ?? {
36
+ relative: ".github/dependabot.yml",
37
+ path: yml,
38
+ stat: ymlStat
39
+ };
40
+ const remainingDiagnostics = await generationDiagnostics({
41
+ diagnostics,
42
+ outputs: [{
43
+ relative: selected.relative,
44
+ destination: selected.path
45
+ }]
46
+ });
47
+ if (remainingDiagnostics.length !== 0) throw new Error(remainingDiagnostics.map(({ path, message }) => `${path}: ${message}`).join("\n"));
48
+ const destination = selected.path;
49
+ const mode = selected.stat?.mode;
50
+ await writeGeneratedFile({
51
+ destination,
52
+ text: generateDependabotConfig({
53
+ files,
54
+ policy: policy.dependabot
55
+ }),
56
+ mode: mode === void 0 ? 420 : mode & 511
57
+ });
58
+ process.stdout.write(`Generated ${selected.relative}\n`);
59
+ };
60
+ main().catch((error) => {
61
+ process.stderr.write(`dependabot: ${error instanceof Error ? error.message : String(error)}\n`);
62
+ process.exitCode = 1;
63
+ });
64
+ //#endregion
65
+ export {};
66
+
67
+ //# sourceMappingURL=dependabot-cli.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependabot-cli.mjs","names":[],"sources":["../src/dependabot-cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { readFile, realpath } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { generateDependabotConfig, parseToolchainPolicy } from \"./dependabot\";\nimport {\n checkGeneratedOutput,\n generationDiagnostics,\n writeGeneratedFile,\n} from \"./generated-file\";\nimport { readToolchainInputs } from \"./toolchain-guard\";\n\nconst usage =\n \"Usage: stll-dependabot (run from repository root)\\n stll-dependabot --help\";\nconst main = async () => {\n const args = process.argv.slice(2);\n if (args.length === 1 && args.at(0) === \"--help\") {\n process.stdout.write(`${usage}\\n`);\n return;\n }\n if (args.length !== 0) throw new Error(usage);\n const root = await realpath(process.cwd());\n const { files, trackedFiles, diagnostics } = readToolchainInputs(root);\n const policy = parseToolchainPolicy(\n JSON.parse(\n await readFile(new URL(\"../toolchain.json\", import.meta.url), \"utf8\"),\n ),\n );\n const yaml = join(root, \".github/dependabot.yaml\");\n const yml = join(root, \".github/dependabot.yml\");\n const yamlStat = await checkGeneratedOutput(yaml);\n const ymlStat = await checkGeneratedOutput(yml);\n const candidates = [\n { relative: \".github/dependabot.yaml\", path: yaml, stat: yamlStat },\n { relative: \".github/dependabot.yml\", path: yml, stat: ymlStat },\n ].filter(\n ({ relative, stat }) => stat !== undefined || trackedFiles.has(relative),\n );\n if (candidates.length > 1)\n throw new Error(\"keep exactly one Dependabot configuration: .yml or .yaml\");\n const selected = candidates.at(0) ?? {\n relative: \".github/dependabot.yml\",\n path: yml,\n stat: ymlStat,\n };\n const remainingDiagnostics = await generationDiagnostics({\n diagnostics,\n outputs: [{ relative: selected.relative, destination: selected.path }],\n });\n if (remainingDiagnostics.length !== 0)\n throw new Error(\n remainingDiagnostics\n .map(({ path, message }) => `${path}: ${message}`)\n .join(\"\\n\"),\n );\n const destination = selected.path;\n const mode = selected.stat?.mode;\n await writeGeneratedFile({\n destination,\n text: generateDependabotConfig({ files, policy: policy.dependabot }),\n mode: mode === undefined ? 0o644 : mode & 0o777,\n });\n process.stdout.write(`Generated ${selected.relative}\\n`);\n};\n\nmain().catch((error: unknown) => {\n process.stderr.write(\n `dependabot: ${error instanceof Error ? error.message : String(error)}\\n`,\n );\n process.exitCode = 1;\n});\n"],"mappings":";;;;;;;;;AAYA,MAAM,QACJ;AACF,MAAM,OAAO,YAAY;CACvB,MAAM,OAAO,QAAQ,KAAK,MAAM,CAAC;CACjC,IAAI,KAAK,WAAW,KAAK,KAAK,GAAG,CAAC,MAAM,UAAU;EAChD,QAAQ,OAAO,MAAM,GAAG,MAAM,GAAG;EACjC;CACF;CACA,IAAI,KAAK,WAAW,GAAG,MAAM,IAAI,MAAM,KAAK;CAC5C,MAAM,OAAO,MAAM,SAAS,QAAQ,IAAI,CAAC;CACzC,MAAM,EAAE,OAAO,cAAc,gBAAgB,oBAAoB,IAAI;CACrE,MAAM,SAAS,qBACb,KAAK,MACH,MAAM,SAAS,IAAI,IAAI,qBAAqB,YAAY,GAAG,GAAG,MAAM,CACtE,CACF;CACA,MAAM,OAAO,KAAK,MAAM,yBAAyB;CACjD,MAAM,MAAM,KAAK,MAAM,wBAAwB;CAC/C,MAAM,WAAW,MAAM,qBAAqB,IAAI;CAChD,MAAM,UAAU,MAAM,qBAAqB,GAAG;CAC9C,MAAM,aAAa,CACjB;EAAE,UAAU;EAA2B,MAAM;EAAM,MAAM;CAAS,GAClE;EAAE,UAAU;EAA0B,MAAM;EAAK,MAAM;CAAQ,CACjE,CAAC,CAAC,QACC,EAAE,UAAU,WAAW,SAAS,KAAA,KAAa,aAAa,IAAI,QAAQ,CACzE;CACA,IAAI,WAAW,SAAS,GACtB,MAAM,IAAI,MAAM,0DAA0D;CAC5E,MAAM,WAAW,WAAW,GAAG,CAAC,KAAK;EACnC,UAAU;EACV,MAAM;EACN,MAAM;CACR;CACA,MAAM,uBAAuB,MAAM,sBAAsB;EACvD;EACA,SAAS,CAAC;GAAE,UAAU,SAAS;GAAU,aAAa,SAAS;EAAK,CAAC;CACvE,CAAC;CACD,IAAI,qBAAqB,WAAW,GAClC,MAAM,IAAI,MACR,qBACG,KAAK,EAAE,MAAM,cAAc,GAAG,KAAK,IAAI,SAAS,CAAC,CACjD,KAAK,IAAI,CACd;CACF,MAAM,cAAc,SAAS;CAC7B,MAAM,OAAO,SAAS,MAAM;CAC5B,MAAM,mBAAmB;EACvB;EACA,MAAM,yBAAyB;GAAE;GAAO,QAAQ,OAAO;EAAW,CAAC;EACnE,MAAM,SAAS,KAAA,IAAY,MAAQ,OAAO;CAC5C,CAAC;CACD,QAAQ,OAAO,MAAM,aAAa,SAAS,SAAS,GAAG;AACzD;AAEA,KAAK,CAAC,CAAC,OAAO,UAAmB;CAC/B,QAAQ,OAAO,MACb,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAAE,GACxE;CACA,QAAQ,WAAW;AACrB,CAAC"}
@@ -0,0 +1,5 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_toolchain_dependabot = require("./toolchain-dependabot.cjs");
3
+ const require_toolchain_schema = require("./toolchain-schema.cjs");
4
+ exports.generateDependabotConfig = require_toolchain_dependabot.generateDependabotConfig;
5
+ exports.parseToolchainPolicy = require_toolchain_schema.parseToolchainPolicy;