@workos/oagen 0.20.0 → 0.21.1
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 +387 -55
- package/dist/cli/index.mjs.map +1 -1
- package/dist/{diff-C8mjApjv.mjs → diff-Dobf9PHC.mjs} +210 -34
- package/dist/diff-Dobf9PHC.mjs.map +1 -0
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +180 -24
- package/dist/index.mjs.map +1 -1
- package/dist/scripts/smoke/baseline.mjs +178 -22
- package/dist/scripts/smoke/baseline.mjs.map +1 -1
- package/dist/smoke.mjs +178 -22
- package/dist/smoke.mjs.map +1 -1
- package/dist/verify/index.mjs +1 -1
- package/package.json +1 -1
- package/skills/generate-smoke-test/SKILL.md +19 -41
- package/skills/generate-smoke-test/references/implementation-patterns.md +87 -0
- package/dist/diff-C8mjApjv.mjs.map +0 -1
|
@@ -1697,10 +1697,10 @@ async function extractClassEndLines(source, language) {
|
|
|
1697
1697
|
const tree = safeParse(await getParser(language), source);
|
|
1698
1698
|
const map = /* @__PURE__ */ new Map();
|
|
1699
1699
|
function processClassNode(node) {
|
|
1700
|
-
const nameNode = node.childForFieldName("name");
|
|
1700
|
+
const nameNode = node.childForFieldName("name") ?? node.children.find((c) => c.type === "type_identifier" || c.type === "identifier");
|
|
1701
1701
|
if (!nameNode) return;
|
|
1702
1702
|
const name = nameNode.text;
|
|
1703
|
-
const body = node.childForFieldName("body");
|
|
1703
|
+
const body = node.childForFieldName("body") ?? node.children.find((c) => c.type === "class_body" || c.type === "body");
|
|
1704
1704
|
const endRow = body ? body.endPosition.row : node.endPosition.row;
|
|
1705
1705
|
if (source[body ? body.endIndex - 1 : node.endIndex - 1] === "}") map.set(name, { bodyEndLine: endRow });
|
|
1706
1706
|
else map.set(name, { bodyEndLine: endRow + 1 });
|
|
@@ -2249,9 +2249,16 @@ async function overwriteWithPreservedRegions(existingContent, generatedContent,
|
|
|
2249
2249
|
if (!existingLines[i].includes("@oagen-ignore-start")) continue;
|
|
2250
2250
|
const startIdx = i;
|
|
2251
2251
|
while (i < existingLines.length && !existingLines[i].includes("@oagen-ignore-end")) i++;
|
|
2252
|
+
let anchor = "";
|
|
2253
|
+
for (let a = i + 1; a < existingLines.length; a++) if (existingLines[a].trim()) {
|
|
2254
|
+
anchor = existingLines[a].trimStart();
|
|
2255
|
+
break;
|
|
2256
|
+
}
|
|
2252
2257
|
blocks.push({
|
|
2253
2258
|
containingClass: findContainingClass(existingLines, startIdx),
|
|
2254
|
-
|
|
2259
|
+
containingScope: findContainingDescribeScope(existingLines, startIdx),
|
|
2260
|
+
lines: existingLines.slice(startIdx, i + 1),
|
|
2261
|
+
anchor
|
|
2255
2262
|
});
|
|
2256
2263
|
}
|
|
2257
2264
|
if (blocks.length === 0) return generatedContent;
|
|
@@ -2261,15 +2268,19 @@ async function overwriteWithPreservedRegions(existingContent, generatedContent,
|
|
|
2261
2268
|
const blocksByClass = /* @__PURE__ */ new Map();
|
|
2262
2269
|
for (const b of blocks) {
|
|
2263
2270
|
if (!blocksByClass.has(b.containingClass)) blocksByClass.set(b.containingClass, []);
|
|
2264
|
-
blocksByClass.get(b.containingClass).push(
|
|
2271
|
+
blocksByClass.get(b.containingClass).push({
|
|
2272
|
+
containingScope: b.containingScope,
|
|
2273
|
+
lines: b.lines,
|
|
2274
|
+
anchor: b.anchor
|
|
2275
|
+
});
|
|
2265
2276
|
}
|
|
2266
2277
|
const replacedClasses = /* @__PURE__ */ new Set();
|
|
2267
2278
|
const handledBlockKeys = /* @__PURE__ */ new Set();
|
|
2268
2279
|
const replacements = [];
|
|
2269
2280
|
for (const [className, classBlocks] of blocksByClass) {
|
|
2270
2281
|
let targetClass = className;
|
|
2271
|
-
if (!targetClass) for (const
|
|
2272
|
-
for (const l of
|
|
2282
|
+
if (!targetClass) for (const entry of classBlocks) {
|
|
2283
|
+
for (const l of entry.lines) {
|
|
2273
2284
|
const m = l.match(/^(?:export\s+)?class\s+(\w+)/);
|
|
2274
2285
|
if (m && classEndLines.has(m[1])) {
|
|
2275
2286
|
targetClass = m[1];
|
|
@@ -2279,7 +2290,7 @@ async function overwriteWithPreservedRegions(existingContent, generatedContent,
|
|
|
2279
2290
|
if (targetClass) break;
|
|
2280
2291
|
}
|
|
2281
2292
|
if (!targetClass) continue;
|
|
2282
|
-
if (!classBlocks.some((
|
|
2293
|
+
if (!classBlocks.some((entry) => entry.lines.some((l) => {
|
|
2283
2294
|
return l.match(/^(?:export\s+)?class\s+(\w+)/)?.[1] === targetClass;
|
|
2284
2295
|
}))) continue;
|
|
2285
2296
|
const info = classEndLines.get(targetClass);
|
|
@@ -2287,9 +2298,9 @@ async function overwriteWithPreservedRegions(existingContent, generatedContent,
|
|
|
2287
2298
|
const startLine = findClassDeclarationStart(result, targetClass, info.bodyEndLine);
|
|
2288
2299
|
if (startLine < 0) continue;
|
|
2289
2300
|
const content = [];
|
|
2290
|
-
for (const
|
|
2301
|
+
for (const entry of classBlocks) {
|
|
2291
2302
|
content.push("");
|
|
2292
|
-
content.push(...
|
|
2303
|
+
content.push(...entry.lines);
|
|
2293
2304
|
}
|
|
2294
2305
|
replacements.push({
|
|
2295
2306
|
startLine,
|
|
@@ -2304,22 +2315,46 @@ async function overwriteWithPreservedRegions(existingContent, generatedContent,
|
|
|
2304
2315
|
let effectiveClassEndLines = classEndLines;
|
|
2305
2316
|
if (replacedClasses.size > 0) effectiveClassEndLines = await extractClassEndLines(result.join("\n"), language);
|
|
2306
2317
|
const insertions = [];
|
|
2318
|
+
let insertionOrder = 0;
|
|
2307
2319
|
for (const [className, classBlocks] of blocksByClass) {
|
|
2308
2320
|
if (handledBlockKeys.has(className) || replacedClasses.has(className)) continue;
|
|
2309
2321
|
const info = className ? effectiveClassEndLines.get(className) : void 0;
|
|
2310
|
-
const
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2322
|
+
for (const entry of classBlocks) {
|
|
2323
|
+
let insertLine;
|
|
2324
|
+
if (entry.anchor && !entry.anchor.includes("@oagen-ignore") && /[a-zA-Z]|^\/\*|^\/\//.test(entry.anchor)) {
|
|
2325
|
+
for (let li = 0; li < result.length; li++) if (result[li].trimStart() === entry.anchor) {
|
|
2326
|
+
insertLine = li;
|
|
2327
|
+
break;
|
|
2328
|
+
}
|
|
2329
|
+
}
|
|
2330
|
+
if (insertLine === void 0) if (info) insertLine = info.bodyEndLine;
|
|
2331
|
+
else {
|
|
2332
|
+
const scopeEndLine = entry.containingScope ? findDescribeScopeEndLine(result, entry.containingScope) : void 0;
|
|
2333
|
+
const blockHasImportsFallback = entry.lines.some((l) => /^\s*(import|from)\s/.test(l));
|
|
2334
|
+
if (scopeEndLine !== void 0) insertLine = scopeEndLine;
|
|
2335
|
+
else if (blockHasImportsFallback || hasTopLevelDeclaration(entry.lines)) {
|
|
2336
|
+
let lastImportLine = 0;
|
|
2337
|
+
for (let li = 0; li < result.length; li++) {
|
|
2338
|
+
const trimmed = result[li].trimStart();
|
|
2339
|
+
if (/^(import|from)\s/.test(trimmed)) lastImportLine = li + 1;
|
|
2340
|
+
}
|
|
2341
|
+
insertLine = lastImportLine;
|
|
2342
|
+
} else insertLine = result.length;
|
|
2343
|
+
}
|
|
2344
|
+
if (entry.lines.some((l) => /^\s*import\s/.test(l))) while (insertLine >= 2 && result[insertLine - 1]?.trim() === "" && /^\s*(import|using|from)\s/.test(result[insertLine - 2] ?? "")) insertLine--;
|
|
2345
|
+
const prevLine = insertLine > 0 ? result[insertLine - 1]?.trimStart() ?? "" : "";
|
|
2346
|
+
const blockContent = /^import\s/.test(prevLine) || /^using\s/.test(prevLine) || /^from\s/.test(prevLine) || insertLine > 0 && prevLine === "" ? [...entry.lines] : ["", ...entry.lines];
|
|
2347
|
+
if ((result[insertLine]?.trimStart() ?? "").startsWith("///")) blockContent.push("");
|
|
2348
|
+
insertions.push({
|
|
2349
|
+
line: insertLine,
|
|
2350
|
+
order: insertionOrder++,
|
|
2351
|
+
content: blockContent
|
|
2352
|
+
});
|
|
2315
2353
|
}
|
|
2316
|
-
insertions.push({
|
|
2317
|
-
line: insertLine,
|
|
2318
|
-
content
|
|
2319
|
-
});
|
|
2320
2354
|
}
|
|
2321
|
-
insertions.sort((a, b) => b.line - a.line);
|
|
2355
|
+
insertions.sort((a, b) => b.line - a.line || b.order - a.order);
|
|
2322
2356
|
for (const ins of insertions) result.splice(ins.line, 0, ...ins.content);
|
|
2357
|
+
removeDuplicateImportsCoveredByIgnoreBlocks(result);
|
|
2323
2358
|
return result.join("\n");
|
|
2324
2359
|
}
|
|
2325
2360
|
/**
|
|
@@ -2347,12 +2382,47 @@ function stripIgnoreRegions(lines) {
|
|
|
2347
2382
|
}
|
|
2348
2383
|
/** Scan backwards from `lineIdx` to find the nearest class declaration name. */
|
|
2349
2384
|
function findContainingClass(lines, lineIdx) {
|
|
2385
|
+
if (/^\S/.test(lines[lineIdx] ?? "")) return "";
|
|
2350
2386
|
for (let j = lineIdx - 1; j >= 0; j--) {
|
|
2351
|
-
const m = lines[j].match(/^\s*(?:export\s+)
|
|
2387
|
+
const m = lines[j].match(/^\s*(?:(?:export|public|private|protected|internal|abstract|sealed|static|partial)\s+)*class\s+(\w+)/);
|
|
2352
2388
|
if (m) return m[1];
|
|
2353
2389
|
}
|
|
2354
2390
|
return "";
|
|
2355
2391
|
}
|
|
2392
|
+
function findContainingDescribeScope(lines, lineIdx) {
|
|
2393
|
+
const markerLine = lines[lineIdx] ?? "";
|
|
2394
|
+
if (/^\S/.test(markerLine)) return "";
|
|
2395
|
+
const markerIndent = leadingSpaces(markerLine);
|
|
2396
|
+
for (let j = lineIdx - 1; j >= 0; j--) {
|
|
2397
|
+
const line = lines[j];
|
|
2398
|
+
if (leadingSpaces(line) >= markerIndent) continue;
|
|
2399
|
+
const match = line.match(/^\s*describe\((['"`])(.+?)\1\s*,/);
|
|
2400
|
+
if (match) return match[2];
|
|
2401
|
+
if (/^\s*(?:export\s+)?class\s+\w+/.test(line)) return "";
|
|
2402
|
+
}
|
|
2403
|
+
return "";
|
|
2404
|
+
}
|
|
2405
|
+
function findDescribeScopeEndLine(lines, scopeName) {
|
|
2406
|
+
for (let i = 0; i < lines.length; i++) {
|
|
2407
|
+
const match = lines[i].match(/^\s*describe\((['"`])(.+?)\1\s*,/);
|
|
2408
|
+
if (!match || match[2] !== scopeName) continue;
|
|
2409
|
+
let depth = 0;
|
|
2410
|
+
for (let j = i; j < lines.length; j++) {
|
|
2411
|
+
depth += countChar(lines[j], "{");
|
|
2412
|
+
depth -= countChar(lines[j], "}");
|
|
2413
|
+
if (j > i && depth <= 0) return j;
|
|
2414
|
+
}
|
|
2415
|
+
}
|
|
2416
|
+
}
|
|
2417
|
+
function leadingSpaces(line) {
|
|
2418
|
+
return line.match(/^\s*/)?.[0].length ?? 0;
|
|
2419
|
+
}
|
|
2420
|
+
function countChar(line, char) {
|
|
2421
|
+
return [...line].filter((c) => c === char).length;
|
|
2422
|
+
}
|
|
2423
|
+
function hasTopLevelDeclaration(lines) {
|
|
2424
|
+
return lines.some((line) => /^(?:export\s+)?(?:interface|type|class|function|const|let|var|enum)\s+\w+/.test(line.trim()));
|
|
2425
|
+
}
|
|
2356
2426
|
/**
|
|
2357
2427
|
* Find the start line of a class declaration (including decorators above it)
|
|
2358
2428
|
* by scanning backwards from `beforeLine`.
|
|
@@ -2430,9 +2500,13 @@ function collectTsImports(lines) {
|
|
|
2430
2500
|
const mod = m[4];
|
|
2431
2501
|
if (defaultName) out.defaults.set(mod, defaultName);
|
|
2432
2502
|
const names = namesRaw.split(",").map((s) => s.trim().replace(/\s+as\s+\w+$/, "")).filter(Boolean);
|
|
2433
|
-
const
|
|
2434
|
-
|
|
2435
|
-
|
|
2503
|
+
for (const rawName of names) {
|
|
2504
|
+
const isInlineTypeOnly = rawName.startsWith("type ");
|
|
2505
|
+
const name = rawName.replace(/^type\s+/, "");
|
|
2506
|
+
const target = isTypeOnly || isInlineTypeOnly ? out.typeOnly : out.named;
|
|
2507
|
+
if (!target.has(mod)) target.set(mod, /* @__PURE__ */ new Set());
|
|
2508
|
+
target.get(mod).add(name);
|
|
2509
|
+
}
|
|
2436
2510
|
continue;
|
|
2437
2511
|
}
|
|
2438
2512
|
m = normalized.match(/^import\s+(?:type\s+)?(\w+)\s+from\s+['"]([^'"]+)['"]$/);
|
|
@@ -2455,12 +2529,99 @@ function collectTsImports(lines) {
|
|
|
2455
2529
|
*
|
|
2456
2530
|
* Mutates `resultLines` in place.
|
|
2457
2531
|
*/
|
|
2532
|
+
function filterOutIgnoreRegions(lines) {
|
|
2533
|
+
const out = [];
|
|
2534
|
+
let skipping = false;
|
|
2535
|
+
for (const line of lines) {
|
|
2536
|
+
if (!skipping && line.includes("@oagen-ignore-start")) {
|
|
2537
|
+
skipping = true;
|
|
2538
|
+
continue;
|
|
2539
|
+
}
|
|
2540
|
+
if (skipping) {
|
|
2541
|
+
if (line.includes("@oagen-ignore-end")) skipping = false;
|
|
2542
|
+
continue;
|
|
2543
|
+
}
|
|
2544
|
+
out.push(line);
|
|
2545
|
+
}
|
|
2546
|
+
return out;
|
|
2547
|
+
}
|
|
2548
|
+
function collectIgnoreRegionUsageText(lines) {
|
|
2549
|
+
const out = [];
|
|
2550
|
+
let skipping = false;
|
|
2551
|
+
for (const line of lines) {
|
|
2552
|
+
if (!skipping && line.includes("@oagen-ignore-start")) {
|
|
2553
|
+
skipping = true;
|
|
2554
|
+
continue;
|
|
2555
|
+
}
|
|
2556
|
+
if (!skipping) continue;
|
|
2557
|
+
if (/^\s*(import|from)\s/.test(line)) continue;
|
|
2558
|
+
out.push(line);
|
|
2559
|
+
if (line.includes("@oagen-ignore-end")) skipping = false;
|
|
2560
|
+
}
|
|
2561
|
+
return out.join("\n");
|
|
2562
|
+
}
|
|
2563
|
+
function removeDuplicateImportsCoveredByIgnoreBlocks(lines) {
|
|
2564
|
+
const ignoredImports = /* @__PURE__ */ new Set();
|
|
2565
|
+
const importStatements = collectImportStatements(lines);
|
|
2566
|
+
for (const stmt of importStatements) if (stmt.inIgnore) ignoredImports.add(normalizeImportStatement(stmt.lines));
|
|
2567
|
+
if (ignoredImports.size === 0) return;
|
|
2568
|
+
for (const stmt of [...importStatements].reverse()) {
|
|
2569
|
+
if (stmt.inIgnore) continue;
|
|
2570
|
+
if (ignoredImports.has(normalizeImportStatement(stmt.lines))) lines.splice(stmt.start, stmt.end - stmt.start + 1);
|
|
2571
|
+
}
|
|
2572
|
+
}
|
|
2573
|
+
function collectImportStatements(lines) {
|
|
2574
|
+
const statements = [];
|
|
2575
|
+
let inIgnore = false;
|
|
2576
|
+
for (let i = 0; i < lines.length; i++) {
|
|
2577
|
+
const line = lines[i];
|
|
2578
|
+
if (!inIgnore && line.includes("@oagen-ignore-start")) {
|
|
2579
|
+
inIgnore = true;
|
|
2580
|
+
continue;
|
|
2581
|
+
}
|
|
2582
|
+
if (inIgnore && line.includes("@oagen-ignore-end")) {
|
|
2583
|
+
inIgnore = false;
|
|
2584
|
+
continue;
|
|
2585
|
+
}
|
|
2586
|
+
if (!isImportLine(line)) continue;
|
|
2587
|
+
const start = i;
|
|
2588
|
+
let end = i;
|
|
2589
|
+
const statementLines = [line];
|
|
2590
|
+
if ((line.match(/[({]/g) ?? []).length > (line.match(/[)}]/g) ?? []).length) {
|
|
2591
|
+
while (end + 1 < lines.length) {
|
|
2592
|
+
end++;
|
|
2593
|
+
statementLines.push(lines[end]);
|
|
2594
|
+
if ((lines[end].match(/[)}]/g) ?? []).length > 0 && /\bfrom\b/.test(lines[end])) break;
|
|
2595
|
+
}
|
|
2596
|
+
i = end;
|
|
2597
|
+
}
|
|
2598
|
+
statements.push({
|
|
2599
|
+
start,
|
|
2600
|
+
end,
|
|
2601
|
+
lines: statementLines,
|
|
2602
|
+
inIgnore
|
|
2603
|
+
});
|
|
2604
|
+
}
|
|
2605
|
+
return statements;
|
|
2606
|
+
}
|
|
2607
|
+
function normalizeImportStatement(lines) {
|
|
2608
|
+
return lines.join("\n").replace(/,\s*}/g, " }").replace(/\s+/g, " ").trim();
|
|
2609
|
+
}
|
|
2610
|
+
function isImportLine(line) {
|
|
2611
|
+
const trimmed = line.trim();
|
|
2612
|
+
return /^import(\s|$)/.test(trimmed) || /^from\s+/.test(trimmed) || /^use\s+[\w\\]/.test(trimmed) || /^require(_relative)?\s+['"]/.test(trimmed);
|
|
2613
|
+
}
|
|
2614
|
+
function identifierUsed(source, identifier) {
|
|
2615
|
+
return new RegExp(`\\b${identifier.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\b`).test(source);
|
|
2616
|
+
}
|
|
2458
2617
|
function spliceExtraImports(existingLines, resultLines) {
|
|
2618
|
+
const existingOutsideIgnore = filterOutIgnoreRegions(existingLines);
|
|
2619
|
+
const ignoreRegionText = collectIgnoreRegionUsageText(existingLines);
|
|
2459
2620
|
const isPythonSimpleImport = (l) => /^import\s+\w/.test(l) && !/\sfrom\s/.test(l) && !/[{}]/.test(l);
|
|
2460
|
-
const existingSimple = new Set(
|
|
2621
|
+
const existingSimple = new Set(existingOutsideIgnore.filter(isPythonSimpleImport).map((l) => l.trim()));
|
|
2461
2622
|
const generatedSimple = new Set(resultLines.filter(isPythonSimpleImport).map((l) => l.trim()));
|
|
2462
2623
|
const extraSimple = [...existingSimple].filter((l) => !generatedSimple.has(l));
|
|
2463
|
-
const existingFrom = collectFromImports(
|
|
2624
|
+
const existingFrom = collectFromImports(existingOutsideIgnore);
|
|
2464
2625
|
const generatedFrom = collectFromImports(resultLines);
|
|
2465
2626
|
const allGeneratedIds = /* @__PURE__ */ new Set();
|
|
2466
2627
|
for (const ids of generatedFrom.values()) for (const id of ids) allGeneratedIds.add(id);
|
|
@@ -2475,29 +2636,33 @@ function spliceExtraImports(existingLines, resultLines) {
|
|
|
2475
2636
|
if (extra.length > 0) extraFromLines.push(`from ${mod} import ${extra.join(", ")}`);
|
|
2476
2637
|
}
|
|
2477
2638
|
}
|
|
2478
|
-
const existingTs = collectTsImports(
|
|
2639
|
+
const existingTs = collectTsImports(existingOutsideIgnore);
|
|
2479
2640
|
const generatedTs = collectTsImports(resultLines);
|
|
2480
2641
|
const extraTsLines = [];
|
|
2481
2642
|
for (const mod of existingTs.sideEffects) if (!generatedTs.sideEffects.has(mod)) extraTsLines.push(`import '${mod}';`);
|
|
2482
2643
|
for (const [mod, name] of existingTs.defaults) {
|
|
2483
2644
|
if (generatedTs.defaults.has(mod)) continue;
|
|
2645
|
+
if (!identifierUsed(ignoreRegionText, name)) continue;
|
|
2484
2646
|
extraTsLines.push(`import ${name} from '${mod}';`);
|
|
2485
2647
|
}
|
|
2486
|
-
for (const [mod, name] of existingTs.namespaces)
|
|
2648
|
+
for (const [mod, name] of existingTs.namespaces) {
|
|
2649
|
+
if (!identifierUsed(ignoreRegionText, name)) continue;
|
|
2650
|
+
if (!generatedTs.namespaces.has(mod)) extraTsLines.push(`import * as ${name} from '${mod}';`);
|
|
2651
|
+
}
|
|
2487
2652
|
for (const [mod, existIds] of existingTs.named) {
|
|
2488
2653
|
const genIds = generatedTs.named.get(mod) ?? /* @__PURE__ */ new Set();
|
|
2489
2654
|
const genTypeIds = generatedTs.typeOnly.get(mod) ?? /* @__PURE__ */ new Set();
|
|
2490
|
-
const extra = [...existIds].filter((id) => !genIds.has(id) && !genTypeIds.has(id));
|
|
2655
|
+
const extra = [...existIds].filter((id) => !genIds.has(id) && !genTypeIds.has(id) && identifierUsed(ignoreRegionText, id));
|
|
2491
2656
|
if (extra.length > 0) extraTsLines.push(`import { ${extra.join(", ")} } from '${mod}';`);
|
|
2492
2657
|
}
|
|
2493
2658
|
for (const [mod, existIds] of existingTs.typeOnly) {
|
|
2494
2659
|
const genIds = generatedTs.typeOnly.get(mod) ?? /* @__PURE__ */ new Set();
|
|
2495
2660
|
const genNamedIds = generatedTs.named.get(mod) ?? /* @__PURE__ */ new Set();
|
|
2496
|
-
const extra = [...existIds].filter((id) => !genIds.has(id) && !genNamedIds.has(id));
|
|
2661
|
+
const extra = [...existIds].filter((id) => !genIds.has(id) && !genNamedIds.has(id) && identifierUsed(ignoreRegionText, id));
|
|
2497
2662
|
if (extra.length > 0) extraTsLines.push(`import type { ${extra.join(", ")} } from '${mod}';`);
|
|
2498
2663
|
}
|
|
2499
2664
|
const isPhpUseImport = (l) => /^use\s+[\w\\]+\\[\w\\]*(\s+as\s+\w+)?\s*;?$/.test(l);
|
|
2500
|
-
const existingPhpUse = new Set(
|
|
2665
|
+
const existingPhpUse = new Set(existingOutsideIgnore.filter(isPhpUseImport).map((l) => l.trim()));
|
|
2501
2666
|
const generatedPhpUse = new Set(resultLines.filter(isPhpUseImport).map((l) => l.trim()));
|
|
2502
2667
|
const extraPhpUse = [...existingPhpUse].filter((l) => !generatedPhpUse.has(l));
|
|
2503
2668
|
const rubyRequireRe = /^(require(?:_relative)?)\s+['"]([^'"]+)['"]\s*$/;
|
|
@@ -2512,7 +2677,7 @@ function spliceExtraImports(existingLines, resultLines) {
|
|
|
2512
2677
|
}
|
|
2513
2678
|
const seenExistingKeys = /* @__PURE__ */ new Set();
|
|
2514
2679
|
const extraRubyRequire = [];
|
|
2515
|
-
for (const l of
|
|
2680
|
+
for (const l of existingOutsideIgnore) {
|
|
2516
2681
|
const key = rubyRequireKey(l);
|
|
2517
2682
|
if (!key) continue;
|
|
2518
2683
|
if (generatedRubyRequireKeys.has(key)) continue;
|
|
@@ -2585,7 +2750,11 @@ function collectReferencedNames(services, models) {
|
|
|
2585
2750
|
for (const err of op.errors) if (err.type) collectFromTypeRef(err.type);
|
|
2586
2751
|
if (op.successResponses) for (const sr of op.successResponses) collectFromTypeRef(sr.type);
|
|
2587
2752
|
}
|
|
2588
|
-
for (const model of models)
|
|
2753
|
+
for (const model of models) {
|
|
2754
|
+
if (isDiscriminatedModel(model)) referencedModels.add(model.name);
|
|
2755
|
+
const disc = model.discriminator;
|
|
2756
|
+
if (disc?.mapping) for (const variantName of Object.values(disc.mapping)) referencedModels.add(variantName);
|
|
2757
|
+
}
|
|
2589
2758
|
const modelsByName = new Map(models.map((m) => [m.name, m]));
|
|
2590
2759
|
const visited = /* @__PURE__ */ new Set();
|
|
2591
2760
|
const queue = [...referencedModels];
|
|
@@ -2900,6 +3069,7 @@ async function readManifest(dir) {
|
|
|
2900
3069
|
}
|
|
2901
3070
|
/** Write `.oagen-manifest.json` to a directory with sorted paths. */
|
|
2902
3071
|
async function writeManifest(dir, opts) {
|
|
3072
|
+
const manifestPath = path$1.join(dir, MANIFEST_FILENAME);
|
|
2903
3073
|
const manifest = {
|
|
2904
3074
|
version: MANIFEST_VERSION,
|
|
2905
3075
|
language: opts.language,
|
|
@@ -2914,10 +3084,16 @@ async function writeManifest(dir, opts) {
|
|
|
2914
3084
|
files: [...new Set(opts.files)].sort(),
|
|
2915
3085
|
...opts.operations !== void 0 ? { operations: opts.operations } : {}
|
|
2916
3086
|
};
|
|
2917
|
-
const
|
|
3087
|
+
const previous = await readManifest(dir);
|
|
3088
|
+
if (previous && sameManifestExceptGeneratedAt(previous, manifest)) manifest.generatedAt = previous.generatedAt;
|
|
2918
3089
|
await fs.mkdir(dir, { recursive: true });
|
|
2919
3090
|
await fs.writeFile(manifestPath, JSON.stringify(manifest, null, 2) + "\n", "utf-8");
|
|
2920
3091
|
}
|
|
3092
|
+
function sameManifestExceptGeneratedAt(a, b) {
|
|
3093
|
+
const { generatedAt: _aGeneratedAt, ...aComparable } = a;
|
|
3094
|
+
const { generatedAt: _bGeneratedAt, ...bComparable } = b;
|
|
3095
|
+
return JSON.stringify(aComparable) === JSON.stringify(bComparable);
|
|
3096
|
+
}
|
|
2921
3097
|
/** Return the set of previous paths no longer present in the current emission. */
|
|
2922
3098
|
function computeStalePaths(prev, currentPaths) {
|
|
2923
3099
|
const current = new Set(currentPaths);
|
|
@@ -3536,4 +3712,4 @@ function summarize(changes) {
|
|
|
3536
3712
|
//#endregion
|
|
3537
3713
|
export { MANIFEST_FILENAME as a, treeShakeFiles as c, collectReferencedNames as d, generateAllFiles as f, resolveOperations as h, generate as i, applyFileHeaders as l, deriveMethodName as m, getEmitter as n, integrateGeneratedFiles as o, generateFiles as p, registerEmitter as r, mapFilesForTargetIntegration as s, diffSpecs as t, buildEmitterContext as u };
|
|
3538
3714
|
|
|
3539
|
-
//# sourceMappingURL=diff-
|
|
3715
|
+
//# sourceMappingURL=diff-Dobf9PHC.mjs.map
|