@stll/oxlint-config 0.12.2 → 0.15.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 (88) hide show
  1. package/README.md +261 -1
  2. package/dist/cloud-setup-cli.cjs +6 -4
  3. package/dist/cloud-setup-cli.cjs.map +1 -1
  4. package/dist/cloud-setup-cli.mjs +3 -1
  5. package/dist/cloud-setup-cli.mjs.map +1 -1
  6. package/dist/compiler-packages.cjs +28 -0
  7. package/dist/compiler-packages.cjs.map +1 -0
  8. package/dist/compiler-packages.mjs +17 -0
  9. package/dist/compiler-packages.mjs.map +1 -0
  10. package/dist/consumer-compat-cli.cjs +1091 -0
  11. package/dist/consumer-compat-cli.cjs.map +1 -0
  12. package/dist/consumer-compat-cli.d.cts +1 -0
  13. package/dist/consumer-compat-cli.d.mts +1 -0
  14. package/dist/consumer-compat-cli.mjs +1089 -0
  15. package/dist/consumer-compat-cli.mjs.map +1 -0
  16. package/dist/index.cjs +50 -40
  17. package/dist/index.cjs.map +1 -1
  18. package/dist/index.d.cts +46 -41
  19. package/dist/index.d.mts +46 -41
  20. package/dist/index.mjs +50 -41
  21. package/dist/index.mjs.map +1 -1
  22. package/dist/publish-build-target-nuxt-helper.cjs +71 -0
  23. package/dist/publish-build-target-nuxt-helper.cjs.map +1 -0
  24. package/dist/publish-build-target-nuxt-helper.d.cts +10 -0
  25. package/dist/publish-build-target-nuxt-helper.d.mts +10 -0
  26. package/dist/publish-build-target-nuxt-helper.mjs +68 -0
  27. package/dist/publish-build-target-nuxt-helper.mjs.map +1 -0
  28. package/dist/publish-build-target-vite-dts-helper.cjs +3 -0
  29. package/dist/publish-build-target-vite-dts-helper.d.cts +24 -0
  30. package/dist/publish-build-target-vite-dts-helper.d.mts +24 -0
  31. package/dist/publish-build-target-vite-dts-helper.mjs +2 -0
  32. package/dist/publish-build-target-vite-dts-helper2.cjs +372 -0
  33. package/dist/publish-build-target-vite-dts-helper2.cjs.map +1 -0
  34. package/dist/publish-build-target-vite-dts-helper2.mjs +359 -0
  35. package/dist/publish-build-target-vite-dts-helper2.mjs.map +1 -0
  36. package/dist/publish-contract-cli.cjs +983 -0
  37. package/dist/publish-contract-cli.cjs.map +1 -0
  38. package/dist/publish-contract-cli.d.cts +1 -0
  39. package/dist/publish-contract-cli.d.mts +1 -0
  40. package/dist/publish-contract-cli.mjs +981 -0
  41. package/dist/publish-contract-cli.mjs.map +1 -0
  42. package/dist/publish-contract.cjs +431 -0
  43. package/dist/publish-contract.cjs.map +1 -0
  44. package/dist/publish-contract.mjs +396 -0
  45. package/dist/publish-contract.mjs.map +1 -0
  46. package/dist/rolldown-runtime.cjs +28 -0
  47. package/dist/toolchain-changed-cli.cjs +34 -0
  48. package/dist/toolchain-changed-cli.cjs.map +1 -0
  49. package/dist/toolchain-changed-cli.d.cts +1 -0
  50. package/dist/toolchain-changed-cli.d.mts +1 -0
  51. package/dist/toolchain-changed-cli.mjs +34 -0
  52. package/dist/toolchain-changed-cli.mjs.map +1 -0
  53. package/dist/toolchain-changed.cjs +1470 -0
  54. package/dist/toolchain-changed.cjs.map +1 -0
  55. package/dist/toolchain-changed.mjs +1463 -0
  56. package/dist/toolchain-changed.mjs.map +1 -0
  57. package/dist/toolchain-check-cli.cjs +2 -1
  58. package/dist/toolchain-check-cli.cjs.map +1 -1
  59. package/dist/toolchain-check-cli.mjs +2 -1
  60. package/dist/toolchain-check-cli.mjs.map +1 -1
  61. package/dist/toolchain-guard.cjs +360 -1161
  62. package/dist/toolchain-guard.cjs.map +1 -1
  63. package/dist/toolchain-guard.mjs +338 -1100
  64. package/dist/toolchain-guard.mjs.map +1 -1
  65. package/dist/toolchain-inputs.cjs +926 -0
  66. package/dist/toolchain-inputs.cjs.map +1 -0
  67. package/dist/toolchain-inputs.mjs +816 -0
  68. package/dist/toolchain-inputs.mjs.map +1 -0
  69. package/dist/toolchain-schema.cjs +702 -0
  70. package/dist/toolchain-schema.cjs.map +1 -0
  71. package/dist/toolchain-schema.mjs +580 -0
  72. package/dist/toolchain-schema.mjs.map +1 -0
  73. package/dist/typecheck-parity-cli.cjs +38 -898
  74. package/dist/typecheck-parity-cli.cjs.map +1 -1
  75. package/dist/typecheck-parity-cli.mjs +39 -899
  76. package/dist/typecheck-parity-cli.mjs.map +1 -1
  77. package/dist/typecheck-parity.cjs +905 -0
  78. package/dist/typecheck-parity.cjs.map +1 -0
  79. package/dist/typecheck-parity.mjs +894 -0
  80. package/dist/typecheck-parity.mjs.map +1 -0
  81. package/dist/typecheck-probe-cli.cjs +176 -0
  82. package/dist/typecheck-probe-cli.cjs.map +1 -0
  83. package/dist/typecheck-probe-cli.d.cts +1 -0
  84. package/dist/typecheck-probe-cli.d.mts +1 -0
  85. package/dist/typecheck-probe-cli.mjs +174 -0
  86. package/dist/typecheck-probe-cli.mjs.map +1 -0
  87. package/package.json +43 -5
  88. package/toolchain.json +9 -1
@@ -0,0 +1,983 @@
1
+ #!/usr/bin/env node
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const require_rolldown_runtime = require("./rolldown-runtime.cjs");
4
+ const require_toolchain_inputs = require("./toolchain-inputs.cjs");
5
+ const require_toolchain_schema = require("./toolchain-schema.cjs");
6
+ const require_publish_contract = require("./publish-contract.cjs");
7
+ const require_publish_build_target_vite_dts_helper = require("./publish-build-target-vite-dts-helper2.cjs");
8
+ let node_fs = require("node:fs");
9
+ let node_child_process = require("node:child_process");
10
+ let node_path = require("node:path");
11
+ node_path = require_rolldown_runtime.__toESM(node_path, 1);
12
+ let node_module = require("node:module");
13
+ let node_os = require("node:os");
14
+ let node_url = require("node:url");
15
+ let acorn = require("acorn");
16
+ let esbuild = require("esbuild");
17
+ //#region src/publish-build-target-nuxt.ts
18
+ const supportedVersions = {
19
+ "@nuxt/module-builder": "1.0.3",
20
+ unbuild: "3.6.1",
21
+ mkdist: "2.4.1"
22
+ };
23
+ const record$2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
24
+ /** Only the reviewed builder and branded target hook may introduce executable build behavior. */
25
+ const assertNuxtOutputOptions = (options) => {
26
+ const visit = (value) => {
27
+ if (typeof value === "function") throw new Error("Unreviewed Nuxt output transform requires a supported target resolver");
28
+ if (Array.isArray(value)) {
29
+ for (const item of value) visit(item);
30
+ return;
31
+ }
32
+ if (typeof value !== "object" || value === null) return;
33
+ if (value instanceof RegExp) return;
34
+ const prototype = Object.getPrototypeOf(value);
35
+ if (prototype !== Object.prototype && prototype !== null) throw new Error("Unsupported Nuxt output option prototype");
36
+ for (const key of Reflect.ownKeys(value)) {
37
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
38
+ if (typeof key !== "string" || !descriptor || !("value" in descriptor)) throw new Error("Unsupported Nuxt output option property");
39
+ const entry = descriptor.value;
40
+ if (key === "plugins" && entry !== void 0 && (!Array.isArray(entry) || entry.length > 0)) throw new Error("Unreviewed Nuxt output plugins require a supported target resolver");
41
+ visit(entry);
42
+ }
43
+ };
44
+ visit(options);
45
+ };
46
+ /** Read actual normalized entry targets, including mkdist's separate transform. */
47
+ const resolvedNuxtTarget = (options) => {
48
+ assertNuxtOutputOptions(options);
49
+ if (!record$2(options) || !Array.isArray(options["entries"]) || options["entries"].length === 0) throw new Error("Nuxt must resolve at least one JavaScript entry");
50
+ const emitted = /* @__PURE__ */ new Set();
51
+ for (const entry of options["entries"]) {
52
+ if (!record$2(entry)) throw new Error("Invalid resolved Nuxt entry");
53
+ let transform;
54
+ switch (entry["builder"]) {
55
+ case "rollup":
56
+ if (!record$2(options["rollup"])) throw new Error("Invalid Nuxt module options");
57
+ transform = options["rollup"]["esbuild"];
58
+ break;
59
+ case "mkdist":
60
+ transform = entry["esbuild"];
61
+ break;
62
+ default: throw new Error("Unsupported Nuxt JavaScript entry builder");
63
+ }
64
+ if (transform !== void 0 && !record$2(transform)) throw new Error("Invalid Nuxt JavaScript transform options");
65
+ const target = record$2(transform) ? transform["target"] : void 0;
66
+ if (target === void 0) {
67
+ emitted.add("esnext");
68
+ continue;
69
+ }
70
+ const targets = typeof target === "string" ? [target] : target;
71
+ if (!Array.isArray(targets) || targets.length === 0) throw new Error("Unsupported resolved Nuxt JavaScript target");
72
+ for (const item of targets) {
73
+ if (typeof item !== "string" || item.length === 0) throw new Error("Unsupported resolved Nuxt JavaScript target");
74
+ emitted.add(item);
75
+ }
76
+ }
77
+ return {
78
+ type: "javascript",
79
+ targets: [...emitted].sort()
80
+ };
81
+ };
82
+ const captureProgram = String.raw`
83
+ import { register } from 'node:module';
84
+ const payload = JSON.parse(process.argv[1]);
85
+ register(payload.loader, import.meta.url);
86
+ const jitiModule = await import(payload.jiti);
87
+ const createJiti = jitiModule.createJiti || jitiModule.default;
88
+ const jiti = createJiti(payload.directory);
89
+ const config = await jiti.import('./build.config', {try: true, default: true}) || {};
90
+ const record = value => typeof value === 'object' && value !== null && !Array.isArray(value);
91
+ if (!record(config) || Object.keys(config).some(key => key !== 'hooks')) throw new Error('Nuxt build configuration only supports the declared target hook');
92
+ globalThis.__stllNuxtTargetHelper = undefined;
93
+ globalThis.__stllNuxtTargetData = undefined;
94
+ if (config.hooks !== undefined) {
95
+ if (!record(config.hooks) || Object.keys(config.hooks).length !== 1 || !('build:before' in config.hooks)) throw new Error('Nuxt build configuration only supports the declared target hook');
96
+ if (!payload.helper) throw new Error('Nuxt target helper must be installed at the same tooling version');
97
+ const helper = await jiti.import(payload.helper, {default: false});
98
+ const targets = helper.nuxtModuleTargetTargets(config.hooks['build:before']);
99
+ if (!targets) throw new Error('Nuxt build configuration requires immutable nuxtModuleTarget data');
100
+ config.hooks['build:before'] = helper.nuxtModuleTarget(targets);
101
+ globalThis.__stllNuxtTargetHelper = helper;
102
+ globalThis.__stllNuxtTargetData = targets;
103
+ }
104
+ globalThis.__stllNuxtAbort = new Error('Nuxt target captured');
105
+ globalThis.__stllNuxtCapture = undefined;
106
+ const tool = await import(payload.tool);
107
+ try {
108
+ await tool.build.run({args: {cwd: payload.directory, rootDir: '.', outDir: 'dist', sourcemap: false, stub: false}});
109
+ throw new Error('Nuxt build did not reach the configuration boundary');
110
+ } catch (error) {
111
+ if (error !== globalThis.__stllNuxtAbort) throw error;
112
+ }
113
+ console.log('__STLL_NUXT_TARGET__' + JSON.stringify(globalThis.__stllNuxtCapture));
114
+ `;
115
+ const captureShim = (unbuild) => `
116
+ import {build as actualBuild} from ${JSON.stringify(unbuild)};
117
+ export const build = (root, stub, input) => {
118
+ const expectedHooks = {...input.hooks};
119
+ const helper = globalThis.__stllNuxtTargetHelper;
120
+ if (helper) expectedHooks['build:before'] = helper.nuxtModuleTarget(globalThis.__stllNuxtTargetData);
121
+ const prepare = context => {
122
+ const helper = globalThis.__stllNuxtTargetHelper;
123
+ const loadedHooks = context.options.hooks;
124
+ if (!loadedHooks || typeof loadedHooks !== 'object' || Array.isArray(loadedHooks)) throw new Error('Nuxt target configuration changed during loading');
125
+ const expectedKeys = Reflect.ownKeys(expectedHooks);
126
+ const loadedKeys = Reflect.ownKeys(loadedHooks);
127
+ if (loadedKeys.length !== expectedKeys.length || loadedKeys.some(key => !expectedKeys.includes(key))) throw new Error('Nuxt target configuration changed during loading');
128
+ for (const key of loadedKeys) {
129
+ const descriptor = Object.getOwnPropertyDescriptor(loadedHooks, key);
130
+ if (!descriptor || !('value' in descriptor)) throw new Error('Nuxt target configuration changed during loading');
131
+ if (key === 'build:before' && helper) continue;
132
+ if (descriptor.value !== expectedHooks[key]) throw new Error('Nuxt target configuration changed during loading');
133
+ }
134
+ const declared = loadedHooks['build:before'];
135
+ if (helper) {
136
+ const targets = helper.nuxtModuleTargetTargets(declared);
137
+ if (!targets || JSON.stringify(targets) !== JSON.stringify(globalThis.__stllNuxtTargetData)) throw new Error('Nuxt target configuration changed during loading');
138
+ if (typeof context.hooks.removeHook !== 'function') throw new Error('Unsupported Nuxt hook registration interface');
139
+ // unbuild registers config hooks before build:prepare; remove that exact callback.
140
+ context.hooks.removeHook('build:before', declared);
141
+ const canonical = helper.nuxtModuleTarget(targets);
142
+ context.options.hooks['build:before'] = canonical;
143
+ context.hooks.hook('build:before', canonical);
144
+ }
145
+ // unbuild 3.6.1 normalizes entries before build:before, then cleans output.
146
+ // Append after all registered config hooks so the target helper runs first.
147
+ context.hooks.hook('build:before', final => {
148
+ // The reviewed constructor owns its later hooks; user config accepts only nuxtModuleTarget.
149
+ // Validate executable output options before projecting away functions for the capture.
150
+ (${assertNuxtOutputOptions.toString()})({entries: final.options.entries, rollup: final.options.rollup});
151
+ globalThis.__stllNuxtCapture = {
152
+ entries: final.options.entries.map(entry => ({builder: entry.builder, esbuild: entry.esbuild})),
153
+ rollup: {esbuild: final.options.rollup.esbuild}
154
+ };
155
+ throw globalThis.__stllNuxtAbort;
156
+ });
157
+ };
158
+ expectedHooks['build:prepare'] = prepare;
159
+ return actualBuild(root, stub, {...input, hooks: {...input.hooks, 'build:prepare': prepare}});
160
+ };
161
+ `;
162
+ const resolveNuxtPublishTarget = (directory) => {
163
+ const canonicalDirectory = (0, node_fs.realpathSync)(directory);
164
+ const require = (0, node_module.createRequire)(node_path.default.join(canonicalDirectory, "package.json"));
165
+ const manifest = JSON.parse((0, node_fs.readFileSync)(node_path.default.join(canonicalDirectory, "package.json"), "utf8"));
166
+ if (!record$2(manifest) || manifest["build"] !== void 0 || manifest["unbuild"] !== void 0 || record$2(manifest["publishConfig"]) && (manifest["publishConfig"]["build"] !== void 0 || manifest["publishConfig"]["unbuild"] !== void 0)) throw new Error("Nuxt manifest build overrides require a supported target resolver");
167
+ const configs = [
168
+ "ts",
169
+ "mts",
170
+ "cts",
171
+ "js",
172
+ "mjs",
173
+ "cjs",
174
+ "json"
175
+ ].filter((extension) => (0, node_fs.existsSync)(node_path.default.join(canonicalDirectory, `build.config.${extension}`)));
176
+ if (configs.length > 1) throw new Error("Nuxt supports exactly one build configuration");
177
+ const tool = (0, node_fs.realpathSync)(require.resolve("@nuxt/module-builder"));
178
+ const unbuild = (0, node_fs.realpathSync)((0, node_module.createRequire)(tool).resolve("unbuild"));
179
+ const unbuildRequire = (0, node_module.createRequire)(unbuild);
180
+ for (const [name, version] of Object.entries(supportedVersions)) {
181
+ let entry;
182
+ switch (name) {
183
+ case "@nuxt/module-builder":
184
+ entry = tool;
185
+ break;
186
+ case "unbuild":
187
+ entry = unbuild;
188
+ break;
189
+ case "mkdist":
190
+ entry = (0, node_fs.realpathSync)(unbuildRequire.resolve("mkdist"));
191
+ break;
192
+ default: throw new Error(`Unsupported Nuxt build tool ${name}`);
193
+ }
194
+ const metadata = JSON.parse((0, node_fs.readFileSync)(node_path.default.resolve(node_path.default.dirname(entry), "../package.json"), "utf8"));
195
+ if (!record$2(metadata) || metadata["version"] !== version) throw new Error(`Publish target resolver supports ${name} ${version}; review the adapter before changing build tools`);
196
+ }
197
+ let helper;
198
+ if (configs.length > 0) {
199
+ const helperEntry = (0, node_fs.realpathSync)(require.resolve("@stll/oxlint-config/build-target"));
200
+ const metadata = JSON.parse((0, node_fs.readFileSync)(node_path.default.resolve(node_path.default.dirname(helperEntry), "../package.json"), "utf8"));
201
+ const ownMetadata = JSON.parse((0, node_fs.readFileSync)(new URL("../package.json", require("url").pathToFileURL(__filename).href), "utf8"));
202
+ if (!record$2(metadata) || !record$2(ownMetadata) || metadata["version"] !== ownMetadata["version"]) throw new Error("Nuxt target helper must use the same tooling version as the resolver");
203
+ helper = (0, node_url.pathToFileURL)(helperEntry).href;
204
+ }
205
+ const shim = `data:text/javascript,${encodeURIComponent(captureShim((0, node_url.pathToFileURL)(unbuild).href))}`;
206
+ const loader = `
207
+ import {realpathSync} from 'node:fs';
208
+ import path from 'node:path';
209
+ import {fileURLToPath} from 'node:url';
210
+ export const resolve=(specifier,context,next)=>{
211
+ if(specifier!=='unbuild')return next(specifier,context);
212
+ if(!context.parentURL||!context.parentURL.startsWith('file:')||path.dirname(realpathSync(fileURLToPath(context.parentURL)))!==${JSON.stringify(node_path.default.dirname(tool))})throw new Error('Unexpected Nuxt unbuild import parent');
213
+ return {url:${JSON.stringify(shim)},shortCircuit:true};
214
+ };`;
215
+ const captures = (0, node_child_process.execFileSync)(process.versions.bun ? "node" : process.execPath, [
216
+ "--input-type=module",
217
+ "-e",
218
+ captureProgram,
219
+ JSON.stringify({
220
+ directory: canonicalDirectory,
221
+ tool: (0, node_url.pathToFileURL)(tool).href,
222
+ unbuild: (0, node_url.pathToFileURL)(unbuild).href,
223
+ jiti: (0, node_url.pathToFileURL)((0, node_fs.realpathSync)(unbuildRequire.resolve("jiti"))).href,
224
+ helper,
225
+ loader: `data:text/javascript,${encodeURIComponent(loader)}`
226
+ })
227
+ ], {
228
+ cwd: canonicalDirectory,
229
+ encoding: "utf8",
230
+ timeout: 3e4,
231
+ maxBuffer: 1024 * 1024,
232
+ env: {
233
+ ...process.env,
234
+ JITI_FS_CACHE: "0",
235
+ JITI_MODULE_CACHE: "1"
236
+ }
237
+ }).split("\n").filter((line) => line.startsWith("__STLL_NUXT_TARGET__"));
238
+ const capture = captures.at(0);
239
+ if (captures.length !== 1 || capture === void 0) throw new Error("Nuxt did not return exactly one resolved build configuration");
240
+ return resolvedNuxtTarget(JSON.parse(capture.slice(20)));
241
+ };
242
+ //#endregion
243
+ //#region src/publish-build-target-vite.ts
244
+ const supportedViteVersion = "8.1.5";
245
+ const declarationHelperImport = "@stll/oxlint-config/declaration-only-dts";
246
+ const record$1 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
247
+ const walkAst = ({ value, visit, parent }) => {
248
+ if (Array.isArray(value)) {
249
+ for (const entry of value) walkAst({
250
+ value: entry,
251
+ visit,
252
+ ...parent === void 0 ? {} : { parent }
253
+ });
254
+ return;
255
+ }
256
+ if (!record$1(value)) return;
257
+ visit(value, parent);
258
+ for (const entry of Object.values(value)) if (typeof entry === "object" && entry !== null) walkAst({
259
+ value: entry,
260
+ visit,
261
+ parent: value
262
+ });
263
+ };
264
+ const astName = (value) => record$1(value) && value["type"] === "Identifier" ? value["name"] : void 0;
265
+ const astLiteral = (value) => {
266
+ if (!record$1(value)) throw new Error("Declaration helper options must be literal");
267
+ if (value["type"] === "Literal" && (typeof value["value"] === "string" || typeof value["value"] === "boolean")) return value["value"];
268
+ if (value["type"] === "ArrayExpression" && Array.isArray(value["elements"])) return value["elements"].map(astLiteral);
269
+ if (value["type"] === "ObjectExpression" && Array.isArray(value["properties"])) {
270
+ const entries = [];
271
+ for (const property of value["properties"]) {
272
+ if (!record$1(property) || property["type"] !== "Property" || property["kind"] !== "init" || property["computed"] === true || property["method"] === true || property["shorthand"] === true) throw new Error("Declaration helper options must be plain literal properties");
273
+ const key = astName(property["key"]) ?? (record$1(property["key"]) ? property["key"]["value"] : void 0);
274
+ if (typeof key !== "string" || entries.some(([previous]) => previous === key)) throw new Error("Invalid declaration helper option key");
275
+ entries.push([key, astLiteral(property["value"])]);
276
+ }
277
+ return Object.fromEntries(entries);
278
+ }
279
+ throw new Error("Declaration helper options must be literal");
280
+ };
281
+ /** Prove the helper owns the directly declared plugin; closure brands alone are insufficient. */
282
+ const reviewedDtsConfiguration = ({ source, directory, loader }) => {
283
+ const ast = (0, acorn.parse)((0, esbuild.transformSync)(source, {
284
+ loader,
285
+ format: "esm",
286
+ target: "esnext"
287
+ }).code, {
288
+ ecmaVersion: "latest",
289
+ sourceType: "module"
290
+ });
291
+ if (!record$1(ast) || !Array.isArray(ast["body"])) throw new Error("Invalid Vite configuration AST");
292
+ const bindings = /* @__PURE__ */ new Set();
293
+ const defineConfigBindings = /* @__PURE__ */ new Set();
294
+ const initializers = /* @__PURE__ */ new Map();
295
+ let exported;
296
+ for (const statement of ast["body"]) {
297
+ if (!record$1(statement)) continue;
298
+ if (statement["type"] === "ImportDeclaration" && record$1(statement["source"])) {
299
+ const imported = statement["source"]["value"];
300
+ if (typeof imported === "string" && /^(?:vite-plugin-dts|unplugin-dts)(?:\/|$)/.test(imported)) throw new Error("Raw declaration emitters cannot accompany the reviewed helper");
301
+ if (Array.isArray(statement["specifiers"])) for (const specifier of statement["specifiers"]) {
302
+ if (!record$1(specifier)) continue;
303
+ const local = astName(specifier["local"]);
304
+ const name = astName(specifier["imported"]);
305
+ if (imported === declarationHelperImport) {
306
+ if (specifier["type"] !== "ImportSpecifier" || name !== "declarationOnlyDts" || typeof local !== "string") throw new Error("Use the named declarationOnlyDts helper import");
307
+ bindings.add(local);
308
+ }
309
+ if (imported === "vite" && name === "defineConfig" && typeof local === "string") defineConfigBindings.add(local);
310
+ }
311
+ }
312
+ if (statement["type"] === "VariableDeclaration" && Array.isArray(statement["declarations"])) {
313
+ for (const declaration of statement["declarations"]) if (record$1(declaration)) initializers.set(astName(declaration["id"]), declaration["init"]);
314
+ }
315
+ if (statement["type"] === "ExportDefaultDeclaration") exported = statement["declaration"];
316
+ if (statement["type"] === "ExportNamedDeclaration" && Array.isArray(statement["specifiers"])) {
317
+ for (const specifier of statement["specifiers"]) if (record$1(specifier) && astName(specifier["exported"]) === "default") exported = specifier["local"];
318
+ }
319
+ }
320
+ if (bindings.size !== 1) throw new Error("Vite declaration plugins require one statically imported helper");
321
+ if (record$1(exported) && exported["type"] === "Identifier") exported = initializers.get(astName(exported));
322
+ if (record$1(exported) && exported["type"] === "CallExpression" && defineConfigBindings.has(String(astName(exported["callee"]))) && Array.isArray(exported["arguments"]) && exported["arguments"].length === 1) exported = exported["arguments"].at(0);
323
+ if (!record$1(exported) || exported["type"] !== "ObjectExpression" || !Array.isArray(exported["properties"])) throw new Error("Declaration helper requires a directly exported static Vite configuration");
324
+ const pluginProperties = exported["properties"].filter((property) => record$1(property) && (astName(property["key"]) === "plugins" || record$1(property["key"]) && property["key"]["value"] === "plugins"));
325
+ const property = pluginProperties.at(0);
326
+ if (pluginProperties.length !== 1 || !record$1(property) || property["computed"] === true || property["kind"] !== "init" || !record$1(property["value"]) || property["value"]["type"] !== "ArrayExpression" || !Array.isArray(property["value"]["elements"])) throw new Error("Declaration helper requires a literal plugins array");
327
+ const calls = property["value"]["elements"].map((element) => record$1(element) && element["type"] === "AwaitExpression" ? element["argument"] : element).filter((element) => record$1(element) && element["type"] === "CallExpression" && bindings.has(String(astName(element["callee"]))));
328
+ const call = calls.at(0);
329
+ if (calls.length !== 1 || !record$1(call) || !Array.isArray(call["arguments"]) || call["arguments"].length !== 1) throw new Error("Declare exactly one direct declaration helper call");
330
+ walkAst({
331
+ value: ast,
332
+ visit: (node, parent) => {
333
+ if (node["type"] === "ImportDeclaration") return;
334
+ const name = astName(node);
335
+ if (typeof name !== "string" || !bindings.has(name)) return;
336
+ if (parent?.["type"] === "ImportSpecifier") return;
337
+ if (parent !== call || call["callee"] !== node) throw new Error("Declaration helper binding cannot be aliased or invoked indirectly");
338
+ }
339
+ });
340
+ const argument = call["arguments"].at(0);
341
+ if (!record$1(argument) || argument["type"] !== "ObjectExpression" || !Array.isArray(argument["properties"])) throw new Error("Declaration helper options must be a literal object");
342
+ const directoryProperties = argument["properties"].filter((entry) => record$1(entry) && astName(entry["key"]) === "directory");
343
+ const directoryProperty = directoryProperties.at(0);
344
+ if (directoryProperties.length !== 1 || !record$1(directoryProperty) || directoryProperty["computed"] === true || directoryProperty["kind"] !== "init") throw new Error("Declaration helper requires its package directory");
345
+ const value = directoryProperty["value"];
346
+ const meta = record$1(value) ? value["object"] : void 0;
347
+ const importDirectory = record$1(value) && value["type"] === "MemberExpression" && value["computed"] === false && astName(value["property"]) === "dirname" && record$1(meta) && meta["type"] === "MetaProperty" && astName(meta["meta"]) === "import" && astName(meta["property"]) === "meta";
348
+ const exactDirectory = record$1(value) && value["type"] === "Literal" && value["value"] === directory;
349
+ if (!importDirectory && !exactDirectory) throw new Error("Declaration helper directory must be import.meta.dirname or the exact package directory");
350
+ return require_publish_build_target_vite_dts_helper.reviewedViteDtsOptions(astLiteral({
351
+ ...argument,
352
+ properties: argument["properties"].filter((entry) => entry !== directoryProperty)
353
+ }));
354
+ };
355
+ const ownEntries = (value) => Reflect.ownKeys(value).map((key) => {
356
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
357
+ if (typeof key !== "string" || !descriptor || !("value" in descriptor)) throw new Error("Unsupported Vite hook property");
358
+ return [key, descriptor.value];
359
+ });
360
+ const metadataSource = (value) => {
361
+ if (value instanceof RegExp) return JSON.stringify([
362
+ "regexp",
363
+ value.source,
364
+ value.flags
365
+ ]);
366
+ if (Array.isArray(value)) return JSON.stringify(["array", value.map(metadataSource)]);
367
+ if (record$1(value)) {
368
+ if (Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) throw new Error("Unsupported Vite hook metadata");
369
+ return JSON.stringify(["object", ownEntries(value).sort(([a], [b]) => a.localeCompare(b)).map(([key, item]) => [key, metadataSource(item)])]);
370
+ }
371
+ if (value === void 0) return "undefined";
372
+ if (value === null || typeof value === "string" || typeof value === "boolean" || typeof value === "number" && Number.isFinite(value)) return JSON.stringify(value);
373
+ throw new Error("Unsupported Vite hook metadata");
374
+ };
375
+ const hookSource = (value) => {
376
+ if (typeof value === "function") return JSON.stringify(["function", Function.prototype.toString.call(value)]);
377
+ if (!record$1(value)) throw new Error("Unsupported Vite build hook");
378
+ if (Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) throw new Error("Unsupported Vite hook metadata");
379
+ const entries = ownEntries(value);
380
+ const handler = entries.find(([key]) => key === "handler")?.[1];
381
+ if (typeof handler !== "function") throw new Error("Unsupported Vite build hook");
382
+ const metadata = entries.filter(([key]) => key !== "handler");
383
+ if (metadata.some(([key]) => ![
384
+ "order",
385
+ "sequential",
386
+ "filter"
387
+ ].includes(key))) throw new Error("Unsupported Vite hook metadata");
388
+ return JSON.stringify([
389
+ "object",
390
+ Function.prototype.toString.call(handler),
391
+ metadataSource(Object.fromEntries(metadata))
392
+ ]);
393
+ };
394
+ const pluginEntries = (plugin) => {
395
+ const entries = /* @__PURE__ */ new Map();
396
+ let current = plugin;
397
+ while (current !== Object.prototype) {
398
+ for (const [key, value] of ownEntries(current)) {
399
+ if (current !== plugin && key === "constructor") continue;
400
+ if (!entries.has(key)) entries.set(key, value);
401
+ }
402
+ const prototype = Object.getPrototypeOf(current);
403
+ if (prototype === null) break;
404
+ if (!record$1(prototype)) throw new Error("Unsupported Vite plugin prototype");
405
+ current = prototype;
406
+ }
407
+ return entries;
408
+ };
409
+ const plugins = (config) => {
410
+ if (!record$1(config) || !record$1(config["build"]) || !record$1(config["environments"])) throw new Error("Invalid Vite plugin configuration");
411
+ const environment = config["environments"][config["build"]["ssr"] === true || typeof config["build"]["ssr"] === "string" && config["build"]["ssr"] !== "" ? "ssr" : "client"];
412
+ if (!record$1(environment) || !Array.isArray(environment["plugins"]) || !Array.isArray(config["plugins"])) throw new Error("Missing resolved Vite environment plugins");
413
+ const options = config["build"]["rolldownOptions"];
414
+ const extra = record$1(options) ? options["plugins"] : void 0;
415
+ if (extra !== void 0 && !Array.isArray(extra)) throw new Error("Dynamic Vite rolldown plugins require a supported target resolver");
416
+ return [
417
+ ...config["plugins"],
418
+ ...environment["plugins"],
419
+ ...extra ?? []
420
+ ].flat(Infinity);
421
+ };
422
+ /** Vue hook closures may only capture the reviewed factory's default options. */
423
+ const assertReviewedVueOptions = ({ plugin, reviewed }) => {
424
+ const fail = () => /* @__PURE__ */ new Error("Custom Vue plugin options require a supported target resolver");
425
+ if (!record$1(plugin) || !record$1(reviewed) || !record$1(plugin["api"]) || !record$1(reviewed["api"])) throw fail();
426
+ const api = plugin["api"];
427
+ const defaults = reviewed["api"];
428
+ const options = api["options"];
429
+ const defaultOptions = defaults["options"];
430
+ if (!record$1(options) || !record$1(defaultOptions)) throw fail();
431
+ if (Object.getPrototypeOf(options) !== Object.prototype && Object.getPrototypeOf(options) !== null) throw fail();
432
+ if (metadataSource(api["include"]) !== metadataSource(defaults["include"]) || api["exclude"] !== void 0) throw fail();
433
+ const lifecycleFields = /* @__PURE__ */ new Set([
434
+ "isProduction",
435
+ "sourceMap",
436
+ "cssDevSourcemap",
437
+ "devToolsEnabled"
438
+ ]);
439
+ for (const [key, value] of ownEntries(options)) {
440
+ if (key === "root") {
441
+ if (typeof value !== "string") throw fail();
442
+ continue;
443
+ }
444
+ if (lifecycleFields.has(key)) {
445
+ if (typeof value !== "boolean") throw fail();
446
+ continue;
447
+ }
448
+ if (key === "compiler") {
449
+ if (value !== null && value !== void 0) throw fail();
450
+ continue;
451
+ }
452
+ if (!Object.hasOwn(defaultOptions, key) || metadataSource(value) !== metadataSource(defaultOptions[key])) throw fail();
453
+ }
454
+ for (const [key] of ownEntries(defaultOptions)) if (!Object.hasOwn(options, key) && key !== "compiler") throw fail();
455
+ };
456
+ const vitePluginMetadata = /* @__PURE__ */ new Set([
457
+ "enforce",
458
+ "_options",
459
+ "perEnvironmentStartEndDuringDev",
460
+ "perEnvironmentWatchChangeDuringDev"
461
+ ]);
462
+ const nativeCallbackFields = /* @__PURE__ */ new Map([
463
+ ["builtin:vite-resolve", "resolveSubpathImports"],
464
+ ["builtin:vite-dynamic-import-vars", "resolver"],
465
+ ["builtin:vite-reporter", "logInfo"]
466
+ ]);
467
+ const nativeOptionsSource = (name, value) => {
468
+ if (!record$1(value)) return metadataSource(value);
469
+ if (Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) throw new Error("Unsupported Vite native options");
470
+ return JSON.stringify(ownEntries(value).sort(([a], [b]) => a.localeCompare(b)).map(([key, item]) => {
471
+ if (key === nativeCallbackFields.get(name) && typeof item === "function") return [
472
+ key,
473
+ "reviewed-callback",
474
+ Function.prototype.toString.call(item)
475
+ ];
476
+ return [
477
+ key,
478
+ "metadata",
479
+ metadataSource(item)
480
+ ];
481
+ }));
482
+ };
483
+ const pluginSources = (plugin) => {
484
+ const entries = pluginEntries(plugin);
485
+ for (const key of [...vitePluginMetadata, "apply"]) if (!entries.has(key)) entries.set(key, void 0);
486
+ const sources = /* @__PURE__ */ new Map();
487
+ for (const [key, value] of entries) {
488
+ if (key === "name" || key === "api") continue;
489
+ if (key === "_options") {
490
+ const name = entries.get("name");
491
+ if (typeof name !== "string") throw new Error("Invalid Vite plugin name");
492
+ sources.set(key, `native:${nativeOptionsSource(name, value)}`);
493
+ continue;
494
+ }
495
+ if (vitePluginMetadata.has(key) || key === "apply" && typeof value !== "function") sources.set(key, `metadata:${metadataSource(value)}`);
496
+ else if (value === void 0) sources.set(key, "absent-hook");
497
+ else sources.set(key, `hook:${hookSource(value)}`);
498
+ }
499
+ return sources;
500
+ };
501
+ /** Reviewed tool versions own the plugin name, hook name and implementation together. */
502
+ const assertReviewedVitePlugins = ({ resolved, reviewed }) => {
503
+ const identities = /* @__PURE__ */ new Map();
504
+ for (const plugin of reviewed) {
505
+ if (!record$1(plugin) || typeof plugin["name"] !== "string") throw new Error("Invalid reviewed Vite plugin");
506
+ const name = plugin["name"];
507
+ const hooks = identities.get(name) ?? /* @__PURE__ */ new Map();
508
+ identities.set(name, hooks);
509
+ for (const [key, source] of pluginSources(plugin)) {
510
+ const sources = hooks.get(key) ?? /* @__PURE__ */ new Set();
511
+ sources.add(source);
512
+ hooks.set(key, sources);
513
+ }
514
+ }
515
+ for (const plugin of resolved) {
516
+ if (plugin === void 0 || plugin === null || plugin === false) continue;
517
+ if (!record$1(plugin) || typeof plugin["name"] !== "string") throw new Error("Dynamic Vite plugins require a supported target resolver");
518
+ const name = plugin["name"];
519
+ const hooks = identities.get(name);
520
+ if (hooks === void 0) throw new Error(`Unreviewed Vite plugin ${name} requires a supported target resolver`);
521
+ for (const [key, source] of pluginSources(plugin)) if (!hooks.get(key)?.has(source)) throw new Error(`Unreviewed Vite hook ${name}:${key} requires a supported target resolver`);
522
+ }
523
+ const pipelineIdentity = (plugin) => {
524
+ if (!record$1(plugin) || typeof plugin["name"] !== "string") throw new Error("Invalid reviewed Vite pipeline entry");
525
+ return JSON.stringify([plugin["name"], [...pluginSources(plugin)].sort(([a], [b]) => a.localeCompare(b))]);
526
+ };
527
+ const actualPipeline = resolved.filter((plugin) => plugin !== void 0 && plugin !== null && plugin !== false);
528
+ if (actualPipeline.length !== reviewed.length || reviewed.some((plugin, index) => pipelineIdentity(plugin) !== pipelineIdentity(actualPipeline[index]))) throw new Error("Vite plugin pipeline must match the complete reviewed order");
529
+ };
530
+ /** Vite 8 spreads transform overrides after its resolved build target. */
531
+ const resolvedViteTarget = (config) => {
532
+ if (!record$1(config) || !record$1(config["build"])) throw new Error("Invalid resolved Vite build configuration");
533
+ if (config["builder"] !== void 0) throw new Error("Custom Vite builders require a supported target resolver");
534
+ const build = config["build"];
535
+ const options = build["rolldownOptions"];
536
+ if (options !== void 0 && !record$1(options)) throw new Error("Vite rolldownOptions must be an object");
537
+ const output = record$1(options) ? options["output"] : void 0;
538
+ if (output !== void 0) {
539
+ const outputs = Array.isArray(output) ? output : [output];
540
+ for (const entry of outputs) {
541
+ if (!record$1(entry)) throw new Error("Unsupported Vite output options");
542
+ for (const key of [
543
+ "banner",
544
+ "footer",
545
+ "intro",
546
+ "outro"
547
+ ]) if (entry[key] !== void 0 && entry[key] !== "") throw new Error("Vite output addons require a supported target resolver");
548
+ const outputPlugins = entry["plugins"];
549
+ if (outputPlugins !== void 0 && (!Array.isArray(outputPlugins) || outputPlugins.length > 0)) throw new Error("Vite output plugins require a supported target resolver");
550
+ }
551
+ }
552
+ const transform = record$1(options) ? options["transform"] : void 0;
553
+ if (transform !== void 0 && !record$1(transform)) throw new Error("Vite transform overrides must be an object");
554
+ let target = build["target"] === false ? void 0 : build["target"];
555
+ if (record$1(transform) && "target" in transform) target = transform["target"];
556
+ if (target === void 0) return {
557
+ type: "javascript",
558
+ targets: ["esnext"]
559
+ };
560
+ const targets = typeof target === "string" ? [target] : target;
561
+ if (!Array.isArray(targets) || targets.length === 0) throw new Error("Unsupported resolved Vite JavaScript target");
562
+ const emitted = /* @__PURE__ */ new Set();
563
+ for (const item of targets) {
564
+ if (typeof item !== "string" || item.length === 0) throw new Error("Unsupported resolved Vite JavaScript target");
565
+ emitted.add(item);
566
+ }
567
+ return {
568
+ type: "javascript",
569
+ targets: [...emitted].sort()
570
+ };
571
+ };
572
+ /** Only static build settings needed by the installed tool's canonical profile cross this boundary. */
573
+ const reviewedViteBuild = (build) => {
574
+ if (!record$1(build)) throw new Error("Invalid Vite build configuration");
575
+ const properties = new Map(ownEntries(build));
576
+ const result = {};
577
+ for (const key of [
578
+ "target",
579
+ "sourcemap",
580
+ "minify",
581
+ "ssr",
582
+ "cssCodeSplit",
583
+ "assetsInlineLimit",
584
+ "assetsDir",
585
+ "reportCompressedSize",
586
+ "chunkSizeWarningLimit",
587
+ "modulePreload"
588
+ ]) {
589
+ const value = properties.get(key);
590
+ metadataSource(value);
591
+ result[key] = value;
592
+ }
593
+ const library = properties.get("lib");
594
+ if (record$1(library)) {
595
+ if (Object.getPrototypeOf(library) !== Object.prototype && Object.getPrototypeOf(library) !== null) throw new Error("Unsupported Vite library configuration");
596
+ const libraryProperties = new Map(ownEntries(library));
597
+ const fields = {};
598
+ for (const key of [
599
+ "entry",
600
+ "formats",
601
+ "name"
602
+ ]) {
603
+ const value = libraryProperties.get(key);
604
+ metadataSource(value);
605
+ fields[key] = value;
606
+ }
607
+ result["lib"] = fields;
608
+ } else if (library === void 0 || library === false) result["lib"] = library;
609
+ else throw new Error("Unsupported Vite library configuration");
610
+ return result;
611
+ };
612
+ const resolveVitePublishTarget = async (directory) => {
613
+ const canonicalDirectory = (0, node_fs.realpathSync)(directory);
614
+ const require = (0, node_module.createRequire)(node_path.default.join(canonicalDirectory, "package.json"));
615
+ const metadata = JSON.parse((0, node_fs.readFileSync)(require.resolve("vite/package.json"), "utf8"));
616
+ if (!record$1(metadata) || metadata["version"] !== supportedViteVersion) throw new Error(`Publish target resolver supports Vite ${supportedViteVersion}; review the adapter before changing build tools`);
617
+ const tool = await import((0, node_url.pathToFileURL)((0, node_fs.realpathSync)(require.resolve("vite"))).href);
618
+ if (!record$1(tool) || typeof tool["resolveConfig"] !== "function") throw new Error("Installed Vite does not expose its configuration resolver");
619
+ const patchConfig = (resolved) => {
620
+ if (!record$1(resolved) || !record$1(resolved["build"]) || !record$1(resolved["environments"])) throw new Error("Invalid Vite environment configuration");
621
+ if (resolved["builder"] !== void 0) throw new Error("Custom Vite builders require a supported target resolver");
622
+ const environment = resolved["environments"][resolved["build"]["ssr"] === true || typeof resolved["build"]["ssr"] === "string" && resolved["build"]["ssr"] !== "" ? "ssr" : "client"];
623
+ if (!record$1(environment) || !record$1(environment["build"])) throw new Error("Missing resolved Vite build environment");
624
+ resolved["build"] = { ...environment["build"] };
625
+ };
626
+ const config = await tool["resolveConfig"]({ root: canonicalDirectory }, "build", "production", "production", false, patchConfig);
627
+ if (!record$1(config) || !record$1(config["build"])) throw new Error("Invalid Vite build configuration");
628
+ const resolvedPlugins = plugins(config);
629
+ const canonicalVuePlugins = [];
630
+ if (resolvedPlugins.some((plugin) => record$1(plugin) && plugin["name"] === "vite:vue")) {
631
+ const vueMetadata = JSON.parse((0, node_fs.readFileSync)(require.resolve("@vitejs/plugin-vue/package.json"), "utf8"));
632
+ if (!record$1(vueMetadata) || vueMetadata["version"] !== "6.0.8") throw new Error("Publish target resolver supports @vitejs/plugin-vue 6.0.8; review the adapter before changing build tools");
633
+ const vue = await import((0, node_url.pathToFileURL)((0, node_fs.realpathSync)(require.resolve("@vitejs/plugin-vue"))).href);
634
+ if (!record$1(vue) || typeof vue["default"] !== "function") throw new Error("Invalid installed Vue plugin factory");
635
+ const plugin = vue["default"]();
636
+ if (!record$1(plugin)) throw new Error("Invalid installed Vue plugin");
637
+ for (const resolved of resolvedPlugins) if (record$1(resolved) && resolved["name"] === "vite:vue") assertReviewedVueOptions({
638
+ plugin: resolved,
639
+ reviewed: plugin
640
+ });
641
+ canonicalVuePlugins.push(plugin);
642
+ }
643
+ if (resolvedPlugins.some((plugin) => record$1(plugin) && plugin["name"] === "stll:declaration-only-dts")) {
644
+ const configFile = config["configFile"];
645
+ if (typeof configFile !== "string" || node_path.default.dirname((0, node_fs.realpathSync)(configFile)) !== canonicalDirectory) throw new Error("Declaration helper requires a package-local Vite config file");
646
+ const options = reviewedDtsConfiguration({
647
+ source: (0, node_fs.readFileSync)(configFile, "utf8"),
648
+ directory: canonicalDirectory,
649
+ loader: /\.[cm]?ts$/.test(configFile) ? "ts" : "js"
650
+ });
651
+ canonicalVuePlugins.push(require_publish_build_target_vite_dts_helper.declarationOnlyDts({
652
+ directory: canonicalDirectory,
653
+ ...options
654
+ }));
655
+ }
656
+ const canonicalBuild = reviewedViteBuild(config["build"]);
657
+ const canonical = await tool["resolveConfig"]({
658
+ root: canonicalDirectory,
659
+ configFile: false,
660
+ plugins: canonicalVuePlugins,
661
+ build: canonicalBuild
662
+ }, "build", "production", "production", false, patchConfig);
663
+ if (!record$1(canonical) || !record$1(canonical["build"]) || hookSource(config["build"]["createEnvironment"]) !== hookSource(canonical["build"]["createEnvironment"])) throw new Error("Custom Vite createEnvironment requires a supported target resolver");
664
+ const reviewedPlugins = plugins(canonical);
665
+ assertReviewedVitePlugins({
666
+ resolved: resolvedPlugins,
667
+ reviewed: reviewedPlugins
668
+ });
669
+ return resolvedViteTarget(config);
670
+ };
671
+ //#endregion
672
+ //#region src/publish-build-target.ts
673
+ const supportedTsdownVersion = "0.22.9";
674
+ const record = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
675
+ const targets = (value) => {
676
+ if (value === void 0) return ["esnext"];
677
+ if (typeof value === "string") {
678
+ const identifier = value.trim();
679
+ if (identifier === "" || identifier.includes(",")) throw new Error("Resolved JavaScript target identifiers must be nonempty and contain no commas");
680
+ return [identifier];
681
+ }
682
+ if (Array.isArray(value) && value.length > 0 && Array.from(value).every((item) => typeof item === "string")) return value.flatMap((item) => targets(item));
683
+ throw new Error("Build tool returned an unsupported resolved JavaScript target");
684
+ };
685
+ /** Only hooks completed by configuration resolution may run before target capture. */
686
+ const assertTsdownBuildExtensions = (options) => {
687
+ const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
688
+ const entries = (value) => {
689
+ const prototype = Object.getPrototypeOf(value);
690
+ if (prototype !== Object.prototype && prototype !== null) throw new Error("Unreviewed build option prototype requires a supported target resolver");
691
+ return Reflect.ownKeys(value).map((key) => {
692
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
693
+ if (typeof key !== "string" || !descriptor || !("value" in descriptor)) throw new Error("Unreviewed build option property requires a supported target resolver");
694
+ return [key, descriptor.value];
695
+ });
696
+ };
697
+ const plugins = (value, phase) => {
698
+ if (value === void 0 || value === null || value === false) return;
699
+ if (Array.isArray(value)) {
700
+ for (const plugin of value) plugins(plugin, phase);
701
+ return;
702
+ }
703
+ if (!isRecord(value)) throw new Error("Dynamic plugins require a supported target resolver");
704
+ for (const [key, item] of entries(value)) {
705
+ if (item === void 0) continue;
706
+ if (key === "name" && typeof item === "string") continue;
707
+ if (phase === "configuration" && ["tsdownConfig", "tsdownConfigResolved"].includes(key) && typeof item === "function") continue;
708
+ throw new Error("Unreviewed plugin hooks require a supported target resolver");
709
+ }
710
+ };
711
+ const output = (value) => {
712
+ if (value === void 0) return;
713
+ if (!isRecord(value)) throw new Error("Dynamic output options require a supported target resolver");
714
+ for (const [key, item] of entries(value)) {
715
+ if (key === "plugins") plugins(item, "output");
716
+ if ([
717
+ "banner",
718
+ "footer",
719
+ "intro",
720
+ "outro"
721
+ ].includes(key) && item !== void 0 && item !== "") throw new Error("Output addons require a supported target resolver");
722
+ }
723
+ };
724
+ if (!isRecord(options)) throw new Error("Invalid build configuration");
725
+ const properties = new Map(entries(options));
726
+ if (properties.get("hooks") !== void 0) throw new Error("Build hooks require a supported target resolver");
727
+ plugins(properties.get("plugins"), "configuration");
728
+ output(properties.get("outputOptions"));
729
+ for (const key of ["banner", "footer"]) {
730
+ const addon = properties.get(key);
731
+ if (addon !== void 0 && addon !== "") throw new Error("Output addons require a supported target resolver");
732
+ }
733
+ const input = properties.get("inputOptions");
734
+ if (input !== void 0) {
735
+ if (!isRecord(input)) throw new Error("Dynamic tsdown inputOptions require a supported target resolver");
736
+ plugins(new Map(entries(input)).get("plugins"), "output");
737
+ }
738
+ };
739
+ /** Extract the final target after supported format and low-level overrides. */
740
+ const resolvedTsdownTarget = (configs) => {
741
+ if (!Array.isArray(configs) || configs.length === 0) throw new Error("tsdown must resolve at least one build configuration");
742
+ const emitted = /* @__PURE__ */ new Set();
743
+ let javascript = false;
744
+ for (const config of configs) {
745
+ if (!record(config)) throw new Error("Invalid resolved tsdown configuration");
746
+ assertTsdownBuildExtensions(config);
747
+ if (record(config["dts"]) && config["dts"]["emitDtsOnly"] === true) continue;
748
+ javascript = true;
749
+ const input = config["inputOptions"];
750
+ if (input !== void 0 && !record(input)) throw new Error("Dynamic tsdown inputOptions require a supported target resolver");
751
+ const transform = record(input) ? input["transform"] : void 0;
752
+ if (transform !== void 0 && !record(transform)) throw new Error("tsdown transform overrides must be an object");
753
+ const target = record(transform) && transform["target"] != null ? transform["target"] : config["target"];
754
+ for (const item of targets(target)) emitted.add(item);
755
+ }
756
+ return javascript ? {
757
+ type: "javascript",
758
+ targets: [...emitted].sort()
759
+ } : { type: "types-only" };
760
+ };
761
+ const exportPaths = (value) => {
762
+ if (typeof value === "string") return [value];
763
+ if (value === null || value === void 0) return [];
764
+ if (Array.isArray(value)) return value.flatMap((item) => exportPaths(item));
765
+ if (record(value)) return Object.values(value).flatMap(exportPaths);
766
+ throw new Error("Invalid package export declaration");
767
+ };
768
+ const publishBuildScript = "build";
769
+ const publishBuildLifecycleScripts = [`pre${publishBuildScript}`, `post${publishBuildScript}`];
770
+ const assertPublishBuildLifecycle = (manifest) => {
771
+ const scripts = manifest["scripts"];
772
+ if (!record(scripts)) return;
773
+ for (const script of publishBuildLifecycleScripts) if (Object.hasOwn(scripts, script)) throw new Error(`Publish target resolver does not support lifecycle script ${script}`);
774
+ };
775
+ /** JSON and declaration-only packages have no emitted JavaScript target. */
776
+ const assetOnlyTarget = (manifest, packer) => {
777
+ if (!record(manifest)) throw new Error("Package manifest must be an object");
778
+ assertPublishBuildLifecycle(manifest);
779
+ if (record(manifest["scripts"]) && manifest["scripts"]["build"] !== void 0) return void 0;
780
+ const published = require_publish_contract.resolveManifestContract({
781
+ manifest,
782
+ packer,
783
+ target: { type: "types-only" }
784
+ });
785
+ const paths = [
786
+ "exports",
787
+ "main",
788
+ "module",
789
+ "types",
790
+ "typings",
791
+ "bin"
792
+ ].flatMap((key) => exportPaths(published.entryPoints[key]));
793
+ if (paths.length === 0 || paths.some((item) => !/(?:\.json|\.d\.(?:ts|mts|cts))$/.test(item))) return void 0;
794
+ return { type: "types-only" };
795
+ };
796
+ /** Supported build commands have no shell composition or runtime relocation. */
797
+ const supportedPublishBuildCommand = (build) => {
798
+ switch (build.replace(/[ \t]+/g, " ").replace(/^ | $/g, "")) {
799
+ case "tsdown": return "tsdown";
800
+ case "vite build": return "vite";
801
+ case "nuxt-module-build build": return "nuxt-module-build";
802
+ }
803
+ throw new Error("Publish target resolver requires an exact single invocation: tsdown, vite build, or nuxt-module-build build; shell composition, launchers, filters and CLI overrides are unsupported");
804
+ };
805
+ const resolvePublishBuildTarget = async (directory, packer) => {
806
+ const manifest = JSON.parse((0, node_fs.readFileSync)(node_path.default.join(directory, "package.json"), "utf8"));
807
+ const assets = assetOnlyTarget(manifest, packer);
808
+ if (assets !== void 0) return assets;
809
+ if (!record(manifest) || !record(manifest["scripts"]) || typeof manifest["scripts"]["build"] !== "string") throw new Error("A JavaScript package needs an explicitly supported build command");
810
+ switch (supportedPublishBuildCommand(manifest["scripts"]["build"])) {
811
+ case "vite": return await resolveVitePublishTarget(directory);
812
+ case "nuxt-module-build": return resolveNuxtPublishTarget(directory);
813
+ case "tsdown": break;
814
+ }
815
+ const configFiles = [
816
+ "ts",
817
+ "mts",
818
+ "cts",
819
+ "js",
820
+ "mjs",
821
+ "cjs",
822
+ "json"
823
+ ].map((extension) => node_path.default.join(directory, `tsdown.config.${extension}`)).filter(node_fs.existsSync);
824
+ if (configFiles.length !== 1) throw new Error("Publish target resolver requires exactly one tsdown configuration");
825
+ const configFile = configFiles.at(0);
826
+ if (configFile === void 0) throw new Error("Missing tsdown configuration");
827
+ const require = (0, node_module.createRequire)(node_path.default.join(directory, "package.json"));
828
+ const metadata = JSON.parse((0, node_fs.readFileSync)(require.resolve("tsdown/package.json"), "utf8"));
829
+ if (!record(metadata) || metadata["version"] !== supportedTsdownVersion) throw new Error(`Publish target resolver supports tsdown ${supportedTsdownVersion}; review the adapter before changing build tools`);
830
+ const loaderRequire = (0, node_module.createRequire)(require("url").pathToFileURL(__filename).href);
831
+ const scratch = (0, node_fs.mkdtempSync)(node_path.default.join((0, node_os.tmpdir)(), "stll-publish-target-"));
832
+ try {
833
+ const resultFile = node_path.default.join(scratch, "targets.json");
834
+ const result = (0, node_child_process.spawnSync)(process.versions.bun ? "node" : process.execPath, [
835
+ "--import",
836
+ (0, node_url.pathToFileURL)(loaderRequire.resolve("tsx")).href,
837
+ "--input-type=module",
838
+ "--eval",
839
+ tsdownConfigProcess,
840
+ JSON.stringify({
841
+ directory,
842
+ configFile,
843
+ toolUrl: (0, node_url.pathToFileURL)(require.resolve("tsdown")).href,
844
+ resultFile
845
+ })
846
+ ], {
847
+ cwd: directory,
848
+ encoding: "utf8",
849
+ timeout: 3e4,
850
+ maxBuffer: 1024 * 1024
851
+ });
852
+ if (result.error) throw result.error;
853
+ if (result.status !== 0) throw new Error(`Node tsdown configuration resolver failed: ${result.stderr.trim()}`);
854
+ const resolved = JSON.parse((0, node_fs.readFileSync)(resultFile, "utf8"));
855
+ return resolvedTsdownTarget(resolved);
856
+ } finally {
857
+ (0, node_fs.rmSync)(scratch, {
858
+ recursive: true,
859
+ force: true
860
+ });
861
+ }
862
+ };
863
+ const tsdownConfigProcess = `
864
+ import { readFileSync, writeFileSync } from 'node:fs';
865
+ import { pathToFileURL } from 'node:url';
866
+ const { directory, configFile, toolUrl, resultFile } = JSON.parse(process.argv[1]);
867
+ const record = value => typeof value === 'object' && value !== null && !Array.isArray(value);
868
+ const tool = await import(toolUrl);
869
+ if (typeof tool.resolveUserConfig !== 'function')
870
+ throw new Error('Installed tsdown does not expose its configuration resolver');
871
+ if (tool.globalLogger) tool.globalLogger.level = 'silent';
872
+ const loaded = configFile.endsWith('.json')
873
+ ? { default: JSON.parse(readFileSync(configFile, 'utf8')) }
874
+ : await import(pathToFileURL(configFile).href);
875
+ if (!record(loaded)) throw new Error('Invalid tsdown module');
876
+ const exported = loaded.default;
877
+ if (typeof exported === 'function')
878
+ throw new Error('Dynamic root tsdown configurations require a supported target resolver');
879
+ const configs = Array.isArray(exported) ? exported : [exported];
880
+ const resolved = [];
881
+ const assertTsdownBuildExtensions = ${assertTsdownBuildExtensions.toString()};
882
+ for (const config of configs) {
883
+ if (!record(config)) throw new Error('tsdown configurations must be objects');
884
+ assertTsdownBuildExtensions(config);
885
+ if (config.cwd !== undefined || config.workspace !== undefined || config.fromVite !== undefined)
886
+ throw new Error('Relocated or inherited build configurations require a supported target resolver');
887
+ const output = await tool.resolveUserConfig(
888
+ { ...config, cwd: directory, logLevel: 'silent' }, { cwd: directory }, new Set(),
889
+ );
890
+ if (!Array.isArray(output)) throw new Error('Invalid tsdown resolved configuration');
891
+ for (const entry of output) {
892
+ if (!record(entry)) throw new Error('Invalid resolved tsdown configuration');
893
+ assertTsdownBuildExtensions(entry);
894
+ const input = entry.inputOptions;
895
+ if (input !== undefined && !record(input))
896
+ throw new Error('Dynamic tsdown inputOptions require a supported target resolver');
897
+ const transform = record(input) ? input.transform : undefined;
898
+ if (transform !== undefined && !record(transform))
899
+ throw new Error('tsdown transform overrides must be an object');
900
+ const target = record(transform) && transform.target != null ? transform.target : entry.target;
901
+ const nonemptyIdentifiers = value => typeof value === 'string' && value.trim() !== '' && !value.includes(',');
902
+ if (target !== undefined && !nonemptyIdentifiers(target) &&
903
+ !(Array.isArray(target) && target.length > 0 && Array.from(target).every(nonemptyIdentifiers)))
904
+ throw new Error('Build tool returned an unsupported resolved JavaScript target');
905
+ resolved.push({ target, dts: { emitDtsOnly: record(entry.dts) && entry.dts.emitDtsOnly === true } });
906
+ }
907
+ }
908
+ writeFileSync(resultFile, JSON.stringify(resolved));
909
+ `;
910
+ //#endregion
911
+ //#region src/publish-contract-cli.ts
912
+ const root = process.cwd();
913
+ const main = async () => {
914
+ const args = process.argv.slice(2);
915
+ if (args.length === 1 && args.at(0) === "--help") process.stdout.write("Usage: stll-publish-contract [--write]\n");
916
+ else {
917
+ if (args.length > 1 || args.length === 1 && args.at(0) !== "--write") throw new Error("Expected no arguments or --write");
918
+ const write = args.at(0) === "--write";
919
+ const policy = require_toolchain_schema.parseToolchainPolicy(JSON.parse((0, node_fs.readFileSync)(new URL("../toolchain.json", require("url").pathToFileURL(__filename).href), "utf8")));
920
+ const consumer = {
921
+ node: policy.consumerNode,
922
+ typescript: policy.consumerTypescript
923
+ };
924
+ const tracked = (0, node_child_process.execFileSync)("git", ["ls-files", "-z"], {
925
+ cwd: root,
926
+ encoding: "utf8"
927
+ }).split("\0");
928
+ const files = {};
929
+ for (const file of tracked) {
930
+ if (file.split("/").some((part) => part === "node_modules" || part === ".git") || !["package.json", "pnpm-workspace.yaml"].includes(node_path.default.posix.basename(file)) && require_toolchain_inputs.githubAutomationFileKind(file) !== "workflow") continue;
931
+ files[file] = (0, node_fs.readFileSync)(node_path.default.join(root, file), "utf8");
932
+ }
933
+ const manifests = require_toolchain_schema.discoverConsumerManifests(files);
934
+ const names = /* @__PURE__ */ new Set();
935
+ for (const manifest of manifests.values()) {
936
+ const name = manifest["name"];
937
+ if (typeof name !== "string" || name === "") continue;
938
+ if (names.has(name)) throw new Error(`duplicate workspace package: ${name}`);
939
+ names.add(name);
940
+ }
941
+ let checked = 0;
942
+ for (const [relative, manifest] of [...manifests].sort(([left], [right]) => left.localeCompare(right))) {
943
+ const file = node_path.default.posix.join(relative, "package.json");
944
+ if (manifest["private"] === true) continue;
945
+ if (relative.split("/").includes("vendor")) throw new Error(`Published workspace packages under vendor directories are not supported by publish-contract: ${file}; move the package to a supported workspace directory`);
946
+ require_toolchain_schema.assertConsumerPublishableManifest({
947
+ manifest,
948
+ directory: relative
949
+ });
950
+ checked++;
951
+ const directory = node_path.default.dirname(node_path.default.join(root, file));
952
+ const contractFile = node_path.default.join(directory, "publish-contract.json");
953
+ const packer = require_publish_contract.resolveConsumerReleasePack(files).manager;
954
+ const target = await resolvePublishBuildTarget(directory, packer);
955
+ const current = require_publish_contract.resolveManifestContract({
956
+ manifest,
957
+ target,
958
+ packer
959
+ });
960
+ const diagnostics = require_publish_contract.checkPublishContract({
961
+ packer,
962
+ manifest,
963
+ target,
964
+ contract: write ? current : JSON.parse((0, node_fs.readFileSync)(contractFile, "utf8")),
965
+ policy: consumer
966
+ });
967
+ for (const diagnostic of diagnostics) process.stderr.write(`${file}:1: [publish-contract] ${diagnostic.message}\n`);
968
+ if (diagnostics.length > 0) {
969
+ process.exitCode = 1;
970
+ continue;
971
+ }
972
+ if (write) (0, node_fs.writeFileSync)(contractFile, `${JSON.stringify(current, null, 2)}\n`);
973
+ }
974
+ if (checked === 0) throw new Error("No published workspace packages found");
975
+ }
976
+ };
977
+ main().catch((error) => {
978
+ process.stderr.write(`publish-contract:1: ${error instanceof Error ? error.message : String(error)}\n`);
979
+ process.exitCode = 1;
980
+ });
981
+ //#endregion
982
+
983
+ //# sourceMappingURL=publish-contract-cli.cjs.map