@contractkit/plugin-typescript 0.17.5 → 0.19.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/.turbo/turbo-build$colon$ci.log +7 -7
- package/.turbo/turbo-test$colon$ci.log +15 -15
- package/CHANGELOG.md +21 -0
- package/README.md +10 -1
- package/coverage/clover.xml +795 -573
- package/coverage/coverage-final.json +6 -6
- package/coverage/index.html +19 -19
- package/coverage/src/codegen-contract.ts.html +3 -3
- package/coverage/src/codegen-operation.ts.html +1 -1
- package/coverage/src/codegen-plain-types.ts.html +1 -1
- package/coverage/src/codegen-sdk.ts.html +989 -236
- package/coverage/src/index.html +39 -39
- package/coverage/src/index.ts.html +1386 -306
- package/coverage/src/path-utils.ts.html +51 -51
- package/coverage/src/ts-render.ts.html +4 -4
- package/coverage/tests/helpers.ts.html +15 -15
- package/coverage/tests/index.html +1 -1
- package/dist/codegen-sdk.d.ts +96 -2
- package/dist/codegen-sdk.d.ts.map +1 -1
- package/dist/index.d.ts +8 -36
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +685 -137
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/codegen-sdk.ts +258 -7
- package/src/index.ts +556 -196
- package/tests/codegen-sdk.test.ts +188 -16
- package/tests/codegen-server.test.ts +101 -1
package/dist/index.js
CHANGED
|
@@ -3,6 +3,7 @@ var __name = (target, value) => __defProp(target, "name", { value, configurable:
|
|
|
3
3
|
|
|
4
4
|
// src/index.ts
|
|
5
5
|
import { resolve as resolve2, join as join2, relative as relative6, dirname as dirname6, basename as basename3 } from "path";
|
|
6
|
+
import { existsSync, readFileSync, rmSync, readdirSync, rmdirSync } from "fs";
|
|
6
7
|
|
|
7
8
|
// src/codegen-contract.ts
|
|
8
9
|
import { relative, dirname } from "path";
|
|
@@ -1734,6 +1735,9 @@ function deriveTypeImportPath(file, template) {
|
|
|
1734
1735
|
}
|
|
1735
1736
|
__name(deriveTypeImportPath, "deriveTypeImportPath");
|
|
1736
1737
|
|
|
1738
|
+
// src/index.ts
|
|
1739
|
+
import { runIncrementalCodegen, parseIncrementalManifest, emptyIncrementalManifest, hashFingerprint, collectTransitiveModelRefs } from "@contractkit/core";
|
|
1740
|
+
|
|
1737
1741
|
// src/codegen-sdk.ts
|
|
1738
1742
|
import { resolveModifiers as resolveModifiers2, isJsonMime, classifyContentType as classifyContentType2 } from "@contractkit/core";
|
|
1739
1743
|
import { basename as basename2, dirname as dirname3, relative as relative3 } from "path";
|
|
@@ -1798,7 +1802,7 @@ function generateSdk(root, options = {}) {
|
|
|
1798
1802
|
const lines = [];
|
|
1799
1803
|
const includeInternal = options.includeInternal ?? false;
|
|
1800
1804
|
const types = collectTypes2(root, options.modelsWithInput, options.modelsWithOutput, includeInternal);
|
|
1801
|
-
const clientClassName = deriveClientClassName(root.file);
|
|
1805
|
+
const clientClassName = options.clientClassName ?? deriveClientClassName(root.file);
|
|
1802
1806
|
if (types.length > 0) {
|
|
1803
1807
|
lines.push(...generateTypeImports2(types, root.file, options));
|
|
1804
1808
|
}
|
|
@@ -1899,6 +1903,26 @@ function generateSdk(root, options = {}) {
|
|
|
1899
1903
|
return lines.join("\n");
|
|
1900
1904
|
}
|
|
1901
1905
|
__name(generateSdk, "generateSdk");
|
|
1906
|
+
function generateClientMethods(root, options) {
|
|
1907
|
+
const lines = [];
|
|
1908
|
+
const methodNames = [];
|
|
1909
|
+
const includeInternal = options.includeInternal ?? false;
|
|
1910
|
+
for (const route of root.routes) {
|
|
1911
|
+
for (const op of route.operations) {
|
|
1912
|
+
const mods = resolveModifiers2(route, op);
|
|
1913
|
+
if (!includeInternal && mods.includes("internal")) continue;
|
|
1914
|
+
lines.push("");
|
|
1915
|
+
if (mods.includes("deprecated")) lines.push(" /** @deprecated */");
|
|
1916
|
+
lines.push(...generateMethod(route, op, root.file, options));
|
|
1917
|
+
methodNames.push(deriveMethodName(op, route));
|
|
1918
|
+
}
|
|
1919
|
+
}
|
|
1920
|
+
return {
|
|
1921
|
+
lines,
|
|
1922
|
+
methodNames
|
|
1923
|
+
};
|
|
1924
|
+
}
|
|
1925
|
+
__name(generateClientMethods, "generateClientMethods");
|
|
1902
1926
|
function generateMethod(route, op, file, options) {
|
|
1903
1927
|
const lines = [];
|
|
1904
1928
|
const methodName = deriveMethodName(op, route);
|
|
@@ -2202,6 +2226,38 @@ function deriveClientPropertyName(file) {
|
|
|
2202
2226
|
return base.charAt(0).toLowerCase() + base.slice(1);
|
|
2203
2227
|
}
|
|
2204
2228
|
__name(deriveClientPropertyName, "deriveClientPropertyName");
|
|
2229
|
+
function getAreaSubarea(root) {
|
|
2230
|
+
return {
|
|
2231
|
+
area: root.meta?.area,
|
|
2232
|
+
subarea: root.meta?.subarea
|
|
2233
|
+
};
|
|
2234
|
+
}
|
|
2235
|
+
__name(getAreaSubarea, "getAreaSubarea");
|
|
2236
|
+
function pascal(value) {
|
|
2237
|
+
return value.split(/[-_\s]+/).filter(Boolean).map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join("");
|
|
2238
|
+
}
|
|
2239
|
+
__name(pascal, "pascal");
|
|
2240
|
+
function camel(value) {
|
|
2241
|
+
const p = pascal(value);
|
|
2242
|
+
return p.charAt(0).toLowerCase() + p.slice(1);
|
|
2243
|
+
}
|
|
2244
|
+
__name(camel, "camel");
|
|
2245
|
+
function deriveAreaClientClassName(area) {
|
|
2246
|
+
return `${pascal(area)}Client`;
|
|
2247
|
+
}
|
|
2248
|
+
__name(deriveAreaClientClassName, "deriveAreaClientClassName");
|
|
2249
|
+
function deriveAreaPropertyName(area) {
|
|
2250
|
+
return camel(area);
|
|
2251
|
+
}
|
|
2252
|
+
__name(deriveAreaPropertyName, "deriveAreaPropertyName");
|
|
2253
|
+
function deriveSubareaClientClassName(area, subarea) {
|
|
2254
|
+
return `${pascal(area)}${pascal(subarea)}Client`;
|
|
2255
|
+
}
|
|
2256
|
+
__name(deriveSubareaClientClassName, "deriveSubareaClientClassName");
|
|
2257
|
+
function deriveSubareaPropertyName(subarea) {
|
|
2258
|
+
return camel(subarea);
|
|
2259
|
+
}
|
|
2260
|
+
__name(deriveSubareaPropertyName, "deriveSubareaPropertyName");
|
|
2205
2261
|
function collectTypes2(root, modelsWithInput, modelsWithOutput, includeInternal = false) {
|
|
2206
2262
|
const types = /* @__PURE__ */ new Set();
|
|
2207
2263
|
for (const route of root.routes) {
|
|
@@ -2516,22 +2572,128 @@ function generateSdkOptions() {
|
|
|
2516
2572
|
].join("\n");
|
|
2517
2573
|
}
|
|
2518
2574
|
__name(generateSdkOptions, "generateSdkOptions");
|
|
2519
|
-
function generateSdkAggregator(
|
|
2575
|
+
function generateSdkAggregator(input) {
|
|
2576
|
+
const sdkOptionsImportPath = input.sdkOptionsImportPath ?? "./sdk-options.js";
|
|
2577
|
+
const sdkClassName = input.sdkClassName ?? "Sdk";
|
|
2578
|
+
const inlinedByArea = /* @__PURE__ */ new Map();
|
|
2579
|
+
const typesByImportPath = /* @__PURE__ */ new Map();
|
|
2580
|
+
const unresolvedTypes = /* @__PURE__ */ new Set();
|
|
2581
|
+
let needsJson = false;
|
|
2582
|
+
let needsBigIntReplacer = false;
|
|
2583
|
+
let needsBigIntReviver = false;
|
|
2584
|
+
let needsQueryString = false;
|
|
2585
|
+
for (const area of input.areas) {
|
|
2586
|
+
const collected = [];
|
|
2587
|
+
const seenMethods = /* @__PURE__ */ new Set();
|
|
2588
|
+
for (const inline of area.inlineFiles) {
|
|
2589
|
+
const includeInternal = inline.codegenOptions.includeInternal ?? false;
|
|
2590
|
+
const { lines: methodLines, methodNames } = generateClientMethods(inline.root, inline.codegenOptions);
|
|
2591
|
+
for (const name of methodNames) {
|
|
2592
|
+
if (seenMethods.has(name)) {
|
|
2593
|
+
throw new Error(`[sdk] duplicate method '${name}' in area '${area.area}': two area-level files contribute the same method. Disambiguate via 'sdk:' or move one into a subarea.`);
|
|
2594
|
+
}
|
|
2595
|
+
seenMethods.add(name);
|
|
2596
|
+
}
|
|
2597
|
+
collected.push(...methodLines);
|
|
2598
|
+
if (sdkNeedsJson(inline.root, includeInternal)) needsJson = true;
|
|
2599
|
+
if (sdkNeedsBigIntReplacer(inline.root, includeInternal)) needsBigIntReplacer = true;
|
|
2600
|
+
if (sdkNeedsBigIntReviver(inline.root, includeInternal)) needsBigIntReviver = true;
|
|
2601
|
+
if (sdkNeedsQueryString(inline.root, includeInternal)) needsQueryString = true;
|
|
2602
|
+
const typesForFile = collectTypes2(inline.root, inline.codegenOptions.modelsWithInput, inline.codegenOptions.modelsWithOutput, includeInternal);
|
|
2603
|
+
const { modelOutPaths, outPath } = inline.codegenOptions;
|
|
2604
|
+
if (modelOutPaths && outPath) {
|
|
2605
|
+
const fromDir = dirname3(outPath);
|
|
2606
|
+
for (const t of typesForFile) {
|
|
2607
|
+
const typeOutPath = modelOutPaths.get(t);
|
|
2608
|
+
if (typeOutPath) {
|
|
2609
|
+
let rel = relative3(fromDir, typeOutPath).replace(/\.ts$/, ".js");
|
|
2610
|
+
if (!rel.startsWith(".")) rel = "./" + rel;
|
|
2611
|
+
const set = typesByImportPath.get(rel) ?? /* @__PURE__ */ new Set();
|
|
2612
|
+
set.add(t);
|
|
2613
|
+
typesByImportPath.set(rel, set);
|
|
2614
|
+
} else {
|
|
2615
|
+
unresolvedTypes.add(t);
|
|
2616
|
+
}
|
|
2617
|
+
}
|
|
2618
|
+
}
|
|
2619
|
+
}
|
|
2620
|
+
inlinedByArea.set(area.area, {
|
|
2621
|
+
lines: collected,
|
|
2622
|
+
methodNames: seenMethods
|
|
2623
|
+
});
|
|
2624
|
+
}
|
|
2520
2625
|
const lines = [];
|
|
2626
|
+
const jsonImport = needsJson ? ", JsonValue" : "";
|
|
2627
|
+
lines.push(`import type { SdkFetch${jsonImport} } from '${sdkOptionsImportPath}';`);
|
|
2628
|
+
const valueImports = [];
|
|
2629
|
+
if (needsBigIntReplacer) valueImports.push("bigIntReplacer");
|
|
2630
|
+
if (needsBigIntReviver) valueImports.push("parseJson");
|
|
2631
|
+
if (needsQueryString) valueImports.push("buildQueryString");
|
|
2632
|
+
if (valueImports.length > 0) {
|
|
2633
|
+
lines.push(`import { ${valueImports.join(", ")} } from '${sdkOptionsImportPath}';`);
|
|
2634
|
+
}
|
|
2521
2635
|
lines.push(`import type { SdkOptions } from '${sdkOptionsImportPath}';`);
|
|
2522
2636
|
lines.push(`import { createSdkFetch } from '${sdkOptionsImportPath}';`);
|
|
2523
|
-
|
|
2637
|
+
const typeImportPaths = [
|
|
2638
|
+
...typesByImportPath.keys()
|
|
2639
|
+
].sort();
|
|
2640
|
+
for (const path of typeImportPaths) {
|
|
2641
|
+
const names = [
|
|
2642
|
+
...typesByImportPath.get(path)
|
|
2643
|
+
].sort();
|
|
2644
|
+
lines.push(`import type { ${names.join(", ")} } from '${path}';`);
|
|
2645
|
+
}
|
|
2646
|
+
for (const t of [
|
|
2647
|
+
...unresolvedTypes
|
|
2648
|
+
].sort()) {
|
|
2649
|
+
lines.push(`import type { ${t} } from './${pascalToDotCase(t)}.js';`);
|
|
2650
|
+
}
|
|
2651
|
+
const importedClients = /* @__PURE__ */ new Set();
|
|
2652
|
+
const pushClientImport = /* @__PURE__ */ __name((c) => {
|
|
2653
|
+
const key = `${c.className}|${c.importPath}`;
|
|
2654
|
+
if (importedClients.has(key)) return;
|
|
2655
|
+
importedClients.add(key);
|
|
2524
2656
|
lines.push(`import { ${c.className} } from '${c.importPath}';`);
|
|
2657
|
+
}, "pushClientImport");
|
|
2658
|
+
for (const c of input.topLevelClients) pushClientImport(c);
|
|
2659
|
+
for (const area of input.areas) {
|
|
2660
|
+
for (const sc of area.subareaClients) pushClientImport(sc.client);
|
|
2525
2661
|
}
|
|
2526
2662
|
lines.push("");
|
|
2663
|
+
for (const area of input.areas) {
|
|
2664
|
+
const areaClassName = deriveAreaClientClassName(area.area);
|
|
2665
|
+
const inlined = inlinedByArea.get(area.area);
|
|
2666
|
+
lines.push(`class ${areaClassName} {`);
|
|
2667
|
+
for (const sc of area.subareaClients) {
|
|
2668
|
+
lines.push(` readonly ${sc.propertyName}: ${sc.client.className};`);
|
|
2669
|
+
}
|
|
2670
|
+
if (area.subareaClients.length > 0) lines.push("");
|
|
2671
|
+
if (inlined.lines.length > 0 || area.subareaClients.length > 0) {
|
|
2672
|
+
const fetchModifier = inlined.lines.length > 0 ? "private " : "";
|
|
2673
|
+
lines.push(` constructor(${fetchModifier}fetch: SdkFetch) {`);
|
|
2674
|
+
for (const sc of area.subareaClients) {
|
|
2675
|
+
lines.push(` this.${sc.propertyName} = new ${sc.client.className}(fetch);`);
|
|
2676
|
+
}
|
|
2677
|
+
lines.push(" }");
|
|
2678
|
+
}
|
|
2679
|
+
for (const ln of inlined.lines) lines.push(ln);
|
|
2680
|
+
lines.push("}");
|
|
2681
|
+
lines.push("");
|
|
2682
|
+
}
|
|
2527
2683
|
lines.push(`export class ${sdkClassName} {`);
|
|
2528
|
-
for (const
|
|
2684
|
+
for (const area of input.areas) {
|
|
2685
|
+
lines.push(` readonly ${deriveAreaPropertyName(area.area)}: ${deriveAreaClientClassName(area.area)};`);
|
|
2686
|
+
}
|
|
2687
|
+
for (const c of input.topLevelClients) {
|
|
2529
2688
|
lines.push(` readonly ${c.propertyName}: ${c.className};`);
|
|
2530
2689
|
}
|
|
2531
2690
|
lines.push("");
|
|
2532
2691
|
lines.push(" constructor(options: SdkOptions) {");
|
|
2533
2692
|
lines.push(" const sdkFetch = options.fetch ?? createSdkFetch(options);");
|
|
2534
|
-
for (const
|
|
2693
|
+
for (const area of input.areas) {
|
|
2694
|
+
lines.push(` this.${deriveAreaPropertyName(area.area)} = new ${deriveAreaClientClassName(area.area)}(sdkFetch);`);
|
|
2695
|
+
}
|
|
2696
|
+
for (const c of input.topLevelClients) {
|
|
2535
2697
|
lines.push(` this.${c.propertyName} = new ${c.className}(sdkFetch);`);
|
|
2536
2698
|
}
|
|
2537
2699
|
lines.push(" }");
|
|
@@ -2945,19 +3107,149 @@ function computePubliclyReachableTypes(opAsts, contractAsts, modelsWithInput, mo
|
|
|
2945
3107
|
__name(computePubliclyReachableTypes, "computePubliclyReachableTypes");
|
|
2946
3108
|
|
|
2947
3109
|
// src/index.ts
|
|
2948
|
-
|
|
3110
|
+
var TYPESCRIPT_CODEGEN_VERSION = "1";
|
|
3111
|
+
var MANIFEST_FILENAME = ".contractkit-typescript-manifest.json";
|
|
3112
|
+
var plugin = {
|
|
3113
|
+
name: "typescript",
|
|
3114
|
+
async generateTargets(inputs, ctx) {
|
|
3115
|
+
const config = ctx.options;
|
|
3116
|
+
await runTypescriptCodegen(inputs, ctx, config, ctx.rootDir);
|
|
3117
|
+
}
|
|
3118
|
+
};
|
|
3119
|
+
var index_default = plugin;
|
|
3120
|
+
function createTypescriptPlugin(config, rootDir) {
|
|
3121
|
+
return {
|
|
3122
|
+
name: "typescript",
|
|
3123
|
+
async generateTargets(inputs, ctx) {
|
|
3124
|
+
await runTypescriptCodegen(inputs, ctx, config, rootDir);
|
|
3125
|
+
}
|
|
3126
|
+
};
|
|
3127
|
+
}
|
|
3128
|
+
__name(createTypescriptPlugin, "createTypescriptPlugin");
|
|
3129
|
+
async function runTypescriptCodegen(inputs, ctx, config, rootDir) {
|
|
3130
|
+
const manifestPath = resolve2(rootDir, MANIFEST_FILENAME);
|
|
3131
|
+
const prevManifest = ctx.cacheEnabled ? readManifest(manifestPath) : emptyIncrementalManifest(TYPESCRIPT_CODEGEN_VERSION);
|
|
3132
|
+
const units = [];
|
|
3133
|
+
const globalFiles = [];
|
|
3134
|
+
if (config.server) collectServerOutput(config.server, rootDir, inputs, units);
|
|
3135
|
+
if (config.sdk) collectSdkOutput(config.sdk, rootDir, inputs, units, globalFiles);
|
|
3136
|
+
if (config.zod) collectZodOutput(config.zod, rootDir, inputs, units);
|
|
3137
|
+
if (config.types) collectTypesOutput(config.types, rootDir, inputs, units);
|
|
3138
|
+
const result = runIncrementalCodegen({
|
|
3139
|
+
codegenVersion: TYPESCRIPT_CODEGEN_VERSION,
|
|
3140
|
+
manifestFilename: manifestPath,
|
|
3141
|
+
prevManifest,
|
|
3142
|
+
globalFiles,
|
|
3143
|
+
units,
|
|
3144
|
+
// Paths are absolute, so existsSync works directly.
|
|
3145
|
+
fileExists: existsSync
|
|
3146
|
+
});
|
|
3147
|
+
deleteStalePaths(result.deletedPaths);
|
|
3148
|
+
for (const { relativePath, content } of result.filesToWrite) {
|
|
3149
|
+
ctx.emitFile(relativePath, content);
|
|
3150
|
+
}
|
|
3151
|
+
}
|
|
3152
|
+
__name(runTypescriptCodegen, "runTypescriptCodegen");
|
|
3153
|
+
function buildModelMap(contractRoots) {
|
|
3154
|
+
const map = /* @__PURE__ */ new Map();
|
|
3155
|
+
for (const root of contractRoots) {
|
|
3156
|
+
for (const model of root.models) map.set(model.name, model);
|
|
3157
|
+
}
|
|
3158
|
+
return map;
|
|
3159
|
+
}
|
|
3160
|
+
__name(buildModelMap, "buildModelMap");
|
|
3161
|
+
function collectContractRootRefs(root, modelMap) {
|
|
3162
|
+
const seeds = [];
|
|
3163
|
+
for (const m of root.models) {
|
|
3164
|
+
if (m.type) seeds.push(m.type);
|
|
3165
|
+
for (const f of m.fields) seeds.push(f.type);
|
|
3166
|
+
if (m.bases) {
|
|
3167
|
+
for (const b of m.bases) seeds.push({
|
|
3168
|
+
kind: "ref",
|
|
3169
|
+
name: b
|
|
3170
|
+
});
|
|
3171
|
+
}
|
|
3172
|
+
}
|
|
3173
|
+
return collectTransitiveModelRefs(seeds, modelMap);
|
|
3174
|
+
}
|
|
3175
|
+
__name(collectContractRootRefs, "collectContractRootRefs");
|
|
3176
|
+
function collectOpRootRefs(root, modelMap) {
|
|
3177
|
+
const seeds = [];
|
|
3178
|
+
for (const route of root.routes) {
|
|
3179
|
+
if (route.params) seeds.push(...paramSourceTypes(route.params));
|
|
3180
|
+
for (const op of route.operations) {
|
|
3181
|
+
if (op.query) seeds.push(...paramSourceTypes(op.query));
|
|
3182
|
+
if (op.headers) seeds.push(...paramSourceTypes(op.headers));
|
|
3183
|
+
if (op.request) {
|
|
3184
|
+
for (const body of op.request.bodies) seeds.push(body.bodyType);
|
|
3185
|
+
}
|
|
3186
|
+
for (const resp of op.responses) {
|
|
3187
|
+
if (resp.bodyType) seeds.push(resp.bodyType);
|
|
3188
|
+
if (resp.headers) {
|
|
3189
|
+
for (const h of resp.headers) seeds.push(h.type);
|
|
3190
|
+
}
|
|
3191
|
+
}
|
|
3192
|
+
}
|
|
3193
|
+
}
|
|
3194
|
+
return collectTransitiveModelRefs(seeds, modelMap);
|
|
3195
|
+
}
|
|
3196
|
+
__name(collectOpRootRefs, "collectOpRootRefs");
|
|
3197
|
+
function paramSourceTypes(src) {
|
|
3198
|
+
const out = [];
|
|
3199
|
+
if (src.kind === "params") {
|
|
3200
|
+
for (const n of src.nodes) out.push(n.type);
|
|
3201
|
+
} else if (src.kind === "ref") {
|
|
3202
|
+
out.push({
|
|
3203
|
+
kind: "ref",
|
|
3204
|
+
name: src.name
|
|
3205
|
+
});
|
|
3206
|
+
} else if (src.kind === "type") {
|
|
3207
|
+
out.push(src.node);
|
|
3208
|
+
}
|
|
3209
|
+
return out;
|
|
3210
|
+
}
|
|
3211
|
+
__name(paramSourceTypes, "paramSourceTypes");
|
|
3212
|
+
function sliceOutPathMap(refs, modelOutPaths, modelsWithInput, modelsWithOutput) {
|
|
3213
|
+
const slice = {};
|
|
3214
|
+
for (const ref of [
|
|
3215
|
+
...refs
|
|
3216
|
+
].sort()) {
|
|
3217
|
+
const p = modelOutPaths.get(ref);
|
|
3218
|
+
if (p) slice[ref] = p;
|
|
3219
|
+
if (modelsWithInput.has(ref)) {
|
|
3220
|
+
const ip = modelOutPaths.get(`${ref}Input`);
|
|
3221
|
+
if (ip) slice[`${ref}Input`] = ip;
|
|
3222
|
+
}
|
|
3223
|
+
if (modelsWithOutput.has(ref)) {
|
|
3224
|
+
const op = modelOutPaths.get(`${ref}Output`);
|
|
3225
|
+
if (op) slice[`${ref}Output`] = op;
|
|
3226
|
+
}
|
|
3227
|
+
}
|
|
3228
|
+
return slice;
|
|
3229
|
+
}
|
|
3230
|
+
__name(sliceOutPathMap, "sliceOutPathMap");
|
|
3231
|
+
function sliceModelSet(refs, ownNames, set) {
|
|
3232
|
+
const result = [];
|
|
3233
|
+
for (const name of set) {
|
|
3234
|
+
if (refs.has(name) || ownNames.has(name)) result.push(name);
|
|
3235
|
+
}
|
|
3236
|
+
return result.sort();
|
|
3237
|
+
}
|
|
3238
|
+
__name(sliceModelSet, "sliceModelSet");
|
|
3239
|
+
function collectServerOutput(config, rootDir, inputs, units) {
|
|
2949
3240
|
const serverBase = resolve2(rootDir, config.baseDir ?? ".");
|
|
2950
3241
|
const modelsWithInput = inputs.modelsWithInput;
|
|
2951
3242
|
const modelsWithOutput = inputs.modelsWithOutput;
|
|
3243
|
+
const modelMap = buildModelMap(inputs.contractRoots);
|
|
2952
3244
|
const allFiles = [
|
|
2953
3245
|
...inputs.contractRoots.map((r) => r.file),
|
|
2954
3246
|
...inputs.opRoots.map((r) => r.file)
|
|
2955
3247
|
];
|
|
2956
3248
|
const commonRoot = commonDir(allFiles, rootDir);
|
|
2957
|
-
|
|
3249
|
+
const subConfigKey = stableSubConfig(config);
|
|
3250
|
+
const serverModelOutPaths = /* @__PURE__ */ new Map();
|
|
3251
|
+
const typeEntries = [];
|
|
2958
3252
|
if (config.output?.types) {
|
|
2959
|
-
serverModelOutPaths = /* @__PURE__ */ new Map();
|
|
2960
|
-
const typeEntries = [];
|
|
2961
3253
|
for (const ast of inputs.contractRoots) {
|
|
2962
3254
|
const typeOutPath = computeContractOutPath(ast.file, serverBase, config.output.types, ".ts", commonRoot, ast.meta);
|
|
2963
3255
|
typeEntries.push({
|
|
@@ -2966,40 +3258,81 @@ function runServerGeneration(config, rootDir, inputs, emitFile) {
|
|
|
2966
3258
|
});
|
|
2967
3259
|
for (const model of ast.models) {
|
|
2968
3260
|
serverModelOutPaths.set(model.name, typeOutPath);
|
|
2969
|
-
if (modelsWithInput.has(model.name)) {
|
|
2970
|
-
|
|
2971
|
-
}
|
|
2972
|
-
if (modelsWithOutput.has(model.name)) {
|
|
2973
|
-
serverModelOutPaths.set(`${model.name}Output`, typeOutPath);
|
|
2974
|
-
}
|
|
3261
|
+
if (modelsWithInput.has(model.name)) serverModelOutPaths.set(`${model.name}Input`, typeOutPath);
|
|
3262
|
+
if (modelsWithOutput.has(model.name)) serverModelOutPaths.set(`${model.name}Output`, typeOutPath);
|
|
2975
3263
|
}
|
|
2976
3264
|
}
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
3265
|
+
}
|
|
3266
|
+
for (const { ast, typeOutPath } of typeEntries) {
|
|
3267
|
+
const refs = collectContractRootRefs(ast, modelMap);
|
|
3268
|
+
const ownNames = new Set(ast.models.map((m) => m.name));
|
|
3269
|
+
const fingerprint = hashFingerprint({
|
|
3270
|
+
kind: "server-types",
|
|
3271
|
+
v: TYPESCRIPT_CODEGEN_VERSION,
|
|
3272
|
+
outPath: typeOutPath,
|
|
3273
|
+
root: ast,
|
|
3274
|
+
outPathSlice: sliceOutPathMap(refs, serverModelOutPaths, modelsWithInput, modelsWithOutput),
|
|
3275
|
+
modelsWithInput: sliceModelSet(refs, ownNames, modelsWithInput),
|
|
3276
|
+
modelsWithOutput: sliceModelSet(refs, ownNames, modelsWithOutput),
|
|
3277
|
+
sub: subConfigKey
|
|
3278
|
+
});
|
|
3279
|
+
units.push({
|
|
3280
|
+
key: `server-types::${typeOutPath}`,
|
|
3281
|
+
fingerprint,
|
|
3282
|
+
render: /* @__PURE__ */ __name(() => {
|
|
3283
|
+
const renderCtx = {
|
|
3284
|
+
modelOutPaths: serverModelOutPaths,
|
|
3285
|
+
currentOutPath: typeOutPath,
|
|
3286
|
+
modelsWithInput,
|
|
3287
|
+
modelsWithOutput
|
|
3288
|
+
};
|
|
3289
|
+
const content = config.zod ? generateContract(ast, renderCtx) : generatePlainTypes(ast, renderCtx);
|
|
3290
|
+
return [
|
|
3291
|
+
{
|
|
3292
|
+
relativePath: typeOutPath,
|
|
3293
|
+
content
|
|
3294
|
+
}
|
|
3295
|
+
];
|
|
3296
|
+
}, "render")
|
|
3297
|
+
});
|
|
2987
3298
|
}
|
|
2988
3299
|
for (const ast of inputs.opRoots) {
|
|
2989
3300
|
const outPath = computeOpOutPath(ast.file, serverBase, config.output?.routes, ".router.ts", commonRoot, ast.meta);
|
|
2990
|
-
const
|
|
2991
|
-
|
|
3301
|
+
const refs = collectOpRootRefs(ast, modelMap);
|
|
3302
|
+
const fingerprint = hashFingerprint({
|
|
3303
|
+
kind: "server-router",
|
|
3304
|
+
v: TYPESCRIPT_CODEGEN_VERSION,
|
|
2992
3305
|
outPath,
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
modelsWithOutput,
|
|
2996
|
-
|
|
3306
|
+
root: ast,
|
|
3307
|
+
// The router imports types from each contract root's type file; the slice covers exactly that.
|
|
3308
|
+
outPathSlice: sliceOutPathMap(refs, serverModelOutPaths, modelsWithInput, modelsWithOutput),
|
|
3309
|
+
modelsWithInput: sliceModelSet(refs, /* @__PURE__ */ new Set(), modelsWithInput),
|
|
3310
|
+
modelsWithOutput: sliceModelSet(refs, /* @__PURE__ */ new Set(), modelsWithOutput),
|
|
3311
|
+
servicePathTemplate: config.servicePathTemplate ?? null,
|
|
3312
|
+
includeInternal: config.includeInternal ?? true,
|
|
3313
|
+
sub: subConfigKey
|
|
3314
|
+
});
|
|
3315
|
+
units.push({
|
|
3316
|
+
key: `server-router::${outPath}`,
|
|
3317
|
+
fingerprint,
|
|
3318
|
+
render: /* @__PURE__ */ __name(() => [
|
|
3319
|
+
{
|
|
3320
|
+
relativePath: outPath,
|
|
3321
|
+
content: generateOp(ast, {
|
|
3322
|
+
servicePathTemplate: config.servicePathTemplate,
|
|
3323
|
+
outPath,
|
|
3324
|
+
modelOutPaths: serverModelOutPaths,
|
|
3325
|
+
modelsWithInput,
|
|
3326
|
+
modelsWithOutput,
|
|
3327
|
+
includeInternal: config.includeInternal
|
|
3328
|
+
})
|
|
3329
|
+
}
|
|
3330
|
+
], "render")
|
|
2997
3331
|
});
|
|
2998
|
-
emitFile(outPath, content);
|
|
2999
3332
|
}
|
|
3000
3333
|
}
|
|
3001
|
-
__name(
|
|
3002
|
-
function
|
|
3334
|
+
__name(collectServerOutput, "collectServerOutput");
|
|
3335
|
+
function collectSdkOutput(config, rootDir, inputs, units, globalFiles) {
|
|
3003
3336
|
const sdkBase = config.baseDir ? resolve2(rootDir, config.baseDir) : rootDir;
|
|
3004
3337
|
const sdkName = config.name;
|
|
3005
3338
|
const sdkOutput = config.output?.sdk;
|
|
@@ -3007,20 +3340,21 @@ function runSdkGeneration(config, rootDir, inputs, emitFile) {
|
|
|
3007
3340
|
name: sdkName ?? "sdk"
|
|
3008
3341
|
}) : sdkOutput) : join2(sdkBase, "sdk.ts");
|
|
3009
3342
|
const sdkOptionsPath = join2(dirname6(sdkEntryPath), "sdk-options.ts");
|
|
3343
|
+
const subConfigKey = stableSubConfig(config);
|
|
3010
3344
|
const modelsWithInput = inputs.modelsWithInput;
|
|
3011
3345
|
const modelsWithOutput = inputs.modelsWithOutput;
|
|
3346
|
+
const modelMap = buildModelMap(inputs.contractRoots);
|
|
3012
3347
|
const allFiles = [
|
|
3013
3348
|
...inputs.contractRoots.map((r) => r.file),
|
|
3014
3349
|
...inputs.opRoots.map((r) => r.file)
|
|
3015
3350
|
];
|
|
3016
3351
|
const ckCommonRoot = commonDir(allFiles, rootDir);
|
|
3017
|
-
|
|
3352
|
+
const sdkModelOutPaths = /* @__PURE__ */ new Map();
|
|
3018
3353
|
const sdkTypePaths = [];
|
|
3019
3354
|
const sdkClientInfos = [];
|
|
3355
|
+
const sdkContractEntries = [];
|
|
3020
3356
|
if (config.output?.types) {
|
|
3021
|
-
sdkModelOutPaths = /* @__PURE__ */ new Map();
|
|
3022
3357
|
const publicTypes = computePubliclyReachableTypes(inputs.opRoots, inputs.contractRoots, modelsWithInput, modelsWithOutput);
|
|
3023
|
-
const sdkContractEntries = [];
|
|
3024
3358
|
for (const ast of inputs.contractRoots) {
|
|
3025
3359
|
const typeOutPath = computeSdkTypeOutPath(ast.file, sdkBase, config.output.types, ckCommonRoot, ast.meta);
|
|
3026
3360
|
if (!typeOutPath) continue;
|
|
@@ -3036,74 +3370,240 @@ function runSdkGeneration(config, rootDir, inputs, emitFile) {
|
|
|
3036
3370
|
if (modelsWithOutput.has(model.name)) sdkModelOutPaths.set(`${model.name}Output`, typeOutPath);
|
|
3037
3371
|
}
|
|
3038
3372
|
}
|
|
3039
|
-
for (const { ast, typeOutPath } of sdkContractEntries) {
|
|
3040
|
-
let content;
|
|
3041
|
-
if (config.zod) {
|
|
3042
|
-
content = generateContract(ast, {
|
|
3043
|
-
modelOutPaths: sdkModelOutPaths,
|
|
3044
|
-
currentOutPath: typeOutPath,
|
|
3045
|
-
modelsWithInput,
|
|
3046
|
-
modelsWithOutput
|
|
3047
|
-
});
|
|
3048
|
-
} else {
|
|
3049
|
-
let rel = relative6(dirname6(typeOutPath), sdkOptionsPath).replace(/\.ts$/, ".js");
|
|
3050
|
-
if (!rel.startsWith(".")) rel = "./" + rel;
|
|
3051
|
-
content = generatePlainTypes(ast, {
|
|
3052
|
-
modelOutPaths: sdkModelOutPaths,
|
|
3053
|
-
currentOutPath: typeOutPath,
|
|
3054
|
-
modelsWithInput,
|
|
3055
|
-
modelsWithOutput,
|
|
3056
|
-
jsonValueImportPath: rel
|
|
3057
|
-
});
|
|
3058
|
-
}
|
|
3059
|
-
emitFile(typeOutPath, content);
|
|
3060
|
-
}
|
|
3061
3373
|
}
|
|
3374
|
+
for (const { ast, typeOutPath } of sdkContractEntries) {
|
|
3375
|
+
const refs = collectContractRootRefs(ast, modelMap);
|
|
3376
|
+
const ownNames = new Set(ast.models.map((m) => m.name));
|
|
3377
|
+
const fingerprint = hashFingerprint({
|
|
3378
|
+
kind: "sdk-types",
|
|
3379
|
+
v: TYPESCRIPT_CODEGEN_VERSION,
|
|
3380
|
+
outPath: typeOutPath,
|
|
3381
|
+
root: ast,
|
|
3382
|
+
outPathSlice: sliceOutPathMap(refs, sdkModelOutPaths, modelsWithInput, modelsWithOutput),
|
|
3383
|
+
modelsWithInput: sliceModelSet(refs, ownNames, modelsWithInput),
|
|
3384
|
+
modelsWithOutput: sliceModelSet(refs, ownNames, modelsWithOutput),
|
|
3385
|
+
sdkOptionsPath,
|
|
3386
|
+
sub: subConfigKey
|
|
3387
|
+
});
|
|
3388
|
+
units.push({
|
|
3389
|
+
key: `sdk-types::${typeOutPath}`,
|
|
3390
|
+
fingerprint,
|
|
3391
|
+
render: /* @__PURE__ */ __name(() => {
|
|
3392
|
+
let content;
|
|
3393
|
+
if (config.zod) {
|
|
3394
|
+
content = generateContract(ast, {
|
|
3395
|
+
modelOutPaths: sdkModelOutPaths,
|
|
3396
|
+
currentOutPath: typeOutPath,
|
|
3397
|
+
modelsWithInput,
|
|
3398
|
+
modelsWithOutput
|
|
3399
|
+
});
|
|
3400
|
+
} else {
|
|
3401
|
+
let rel = relative6(dirname6(typeOutPath), sdkOptionsPath).replace(/\.ts$/, ".js");
|
|
3402
|
+
if (!rel.startsWith(".")) rel = "./" + rel;
|
|
3403
|
+
content = generatePlainTypes(ast, {
|
|
3404
|
+
modelOutPaths: sdkModelOutPaths,
|
|
3405
|
+
currentOutPath: typeOutPath,
|
|
3406
|
+
modelsWithInput,
|
|
3407
|
+
modelsWithOutput,
|
|
3408
|
+
jsonValueImportPath: rel
|
|
3409
|
+
});
|
|
3410
|
+
}
|
|
3411
|
+
return [
|
|
3412
|
+
{
|
|
3413
|
+
relativePath: typeOutPath,
|
|
3414
|
+
content
|
|
3415
|
+
}
|
|
3416
|
+
];
|
|
3417
|
+
}, "render")
|
|
3418
|
+
});
|
|
3419
|
+
}
|
|
3420
|
+
const areaBuckets = /* @__PURE__ */ new Map();
|
|
3421
|
+
const topLevelEntries = [];
|
|
3062
3422
|
if (config.output?.clients) {
|
|
3063
3423
|
for (const ast of inputs.opRoots) {
|
|
3064
3424
|
const sdkOutPath = computeSdkOutPath(ast.file, sdkBase, config.output.clients, ckCommonRoot, ast.meta);
|
|
3065
3425
|
if (!sdkOutPath || !hasPublicOperations(ast, config.includeInternal)) continue;
|
|
3426
|
+
const { area, subarea } = getAreaSubarea(ast);
|
|
3427
|
+
if (area && subarea) {
|
|
3428
|
+
const bucket = areaBuckets.get(area) ?? {
|
|
3429
|
+
leaves: [],
|
|
3430
|
+
inlineRoots: []
|
|
3431
|
+
};
|
|
3432
|
+
bucket.leaves.push({
|
|
3433
|
+
ast,
|
|
3434
|
+
outPath: sdkOutPath,
|
|
3435
|
+
subarea
|
|
3436
|
+
});
|
|
3437
|
+
areaBuckets.set(area, bucket);
|
|
3438
|
+
} else if (area) {
|
|
3439
|
+
const bucket = areaBuckets.get(area) ?? {
|
|
3440
|
+
leaves: [],
|
|
3441
|
+
inlineRoots: []
|
|
3442
|
+
};
|
|
3443
|
+
bucket.inlineRoots.push(ast);
|
|
3444
|
+
areaBuckets.set(area, bucket);
|
|
3445
|
+
} else {
|
|
3446
|
+
topLevelEntries.push({
|
|
3447
|
+
ast,
|
|
3448
|
+
outPath: sdkOutPath
|
|
3449
|
+
});
|
|
3450
|
+
}
|
|
3451
|
+
}
|
|
3452
|
+
for (const [area, bucket] of areaBuckets.entries()) {
|
|
3453
|
+
for (const leaf of bucket.leaves) {
|
|
3454
|
+
const className = deriveSubareaClientClassName(area, leaf.subarea);
|
|
3455
|
+
sdkClientInfos.push({
|
|
3456
|
+
outPath: leaf.outPath,
|
|
3457
|
+
className,
|
|
3458
|
+
propertyName: deriveSubareaPropertyName(leaf.subarea)
|
|
3459
|
+
});
|
|
3460
|
+
const refs = collectOpRootRefs(leaf.ast, modelMap);
|
|
3461
|
+
const fingerprint = hashFingerprint({
|
|
3462
|
+
kind: "sdk-leaf-client",
|
|
3463
|
+
v: TYPESCRIPT_CODEGEN_VERSION,
|
|
3464
|
+
outPath: leaf.outPath,
|
|
3465
|
+
root: leaf.ast,
|
|
3466
|
+
outPathSlice: sliceOutPathMap(refs, sdkModelOutPaths, modelsWithInput, modelsWithOutput),
|
|
3467
|
+
modelsWithInput: sliceModelSet(refs, /* @__PURE__ */ new Set(), modelsWithInput),
|
|
3468
|
+
modelsWithOutput: sliceModelSet(refs, /* @__PURE__ */ new Set(), modelsWithOutput),
|
|
3469
|
+
sdkOptionsPath,
|
|
3470
|
+
className,
|
|
3471
|
+
includeInternal: config.includeInternal ?? false,
|
|
3472
|
+
sub: subConfigKey
|
|
3473
|
+
});
|
|
3474
|
+
units.push({
|
|
3475
|
+
key: `sdk-leaf-client::${leaf.outPath}`,
|
|
3476
|
+
fingerprint,
|
|
3477
|
+
render: /* @__PURE__ */ __name(() => [
|
|
3478
|
+
{
|
|
3479
|
+
relativePath: leaf.outPath,
|
|
3480
|
+
content: generateSdk(leaf.ast, {
|
|
3481
|
+
typeImportPathTemplate: void 0,
|
|
3482
|
+
outPath: leaf.outPath,
|
|
3483
|
+
modelOutPaths: sdkModelOutPaths,
|
|
3484
|
+
sdkOptionsPath,
|
|
3485
|
+
modelsWithInput,
|
|
3486
|
+
modelsWithOutput,
|
|
3487
|
+
includeInternal: config.includeInternal,
|
|
3488
|
+
clientClassName: className
|
|
3489
|
+
})
|
|
3490
|
+
}
|
|
3491
|
+
], "render")
|
|
3492
|
+
});
|
|
3493
|
+
}
|
|
3494
|
+
}
|
|
3495
|
+
for (const { ast, outPath } of topLevelEntries) {
|
|
3496
|
+
const className = deriveClientClassName(ast.file);
|
|
3066
3497
|
sdkClientInfos.push({
|
|
3067
|
-
outPath
|
|
3068
|
-
className
|
|
3498
|
+
outPath,
|
|
3499
|
+
className,
|
|
3069
3500
|
propertyName: deriveClientPropertyName(ast.file)
|
|
3070
3501
|
});
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3502
|
+
const refs = collectOpRootRefs(ast, modelMap);
|
|
3503
|
+
const fingerprint = hashFingerprint({
|
|
3504
|
+
kind: "sdk-top-client",
|
|
3505
|
+
v: TYPESCRIPT_CODEGEN_VERSION,
|
|
3506
|
+
outPath,
|
|
3507
|
+
root: ast,
|
|
3508
|
+
outPathSlice: sliceOutPathMap(refs, sdkModelOutPaths, modelsWithInput, modelsWithOutput),
|
|
3509
|
+
modelsWithInput: sliceModelSet(refs, /* @__PURE__ */ new Set(), modelsWithInput),
|
|
3510
|
+
modelsWithOutput: sliceModelSet(refs, /* @__PURE__ */ new Set(), modelsWithOutput),
|
|
3075
3511
|
sdkOptionsPath,
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3512
|
+
includeInternal: config.includeInternal ?? false,
|
|
3513
|
+
sub: subConfigKey
|
|
3514
|
+
});
|
|
3515
|
+
units.push({
|
|
3516
|
+
key: `sdk-top-client::${outPath}`,
|
|
3517
|
+
fingerprint,
|
|
3518
|
+
render: /* @__PURE__ */ __name(() => [
|
|
3519
|
+
{
|
|
3520
|
+
relativePath: outPath,
|
|
3521
|
+
content: generateSdk(ast, {
|
|
3522
|
+
typeImportPathTemplate: void 0,
|
|
3523
|
+
outPath,
|
|
3524
|
+
modelOutPaths: sdkModelOutPaths,
|
|
3525
|
+
sdkOptionsPath,
|
|
3526
|
+
modelsWithInput,
|
|
3527
|
+
modelsWithOutput,
|
|
3528
|
+
includeInternal: config.includeInternal
|
|
3529
|
+
})
|
|
3530
|
+
}
|
|
3531
|
+
], "render")
|
|
3532
|
+
});
|
|
3080
3533
|
}
|
|
3081
3534
|
}
|
|
3082
|
-
|
|
3083
|
-
|
|
3535
|
+
globalFiles.push({
|
|
3536
|
+
relativePath: sdkOptionsPath,
|
|
3537
|
+
content: generateSdkOptions()
|
|
3538
|
+
});
|
|
3539
|
+
const hasAnything = sdkClientInfos.length > 0 || areaBuckets.size > 0;
|
|
3540
|
+
if (hasAnything) {
|
|
3084
3541
|
const sdkEntryDir = dirname6(sdkEntryPath);
|
|
3085
|
-
const
|
|
3086
|
-
|
|
3542
|
+
const sdkOptionsRel = relative6(sdkEntryDir, sdkOptionsPath).replace(/\.ts$/, ".js");
|
|
3543
|
+
const sdkOptionsImportPath = sdkOptionsRel.startsWith(".") ? sdkOptionsRel : "./" + sdkOptionsRel;
|
|
3544
|
+
const sdkClassName = sdkName ? sdkName.split(/[-._\s]+/).map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join("") + "Sdk" : "Sdk";
|
|
3545
|
+
const toClientImport = /* @__PURE__ */ __name((info) => {
|
|
3546
|
+
let rel = relative6(sdkEntryDir, info.outPath).replace(/\.ts$/, ".js");
|
|
3087
3547
|
if (!rel.startsWith(".")) rel = "./" + rel;
|
|
3088
3548
|
return {
|
|
3089
|
-
className:
|
|
3090
|
-
propertyName:
|
|
3549
|
+
className: info.className,
|
|
3550
|
+
propertyName: info.propertyName,
|
|
3091
3551
|
importPath: rel
|
|
3092
3552
|
};
|
|
3553
|
+
}, "toClientImport");
|
|
3554
|
+
const topLevelClients = topLevelEntries.map((e) => ({
|
|
3555
|
+
className: deriveClientClassName(e.ast.file),
|
|
3556
|
+
propertyName: deriveClientPropertyName(e.ast.file),
|
|
3557
|
+
importPath: (() => {
|
|
3558
|
+
const rel = relative6(sdkEntryDir, e.outPath).replace(/\.ts$/, ".js");
|
|
3559
|
+
return rel.startsWith(".") ? rel : "./" + rel;
|
|
3560
|
+
})()
|
|
3561
|
+
}));
|
|
3562
|
+
const areas = [
|
|
3563
|
+
...areaBuckets.entries()
|
|
3564
|
+
].sort(([a], [b]) => a.localeCompare(b)).map(([area, bucket]) => ({
|
|
3565
|
+
area,
|
|
3566
|
+
inlineFiles: bucket.inlineRoots.map((root) => ({
|
|
3567
|
+
root,
|
|
3568
|
+
codegenOptions: {
|
|
3569
|
+
typeImportPathTemplate: void 0,
|
|
3570
|
+
outPath: sdkEntryPath,
|
|
3571
|
+
modelOutPaths: sdkModelOutPaths,
|
|
3572
|
+
sdkOptionsPath,
|
|
3573
|
+
modelsWithInput,
|
|
3574
|
+
modelsWithOutput,
|
|
3575
|
+
includeInternal: config.includeInternal
|
|
3576
|
+
}
|
|
3577
|
+
})),
|
|
3578
|
+
subareaClients: bucket.leaves.sort((a, b) => a.subarea.localeCompare(b.subarea)).map((l) => ({
|
|
3579
|
+
propertyName: deriveSubareaPropertyName(l.subarea),
|
|
3580
|
+
client: toClientImport({
|
|
3581
|
+
outPath: l.outPath,
|
|
3582
|
+
className: deriveSubareaClientClassName(area, l.subarea),
|
|
3583
|
+
propertyName: deriveSubareaPropertyName(l.subarea)
|
|
3584
|
+
})
|
|
3585
|
+
}))
|
|
3586
|
+
}));
|
|
3587
|
+
globalFiles.push({
|
|
3588
|
+
relativePath: sdkEntryPath,
|
|
3589
|
+
content: generateSdkAggregator({
|
|
3590
|
+
topLevelClients,
|
|
3591
|
+
areas,
|
|
3592
|
+
sdkOptionsImportPath,
|
|
3593
|
+
sdkClassName
|
|
3594
|
+
})
|
|
3093
3595
|
});
|
|
3094
|
-
const sdkOptionsRel = relative6(sdkEntryDir, sdkOptionsPath).replace(/\.ts$/, ".js");
|
|
3095
|
-
const sdkClassName = sdkName ? sdkName.split(/[-._\s]+/).map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join("") + "Sdk" : "Sdk";
|
|
3096
|
-
emitFile(sdkEntryPath, generateSdkAggregator(clients, sdkOptionsRel.startsWith(".") ? sdkOptionsRel : "./" + sdkOptionsRel, sdkClassName));
|
|
3097
3596
|
}
|
|
3098
3597
|
const sdkSrcDir = dirname6(sdkEntryPath);
|
|
3099
3598
|
const sdkTypeBarrels = generateBarrelFiles(sdkTypePaths);
|
|
3100
|
-
for (const barrel of sdkTypeBarrels)
|
|
3599
|
+
for (const barrel of sdkTypeBarrels) globalFiles.push({
|
|
3600
|
+
relativePath: barrel.outPath,
|
|
3601
|
+
content: barrel.content
|
|
3602
|
+
});
|
|
3101
3603
|
const rootExports = [
|
|
3102
3604
|
`export * from './${basename3(sdkOptionsPath).replace(/\.ts$/, ".js")}';`
|
|
3103
3605
|
];
|
|
3104
|
-
if (
|
|
3105
|
-
rootExports.push(`export * from './${basename3(sdkEntryPath).replace(/\.ts$/, ".js")}';`);
|
|
3106
|
-
}
|
|
3606
|
+
if (hasAnything) rootExports.push(`export * from './${basename3(sdkEntryPath).replace(/\.ts$/, ".js")}';`);
|
|
3107
3607
|
for (const c of sdkClientInfos) {
|
|
3108
3608
|
let rel = relative6(sdkSrcDir, c.outPath).replace(/\.ts$/, ".js");
|
|
3109
3609
|
if (!rel.startsWith(".")) rel = "./" + rel;
|
|
@@ -3114,12 +3614,15 @@ function runSdkGeneration(config, rootDir, inputs, emitFile) {
|
|
|
3114
3614
|
if (!rel.startsWith(".")) rel = "./" + rel;
|
|
3115
3615
|
rootExports.push(`export * from '${rel}';`);
|
|
3116
3616
|
}
|
|
3117
|
-
|
|
3617
|
+
globalFiles.push({
|
|
3618
|
+
relativePath: join2(sdkSrcDir, "index.ts"),
|
|
3619
|
+
content: `// Auto-generated barrel file
|
|
3118
3620
|
${rootExports.sort().join("\n")}
|
|
3119
|
-
`
|
|
3621
|
+
`
|
|
3622
|
+
});
|
|
3120
3623
|
}
|
|
3121
|
-
__name(
|
|
3122
|
-
function
|
|
3624
|
+
__name(collectSdkOutput, "collectSdkOutput");
|
|
3625
|
+
function collectZodOutput(config, rootDir, inputs, units) {
|
|
3123
3626
|
const zodBase = resolve2(rootDir, config.baseDir ?? ".");
|
|
3124
3627
|
const allFiles = [
|
|
3125
3628
|
...inputs.contractRoots.map((r) => r.file),
|
|
@@ -3128,6 +3631,8 @@ function runZodGeneration(config, rootDir, inputs, emitFile) {
|
|
|
3128
3631
|
const commonRoot = commonDir(allFiles, rootDir);
|
|
3129
3632
|
const modelsWithInput = inputs.modelsWithInput;
|
|
3130
3633
|
const modelsWithOutput = inputs.modelsWithOutput;
|
|
3634
|
+
const modelMap = buildModelMap(inputs.contractRoots);
|
|
3635
|
+
const subConfigKey = stableSubConfig(config);
|
|
3131
3636
|
const modelOutPaths = /* @__PURE__ */ new Map();
|
|
3132
3637
|
const entries = [];
|
|
3133
3638
|
for (const ast of inputs.contractRoots) {
|
|
@@ -3143,17 +3648,37 @@ function runZodGeneration(config, rootDir, inputs, emitFile) {
|
|
|
3143
3648
|
}
|
|
3144
3649
|
}
|
|
3145
3650
|
for (const { ast, outPath } of entries) {
|
|
3146
|
-
const
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3651
|
+
const refs = collectContractRootRefs(ast, modelMap);
|
|
3652
|
+
const ownNames = new Set(ast.models.map((m) => m.name));
|
|
3653
|
+
const fingerprint = hashFingerprint({
|
|
3654
|
+
kind: "zod",
|
|
3655
|
+
v: TYPESCRIPT_CODEGEN_VERSION,
|
|
3656
|
+
outPath,
|
|
3657
|
+
root: ast,
|
|
3658
|
+
outPathSlice: sliceOutPathMap(refs, modelOutPaths, modelsWithInput, modelsWithOutput),
|
|
3659
|
+
modelsWithInput: sliceModelSet(refs, ownNames, modelsWithInput),
|
|
3660
|
+
modelsWithOutput: sliceModelSet(refs, ownNames, modelsWithOutput),
|
|
3661
|
+
sub: subConfigKey
|
|
3662
|
+
});
|
|
3663
|
+
units.push({
|
|
3664
|
+
key: `zod::${outPath}`,
|
|
3665
|
+
fingerprint,
|
|
3666
|
+
render: /* @__PURE__ */ __name(() => [
|
|
3667
|
+
{
|
|
3668
|
+
relativePath: outPath,
|
|
3669
|
+
content: generateContract(ast, {
|
|
3670
|
+
modelOutPaths,
|
|
3671
|
+
currentOutPath: outPath,
|
|
3672
|
+
modelsWithInput,
|
|
3673
|
+
modelsWithOutput
|
|
3674
|
+
})
|
|
3675
|
+
}
|
|
3676
|
+
], "render")
|
|
3151
3677
|
});
|
|
3152
|
-
emitFile(outPath, content);
|
|
3153
3678
|
}
|
|
3154
3679
|
}
|
|
3155
|
-
__name(
|
|
3156
|
-
function
|
|
3680
|
+
__name(collectZodOutput, "collectZodOutput");
|
|
3681
|
+
function collectTypesOutput(config, rootDir, inputs, units) {
|
|
3157
3682
|
const typesBase = resolve2(rootDir, config.baseDir ?? ".");
|
|
3158
3683
|
const allFiles = [
|
|
3159
3684
|
...inputs.contractRoots.map((r) => r.file),
|
|
@@ -3162,6 +3687,8 @@ function runTypesGeneration(config, rootDir, inputs, emitFile) {
|
|
|
3162
3687
|
const commonRoot = commonDir(allFiles, rootDir);
|
|
3163
3688
|
const modelsWithInput = inputs.modelsWithInput;
|
|
3164
3689
|
const modelsWithOutput = inputs.modelsWithOutput;
|
|
3690
|
+
const modelMap = buildModelMap(inputs.contractRoots);
|
|
3691
|
+
const subConfigKey = stableSubConfig(config);
|
|
3165
3692
|
const modelOutPaths = /* @__PURE__ */ new Map();
|
|
3166
3693
|
const entries = [];
|
|
3167
3694
|
for (const ast of inputs.contractRoots) {
|
|
@@ -3177,58 +3704,79 @@ function runTypesGeneration(config, rootDir, inputs, emitFile) {
|
|
|
3177
3704
|
}
|
|
3178
3705
|
}
|
|
3179
3706
|
for (const { ast, outPath } of entries) {
|
|
3180
|
-
const
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3707
|
+
const refs = collectContractRootRefs(ast, modelMap);
|
|
3708
|
+
const ownNames = new Set(ast.models.map((m) => m.name));
|
|
3709
|
+
const fingerprint = hashFingerprint({
|
|
3710
|
+
kind: "plain-types",
|
|
3711
|
+
v: TYPESCRIPT_CODEGEN_VERSION,
|
|
3712
|
+
outPath,
|
|
3713
|
+
root: ast,
|
|
3714
|
+
outPathSlice: sliceOutPathMap(refs, modelOutPaths, modelsWithInput, modelsWithOutput),
|
|
3715
|
+
modelsWithInput: sliceModelSet(refs, ownNames, modelsWithInput),
|
|
3716
|
+
modelsWithOutput: sliceModelSet(refs, ownNames, modelsWithOutput),
|
|
3717
|
+
sub: subConfigKey
|
|
3718
|
+
});
|
|
3719
|
+
units.push({
|
|
3720
|
+
key: `plain-types::${outPath}`,
|
|
3721
|
+
fingerprint,
|
|
3722
|
+
render: /* @__PURE__ */ __name(() => [
|
|
3723
|
+
{
|
|
3724
|
+
relativePath: outPath,
|
|
3725
|
+
content: generatePlainTypes(ast, {
|
|
3726
|
+
modelOutPaths,
|
|
3727
|
+
currentOutPath: outPath,
|
|
3728
|
+
modelsWithInput,
|
|
3729
|
+
modelsWithOutput
|
|
3730
|
+
})
|
|
3731
|
+
}
|
|
3732
|
+
], "render")
|
|
3185
3733
|
});
|
|
3186
|
-
emitFile(outPath, content);
|
|
3187
3734
|
}
|
|
3188
3735
|
}
|
|
3189
|
-
__name(
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3736
|
+
__name(collectTypesOutput, "collectTypesOutput");
|
|
3737
|
+
function readManifest(manifestPath) {
|
|
3738
|
+
if (!existsSync(manifestPath)) return emptyIncrementalManifest(TYPESCRIPT_CODEGEN_VERSION);
|
|
3739
|
+
try {
|
|
3740
|
+
return parseIncrementalManifest(readFileSync(manifestPath, "utf-8"));
|
|
3741
|
+
} catch {
|
|
3742
|
+
return emptyIncrementalManifest(TYPESCRIPT_CODEGEN_VERSION);
|
|
3743
|
+
}
|
|
3744
|
+
}
|
|
3745
|
+
__name(readManifest, "readManifest");
|
|
3746
|
+
function deleteStalePaths(absPaths) {
|
|
3747
|
+
if (absPaths.length === 0) return;
|
|
3748
|
+
const removedDirs = /* @__PURE__ */ new Set();
|
|
3749
|
+
for (const abs of absPaths) {
|
|
3750
|
+
if (existsSync(abs)) {
|
|
3751
|
+
rmSync(abs, {
|
|
3752
|
+
force: true
|
|
3753
|
+
});
|
|
3754
|
+
removedDirs.add(dirname6(abs));
|
|
3206
3755
|
}
|
|
3207
3756
|
}
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
}
|
|
3221
|
-
if (config.zod) {
|
|
3222
|
-
runZodGeneration(config.zod, rootDir, inputs, ctx.emitFile.bind(ctx));
|
|
3223
|
-
}
|
|
3224
|
-
if (config.types) {
|
|
3225
|
-
runTypesGeneration(config.types, rootDir, inputs, ctx.emitFile.bind(ctx));
|
|
3757
|
+
for (const dir of removedDirs) {
|
|
3758
|
+
let current = dir;
|
|
3759
|
+
while (current.length > 1) {
|
|
3760
|
+
try {
|
|
3761
|
+
if (readdirSync(current).length === 0) {
|
|
3762
|
+
rmdirSync(current);
|
|
3763
|
+
current = dirname6(current);
|
|
3764
|
+
} else {
|
|
3765
|
+
break;
|
|
3766
|
+
}
|
|
3767
|
+
} catch {
|
|
3768
|
+
break;
|
|
3226
3769
|
}
|
|
3227
3770
|
}
|
|
3228
|
-
}
|
|
3771
|
+
}
|
|
3229
3772
|
}
|
|
3230
|
-
__name(
|
|
3773
|
+
__name(deleteStalePaths, "deleteStalePaths");
|
|
3774
|
+
function stableSubConfig(config) {
|
|
3775
|
+
return JSON.stringify(config ?? null);
|
|
3776
|
+
}
|
|
3777
|
+
__name(stableSubConfig, "stableSubConfig");
|
|
3231
3778
|
export {
|
|
3779
|
+
TYPESCRIPT_CODEGEN_VERSION,
|
|
3232
3780
|
createTypescriptPlugin,
|
|
3233
3781
|
index_default as default
|
|
3234
3782
|
};
|