@dudousxd/nestjs-codegen 0.25.2 → 0.26.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/index.js CHANGED
@@ -523,22 +523,22 @@ import { isAbsolute as isAbsolute2, join as join5, relative as relative4 } from
523
523
 
524
524
  // src/extension/registry.ts
525
525
  import { relative as relative3, resolve as resolve4 } from "path";
526
- import { Project as Project4 } from "ts-morph";
526
+ import { Project as Project5 } from "ts-morph";
527
527
 
528
528
  // src/discovery/contracts-fast.ts
529
529
  import { existsSync } from "fs";
530
530
  import { dirname as dirname2, join as join4, resolve as resolve3 } from "path";
531
531
  import fg2 from "fast-glob";
532
532
  import {
533
- Node as Node9,
534
- Project as Project3,
535
- ts
533
+ Node as Node11,
534
+ Project as Project4,
535
+ ts as ts3
536
536
  } from "ts-morph";
537
537
 
538
538
  // src/discovery/dto-type-resolver.ts
539
539
  import {
540
- Node as Node7,
541
- SyntaxKind as SyntaxKind3
540
+ Node as Node10,
541
+ SyntaxKind as SyntaxKind4
542
542
  } from "ts-morph";
543
543
 
544
544
  // src/discovery/dto-to-ir.ts
@@ -2076,6 +2076,674 @@ function extractFilterableEntityFields(filterClass, project, entityOverride, pre
2076
2076
  return fields;
2077
2077
  }
2078
2078
 
2079
+ // src/discovery/pipe-schema.ts
2080
+ import { Node as Node9 } from "ts-morph";
2081
+
2082
+ // src/discovery/schema-type-inference.ts
2083
+ import {
2084
+ ts as ts2
2085
+ } from "ts-morph";
2086
+
2087
+ // src/discovery/schema-type-program.ts
2088
+ import { Node as Node7, Project as Project3, ts } from "ts-morph";
2089
+ var PARAM_DECORATORS = /* @__PURE__ */ new Set(["Body", "Query", "Param"]);
2090
+ var SchemaTypeProgram = class {
2091
+ constructor(discovery) {
2092
+ this.discovery = discovery;
2093
+ const base = discovery.getCompilerOptions();
2094
+ this.options = {
2095
+ ...base,
2096
+ // A tsconfig-less consumer gets ES5 by default, whose lib has no `Map`/`Set`/
2097
+ // `Promise` for the schema libraries' declarations to lean on.
2098
+ target: base.target ?? ts.ScriptTarget.ES2022,
2099
+ // With neither set, resolve the way a bundler does: package `exports`
2100
+ // (`zod/v4`) and extensionless or `.js` relative imports all resolve.
2101
+ ...base.module === void 0 && base.moduleResolution === void 0 ? { module: ts.ModuleKind.ESNext, moduleResolution: ts.ModuleResolutionKind.Bundler } : {},
2102
+ // Without it `.nullable()` and `.optional()` would erase to the bare type.
2103
+ strictNullChecks: true,
2104
+ // No ambient `@types/*` (a tsconfig's `types: ['node']`): a schema does not
2105
+ // need them, and they are a hundred-odd files of program to build.
2106
+ types: [],
2107
+ noEmit: true
2108
+ };
2109
+ this.project = new Project3({
2110
+ skipAddingFilesFromTsConfig: true,
2111
+ compilerOptions: this.options
2112
+ });
2113
+ for (const sf of discovery.getSourceFiles()) this.request(sf.getFilePath(), { schema: true });
2114
+ this.flush();
2115
+ }
2116
+ project;
2117
+ options;
2118
+ /** Parses a file that is not in discovery's Project, without adding it there. */
2119
+ scratch = new Project3({
2120
+ skipAddingFilesFromTsConfig: true,
2121
+ skipLoadingLibFiles: true,
2122
+ skipFileDependencyResolution: true
2123
+ });
2124
+ needs = /* @__PURE__ */ new Map();
2125
+ /** Pruned text per file, as last written into {@link project}. */
2126
+ written = /* @__PURE__ */ new Map();
2127
+ /**
2128
+ * The typed copy of a discovery file, with its schema positions kept. Adding one
2129
+ * that was not there yet (a contract file discovery reached lazily) rebuilds the
2130
+ * program once.
2131
+ */
2132
+ sourceFileFor(sf) {
2133
+ this.request(sf.getFilePath(), { schema: true });
2134
+ this.flush();
2135
+ return this.project.getSourceFile(sf.getFilePath());
2136
+ }
2137
+ // -------------------------------------------------------------------------
2138
+ queue = [];
2139
+ request(path, want) {
2140
+ let needs = this.needs.get(path);
2141
+ const isNew = !needs;
2142
+ needs ??= { schema: false, all: false, names: /* @__PURE__ */ new Set() };
2143
+ let grew = isNew;
2144
+ if (want.schema && !needs.schema) {
2145
+ needs.schema = true;
2146
+ grew = true;
2147
+ }
2148
+ if (want.all && !needs.all) {
2149
+ needs.all = true;
2150
+ grew = true;
2151
+ }
2152
+ for (const name of want.names ?? []) {
2153
+ if (!needs.names.has(name)) {
2154
+ needs.names.add(name);
2155
+ grew = true;
2156
+ }
2157
+ }
2158
+ this.needs.set(path, needs);
2159
+ if (grew) this.queue.push(path);
2160
+ }
2161
+ /** Run the worklist to a fixpoint, then write every changed file into the program. */
2162
+ flush() {
2163
+ const changed = /* @__PURE__ */ new Map();
2164
+ while (this.queue.length > 0) {
2165
+ const path = this.queue.pop();
2166
+ const original = this.original(path);
2167
+ if (!original) continue;
2168
+ const needs = this.needs.get(path);
2169
+ const text = this.prune(original, needs);
2170
+ if (this.written.get(path) !== text) changed.set(path, text);
2171
+ }
2172
+ for (const [path, text] of changed) {
2173
+ this.project.createSourceFile(path, text, { overwrite: true });
2174
+ this.written.set(path, text);
2175
+ }
2176
+ }
2177
+ /** The file as discovery sees it (its in-memory text), else as it is on disk. */
2178
+ original(path) {
2179
+ return this.discovery.getSourceFile(path) ?? this.scratch.getSourceFile(path) ?? this.scratch.addSourceFileAtPathIfExists(path);
2180
+ }
2181
+ /**
2182
+ * `sf`'s text with every import/re-export nothing in `needs` references blanked,
2183
+ * requesting from each kept one's target the names it brings in.
2184
+ */
2185
+ prune(sf, needs) {
2186
+ const locals = topLevelDeclarations(sf);
2187
+ const roots = [];
2188
+ if (needs.all) roots.push(...sf.getStatements());
2189
+ if (needs.schema) roots.push(...schemaPositions(sf));
2190
+ const reexported = /* @__PURE__ */ new Map();
2191
+ for (const exp of sf.getExportDeclarations()) {
2192
+ const spec = exp.getModuleSpecifierValue();
2193
+ if (spec === void 0) {
2194
+ for (const named of exp.getNamedExports()) {
2195
+ const exposed = (named.getAliasNode() ?? named.getNameNode()).getText();
2196
+ if (needs.all || needs.names.has(exposed)) roots.push(named.getNameNode());
2197
+ }
2198
+ continue;
2199
+ }
2200
+ if (exp.isNamespaceExport() || exp.getNamedExports().length === 0) continue;
2201
+ for (const named of exp.getNamedExports()) {
2202
+ const exposed = (named.getAliasNode() ?? named.getNameNode()).getText();
2203
+ const list = reexported.get(exposed) ?? [];
2204
+ list.push({ from: spec, name: named.getNameNode().getText() });
2205
+ reexported.set(exposed, list);
2206
+ }
2207
+ }
2208
+ const unresolvedNames = [];
2209
+ for (const name of needs.names) {
2210
+ const decls = name === "default" ? defaultExport(sf) : locals.get(name) ?? [];
2211
+ if (decls.length > 0) roots.push(...decls);
2212
+ else if (!reexported.has(name)) unresolvedNames.push(name);
2213
+ }
2214
+ const referenced = /* @__PURE__ */ new Set();
2215
+ const queue = [...roots];
2216
+ const seen = new Set(queue);
2217
+ while (queue.length > 0) {
2218
+ const node = queue.pop();
2219
+ const ids = Node7.isIdentifier(node) ? [node] : node.getDescendantsOfKind(ts.SyntaxKind.Identifier);
2220
+ for (const id of ids) {
2221
+ const name = id.getText();
2222
+ if (referenced.has(name)) continue;
2223
+ referenced.add(name);
2224
+ for (const local of locals.get(name) ?? []) {
2225
+ if (seen.has(local)) continue;
2226
+ seen.add(local);
2227
+ queue.push(local);
2228
+ }
2229
+ }
2230
+ }
2231
+ const chars = sf.getFullText().split("");
2232
+ const blank = (node) => {
2233
+ for (let i = node.getStart(); i < node.getEnd(); i++) {
2234
+ if (chars[i] !== "\n" && chars[i] !== "\r") chars[i] = " ";
2235
+ }
2236
+ };
2237
+ for (const decl of sf.getImportDeclarations()) {
2238
+ const target = this.resolve(decl.getModuleSpecifierValue(), sf);
2239
+ const namespace = decl.getNamespaceImport()?.getText();
2240
+ const def = decl.getDefaultImport()?.getText();
2241
+ const named = decl.getNamedImports().map((n) => ({
2242
+ local: (n.getAliasNode() ?? n.getNameNode()).getText(),
2243
+ imported: n.getName()
2244
+ })).filter((n) => referenced.has(n.local));
2245
+ const wantsNamespace = namespace !== void 0 && referenced.has(namespace);
2246
+ const wantsDefault = def !== void 0 && referenced.has(def);
2247
+ if (!wantsNamespace && !wantsDefault && named.length === 0) {
2248
+ blank(decl);
2249
+ continue;
2250
+ }
2251
+ if (target) {
2252
+ this.request(target, {
2253
+ all: wantsNamespace,
2254
+ names: [...wantsDefault ? ["default"] : [], ...named.map((n) => n.imported)]
2255
+ });
2256
+ }
2257
+ }
2258
+ for (const exp of sf.getExportDeclarations()) {
2259
+ const spec = exp.getModuleSpecifierValue();
2260
+ if (spec === void 0) continue;
2261
+ const target = this.resolve(spec, sf);
2262
+ if (exp.isNamespaceExport() || exp.getNamedExports().length === 0) {
2263
+ if (!needs.all && unresolvedNames.length === 0) {
2264
+ blank(exp);
2265
+ } else if (target) {
2266
+ this.request(target, { all: needs.all, names: unresolvedNames });
2267
+ }
2268
+ continue;
2269
+ }
2270
+ const wanted = exp.getNamedExports().filter(
2271
+ (n) => needs.all || needs.names.has((n.getAliasNode() ?? n.getNameNode()).getText())
2272
+ ).map((n) => n.getNameNode().getText());
2273
+ if (wanted.length === 0) blank(exp);
2274
+ else if (target) this.request(target, { names: wanted });
2275
+ }
2276
+ return chars.join("");
2277
+ }
2278
+ /**
2279
+ * The project source file a module specifier resolves to, or undefined for a
2280
+ * package (read unpruned by the program itself) or an unresolvable one.
2281
+ */
2282
+ resolve(specifier, from) {
2283
+ const resolved = ts.resolveModuleName(
2284
+ specifier,
2285
+ from.getFilePath(),
2286
+ this.options,
2287
+ ts.sys
2288
+ ).resolvedModule;
2289
+ if (!resolved || resolved.isExternalLibraryImport) return void 0;
2290
+ const file = resolved.resolvedFileName;
2291
+ if (file.endsWith(".d.ts") || !/\.(m|c)?tsx?$/.test(file)) return void 0;
2292
+ return file;
2293
+ }
2294
+ };
2295
+ function schemaPositions(sf) {
2296
+ const roots = [];
2297
+ sf.forEachDescendant((node) => {
2298
+ if (Node7.isDecorator(node)) {
2299
+ const name = node.getName();
2300
+ if (name === "ApplyContract") {
2301
+ roots.push(...node.getArguments());
2302
+ } else if (PARAM_DECORATORS.has(name)) {
2303
+ for (const arg of node.getArguments()) {
2304
+ if (Node7.isNewExpression(arg) || Node7.isCallExpression(arg)) {
2305
+ roots.push(...arg.getArguments());
2306
+ }
2307
+ }
2308
+ }
2309
+ } else if (Node7.isCallExpression(node)) {
2310
+ const callee = node.getExpression();
2311
+ const name = Node7.isIdentifier(callee) ? callee.getText() : Node7.isPropertyAccessExpression(callee) ? callee.getName() : void 0;
2312
+ if (name === "defineContract") roots.push(...node.getArguments());
2313
+ }
2314
+ });
2315
+ return roots;
2316
+ }
2317
+ function topLevelDeclarations(sf) {
2318
+ const byName = /* @__PURE__ */ new Map();
2319
+ const add = (name, node) => {
2320
+ if (!name) return;
2321
+ const list = byName.get(name);
2322
+ if (list) list.push(node);
2323
+ else byName.set(name, [node]);
2324
+ };
2325
+ for (const decl of sf.getVariableDeclarations()) add(decl.getName(), decl);
2326
+ for (const decl of sf.getFunctions()) add(decl.getName(), decl);
2327
+ for (const decl of sf.getClasses()) add(decl.getName(), decl);
2328
+ for (const decl of sf.getEnums()) add(decl.getName(), decl);
2329
+ for (const decl of sf.getInterfaces()) add(decl.getName(), decl);
2330
+ for (const decl of sf.getTypeAliases()) add(decl.getName(), decl);
2331
+ for (const decl of sf.getModules()) add(decl.getName(), decl);
2332
+ return byName;
2333
+ }
2334
+ function defaultExport(sf) {
2335
+ const nodes = [];
2336
+ for (const assignment of sf.getExportAssignments()) nodes.push(assignment);
2337
+ for (const fn of sf.getFunctions()) if (fn.isDefaultExport()) nodes.push(fn);
2338
+ for (const cls of sf.getClasses()) if (cls.isDefaultExport()) nodes.push(cls);
2339
+ return nodes;
2340
+ }
2341
+
2342
+ // src/discovery/schema-type-inference.ts
2343
+ var programs = /* @__PURE__ */ new WeakMap();
2344
+ function programFor(discovery) {
2345
+ let program = programs.get(discovery);
2346
+ if (!program) {
2347
+ program = new SchemaTypeProgram(discovery);
2348
+ programs.set(discovery, program);
2349
+ }
2350
+ return program;
2351
+ }
2352
+ function clearSchemaTypeProject(discovery) {
2353
+ programs.delete(discovery);
2354
+ }
2355
+ function counterpart(typedSf, node) {
2356
+ const start = node.getStart();
2357
+ const end = node.getEnd();
2358
+ const kind = node.getKind();
2359
+ let candidate = typedSf.getDescendantAtPos(start);
2360
+ while (candidate) {
2361
+ if (candidate.getStart() === start && candidate.getEnd() === end && candidate.getKind() === kind) {
2362
+ return candidate;
2363
+ }
2364
+ if (candidate.getStart() < start || candidate.getEnd() > end) return void 0;
2365
+ candidate = candidate.getParent();
2366
+ }
2367
+ return void 0;
2368
+ }
2369
+ function propType(type, name, at) {
2370
+ return type.getProperty(name)?.getTypeAtLocation(at);
2371
+ }
2372
+ function isAnyOrUnknown(type) {
2373
+ return type.isAny() || type.isUnknown();
2374
+ }
2375
+ function inferSchema(expr, discovery) {
2376
+ try {
2377
+ const typedSf = programFor(discovery).sourceFileFor(expr.getSourceFile());
2378
+ const at = typedSf && counterpart(typedSf, expr);
2379
+ if (!at) return { kind: "unresolved" };
2380
+ const schemaType = at.getType();
2381
+ if (isAnyOrUnknown(schemaType)) return { kind: "unresolved" };
2382
+ const standard = propType(schemaType, "~standard", at);
2383
+ const stdTypes = standard ? propType(standard, "types", at)?.getNonNullableType() : void 0;
2384
+ const stdInput = stdTypes ? propType(stdTypes, "input", at) : void 0;
2385
+ const stdOutput = stdTypes ? propType(stdTypes, "output", at) : void 0;
2386
+ if (stdInput && stdOutput) {
2387
+ return { kind: "schema", types: { input: stdInput, output: stdOutput, at } };
2388
+ }
2389
+ const zodInput = propType(schemaType, "_input", at);
2390
+ const zodOutput = propType(schemaType, "_output", at);
2391
+ if (zodInput && zodOutput) {
2392
+ return { kind: "schema", types: { input: zodInput, output: zodOutput, at } };
2393
+ }
2394
+ return { kind: "not-schema" };
2395
+ } catch (err) {
2396
+ dbg("schema inference failed:", err);
2397
+ return { kind: "unresolved" };
2398
+ }
2399
+ }
2400
+ var GLOBAL_NAMED_TYPES = /* @__PURE__ */ new Set([
2401
+ "Date",
2402
+ "File",
2403
+ "Blob",
2404
+ "FormData",
2405
+ "URL",
2406
+ "RegExp",
2407
+ "Map",
2408
+ "Set",
2409
+ "ArrayBuffer",
2410
+ "Uint8Array"
2411
+ ]);
2412
+ var MAX_DEPTH = 12;
2413
+ function objectKey(name) {
2414
+ return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name) ? name : JSON.stringify(name);
2415
+ }
2416
+ function isOptionalSymbol(sym) {
2417
+ return (sym.getFlags() & ts2.SymbolFlags.Optional) !== 0;
2418
+ }
2419
+ function isSymbolKeyed(sym) {
2420
+ return sym.getName().startsWith("__@");
2421
+ }
2422
+ function orderedProperties(type) {
2423
+ const position = (sym) => {
2424
+ const decl = sym.getDeclarations()[0];
2425
+ return decl ? [decl.getSourceFile().getFilePath(), decl.getStart()] : void 0;
2426
+ };
2427
+ return type.getProperties().map((sym, index) => ({ sym, index, at: position(sym) })).sort((a, b) => {
2428
+ if (a.at && b.at) {
2429
+ if (a.at[0] !== b.at[0]) return a.at[0] < b.at[0] ? -1 : 1;
2430
+ if (a.at[1] !== b.at[1]) return a.at[1] - b.at[1];
2431
+ } else if (a.at || b.at) {
2432
+ return a.at ? -1 : 1;
2433
+ }
2434
+ return a.index - b.index;
2435
+ }).map((entry) => entry.sym);
2436
+ }
2437
+ function isFromDeclarationFile(sym) {
2438
+ const decl = sym?.getDeclarations()[0];
2439
+ return !!decl && decl.getSourceFile().isDeclarationFile();
2440
+ }
2441
+ function render(type, state, paired) {
2442
+ if (state.depth > MAX_DEPTH) return "unknown";
2443
+ if (isAnyOrUnknown(type)) {
2444
+ return paired && !isAnyOrUnknown(paired) ? render(paired, state) : "unknown";
2445
+ }
2446
+ if (type.isNever()) return "never";
2447
+ if (type.isString() || type.isTemplateLiteral()) return "string";
2448
+ if (type.isNumber()) return "number";
2449
+ if (type.isBoolean()) return "boolean";
2450
+ if (type.isBigInt()) return "bigint";
2451
+ if (type.isNull()) return "null";
2452
+ if (type.isUndefined() || type.isVoid()) return "undefined";
2453
+ if (type.isBooleanLiteral()) return type.getText();
2454
+ if (type.isStringLiteral() || type.isNumberLiteral() || type.isEnumLiteral()) {
2455
+ const value = type.getLiteralValue();
2456
+ return typeof value === "string" ? JSON.stringify(value) : String(value);
2457
+ }
2458
+ if (type.isBigIntLiteral()) return type.getText();
2459
+ if (type.isTypeParameter()) return "unknown";
2460
+ if (type.isUnion()) return renderUnion(type, state, paired);
2461
+ if (type.isIntersection()) return renderIntersection(type, state);
2462
+ const next = { ...state, depth: state.depth + 1 };
2463
+ if (type.isArray() || type.isReadonlyArray()) {
2464
+ const element = type.getArrayElementType() ?? type.getTypeArguments()[0];
2465
+ const pairedElement = paired?.getArrayElementType() ?? paired?.getTypeArguments()[0];
2466
+ return element ? `Array<${render(element, next, pairedElement)}>` : "Array<unknown>";
2467
+ }
2468
+ if (type.isTuple()) {
2469
+ const elements = type.getTupleElements();
2470
+ const pairedElements = paired?.isTuple() ? paired.getTupleElements() : [];
2471
+ return `[${elements.map((e, i) => render(e, next, pairedElements[i])).join(", ")}]`;
2472
+ }
2473
+ if (type.isObject()) return renderObject(type, next, paired);
2474
+ return "unknown";
2475
+ }
2476
+ function renderUnion(type, state, paired) {
2477
+ const members = type.getUnionTypes();
2478
+ const hasTrue = members.some((m) => m.isBooleanLiteral() && m.getText() === "true");
2479
+ const hasFalse = members.some((m) => m.isBooleanLiteral() && m.getText() === "false");
2480
+ const pairedNonNull = paired?.getNonNullableType();
2481
+ const arms = [];
2482
+ let sawBoolean = false;
2483
+ let hasNull = false;
2484
+ let hasUndefined = false;
2485
+ for (const member of members) {
2486
+ if (member.isNull()) {
2487
+ hasNull = true;
2488
+ continue;
2489
+ }
2490
+ if (member.isUndefined()) {
2491
+ hasUndefined = true;
2492
+ continue;
2493
+ }
2494
+ if (member.isBooleanLiteral() && hasTrue && hasFalse) {
2495
+ if (!sawBoolean) arms.push("boolean");
2496
+ sawBoolean = true;
2497
+ continue;
2498
+ }
2499
+ arms.push(render(member, state, members.length === 1 ? paired : pairedNonNull));
2500
+ }
2501
+ if (hasNull) arms.push("null");
2502
+ if (hasUndefined) arms.push("undefined");
2503
+ const unique = [...new Set(arms)];
2504
+ if (unique.includes("unknown")) return "unknown";
2505
+ return unique.join(" | ");
2506
+ }
2507
+ function renderIntersection(type, state) {
2508
+ const members = type.getIntersectionTypes();
2509
+ const primitive = members.find((m) => !m.isObject());
2510
+ if (primitive) return render(primitive, state);
2511
+ return renderObject(type, { ...state, depth: state.depth + 1 }, void 0);
2512
+ }
2513
+ function renderObject(type, state, paired) {
2514
+ const symbol = type.getSymbol() ?? type.getAliasSymbol();
2515
+ const name = symbol?.getName();
2516
+ if (name && GLOBAL_NAMED_TYPES.has(name) && isFromDeclarationFile(symbol)) {
2517
+ const args = type.getTypeArguments();
2518
+ return args.length ? `${name}<${args.map((a) => render(a, state)).join(", ")}>` : name;
2519
+ }
2520
+ if (type.getCallSignatures().length > 0 || type.getConstructSignatures().length > 0) {
2521
+ return "unknown";
2522
+ }
2523
+ if (type.isClassOrInterface() && isFromDeclarationFile(symbol)) return "unknown";
2524
+ if (state.stack.has(type.compilerType)) return "unknown";
2525
+ const stack = new Set(state.stack).add(type.compilerType);
2526
+ const inner = { ...state, stack };
2527
+ const fields = [];
2528
+ for (const prop of orderedProperties(type)) {
2529
+ if (isSymbolKeyed(prop)) continue;
2530
+ const propName = prop.getName();
2531
+ const propT = prop.getTypeAtLocation(state.at);
2532
+ if (propT.getCallSignatures().length > 0 && !propT.isUnion()) continue;
2533
+ const pairedProp = paired?.getProperty(propName)?.getTypeAtLocation(state.at);
2534
+ const optional = isOptionalSymbol(prop) ? "?" : "";
2535
+ fields.push(`${objectKey(propName)}${optional}: ${render(propT, inner, pairedProp)}`);
2536
+ }
2537
+ const stringIndex = type.getStringIndexType();
2538
+ if (stringIndex) {
2539
+ const pairedIndex = paired?.getStringIndexType();
2540
+ const value = render(stringIndex, inner, pairedIndex);
2541
+ if (fields.length === 0) return `Record<string, ${value}>`;
2542
+ fields.push(`[key: string]: ${value}`);
2543
+ }
2544
+ return fields.length ? `{ ${fields.join("; ")} }` : "{}";
2545
+ }
2546
+ function stateAt(at) {
2547
+ return { at, stack: /* @__PURE__ */ new Set(), depth: 0 };
2548
+ }
2549
+ function requestTypeOf(types) {
2550
+ return render(types.input, stateAt(types.at), types.output);
2551
+ }
2552
+ function responseTypeOf(types) {
2553
+ return render(types.output, stateAt(types.at));
2554
+ }
2555
+ function requestFieldsOf(types) {
2556
+ const { input, output, at } = types;
2557
+ const objectInput = input.getNonNullableType();
2558
+ if (!objectInput.isObject() || objectInput.isArray() || objectInput.isTuple()) return null;
2559
+ const state = stateAt(at);
2560
+ return orderedProperties(objectInput).filter((prop) => !isSymbolKeyed(prop)).map((prop) => ({
2561
+ name: prop.getName(),
2562
+ type: render(
2563
+ prop.getTypeAtLocation(at),
2564
+ state,
2565
+ output.getProperty(prop.getName())?.getTypeAtLocation(at)
2566
+ ),
2567
+ optional: isOptionalSymbol(prop)
2568
+ }));
2569
+ }
2570
+ function acceptsUndefined(types) {
2571
+ const { input, output } = types;
2572
+ const accepted = isAnyOrUnknown(input) ? output : input;
2573
+ if (isAnyOrUnknown(accepted) || accepted.isUndefined()) return true;
2574
+ return accepted.isUnion() && accepted.getUnionTypes().some((t) => t.isUndefined());
2575
+ }
2576
+
2577
+ // src/discovery/zod-ast-to-ts.ts
2578
+ import { Node as Node8, SyntaxKind as SyntaxKind3 } from "ts-morph";
2579
+ function zodAstToTs(node) {
2580
+ if (!Node8.isCallExpression(node)) return "unknown";
2581
+ const expr = node.getExpression();
2582
+ if (Node8.isPropertyAccessExpression(expr)) {
2583
+ const methodName = expr.getName();
2584
+ const receiver = expr.getExpression();
2585
+ if (methodName === "optional") {
2586
+ return `${zodAstToTs(receiver)} | undefined`;
2587
+ }
2588
+ if (methodName === "nullable") {
2589
+ return `${zodAstToTs(receiver)} | null`;
2590
+ }
2591
+ const args = node.getArguments();
2592
+ switch (methodName) {
2593
+ case "string":
2594
+ return "string";
2595
+ case "number":
2596
+ return "number";
2597
+ case "boolean":
2598
+ return "boolean";
2599
+ case "unknown":
2600
+ return "unknown";
2601
+ case "any":
2602
+ return "unknown";
2603
+ case "literal": {
2604
+ const lit = args[0];
2605
+ if (!lit) return "unknown";
2606
+ if (Node8.isStringLiteral(lit)) return JSON.stringify(lit.getLiteralValue());
2607
+ if (Node8.isNumericLiteral(lit)) return lit.getLiteralValue().toString();
2608
+ if (lit.getKind() === SyntaxKind3.TrueKeyword) return "true";
2609
+ if (lit.getKind() === SyntaxKind3.FalseKeyword) return "false";
2610
+ return "unknown";
2611
+ }
2612
+ case "enum": {
2613
+ const arrArg = args[0];
2614
+ if (!arrArg || !Node8.isArrayLiteralExpression(arrArg)) return "unknown";
2615
+ const members = arrArg.getElements().map(
2616
+ (el) => Node8.isStringLiteral(el) ? JSON.stringify(el.getLiteralValue()) : "unknown"
2617
+ );
2618
+ return members.join(" | ");
2619
+ }
2620
+ case "array": {
2621
+ const inner = args[0];
2622
+ if (!inner) return "unknown";
2623
+ return `Array<${zodAstToTs(inner)}>`;
2624
+ }
2625
+ case "object": {
2626
+ const objArg = args[0];
2627
+ if (!objArg || !Node8.isObjectLiteralExpression(objArg)) return "unknown";
2628
+ const lines = [];
2629
+ for (const prop of objArg.getProperties()) {
2630
+ if (!Node8.isPropertyAssignment(prop)) continue;
2631
+ const key = prop.getName();
2632
+ const valNode = prop.getInitializer();
2633
+ if (!valNode) continue;
2634
+ const tsType = zodAstToTs(valNode);
2635
+ const isOpt = isOptionalChain(valNode);
2636
+ lines.push(`${key}${isOpt ? "?" : ""}: ${tsType}`);
2637
+ }
2638
+ return `{ ${lines.join("; ")} }`;
2639
+ }
2640
+ case "union": {
2641
+ const arrArg = args[0];
2642
+ if (!arrArg || !Node8.isArrayLiteralExpression(arrArg)) return "unknown";
2643
+ return arrArg.getElements().map(zodAstToTs).join(" | ");
2644
+ }
2645
+ case "record": {
2646
+ const valArg = args.length === 1 ? args[0] : args[1];
2647
+ if (!valArg) return "unknown";
2648
+ return `Record<string, ${zodAstToTs(valArg)}>`;
2649
+ }
2650
+ case "tuple": {
2651
+ const arrArg = args[0];
2652
+ if (!arrArg || !Node8.isArrayLiteralExpression(arrArg)) return "unknown";
2653
+ return `[${arrArg.getElements().map(zodAstToTs).join(", ")}]`;
2654
+ }
2655
+ default:
2656
+ return "unknown";
2657
+ }
2658
+ }
2659
+ return "unknown";
2660
+ }
2661
+ function isOptionalChain(node) {
2662
+ if (!Node8.isCallExpression(node)) return false;
2663
+ const expr = node.getExpression();
2664
+ return Node8.isPropertyAccessExpression(expr) && expr.getName() === "optional";
2665
+ }
2666
+ function memberType(val, position, project) {
2667
+ if (project) {
2668
+ const inferred = inferSchema(val, project);
2669
+ if (inferred.kind === "schema") {
2670
+ return position === "request" ? requestTypeOf(inferred.types) : responseTypeOf(inferred.types);
2671
+ }
2672
+ }
2673
+ return zodAstToTs(val);
2674
+ }
2675
+ function parseDefineContractCall(callExpr, project) {
2676
+ if (!Node8.isCallExpression(callExpr)) return null;
2677
+ const callee = callExpr.getExpression();
2678
+ const calleeName = Node8.isIdentifier(callee) ? callee.getText() : Node8.isPropertyAccessExpression(callee) ? callee.getName() : "";
2679
+ if (calleeName !== "defineContract") return null;
2680
+ const args = callExpr.getArguments();
2681
+ const optsArg = args[0];
2682
+ if (!optsArg || !Node8.isObjectLiteralExpression(optsArg)) return null;
2683
+ let query = null;
2684
+ let body = null;
2685
+ let response = "unknown";
2686
+ let error = null;
2687
+ let bodyZodText = null;
2688
+ let queryZodText = null;
2689
+ for (const prop of optsArg.getProperties()) {
2690
+ if (!Node8.isPropertyAssignment(prop)) continue;
2691
+ const propName = prop.getName();
2692
+ const val = prop.getInitializer();
2693
+ if (!val) continue;
2694
+ if (propName === "query") {
2695
+ query = memberType(val, "request", project);
2696
+ queryZodText = val.getText();
2697
+ } else if (propName === "body") {
2698
+ body = memberType(val, "request", project);
2699
+ bodyZodText = val.getText();
2700
+ } else if (propName === "response") {
2701
+ response = memberType(val, "response", project);
2702
+ } else if (propName === "error") {
2703
+ error = memberType(val, "response", project);
2704
+ }
2705
+ }
2706
+ return { query, body, response, error, bodyZodText, queryZodText };
2707
+ }
2708
+
2709
+ // src/discovery/pipe-schema.ts
2710
+ function pipeSchemaOf(decorator, project) {
2711
+ for (const pipe of decorator.getArguments()) {
2712
+ if (!Node9.isNewExpression(pipe) && !Node9.isCallExpression(pipe)) continue;
2713
+ for (const arg of pipe.getArguments()) {
2714
+ if (!couldBeSchema(arg)) continue;
2715
+ const inferred = inferSchema(arg, project);
2716
+ if (inferred.kind === "schema") {
2717
+ return {
2718
+ type: requestTypeOf(inferred.types),
2719
+ optional: acceptsUndefined(inferred.types),
2720
+ fields: requestFieldsOf(inferred.types)
2721
+ };
2722
+ }
2723
+ if (inferred.kind === "unresolved") {
2724
+ const fallback = syntacticZodType(arg, project);
2725
+ if (fallback) {
2726
+ return { type: fallback, optional: fallback.endsWith("| undefined"), fields: null };
2727
+ }
2728
+ }
2729
+ }
2730
+ }
2731
+ return null;
2732
+ }
2733
+ function couldBeSchema(arg) {
2734
+ return Node9.isIdentifier(arg) || Node9.isPropertyAccessExpression(arg) || Node9.isCallExpression(arg) || Node9.isAsExpression(arg) || Node9.isSatisfiesExpression(arg) || Node9.isParenthesizedExpression(arg);
2735
+ }
2736
+ function syntacticZodType(arg, project) {
2737
+ let expr = arg;
2738
+ if (Node9.isIdentifier(arg)) {
2739
+ const resolved = resolveImportedVariable(arg.getText(), arg.getSourceFile(), project);
2740
+ expr = resolved?.decl.getInitializer();
2741
+ }
2742
+ if (!expr || !Node9.isCallExpression(expr)) return null;
2743
+ const type = zodAstToTs(expr);
2744
+ return type === "unknown" ? null : type;
2745
+ }
2746
+
2079
2747
  // src/discovery/dto-type-resolver.ts
2080
2748
  var WRAPPER_TYPES = {
2081
2749
  // MikroORM Ref/Reference/LoadedReference/IdentifiedReference are server-side
@@ -2107,22 +2775,22 @@ var PASSTHROUGH_UTILITY = /* @__PURE__ */ new Set([
2107
2775
  ]);
2108
2776
  function resolveTypeNodeToString(typeNode, sourceFile, project, depth, subst = /* @__PURE__ */ new Map()) {
2109
2777
  if (depth <= 0) return "unknown";
2110
- if (Node7.isArrayTypeNode(typeNode)) {
2778
+ if (Node10.isArrayTypeNode(typeNode)) {
2111
2779
  const elementType = typeNode.getElementTypeNode();
2112
2780
  return `Array<${resolveTypeNodeToString(elementType, sourceFile, project, depth, subst)}>`;
2113
2781
  }
2114
- if (Node7.isUnionTypeNode(typeNode)) {
2782
+ if (Node10.isUnionTypeNode(typeNode)) {
2115
2783
  return typeNode.getTypeNodes().map((t) => resolveTypeNodeToString(t, sourceFile, project, depth, subst)).join(" | ");
2116
2784
  }
2117
- if (Node7.isIntersectionTypeNode(typeNode)) {
2785
+ if (Node10.isIntersectionTypeNode(typeNode)) {
2118
2786
  return typeNode.getTypeNodes().map((t) => resolveTypeNodeToString(t, sourceFile, project, depth, subst)).join(" & ");
2119
2787
  }
2120
- if (Node7.isParenthesizedTypeNode(typeNode)) {
2788
+ if (Node10.isParenthesizedTypeNode(typeNode)) {
2121
2789
  return `(${resolveTypeNodeToString(typeNode.getTypeNode(), sourceFile, project, depth, subst)})`;
2122
2790
  }
2123
- if (Node7.isTypeReference(typeNode)) {
2791
+ if (Node10.isTypeReference(typeNode)) {
2124
2792
  const typeName = typeNode.getTypeName();
2125
- const name = Node7.isIdentifier(typeName) ? typeName.getText() : typeNode.getText();
2793
+ const name = Node10.isIdentifier(typeName) ? typeName.getText() : typeNode.getText();
2126
2794
  const bound = subst.get(name);
2127
2795
  if (bound !== void 0) return bound;
2128
2796
  if (name === "string" || name === "number" || name === "boolean") return name;
@@ -2145,13 +2813,13 @@ function resolveTypeNodeToString(typeNode, sourceFile, project, depth, subst = /
2145
2813
  dbg("unresolvable type:", name, "in", sourceFile.getFilePath());
2146
2814
  return "unknown";
2147
2815
  }
2148
- if (Node7.isTypeLiteral(typeNode)) {
2816
+ if (Node10.isTypeLiteral(typeNode)) {
2149
2817
  const members = [];
2150
2818
  for (const member of typeNode.getMembers()) {
2151
- if (Node7.isPropertySignature(member)) {
2819
+ if (Node10.isPropertySignature(member)) {
2152
2820
  const memberTypeNode = member.getTypeNode();
2153
- const memberType = memberTypeNode ? resolveTypeNodeToString(memberTypeNode, sourceFile, project, depth, subst) : "unknown";
2154
- members.push(`${member.getName()}${member.hasQuestionToken() ? "?" : ""}: ${memberType}`);
2821
+ const memberType2 = memberTypeNode ? resolveTypeNodeToString(memberTypeNode, sourceFile, project, depth, subst) : "unknown";
2822
+ members.push(`${member.getName()}${member.hasQuestionToken() ? "?" : ""}: ${memberType2}`);
2155
2823
  } else {
2156
2824
  members.push(member.getText());
2157
2825
  }
@@ -2159,11 +2827,11 @@ function resolveTypeNodeToString(typeNode, sourceFile, project, depth, subst = /
2159
2827
  return members.length > 0 ? `{ ${members.join("; ")} }` : "{}";
2160
2828
  }
2161
2829
  const kind = typeNode.getKind();
2162
- if (kind === SyntaxKind3.StringKeyword) return "string";
2163
- if (kind === SyntaxKind3.NumberKeyword) return "number";
2164
- if (kind === SyntaxKind3.BooleanKeyword) return "boolean";
2165
- if (kind === SyntaxKind3.UnknownKeyword) return "unknown";
2166
- if (kind === SyntaxKind3.AnyKeyword) return "unknown";
2830
+ if (kind === SyntaxKind4.StringKeyword) return "string";
2831
+ if (kind === SyntaxKind4.NumberKeyword) return "number";
2832
+ if (kind === SyntaxKind4.BooleanKeyword) return "boolean";
2833
+ if (kind === SyntaxKind4.UnknownKeyword) return "unknown";
2834
+ if (kind === SyntaxKind4.AnyKeyword) return "unknown";
2167
2835
  return typeNode.getText();
2168
2836
  }
2169
2837
  function unwrapFirstTypeArg(typeNode, sourceFile, project, depth, mode, subst = /* @__PURE__ */ new Map()) {
@@ -2211,20 +2879,24 @@ function resolvePropertied(decl, sourceFile, project, depth, subst = /* @__PURE_
2211
2879
  const propName = prop.getName();
2212
2880
  const isOptional = prop.hasQuestionToken();
2213
2881
  const propTypeNode = prop.getTypeNode();
2214
- let propType = "unknown";
2882
+ let propType2 = "unknown";
2215
2883
  if (propTypeNode) {
2216
- propType = resolveTypeNodeToString(propTypeNode, sourceFile, project, depth, subst);
2884
+ propType2 = resolveTypeNodeToString(propTypeNode, sourceFile, project, depth, subst);
2217
2885
  }
2218
- lines.push(`${propName}${isOptional ? "?" : ""}: ${propType}`);
2886
+ lines.push(`${propName}${isOptional ? "?" : ""}: ${propType2}`);
2219
2887
  }
2220
2888
  return `{ ${lines.join("; ")} }`;
2221
2889
  }
2890
+ function namedField(decorator) {
2891
+ const first = decorator.getArguments()[0];
2892
+ return first && Node10.isStringLiteral(first) ? first.getLiteralValue() : null;
2893
+ }
2222
2894
  function extractBodyType(method, sourceFile, project) {
2223
2895
  for (const param of method.getParameters()) {
2224
2896
  const bodyDecorator = param.getDecorators().find((d) => d.getName() === "Body");
2225
- if (!bodyDecorator) continue;
2226
- const bodyArgs = bodyDecorator.getArguments();
2227
- if (bodyArgs.length > 0) continue;
2897
+ if (!bodyDecorator || namedField(bodyDecorator) !== null) continue;
2898
+ const piped = pipeSchemaOf(bodyDecorator, project);
2899
+ if (piped) return piped.type;
2228
2900
  const typeNode = param.getTypeNode();
2229
2901
  if (typeNode) {
2230
2902
  return resolveTypeNodeToString(typeNode, sourceFile, project, 3);
@@ -2232,11 +2904,16 @@ function extractBodyType(method, sourceFile, project) {
2232
2904
  }
2233
2905
  return null;
2234
2906
  }
2907
+ function hasPipeSchema(param, decoratorName, project) {
2908
+ const decorator = param.getDecorators().find((d) => d.getName() === decoratorName);
2909
+ return !!decorator && pipeSchemaOf(decorator, project) !== null;
2910
+ }
2235
2911
  function extractQueryType(method, sourceFile, project) {
2236
2912
  for (const param of method.getParameters()) {
2237
2913
  const queryDecorator = param.getDecorators().find((d) => d.getName() === "Query");
2238
- if (!queryDecorator) continue;
2239
- if (queryDecorator.getArguments().length > 0) continue;
2914
+ if (!queryDecorator || namedField(queryDecorator) !== null) continue;
2915
+ const piped = pipeSchemaOf(queryDecorator, project);
2916
+ if (piped) return piped.type;
2240
2917
  const typeNode = param.getTypeNode();
2241
2918
  if (typeNode) {
2242
2919
  return resolveTypeNodeToString(typeNode, sourceFile, project, 3);
@@ -2246,10 +2923,13 @@ function extractQueryType(method, sourceFile, project) {
2246
2923
  for (const param of method.getParameters()) {
2247
2924
  const queryDecorator = param.getDecorators().find((d) => d.getName() === "Query");
2248
2925
  if (!queryDecorator) continue;
2249
- const queryArgs = queryDecorator.getArguments();
2250
- const nameArg = queryArgs[0];
2251
- if (!nameArg || !Node7.isStringLiteral(nameArg)) continue;
2252
- const queryName = nameArg.getLiteralValue();
2926
+ const queryName = namedField(queryDecorator);
2927
+ if (queryName === null) continue;
2928
+ const piped = pipeSchemaOf(queryDecorator, project);
2929
+ if (piped) {
2930
+ entries.push(`${queryName}${piped.optional ? "?" : ""}: ${piped.type}`);
2931
+ continue;
2932
+ }
2253
2933
  const typeNode = param.getTypeNode();
2254
2934
  const queryType = typeNode ? resolveTypeNodeToString(typeNode, sourceFile, project, 3) : "string";
2255
2935
  entries.push(`${queryName}${isParamOptional(param) ? "?" : ""}: ${queryType}`);
@@ -2259,8 +2939,8 @@ function extractQueryType(method, sourceFile, project) {
2259
2939
  function isParamOptional(param) {
2260
2940
  if (param.hasQuestionToken() || param.hasInitializer()) return true;
2261
2941
  const typeNode = param.getTypeNode();
2262
- if (typeNode && Node7.isUnionTypeNode(typeNode)) {
2263
- return typeNode.getTypeNodes().some((t) => t.getKind() === SyntaxKind3.UndefinedKeyword);
2942
+ if (typeNode && Node10.isUnionTypeNode(typeNode)) {
2943
+ return typeNode.getTypeNodes().some((t) => t.getKind() === SyntaxKind4.UndefinedKeyword);
2264
2944
  }
2265
2945
  return false;
2266
2946
  }
@@ -2272,7 +2952,7 @@ function extractParamsType(method, sourceFile, project) {
2272
2952
  const paramArgs = paramDecorator.getArguments();
2273
2953
  if (paramArgs.length === 0) continue;
2274
2954
  const nameArg = paramArgs[0];
2275
- if (!Node7.isStringLiteral(nameArg)) continue;
2955
+ if (!Node10.isStringLiteral(nameArg)) continue;
2276
2956
  const paramName = nameArg.getLiteralValue();
2277
2957
  const typeNode = param.getTypeNode();
2278
2958
  const paramType = typeNode ? resolveTypeNodeToString(typeNode, sourceFile, project, 3) : "string";
@@ -2280,6 +2960,22 @@ function extractParamsType(method, sourceFile, project) {
2280
2960
  }
2281
2961
  return entries.length > 0 ? `{ ${entries.join("; ")} }` : null;
2282
2962
  }
2963
+ function extractPipedParamTypes(method, project) {
2964
+ const types = {};
2965
+ for (const param of method.getParameters()) {
2966
+ const paramDecorator = param.getDecorators().find((d) => d.getName() === "Param");
2967
+ if (!paramDecorator) continue;
2968
+ const piped = pipeSchemaOf(paramDecorator, project);
2969
+ if (!piped) continue;
2970
+ const name = namedField(paramDecorator);
2971
+ if (name !== null) {
2972
+ types[name] = piped.type;
2973
+ } else {
2974
+ for (const field of piped.fields ?? []) types[field.name] = field.type;
2975
+ }
2976
+ }
2977
+ return Object.keys(types).length > 0 ? types : null;
2978
+ }
2283
2979
  function extractUploadedFiles(method) {
2284
2980
  const FILE = "File | Blob";
2285
2981
  const entries = [];
@@ -2293,28 +2989,28 @@ function extractUploadedFiles(method) {
2293
2989
  for (const decorator of method.getDecorators()) {
2294
2990
  if (decorator.getName() !== "UseInterceptors") continue;
2295
2991
  for (const arg of decorator.getArguments()) {
2296
- if (!Node7.isCallExpression(arg)) continue;
2992
+ if (!Node10.isCallExpression(arg)) continue;
2297
2993
  const interceptor = arg.getExpression().getText();
2298
2994
  const callArgs = arg.getArguments();
2299
2995
  const firstArg2 = callArgs[0];
2300
2996
  if (interceptor === "FileInterceptor") {
2301
- if (firstArg2 && Node7.isStringLiteral(firstArg2)) {
2997
+ if (firstArg2 && Node10.isStringLiteral(firstArg2)) {
2302
2998
  entries.push(`${firstArg2.getLiteralValue()}: ${FILE}`);
2303
2999
  multipart = true;
2304
3000
  }
2305
3001
  } else if (interceptor === "FilesInterceptor") {
2306
- if (firstArg2 && Node7.isStringLiteral(firstArg2)) {
3002
+ if (firstArg2 && Node10.isStringLiteral(firstArg2)) {
2307
3003
  entries.push(`${firstArg2.getLiteralValue()}: Array<${FILE}>`);
2308
3004
  multipart = true;
2309
3005
  }
2310
3006
  } else if (interceptor === "FileFieldsInterceptor") {
2311
- if (firstArg2 && Node7.isArrayLiteralExpression(firstArg2)) {
3007
+ if (firstArg2 && Node10.isArrayLiteralExpression(firstArg2)) {
2312
3008
  for (const el of firstArg2.getElements()) {
2313
- if (!Node7.isObjectLiteralExpression(el)) continue;
3009
+ if (!Node10.isObjectLiteralExpression(el)) continue;
2314
3010
  const nameProp = el.getProperty("name");
2315
- if (nameProp && Node7.isPropertyAssignment(nameProp)) {
3011
+ if (nameProp && Node10.isPropertyAssignment(nameProp)) {
2316
3012
  const init = nameProp.getInitializer();
2317
- if (init && Node7.isStringLiteral(init)) {
3013
+ if (init && Node10.isStringLiteral(init)) {
2318
3014
  entries.push(`${init.getLiteralValue()}: Array<${FILE}>`);
2319
3015
  }
2320
3016
  }
@@ -2334,13 +3030,13 @@ function extractResponseType(method, sourceFile, project) {
2334
3030
  if (apiResponseDecorator) {
2335
3031
  const args = apiResponseDecorator.getArguments();
2336
3032
  const optsArg = args[0];
2337
- if (optsArg && Node7.isObjectLiteralExpression(optsArg)) {
3033
+ if (optsArg && Node10.isObjectLiteralExpression(optsArg)) {
2338
3034
  for (const prop of optsArg.getProperties()) {
2339
- if (!Node7.isPropertyAssignment(prop)) continue;
3035
+ if (!Node10.isPropertyAssignment(prop)) continue;
2340
3036
  if (prop.getName() !== "type") continue;
2341
3037
  const val = prop.getInitializer();
2342
3038
  if (!val) continue;
2343
- if (Node7.isArrayLiteralExpression(val)) {
3039
+ if (Node10.isArrayLiteralExpression(val)) {
2344
3040
  const elements = val.getElements();
2345
3041
  const firstEl = elements[0];
2346
3042
  if (elements.length > 0 && firstEl !== void 0) {
@@ -2361,24 +3057,24 @@ function extractResponseType(method, sourceFile, project) {
2361
3057
  }
2362
3058
  function apiResponseStatus(decorator) {
2363
3059
  const optsArg = decorator.getArguments()[0];
2364
- if (!optsArg || !Node7.isObjectLiteralExpression(optsArg)) return null;
3060
+ if (!optsArg || !Node10.isObjectLiteralExpression(optsArg)) return null;
2365
3061
  for (const prop of optsArg.getProperties()) {
2366
- if (!Node7.isPropertyAssignment(prop)) continue;
3062
+ if (!Node10.isPropertyAssignment(prop)) continue;
2367
3063
  if (prop.getName() !== "status") continue;
2368
3064
  const val = prop.getInitializer();
2369
- if (val && Node7.isNumericLiteral(val)) return Number(val.getLiteralValue());
3065
+ if (val && Node10.isNumericLiteral(val)) return Number(val.getLiteralValue());
2370
3066
  }
2371
3067
  return null;
2372
3068
  }
2373
3069
  function apiResponseTypeNode(decorator) {
2374
3070
  const optsArg = decorator.getArguments()[0];
2375
- if (!optsArg || !Node7.isObjectLiteralExpression(optsArg)) return null;
3071
+ if (!optsArg || !Node10.isObjectLiteralExpression(optsArg)) return null;
2376
3072
  for (const prop of optsArg.getProperties()) {
2377
- if (!Node7.isPropertyAssignment(prop)) continue;
3073
+ if (!Node10.isPropertyAssignment(prop)) continue;
2378
3074
  if (prop.getName() !== "type") continue;
2379
3075
  const val = prop.getInitializer();
2380
3076
  if (!val) return null;
2381
- if (Node7.isArrayLiteralExpression(val)) {
3077
+ if (Node10.isArrayLiteralExpression(val)) {
2382
3078
  const first = val.getElements()[0];
2383
3079
  return first ? { node: first, isArray: true } : null;
2384
3080
  }
@@ -2396,7 +3092,7 @@ function extractErrorType(method, sourceFile, project) {
2396
3092
  const inner = resolveIdentifierToClassType(typeInfo.node, sourceFile, project, 3);
2397
3093
  const type = typeInfo.isArray ? `Array<${inner}>` : inner;
2398
3094
  let ref = null;
2399
- if (Node7.isIdentifier(typeInfo.node)) {
3095
+ if (Node10.isIdentifier(typeInfo.node)) {
2400
3096
  const name = typeInfo.node.getText();
2401
3097
  const localDecl = sourceFile.getInterface(name) || sourceFile.getClass(name) || sourceFile.getTypeAlias(name);
2402
3098
  if (localDecl?.isExported()) {
@@ -2413,7 +3109,7 @@ function extractErrorType(method, sourceFile, project) {
2413
3109
  return null;
2414
3110
  }
2415
3111
  function resolveIdentifierToClassType(node, sourceFile, project, depth) {
2416
- if (!Node7.isIdentifier(node)) return "unknown";
3112
+ if (!Node10.isIdentifier(node)) return "unknown";
2417
3113
  const name = node.getText();
2418
3114
  const resolved = findType(name, sourceFile, project);
2419
3115
  if (resolved) {
@@ -2433,9 +3129,9 @@ var STREAM_ENVELOPES = /* @__PURE__ */ new Set(["MessageEvent", "MessageEventLik
2433
3129
  var BINARY_RESPONSE_TYPES = /* @__PURE__ */ new Set(["StreamableFile", "Buffer"]);
2434
3130
  function detectBinaryResponse(method) {
2435
3131
  const node = unwrapNamedContainer(method.getReturnTypeNode(), /* @__PURE__ */ new Set(["Promise"]));
2436
- if (!node || !Node7.isTypeReference(node)) return false;
3132
+ if (!node || !Node10.isTypeReference(node)) return false;
2437
3133
  const typeName = node.getTypeName();
2438
- const name = Node7.isIdentifier(typeName) ? typeName.getText() : "";
3134
+ const name = Node10.isIdentifier(typeName) ? typeName.getText() : "";
2439
3135
  return BINARY_RESPONSE_TYPES.has(name);
2440
3136
  }
2441
3137
  function detectStreamElement(method) {
@@ -2450,9 +3146,9 @@ function detectStreamElement(method) {
2450
3146
  return null;
2451
3147
  }
2452
3148
  function streamContainerElement(node) {
2453
- if (!node || !Node7.isTypeReference(node)) return null;
3149
+ if (!node || !Node10.isTypeReference(node)) return null;
2454
3150
  const typeName = node.getTypeName();
2455
- const name = Node7.isIdentifier(typeName) ? typeName.getText() : "";
3151
+ const name = Node10.isIdentifier(typeName) ? typeName.getText() : "";
2456
3152
  if (STREAM_CONTAINERS.has(name) || STREAM_CONTAINERS_GENERATOR.has(name)) {
2457
3153
  return node.getTypeArguments()[0] ?? null;
2458
3154
  }
@@ -2462,9 +3158,9 @@ function hasAsQueryDecorator(method) {
2462
3158
  return method.getDecorators().some((d) => d.getName() === "AsQuery");
2463
3159
  }
2464
3160
  function unwrapNamedContainer(node, names) {
2465
- if (!node || !Node7.isTypeReference(node)) return node;
3161
+ if (!node || !Node10.isTypeReference(node)) return node;
2466
3162
  const typeName = node.getTypeName();
2467
- const name = Node7.isIdentifier(typeName) ? typeName.getText() : "";
3163
+ const name = Node10.isIdentifier(typeName) ? typeName.getText() : "";
2468
3164
  if (names.has(name)) {
2469
3165
  return node.getTypeArguments()[0] ?? node;
2470
3166
  }
@@ -2485,19 +3181,20 @@ function extractDtoContract(method, sourceFile, project, mixin, controllerClass)
2485
3181
  body = body ?? bodyType;
2486
3182
  }
2487
3183
  const paramsType = extractParamsType(method, sourceFile, project);
3184
+ const paramTypes = extractPipedParamTypes(method, project);
2488
3185
  const response = isStream ? resolveTypeNodeToString(streamElement, sourceFile, project, 3) : extractResponseType(method, sourceFile, project);
2489
3186
  const errorInfo = extractErrorType(method, sourceFile, project);
2490
- if (body === null && query === null && paramsType === null && response === "unknown" && errorInfo === null && filterInfo === null && !isStream && !uploads.multipart && !binaryResponse && !asQuery) {
3187
+ if (body === null && query === null && paramsType === null && paramTypes === null && response === "unknown" && errorInfo === null && filterInfo === null && !isStream && !uploads.multipart && !binaryResponse && !asQuery) {
2491
3188
  return null;
2492
3189
  }
2493
3190
  let bodyRef = null;
2494
3191
  let queryRef = null;
2495
3192
  let responseRef = null;
2496
3193
  for (const param of method.getParameters()) {
2497
- if (param.getDecorators().some((d) => d.getName() === "Body") && param.getTypeNode()) {
3194
+ if (param.getDecorators().some((d) => d.getName() === "Body") && param.getTypeNode() && !hasPipeSchema(param, "Body", project)) {
2498
3195
  bodyRef = resolveBodyQueryResponseRef(param.getTypeNode(), sourceFile, project);
2499
3196
  }
2500
- if (param.getDecorators().some((d) => d.getName() === "Query") && param.getTypeNode()) {
3197
+ if (param.getDecorators().some((d) => d.getName() === "Query") && param.getTypeNode() && !hasPipeSchema(param, "Query", project)) {
2501
3198
  queryRef = resolveBodyQueryResponseRef(param.getTypeNode(), sourceFile, project);
2502
3199
  }
2503
3200
  }
@@ -2510,11 +3207,11 @@ function extractDtoContract(method, sourceFile, project, mixin, controllerClass)
2510
3207
  if (apiResp) {
2511
3208
  const args = apiResp.getArguments();
2512
3209
  const optsArg = args[0];
2513
- if (optsArg && Node7.isObjectLiteralExpression(optsArg)) {
3210
+ if (optsArg && Node10.isObjectLiteralExpression(optsArg)) {
2514
3211
  for (const prop of optsArg.getProperties()) {
2515
- if (Node7.isPropertyAssignment(prop) && prop.getName() === "type") {
3212
+ if (Node10.isPropertyAssignment(prop) && prop.getName() === "type") {
2516
3213
  const val = prop.getInitializer();
2517
- if (val && Node7.isIdentifier(val)) {
3214
+ if (val && Node10.isIdentifier(val)) {
2518
3215
  const name = val.getText();
2519
3216
  const localDecl = sourceFile.getInterface(name) || sourceFile.getClass(name) || sourceFile.getTypeAlias(name);
2520
3217
  if (localDecl?.isExported()) {
@@ -2550,6 +3247,7 @@ function extractDtoContract(method, sourceFile, project, mixin, controllerClass)
2550
3247
  response,
2551
3248
  error: errorInfo?.type ?? null,
2552
3249
  params: paramsType,
3250
+ paramTypes,
2553
3251
  queryRef,
2554
3252
  bodyRef,
2555
3253
  responseRef,
@@ -2570,6 +3268,7 @@ function extractDtoContract(method, sourceFile, project, mixin, controllerClass)
2570
3268
  function resolveParamClass(method, decoratorName, sourceFile, project) {
2571
3269
  for (const param of method.getParameters()) {
2572
3270
  if (!param.getDecorators().some((d) => d.getName() === decoratorName)) continue;
3271
+ if (hasPipeSchema(param, decoratorName, project)) continue;
2573
3272
  const typeNode = param.getTypeNode();
2574
3273
  if (!typeNode) continue;
2575
3274
  const text = typeNode.getText().replace(/\[\]$/, "");
@@ -2582,129 +3281,6 @@ function resolveParamClass(method, decoratorName, sourceFile, project) {
2582
3281
  return null;
2583
3282
  }
2584
3283
 
2585
- // src/discovery/zod-ast-to-ts.ts
2586
- import { Node as Node8, SyntaxKind as SyntaxKind4 } from "ts-morph";
2587
- function zodAstToTs(node) {
2588
- if (!Node8.isCallExpression(node)) return "unknown";
2589
- const expr = node.getExpression();
2590
- if (Node8.isPropertyAccessExpression(expr)) {
2591
- const methodName = expr.getName();
2592
- const receiver = expr.getExpression();
2593
- if (methodName === "optional") {
2594
- return `${zodAstToTs(receiver)} | undefined`;
2595
- }
2596
- if (methodName === "nullable") {
2597
- return `${zodAstToTs(receiver)} | null`;
2598
- }
2599
- const args = node.getArguments();
2600
- switch (methodName) {
2601
- case "string":
2602
- return "string";
2603
- case "number":
2604
- return "number";
2605
- case "boolean":
2606
- return "boolean";
2607
- case "unknown":
2608
- return "unknown";
2609
- case "any":
2610
- return "unknown";
2611
- case "literal": {
2612
- const lit = args[0];
2613
- if (!lit) return "unknown";
2614
- if (Node8.isStringLiteral(lit)) return JSON.stringify(lit.getLiteralValue());
2615
- if (Node8.isNumericLiteral(lit)) return lit.getLiteralValue().toString();
2616
- if (lit.getKind() === SyntaxKind4.TrueKeyword) return "true";
2617
- if (lit.getKind() === SyntaxKind4.FalseKeyword) return "false";
2618
- return "unknown";
2619
- }
2620
- case "enum": {
2621
- const arrArg = args[0];
2622
- if (!arrArg || !Node8.isArrayLiteralExpression(arrArg)) return "unknown";
2623
- const members = arrArg.getElements().map(
2624
- (el) => Node8.isStringLiteral(el) ? JSON.stringify(el.getLiteralValue()) : "unknown"
2625
- );
2626
- return members.join(" | ");
2627
- }
2628
- case "array": {
2629
- const inner = args[0];
2630
- if (!inner) return "unknown";
2631
- return `Array<${zodAstToTs(inner)}>`;
2632
- }
2633
- case "object": {
2634
- const objArg = args[0];
2635
- if (!objArg || !Node8.isObjectLiteralExpression(objArg)) return "unknown";
2636
- const lines = [];
2637
- for (const prop of objArg.getProperties()) {
2638
- if (!Node8.isPropertyAssignment(prop)) continue;
2639
- const key = prop.getName();
2640
- const valNode = prop.getInitializer();
2641
- if (!valNode) continue;
2642
- const tsType = zodAstToTs(valNode);
2643
- const isOpt = isOptionalChain(valNode);
2644
- lines.push(`${key}${isOpt ? "?" : ""}: ${tsType}`);
2645
- }
2646
- return `{ ${lines.join("; ")} }`;
2647
- }
2648
- case "union": {
2649
- const arrArg = args[0];
2650
- if (!arrArg || !Node8.isArrayLiteralExpression(arrArg)) return "unknown";
2651
- return arrArg.getElements().map(zodAstToTs).join(" | ");
2652
- }
2653
- case "record": {
2654
- const valArg = args.length === 1 ? args[0] : args[1];
2655
- if (!valArg) return "unknown";
2656
- return `Record<string, ${zodAstToTs(valArg)}>`;
2657
- }
2658
- case "tuple": {
2659
- const arrArg = args[0];
2660
- if (!arrArg || !Node8.isArrayLiteralExpression(arrArg)) return "unknown";
2661
- return `[${arrArg.getElements().map(zodAstToTs).join(", ")}]`;
2662
- }
2663
- default:
2664
- return "unknown";
2665
- }
2666
- }
2667
- return "unknown";
2668
- }
2669
- function isOptionalChain(node) {
2670
- if (!Node8.isCallExpression(node)) return false;
2671
- const expr = node.getExpression();
2672
- return Node8.isPropertyAccessExpression(expr) && expr.getName() === "optional";
2673
- }
2674
- function parseDefineContractCall(callExpr) {
2675
- if (!Node8.isCallExpression(callExpr)) return null;
2676
- const callee = callExpr.getExpression();
2677
- const calleeName = Node8.isIdentifier(callee) ? callee.getText() : Node8.isPropertyAccessExpression(callee) ? callee.getName() : "";
2678
- if (calleeName !== "defineContract") return null;
2679
- const args = callExpr.getArguments();
2680
- const optsArg = args[0];
2681
- if (!optsArg || !Node8.isObjectLiteralExpression(optsArg)) return null;
2682
- let query = null;
2683
- let body = null;
2684
- let response = "unknown";
2685
- let error = null;
2686
- let bodyZodText = null;
2687
- let queryZodText = null;
2688
- for (const prop of optsArg.getProperties()) {
2689
- if (!Node8.isPropertyAssignment(prop)) continue;
2690
- const propName = prop.getName();
2691
- const val = prop.getInitializer();
2692
- if (!val) continue;
2693
- if (propName === "query") {
2694
- query = zodAstToTs(val);
2695
- queryZodText = val.getText();
2696
- } else if (propName === "body") {
2697
- body = zodAstToTs(val);
2698
- bodyZodText = val.getText();
2699
- } else if (propName === "response") {
2700
- response = zodAstToTs(val);
2701
- } else if (propName === "error") {
2702
- error = zodAstToTs(val);
2703
- }
2704
- }
2705
- return { query, body, response, error, bodyZodText, queryZodText };
2706
- }
2707
-
2708
3284
  // src/discovery/contracts-fast.ts
2709
3285
  async function discoverContractsFast(opts) {
2710
3286
  const { cwd, glob, tsconfig } = opts;
@@ -2717,7 +3293,9 @@ async function discoverContractsFast(opts) {
2717
3293
  }
2718
3294
  bindDiscoveryContext(project, cwd, tsconfigPath, loaded);
2719
3295
  clearMixinTypeProject();
2720
- return extractAllRoutes(project);
3296
+ const routes = extractAllRoutes(project);
3297
+ clearSchemaTypeProject(project);
3298
+ return routes;
2721
3299
  }
2722
3300
  function resolveTsconfigPath(cwd, tsconfig) {
2723
3301
  return tsconfig ? resolve3(tsconfig) : join4(cwd, "tsconfig.json");
@@ -2729,25 +3307,25 @@ var NO_TSCONFIG_OPTIONS = {
2729
3307
  };
2730
3308
  function loadDiscoveryTsconfig(tsconfigPath) {
2731
3309
  if (!existsSync(tsconfigPath)) return { options: null, files: [] };
2732
- const read = ts.readConfigFile(tsconfigPath, (path) => ts.sys.readFile(path));
3310
+ const read = ts3.readConfigFile(tsconfigPath, (path) => ts3.sys.readFile(path));
2733
3311
  if (read.error) {
2734
3312
  return {
2735
3313
  options: null,
2736
3314
  files: [tsconfigPath],
2737
- error: ts.flattenDiagnosticMessageText(read.error.messageText, " ")
3315
+ error: ts3.flattenDiagnosticMessageText(read.error.messageText, " ")
2738
3316
  };
2739
3317
  }
2740
3318
  const host = {
2741
- useCaseSensitiveFileNames: ts.sys.useCaseSensitiveFileNames,
3319
+ useCaseSensitiveFileNames: ts3.sys.useCaseSensitiveFileNames,
2742
3320
  // The one line that keeps a tsconfig from being a filesystem walk.
2743
3321
  readDirectory: () => [],
2744
- fileExists: (path) => ts.sys.fileExists(path),
3322
+ fileExists: (path) => ts3.sys.fileExists(path),
2745
3323
  // `extends` is resolved through the host, so a consumer whose `paths` live
2746
3324
  // in a base tsconfig keeps working.
2747
- readFile: (path) => ts.sys.readFile(path)
3325
+ readFile: (path) => ts3.sys.readFile(path)
2748
3326
  };
2749
- const sourceFile = ts.readJsonConfigFile(tsconfigPath, (path) => ts.sys.readFile(path));
2750
- const parsed = ts.parseJsonSourceFileConfigFileContent(
3327
+ const sourceFile = ts3.readJsonConfigFile(tsconfigPath, (path) => ts3.sys.readFile(path));
3328
+ const parsed = ts3.parseJsonSourceFileConfigFileContent(
2751
3329
  sourceFile,
2752
3330
  host,
2753
3331
  dirname2(tsconfigPath),
@@ -2770,7 +3348,7 @@ function createDiscoveryProject(tsconfigPath, tsconfig = loadDiscoveryTsconfig(t
2770
3348
  `[nestjs-codegen/fast] Could not load ${tsconfigPath}: ${tsconfig.error} \u2014 continuing WITHOUT its compiler options, so path alias imports (e.g. '@/...') will not resolve and controllers extending an alias-imported factory will contribute NO routes to the generated client.`
2771
3349
  );
2772
3350
  }
2773
- return new Project3({
3351
+ return new Project4({
2774
3352
  compilerOptions: tsconfig.options ?? { ...NO_TSCONFIG_OPTIONS },
2775
3353
  skipAddingFilesFromTsConfig: true,
2776
3354
  skipLoadingLibFiles: true,
@@ -2882,15 +3460,16 @@ var PersistentDiscovery = class _PersistentDiscovery {
2882
3460
  clearTypeResolutionCaches(this.project);
2883
3461
  clearEnumCache(this.project);
2884
3462
  clearMixinTypeProject();
3463
+ clearSchemaTypeProject(this.project);
2885
3464
  return extractRoutesFrom(this.project, this.controllerPaths);
2886
3465
  }
2887
3466
  };
2888
3467
  function decoratorStringArg(decoratorExpr) {
2889
3468
  if (!decoratorExpr) return void 0;
2890
- if (Node9.isStringLiteral(decoratorExpr)) return decoratorExpr.getLiteralValue();
2891
- if (Node9.isArrayLiteralExpression(decoratorExpr)) {
3469
+ if (Node11.isStringLiteral(decoratorExpr)) return decoratorExpr.getLiteralValue();
3470
+ if (Node11.isArrayLiteralExpression(decoratorExpr)) {
2892
3471
  const first = decoratorExpr.getElements()[0];
2893
- if (first && Node9.isStringLiteral(first)) return first.getLiteralValue();
3472
+ if (first && Node11.isStringLiteral(first)) return first.getLiteralValue();
2894
3473
  }
2895
3474
  return void 0;
2896
3475
  }
@@ -3011,9 +3590,9 @@ function extractContractRoute(args) {
3011
3590
  let contractDef = null;
3012
3591
  let bodyZodRef = null;
3013
3592
  let queryZodRef = null;
3014
- if (Node9.isCallExpression(firstDecoratorArg)) {
3015
- contractDef = parseDefineContractCall(firstDecoratorArg);
3016
- } else if (Node9.isIdentifier(firstDecoratorArg)) {
3593
+ if (Node11.isCallExpression(firstDecoratorArg)) {
3594
+ contractDef = parseDefineContractCall(firstDecoratorArg, project);
3595
+ } else if (Node11.isIdentifier(firstDecoratorArg)) {
3017
3596
  const identName = firstDecoratorArg.getText();
3018
3597
  const resolvedVar = resolveImportedVariable(identName, sourceFile, project);
3019
3598
  if (!resolvedVar) {
@@ -3025,7 +3604,7 @@ function extractContractRoute(args) {
3025
3604
  const { decl: varDecl, file: declFile } = resolvedVar;
3026
3605
  const initializer = varDecl.getInitializer();
3027
3606
  if (!initializer) return null;
3028
- contractDef = parseDefineContractCall(initializer);
3607
+ contractDef = parseDefineContractCall(initializer, project);
3029
3608
  if (contractDef && varDecl.isExported()) {
3030
3609
  const filePath = declFile.getFilePath();
3031
3610
  if (contractDef.body !== null) {
@@ -3096,6 +3675,7 @@ function extractDtoRoute(args) {
3096
3675
  body: dtoContract?.body ?? null,
3097
3676
  response: mixinResponse ?? dtoContract?.response ?? "unknown",
3098
3677
  error: dtoContract?.error ?? null,
3678
+ paramTypes: dtoContract?.paramTypes ?? null,
3099
3679
  queryRef: dtoContract?.queryRef ?? null,
3100
3680
  bodyRef: dtoContract?.bodyRef ?? null,
3101
3681
  responseRef: dtoContract?.responseRef ?? null,
@@ -3218,7 +3798,7 @@ function createExtensionContext(config, getRoutes, trackedInputs) {
3218
3798
  },
3219
3799
  project() {
3220
3800
  if (!project) {
3221
- project = new Project4({
3801
+ project = new Project5({
3222
3802
  skipAddingFilesFromTsConfig: true,
3223
3803
  skipLoadingLibFiles: true,
3224
3804
  skipFileDependencyResolution: true,
@@ -3336,10 +3916,11 @@ function insertIntoTree(tree, segments, leaf, fullName) {
3336
3916
  insertIntoTree(branch.children, rest, leaf, fullName);
3337
3917
  }
3338
3918
  }
3339
- function buildParamsType(params) {
3919
+ function buildParamsType(params, paramTypes) {
3340
3920
  const pathParams = params.filter((p) => p.source === "path");
3341
3921
  if (pathParams.length === 0) return "never";
3342
- return `{ ${pathParams.map((p) => `${p.name}: string`).join("; ")} }`;
3922
+ const typeOf = (name) => paramTypes && Object.hasOwn(paramTypes, name) && paramTypes[name] || "string";
3923
+ return `{ ${pathParams.map((p) => `${p.name}: ${typeOf(p.name)}`).join("; ")} }`;
3343
3924
  }
3344
3925
  function hasPathParams(params) {
3345
3926
  return params.some((p) => p.source === "path");
@@ -3433,7 +4014,7 @@ function emitRouterTypeBlock(tree, indent, outDir, serialization) {
3433
4014
  }
3434
4015
  const response = buildResponseType(c, outDir, serialization);
3435
4016
  const error = buildErrorType(c);
3436
- const params = buildParamsType(c.params);
4017
+ const params = buildParamsType(c.params, c.contractSource.paramTypes);
3437
4018
  const safeMethod = JSON.stringify(method);
3438
4019
  const safeUrl = JSON.stringify(c.path);
3439
4020
  const filterLiterals = filterFieldLiterals(c.contractSource.filterFields);
@@ -3702,6 +4283,9 @@ var EMPTY_PATH_NAMESPACE = [
3702
4283
  "}",
3703
4284
  ""
3704
4285
  ];
4286
+ function isClientCallable(route) {
4287
+ return route.method.toUpperCase() !== "ALL";
4288
+ }
3705
4289
  function buildApiFile(routes, outDir, opts = {}) {
3706
4290
  const fetcherImportPath = opts.fetcherImportPath;
3707
4291
  const serialization = opts.serialization ?? "json";
@@ -3709,7 +4293,7 @@ function buildApiFile(routes, outDir, opts = {}) {
3709
4293
  const { layer } = resolveApiSlots(extensions);
3710
4294
  const memberExts = extensions.filter((e) => e.apiMembers);
3711
4295
  const headerExts = extensions.filter((e) => e.apiHeader);
3712
- const contracted = routes.filter((r) => r.contract);
4296
+ const contracted = routes.filter((r) => r.contract && isClientCallable(r));
3713
4297
  const ctx = opts.ctx ?? {
3714
4298
  cwd: outDir ?? "",
3715
4299
  outDir: outDir ?? "",
@@ -4630,6 +5214,7 @@ function buildOpenApiSpec(routes, opts = {}) {
4630
5214
  const paths = {};
4631
5215
  for (const route of routes) {
4632
5216
  if (!route.contract) continue;
5217
+ if (route.method.toUpperCase() === "ALL") continue;
4633
5218
  const oaPath = toOpenApiPath(route.path);
4634
5219
  const method = route.method.toLowerCase();
4635
5220
  let pathItem = paths[oaPath];
@@ -5345,7 +5930,7 @@ function toObjectKey2(name) {
5345
5930
  return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name) ? name : JSON.stringify(name);
5346
5931
  }
5347
5932
  function createChainModuleRenderer(opts) {
5348
- const { render, recursiveAnnotation } = opts;
5933
+ const { render: render2, recursiveAnnotation } = opts;
5349
5934
  return (mod) => {
5350
5935
  const ctx = { named: mod.named };
5351
5936
  const recursive = mod.recursive ?? /* @__PURE__ */ new Set();
@@ -5354,7 +5939,7 @@ function createChainModuleRenderer(opts) {
5354
5939
  const namedTypeAliases = /* @__PURE__ */ new Map();
5355
5940
  const namedAnnotations = /* @__PURE__ */ new Map();
5356
5941
  for (const [name, node] of mod.named) {
5357
- namedNestedSchemas.set(name, render(node, ctx));
5942
+ namedNestedSchemas.set(name, render2(node, ctx));
5358
5943
  if (recursive.has(name)) {
5359
5944
  const typeName = typeNameFor(name);
5360
5945
  namedTypeAliases.set(name, `type ${typeName} = ${renderTsType(node, tctx)}`);
@@ -5362,7 +5947,7 @@ function createChainModuleRenderer(opts) {
5362
5947
  }
5363
5948
  }
5364
5949
  return {
5365
- schemaText: render(mod.root, ctx),
5950
+ schemaText: render2(mod.root, ctx),
5366
5951
  namedNestedSchemas,
5367
5952
  namedTypeAliases,
5368
5953
  namedAnnotations,
@@ -5372,7 +5957,7 @@ function createChainModuleRenderer(opts) {
5372
5957
  }
5373
5958
 
5374
5959
  // src/index.ts
5375
- var VERSION = "0.25.2";
5960
+ var VERSION = "0.26.0";
5376
5961
  export {
5377
5962
  CodegenError,
5378
5963
  ConfigError,