@workos/oagen 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.mjs +238 -23
- package/dist/cli/index.mjs.map +1 -1
- package/dist/compat/index.mjs +2 -2
- package/dist/{diff-DyQF4sel.mjs → diff-Cn6S74vV.mjs} +194 -12
- package/dist/diff-Cn6S74vV.mjs.map +1 -0
- package/dist/{differ-BwelBJN0.mjs → differ-B6472Yef.mjs} +2 -2
- package/dist/{differ-BwelBJN0.mjs.map → differ-B6472Yef.mjs.map} +1 -1
- package/dist/index.d.mts +30 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +3 -3
- package/dist/scripts/smoke/baseline.mjs +37 -2
- package/dist/scripts/smoke/baseline.mjs.map +1 -1
- package/dist/smoke.d.mts.map +1 -1
- package/dist/smoke.mjs +37 -2
- package/dist/smoke.mjs.map +1 -1
- package/dist/{tree-sitter-BPNfbEzY.mjs → tree-sitter-DFRXfWg9.mjs} +38 -3
- package/dist/{tree-sitter-BPNfbEzY.mjs.map → tree-sitter-DFRXfWg9.mjs.map} +1 -1
- package/dist/verify/index.mjs +4 -4
- package/package.json +1 -1
- package/dist/diff-DyQF4sel.mjs.map +0 -1
package/dist/cli/index.mjs
CHANGED
|
@@ -3,13 +3,14 @@ import "dotenv/config";
|
|
|
3
3
|
import { Command } from "commander";
|
|
4
4
|
import * as fs from "node:fs/promises";
|
|
5
5
|
import { readFile } from "node:fs/promises";
|
|
6
|
-
import * as path from "node:path";
|
|
7
|
-
import { relative, resolve } from "node:path";
|
|
6
|
+
import * as path$1 from "node:path";
|
|
7
|
+
import path, { relative, resolve } from "node:path";
|
|
8
8
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
9
9
|
import { BaseResolver, bundleDocument, createConfig, makeDocumentFromString } from "@redocly/openapi-core";
|
|
10
10
|
import Parser from "tree-sitter";
|
|
11
|
+
import { execFile, execFileSync } from "node:child_process";
|
|
12
|
+
import { promisify } from "node:util";
|
|
11
13
|
import { closeSync, existsSync, mkdirSync, openSync, readFileSync, readSync, readdirSync, statSync, unlinkSync, writeFileSync } from "node:fs";
|
|
12
|
-
import { execFileSync } from "node:child_process";
|
|
13
14
|
//#region src/errors.ts
|
|
14
15
|
/**
|
|
15
16
|
* Structured error hierarchy for oagen.
|
|
@@ -143,15 +144,49 @@ function walkTypeRef(ref, visitor) {
|
|
|
143
144
|
//#endregion
|
|
144
145
|
//#region src/utils/naming.ts
|
|
145
146
|
/**
|
|
147
|
+
* Known compound tokens that the regex-based splitter over-splits.
|
|
148
|
+
* Each entry is [lowercase-word-sequence, canonical-form].
|
|
149
|
+
* Sorted longest-first so greedy matching works correctly.
|
|
150
|
+
*/
|
|
151
|
+
const COMPOUND_WORDS = [[[
|
|
152
|
+
"m",
|
|
153
|
+
"2",
|
|
154
|
+
"m"
|
|
155
|
+
], "M2M"], [["o", "auth"], "OAuth"]];
|
|
156
|
+
/**
|
|
157
|
+
* Recombine adjacent words that form a known compound token.
|
|
158
|
+
*/
|
|
159
|
+
function recombineCompounds(words) {
|
|
160
|
+
const result = [];
|
|
161
|
+
let i = 0;
|
|
162
|
+
while (i < words.length) {
|
|
163
|
+
let matched = false;
|
|
164
|
+
for (const [pattern, canonical] of COMPOUND_WORDS) if (i + pattern.length <= words.length) {
|
|
165
|
+
if (pattern.every((p, j) => words[i + j].toLowerCase() === p)) {
|
|
166
|
+
result.push(canonical);
|
|
167
|
+
i += pattern.length;
|
|
168
|
+
matched = true;
|
|
169
|
+
break;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
if (!matched) {
|
|
173
|
+
result.push(words[i]);
|
|
174
|
+
i++;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return result;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
146
180
|
* Split a string into words, handling:
|
|
147
181
|
* - camelCase / PascalCase boundaries
|
|
148
182
|
* - snake_case / kebab-case separators
|
|
149
183
|
* - Consecutive capitals (e.g., "HTTPClient" → ["HTTP", "Client"])
|
|
150
184
|
* - Numbers as word boundaries (e.g., "OAuth2Token" → ["OAuth", "2", "Token"])
|
|
185
|
+
* - Known compounds are recombined (e.g., "M2M" stays as one word)
|
|
151
186
|
*/
|
|
152
187
|
function splitWords(s) {
|
|
153
188
|
if (!s) return [];
|
|
154
|
-
return s.replace(/[^a-zA-Z0-9_\-\s.]/g, "_").replace(/([a-z])([A-Z])/g, "$1\0$2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1\0$2").replace(/([a-zA-Z])(\d)/g, "$1\0$2").replace(/(\d)([a-zA-Z])/g, "$1\0$2").split(/[\0_\-\s.]+/).filter((w) => w.length > 0);
|
|
189
|
+
return recombineCompounds(s.replace(/[^a-zA-Z0-9_\-\s.]/g, "_").replace(/([a-z])([A-Z])/g, "$1\0$2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1\0$2").replace(/([a-zA-Z])(\d)/g, "$1\0$2").replace(/(\d)([a-zA-Z])/g, "$1\0$2").split(/[\0_\-\s.]+/).filter((w) => w.length > 0));
|
|
155
190
|
}
|
|
156
191
|
const ACRONYM_SET = new Set([
|
|
157
192
|
"SSO",
|
|
@@ -159,7 +194,8 @@ const ACRONYM_SET = new Set([
|
|
|
159
194
|
"SAML",
|
|
160
195
|
"SCIM",
|
|
161
196
|
"JWT",
|
|
162
|
-
"HMAC"
|
|
197
|
+
"HMAC",
|
|
198
|
+
"M2M"
|
|
163
199
|
]);
|
|
164
200
|
function toPascalCase(s, acronyms) {
|
|
165
201
|
const merged = acronyms ? new Set([...ACRONYM_SET, ...acronyms]) : ACRONYM_SET;
|
|
@@ -3310,11 +3346,27 @@ async function mergeIntoExisting(existingContent, generatedContent, language, he
|
|
|
3310
3346
|
const addedParts = [...toAppend];
|
|
3311
3347
|
if (insertions) for (const ins of insertions) addedParts.push(ins.text);
|
|
3312
3348
|
const addedCodeText = addedParts.join("\n");
|
|
3313
|
-
const filteredImports =
|
|
3349
|
+
const filteredImports = [];
|
|
3350
|
+
for (const imp of newImports) {
|
|
3314
3351
|
const braceMatch = imp.text.match(/\{([^}]+)\}/);
|
|
3315
|
-
if (!braceMatch)
|
|
3316
|
-
|
|
3317
|
-
|
|
3352
|
+
if (!braceMatch) {
|
|
3353
|
+
filteredImports.push(imp);
|
|
3354
|
+
continue;
|
|
3355
|
+
}
|
|
3356
|
+
const names = braceMatch[1].split(",").map((n) => n.replace(/\btype\b/, "").trim()).filter(Boolean);
|
|
3357
|
+
const usedNames = names.filter((name) => addedCodeText.includes(name));
|
|
3358
|
+
if (usedNames.length === 0) continue;
|
|
3359
|
+
if (usedNames.length === names.length) filteredImports.push(imp);
|
|
3360
|
+
else {
|
|
3361
|
+
const prefix = imp.text.trimStart().startsWith("import type") ? "import type" : "import";
|
|
3362
|
+
const sourceMatch = imp.text.match(/from\s+(['"][^'"]+['"]);?/);
|
|
3363
|
+
if (sourceMatch) filteredImports.push({
|
|
3364
|
+
key: imp.key,
|
|
3365
|
+
text: `${prefix} { ${usedNames.join(", ")} } from ${sourceMatch[1]};`
|
|
3366
|
+
});
|
|
3367
|
+
else filteredImports.push(imp);
|
|
3368
|
+
}
|
|
3369
|
+
}
|
|
3318
3370
|
if (filteredImports.length > 0) {
|
|
3319
3371
|
const renderedImports = adapter.renderImports ? adapter.renderImports(filteredImports) : filteredImports.map((entry) => entry.text);
|
|
3320
3372
|
const lines = result.split("\n");
|
|
@@ -3472,13 +3524,13 @@ async function writeFiles(files, outputDir, options) {
|
|
|
3472
3524
|
const language = options?.language;
|
|
3473
3525
|
const header = options?.header ?? "";
|
|
3474
3526
|
for (const file of sorted) {
|
|
3475
|
-
const fullPath = path.join(outputDir, file.path);
|
|
3527
|
+
const fullPath = path$1.join(outputDir, file.path);
|
|
3476
3528
|
let existingContent = null;
|
|
3477
3529
|
try {
|
|
3478
3530
|
existingContent = await fs.readFile(fullPath, "utf-8");
|
|
3479
3531
|
} catch {}
|
|
3480
3532
|
if (existingContent === null) {
|
|
3481
|
-
await fs.mkdir(path.dirname(fullPath), { recursive: true });
|
|
3533
|
+
await fs.mkdir(path$1.dirname(fullPath), { recursive: true });
|
|
3482
3534
|
await fs.writeFile(fullPath, file.content, "utf-8");
|
|
3483
3535
|
result.written.push(file.path);
|
|
3484
3536
|
continue;
|
|
@@ -3558,17 +3610,71 @@ function buildEmitterContext(spec, options) {
|
|
|
3558
3610
|
overlayLookup: options.overlayLookup
|
|
3559
3611
|
};
|
|
3560
3612
|
}
|
|
3613
|
+
/**
|
|
3614
|
+
* Collect model and enum names transitively referenced by service operations.
|
|
3615
|
+
* Walks operation parameters, request bodies, responses, and pagination item
|
|
3616
|
+
* types, then chases model field references until the set stabilizes.
|
|
3617
|
+
*/
|
|
3618
|
+
function collectReferencedNames(services, models) {
|
|
3619
|
+
const referencedModels = /* @__PURE__ */ new Set();
|
|
3620
|
+
const referencedEnums = /* @__PURE__ */ new Set();
|
|
3621
|
+
const collectFromTypeRef = (ref) => {
|
|
3622
|
+
walkTypeRef(ref, {
|
|
3623
|
+
model: (r) => referencedModels.add(r.name),
|
|
3624
|
+
enum: (r) => referencedEnums.add(r.name)
|
|
3625
|
+
});
|
|
3626
|
+
};
|
|
3627
|
+
for (const service of services) for (const op of service.operations) {
|
|
3628
|
+
for (const p of [
|
|
3629
|
+
...op.pathParams,
|
|
3630
|
+
...op.queryParams,
|
|
3631
|
+
...op.headerParams,
|
|
3632
|
+
...op.cookieParams ?? []
|
|
3633
|
+
]) collectFromTypeRef(p.type);
|
|
3634
|
+
if (op.requestBody) collectFromTypeRef(op.requestBody);
|
|
3635
|
+
collectFromTypeRef(op.response);
|
|
3636
|
+
if (op.pagination) collectFromTypeRef(op.pagination.itemType);
|
|
3637
|
+
for (const err of op.errors) if (err.type) collectFromTypeRef(err.type);
|
|
3638
|
+
if (op.successResponses) for (const sr of op.successResponses) collectFromTypeRef(sr.type);
|
|
3639
|
+
}
|
|
3640
|
+
const modelsByName = new Map(models.map((m) => [m.name, m]));
|
|
3641
|
+
const visited = /* @__PURE__ */ new Set();
|
|
3642
|
+
const queue = [...referencedModels];
|
|
3643
|
+
while (queue.length > 0) {
|
|
3644
|
+
const name = queue.pop();
|
|
3645
|
+
if (visited.has(name)) continue;
|
|
3646
|
+
visited.add(name);
|
|
3647
|
+
const model = modelsByName.get(name);
|
|
3648
|
+
if (!model) continue;
|
|
3649
|
+
for (const field of model.fields) {
|
|
3650
|
+
collectFromTypeRef(field.type);
|
|
3651
|
+
for (const m of referencedModels) if (!visited.has(m)) queue.push(m);
|
|
3652
|
+
}
|
|
3653
|
+
}
|
|
3654
|
+
return {
|
|
3655
|
+
models: referencedModels,
|
|
3656
|
+
enums: referencedEnums
|
|
3657
|
+
};
|
|
3658
|
+
}
|
|
3561
3659
|
/** Collect all generated files from an emitter (no headers, no path prefixes). */
|
|
3562
3660
|
function generateAllFiles(spec, emitter, ctx) {
|
|
3661
|
+
const referenced = collectReferencedNames(spec.services, spec.models);
|
|
3662
|
+
const reachableModels = spec.models.filter((m) => referenced.models.has(m.name));
|
|
3663
|
+
const reachableEnums = spec.enums.filter((e) => referenced.enums.has(e.name));
|
|
3664
|
+
const reachableSpec = {
|
|
3665
|
+
...spec,
|
|
3666
|
+
models: reachableModels,
|
|
3667
|
+
enums: reachableEnums
|
|
3668
|
+
};
|
|
3563
3669
|
return [
|
|
3564
|
-
...emitter.generateModels(
|
|
3565
|
-
...emitter.generateEnums(
|
|
3670
|
+
...emitter.generateModels(reachableModels, ctx),
|
|
3671
|
+
...emitter.generateEnums(reachableEnums, ctx),
|
|
3566
3672
|
...emitter.generateResources(spec.services, ctx),
|
|
3567
3673
|
...emitter.generateClient(spec, ctx),
|
|
3568
3674
|
...emitter.generateErrors(ctx),
|
|
3569
3675
|
...emitter.generateConfig(ctx),
|
|
3570
|
-
...emitter.generateTypeSignatures?.(
|
|
3571
|
-
...emitter.generateTests(
|
|
3676
|
+
...emitter.generateTypeSignatures?.(reachableSpec, ctx) ?? [],
|
|
3677
|
+
...emitter.generateTests(reachableSpec, ctx),
|
|
3572
3678
|
...emitter.generateManifest?.(spec, ctx) ?? []
|
|
3573
3679
|
];
|
|
3574
3680
|
}
|
|
@@ -3592,6 +3698,81 @@ function generateFiles(spec, emitter, options) {
|
|
|
3592
3698
|
}
|
|
3593
3699
|
//#endregion
|
|
3594
3700
|
//#region src/engine/integrate.ts
|
|
3701
|
+
/**
|
|
3702
|
+
* Resolve a relative import path against a source file path to get the
|
|
3703
|
+
* target file path. Handles implicit .ts extensions and /index.ts.
|
|
3704
|
+
*/
|
|
3705
|
+
function resolveImportPath(fromFilePath, importModulePath, knownPaths) {
|
|
3706
|
+
const cleaned = importModulePath.replace(/^['"]|['"]$/g, "");
|
|
3707
|
+
if (!cleaned.startsWith(".")) return void 0;
|
|
3708
|
+
const dir = path.dirname(fromFilePath);
|
|
3709
|
+
const resolved = path.normalize(path.join(dir, cleaned));
|
|
3710
|
+
for (const candidate of [
|
|
3711
|
+
resolved,
|
|
3712
|
+
`${resolved}.ts`,
|
|
3713
|
+
`${resolved}/index.ts`
|
|
3714
|
+
]) if (knownPaths.has(candidate)) return candidate;
|
|
3715
|
+
}
|
|
3716
|
+
/**
|
|
3717
|
+
* Determine whether a generated file is a "root" — a file that should always
|
|
3718
|
+
* be integrated into the target. Roots are entry points from which we trace
|
|
3719
|
+
* the import graph. Everything else must be reachable from a root.
|
|
3720
|
+
*
|
|
3721
|
+
* Roots: resource classes, client, config, errors, enums, barrel index files.
|
|
3722
|
+
* Non-roots: serializers, fixtures, standalone interfaces, test files.
|
|
3723
|
+
*/
|
|
3724
|
+
function isRootFile(filePath) {
|
|
3725
|
+
if (filePath.includes("/fixtures/")) return false;
|
|
3726
|
+
if (filePath.endsWith(".spec.ts") || filePath.endsWith(".test.ts")) return false;
|
|
3727
|
+
if (filePath.includes("/serializers/")) return false;
|
|
3728
|
+
if (filePath.includes("/interfaces/") && !filePath.endsWith("/index.ts")) return false;
|
|
3729
|
+
return true;
|
|
3730
|
+
}
|
|
3731
|
+
/**
|
|
3732
|
+
* Build a file-level dependency graph from generated files and return only
|
|
3733
|
+
* files reachable from root entry points. Uses tree-sitter to parse imports.
|
|
3734
|
+
*/
|
|
3735
|
+
async function treeShakeFiles(files, language) {
|
|
3736
|
+
if (!hasGrammar(language)) return files;
|
|
3737
|
+
const knownPaths = new Set(files.map((f) => f.path));
|
|
3738
|
+
const deps = /* @__PURE__ */ new Map();
|
|
3739
|
+
for (const file of files) {
|
|
3740
|
+
if (!file.path.endsWith(".ts") && !file.path.endsWith(".js")) {
|
|
3741
|
+
deps.set(file.path, /* @__PURE__ */ new Set());
|
|
3742
|
+
continue;
|
|
3743
|
+
}
|
|
3744
|
+
const parsed = await extractStatements(file.content, language);
|
|
3745
|
+
const fileDeps = /* @__PURE__ */ new Set();
|
|
3746
|
+
for (const imp of parsed.imports) {
|
|
3747
|
+
const resolved = resolveImportPath(file.path, imp.key, knownPaths);
|
|
3748
|
+
if (resolved) fileDeps.add(resolved);
|
|
3749
|
+
}
|
|
3750
|
+
for (const stmt of parsed.statements) if (stmt.kind === "reexport") {
|
|
3751
|
+
const match = stmt.text.match(/from\s+['"]([^'"]+)['"]/);
|
|
3752
|
+
if (match) {
|
|
3753
|
+
const resolved = resolveImportPath(file.path, match[1], knownPaths);
|
|
3754
|
+
if (resolved) fileDeps.add(resolved);
|
|
3755
|
+
}
|
|
3756
|
+
}
|
|
3757
|
+
deps.set(file.path, fileDeps);
|
|
3758
|
+
}
|
|
3759
|
+
const reachable = /* @__PURE__ */ new Set();
|
|
3760
|
+
const queue = [];
|
|
3761
|
+
for (const file of files) if (isRootFile(file.path)) {
|
|
3762
|
+
reachable.add(file.path);
|
|
3763
|
+
queue.push(file.path);
|
|
3764
|
+
}
|
|
3765
|
+
while (queue.length > 0) {
|
|
3766
|
+
const current = queue.pop();
|
|
3767
|
+
const fileDeps = deps.get(current);
|
|
3768
|
+
if (!fileDeps) continue;
|
|
3769
|
+
for (const dep of fileDeps) if (!reachable.has(dep)) {
|
|
3770
|
+
reachable.add(dep);
|
|
3771
|
+
queue.push(dep);
|
|
3772
|
+
}
|
|
3773
|
+
}
|
|
3774
|
+
return files.filter((f) => reachable.has(f.path));
|
|
3775
|
+
}
|
|
3595
3776
|
function mapFilesForTargetIntegration(files, language) {
|
|
3596
3777
|
const langPrefix = `${language}/`;
|
|
3597
3778
|
return files.filter((f) => f.integrateTarget !== false).map((f) => {
|
|
@@ -3604,12 +3785,44 @@ function mapFilesForTargetIntegration(files, language) {
|
|
|
3604
3785
|
});
|
|
3605
3786
|
}
|
|
3606
3787
|
async function integrateGeneratedFiles(opts) {
|
|
3607
|
-
return writeFiles(mapFilesForTargetIntegration(opts.files, opts.language), opts.targetDir, {
|
|
3788
|
+
return writeFiles(await treeShakeFiles(mapFilesForTargetIntegration(opts.files, opts.language), opts.language), opts.targetDir, {
|
|
3608
3789
|
language: opts.language,
|
|
3609
3790
|
header: opts.header
|
|
3610
3791
|
});
|
|
3611
3792
|
}
|
|
3612
3793
|
//#endregion
|
|
3794
|
+
//#region src/engine/formatter.ts
|
|
3795
|
+
/**
|
|
3796
|
+
* Post-integration formatter.
|
|
3797
|
+
*
|
|
3798
|
+
* After generating and merging files into a target directory, runs the
|
|
3799
|
+
* emitter-provided format command on all written/merged files so that
|
|
3800
|
+
* generated code matches the target project's style conventions.
|
|
3801
|
+
*/
|
|
3802
|
+
const execFileAsync = promisify(execFile);
|
|
3803
|
+
/**
|
|
3804
|
+
* Run the emitter's format command on the given target files.
|
|
3805
|
+
* Silently skips if the emitter has no formatCommand or returns null.
|
|
3806
|
+
*/
|
|
3807
|
+
async function formatTargetFiles(emitter, targetDir, filePaths) {
|
|
3808
|
+
if (filePaths.length === 0) return;
|
|
3809
|
+
if (!emitter.formatCommand) return;
|
|
3810
|
+
const formatCmd = emitter.formatCommand(targetDir);
|
|
3811
|
+
if (!formatCmd) return;
|
|
3812
|
+
const absolutePaths = filePaths.map((f) => path$1.resolve(targetDir, f));
|
|
3813
|
+
const batchSize = formatCmd.batchSize ?? 100;
|
|
3814
|
+
for (let i = 0; i < absolutePaths.length; i += batchSize) {
|
|
3815
|
+
const batch = absolutePaths.slice(i, i + batchSize);
|
|
3816
|
+
try {
|
|
3817
|
+
await execFileAsync(formatCmd.cmd, [...formatCmd.args, ...batch], {
|
|
3818
|
+
cwd: targetDir,
|
|
3819
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
3820
|
+
timeout: 12e4
|
|
3821
|
+
});
|
|
3822
|
+
} catch {}
|
|
3823
|
+
}
|
|
3824
|
+
}
|
|
3825
|
+
//#endregion
|
|
3613
3826
|
//#region src/engine/orchestrator.ts
|
|
3614
3827
|
async function generate(spec, emitter, options) {
|
|
3615
3828
|
const { files: withHeaders, header } = generateFiles(spec, emitter, options);
|
|
@@ -3636,6 +3849,8 @@ async function generate(spec, emitter, options) {
|
|
|
3636
3849
|
if (targetResult.written.length > 0) console.log(`Target: created ${targetResult.written.length} new files`);
|
|
3637
3850
|
if (targetResult.merged.length > 0) console.log(`Target: merged into ${targetResult.merged.length} existing files (additive only)`);
|
|
3638
3851
|
if (targetResult.skipped.length > 0) console.log(`Target: skipped ${targetResult.skipped.length} files (excluded or no grammar)`);
|
|
3852
|
+
const allTargetFiles = [...targetResult.written, ...targetResult.merged];
|
|
3853
|
+
if (allTargetFiles.length > 0) await formatTargetFiles(emitter, options.target, allTargetFiles);
|
|
3639
3854
|
}
|
|
3640
3855
|
return withHeaders;
|
|
3641
3856
|
}
|
|
@@ -4204,7 +4419,7 @@ function loadOverlayContext(opts) {
|
|
|
4204
4419
|
throw new ConfigError(`Failed to parse API surface JSON: ${err instanceof Error ? err.message : String(err)}`, `Ensure "${opts.apiSurfacePath}" contains valid JSON. Re-run \`oagen extract\` to regenerate it.`);
|
|
4205
4420
|
}
|
|
4206
4421
|
let manifest;
|
|
4207
|
-
const resolvedManifestPath = opts.manifestPath ?? path.join(opts.outputDir, "smoke-manifest.json");
|
|
4422
|
+
const resolvedManifestPath = opts.manifestPath ?? path$1.join(opts.outputDir, "smoke-manifest.json");
|
|
4208
4423
|
if (opts.manifestPath || existsSync(resolvedManifestPath)) try {
|
|
4209
4424
|
const parsed = JSON.parse(readFileSync(resolvedManifestPath, "utf-8"));
|
|
4210
4425
|
if (Array.isArray(parsed)) manifest = parsed;
|
|
@@ -5277,7 +5492,7 @@ function cleanGeneratedFiles(dir) {
|
|
|
5277
5492
|
return;
|
|
5278
5493
|
}
|
|
5279
5494
|
for (const entry of entries) {
|
|
5280
|
-
const full = path.join(dir, entry);
|
|
5495
|
+
const full = path$1.join(dir, entry);
|
|
5281
5496
|
let stat;
|
|
5282
5497
|
try {
|
|
5283
5498
|
stat = statSync(full);
|
|
@@ -5307,7 +5522,7 @@ function cleanGeneratedFiles(dir) {
|
|
|
5307
5522
|
* it to ManifestEntry[] for the overlay builder.
|
|
5308
5523
|
*/
|
|
5309
5524
|
function loadManifestFromDir(outputDir) {
|
|
5310
|
-
const manifestPath = path.join(outputDir, "smoke-manifest.json");
|
|
5525
|
+
const manifestPath = path$1.join(outputDir, "smoke-manifest.json");
|
|
5311
5526
|
if (!existsSync(manifestPath)) return void 0;
|
|
5312
5527
|
try {
|
|
5313
5528
|
const parsed = JSON.parse(readFileSync(manifestPath, "utf-8"));
|
|
@@ -5468,16 +5683,16 @@ function runStalenessCheck(baseline, oldSpec, newSpec, lang) {
|
|
|
5468
5683
|
//#endregion
|
|
5469
5684
|
//#region src/verify/run-smoke-check.ts
|
|
5470
5685
|
const __filename = fileURLToPath(import.meta.url);
|
|
5471
|
-
const __dirname = path.dirname(__filename);
|
|
5686
|
+
const __dirname = path$1.dirname(__filename);
|
|
5472
5687
|
function resolveScript(scriptRelPath) {
|
|
5473
|
-
const distScript = path.resolve(__dirname, "..", "..", "dist", "scripts", scriptRelPath.replace(/\.ts$/, ".js"));
|
|
5688
|
+
const distScript = path$1.resolve(__dirname, "..", "..", "dist", "scripts", scriptRelPath.replace(/\.ts$/, ".js"));
|
|
5474
5689
|
if (existsSync(distScript)) return {
|
|
5475
5690
|
bin: "node",
|
|
5476
5691
|
script: distScript
|
|
5477
5692
|
};
|
|
5478
5693
|
return {
|
|
5479
5694
|
bin: "npx",
|
|
5480
|
-
script: path.resolve(__dirname, "..", "..", "scripts", scriptRelPath)
|
|
5695
|
+
script: path$1.resolve(__dirname, "..", "..", "scripts", scriptRelPath)
|
|
5481
5696
|
};
|
|
5482
5697
|
}
|
|
5483
5698
|
function runPackagedScript(scriptRelPath, args) {
|
|
@@ -5928,7 +6143,7 @@ const CONFIG_NAMES = [
|
|
|
5928
6143
|
];
|
|
5929
6144
|
async function loadConfig(cwd = process.cwd()) {
|
|
5930
6145
|
for (const name of CONFIG_NAMES) {
|
|
5931
|
-
const configPath = path.resolve(cwd, name);
|
|
6146
|
+
const configPath = path$1.resolve(cwd, name);
|
|
5932
6147
|
if (!existsSync(configPath)) continue;
|
|
5933
6148
|
try {
|
|
5934
6149
|
const mod = await import(pathToFileURL(configPath).href);
|