mobx-tanstack-query-api 0.37.0 → 0.38.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/cli.cjs CHANGED
@@ -219,6 +219,301 @@ const createShortModelType = (shortModelType) => {
219
219
  description: shortModelType.description || ""
220
220
  };
221
221
  };
222
+ const REF_PREFIX = "#/components/schemas/";
223
+ function parseRef(ref) {
224
+ if (typeof ref !== "string" || !ref.startsWith(REF_PREFIX)) return null;
225
+ return ref.slice(REF_PREFIX.length);
226
+ }
227
+ function getResponseSchemaKeyFromOperation(rawOperation) {
228
+ const op = rawOperation;
229
+ const responses = op?.responses;
230
+ if (!responses || typeof responses !== "object") return null;
231
+ const successStatus = Object.keys(responses).find((s) => {
232
+ const code = Number.parseInt(s, 10);
233
+ return code >= 200 && code < 300;
234
+ });
235
+ if (!successStatus) return null;
236
+ const successResponse = responses[successStatus];
237
+ const content = successResponse?.content;
238
+ if (!content || typeof content !== "object") return null;
239
+ const jsonContent = content["application/json"] ?? Object.values(content)[0];
240
+ const ref = jsonContent?.schema?.$ref;
241
+ if (typeof ref !== "string") return null;
242
+ return parseRef(ref);
243
+ }
244
+ function typeNameToSchemaKey(typeName, typeSuffix = "DC") {
245
+ const t = typeName.trim();
246
+ if (typeSuffix && t.endsWith(typeSuffix))
247
+ return t.slice(0, -typeSuffix.length);
248
+ return t;
249
+ }
250
+ function schemaToString(schema) {
251
+ let s = "z.string()";
252
+ if (schema.minLength != null) s += `.min(${schema.minLength})`;
253
+ if (schema.maxLength != null) s += `.max(${schema.maxLength})`;
254
+ if (schema.pattern != null)
255
+ s += `.regex(new RegExp(${JSON.stringify(schema.pattern)}))`;
256
+ if (schema.enum != null)
257
+ s = `z.enum([${schema.enum.map((e) => JSON.stringify(e)).join(", ")}])`;
258
+ return s;
259
+ }
260
+ function schemaToNumber(schema) {
261
+ let n = "z.number()";
262
+ if (schema.type === "integer") n += ".int()";
263
+ if (schema.minimum != null) n += `.min(${schema.minimum})`;
264
+ if (schema.maximum != null) n += `.max(${schema.maximum})`;
265
+ return n;
266
+ }
267
+ function schemaToArray(schema, schemas, schemaKeyToVarName2, visited) {
268
+ const items = schema.items ? schemaToZodExpr(schema.items, schemas, schemaKeyToVarName2) : "z.any()";
269
+ let a = `z.array(${items})`;
270
+ if (schema.minItems != null) a += `.min(${schema.minItems})`;
271
+ if (schema.maxItems != null) a += `.max(${schema.maxItems})`;
272
+ return a;
273
+ }
274
+ function schemaToObject(schema, schemas, schemaKeyToVarName2, visited) {
275
+ if (schema.properties && Object.keys(schema.properties).length > 0) {
276
+ const required = new Set(schema.required ?? []);
277
+ const entries = Object.entries(schema.properties).map(
278
+ ([propName, propSchema]) => {
279
+ const expr = schemaToZodExpr(
280
+ propSchema,
281
+ schemas,
282
+ schemaKeyToVarName2
283
+ );
284
+ const optional = !required.has(propName);
285
+ const field = optional ? `${expr}.optional()` : expr;
286
+ return ` ${JSON.stringify(propName)}: ${field}`;
287
+ }
288
+ );
289
+ return `z.object({
290
+ ${entries.join(",\n")}
291
+ })`;
292
+ }
293
+ if (schema.additionalProperties === true)
294
+ return "z.record(z.string(), z.any())";
295
+ if (typeof schema.additionalProperties === "object") {
296
+ const value = schemaToZodExpr(
297
+ schema.additionalProperties,
298
+ schemas,
299
+ schemaKeyToVarName2
300
+ );
301
+ return `z.record(z.string(), ${value})`;
302
+ }
303
+ return "z.record(z.string(), z.any())";
304
+ }
305
+ function schemaToZodExpr(schema, schemas, schemaKeyToVarName2, visited) {
306
+ if (!schema) return "z.any()";
307
+ if (schema.$ref) {
308
+ const key = parseRef(schema.$ref);
309
+ if (key && key in schemas)
310
+ return `z.lazy(() => ${schemaKeyToVarName2(key)})`;
311
+ return "z.any()";
312
+ }
313
+ if (schema.allOf && schema.allOf.length > 0) {
314
+ const parts = schema.allOf.map(
315
+ (part) => schemaToZodExpr(part, schemas, schemaKeyToVarName2)
316
+ );
317
+ const base2 = parts.length === 1 ? parts[0] : parts.reduce((acc, p) => `z.intersection(${acc}, ${p})`);
318
+ return schema.nullable === true ? `${base2}.nullable()` : base2;
319
+ }
320
+ const nullable = schema.nullable === true;
321
+ let base;
322
+ switch (schema.type) {
323
+ case "string":
324
+ base = schemaToString(schema);
325
+ break;
326
+ case "integer":
327
+ case "number":
328
+ base = schemaToNumber(schema);
329
+ break;
330
+ case "boolean":
331
+ base = "z.boolean()";
332
+ break;
333
+ case "array":
334
+ base = schemaToArray(schema, schemas, schemaKeyToVarName2);
335
+ break;
336
+ case "object":
337
+ base = schemaToObject(schema, schemas, schemaKeyToVarName2);
338
+ break;
339
+ default:
340
+ base = "z.any()";
341
+ }
342
+ return nullable ? `${base}.nullable()` : base;
343
+ }
344
+ function collectRefs(schema, schemas, out) {
345
+ if (!schema) return;
346
+ if (schema.$ref) {
347
+ const key = parseRef(schema.$ref);
348
+ if (key && key in schemas && !out.has(key)) {
349
+ out.add(key);
350
+ collectRefs(schemas[key], schemas, out);
351
+ }
352
+ return;
353
+ }
354
+ if (schema.allOf) {
355
+ for (const part of schema.allOf) collectRefs(part, schemas, out);
356
+ }
357
+ if (schema.properties) {
358
+ for (const v of Object.values(schema.properties)) {
359
+ collectRefs(v, schemas, out);
360
+ }
361
+ }
362
+ if (schema.items) collectRefs(schema.items, schemas, out);
363
+ if (typeof schema.additionalProperties === "object") {
364
+ collectRefs(schema.additionalProperties, schemas, out);
365
+ }
366
+ }
367
+ function schemaKeyToVarName(key, utils) {
368
+ const _ = utils._;
369
+ return `${_.camelCase(key)}Schema`;
370
+ }
371
+ function generateAuxiliarySchemas(schemaKeys, schemas, schemaKeyToVarNameFn, visited) {
372
+ const lines = [];
373
+ for (const key of schemaKeys) {
374
+ if (visited.has(key)) continue;
375
+ visited.add(key);
376
+ const schema = schemas[key];
377
+ if (!schema) continue;
378
+ const varName = schemaKeyToVarNameFn(key);
379
+ const expr = schemaToZodExpr(
380
+ schema,
381
+ schemas,
382
+ schemaKeyToVarNameFn
383
+ );
384
+ lines.push(`export const ${varName} = ${expr};`);
385
+ }
386
+ return lines;
387
+ }
388
+ function buildCentralZodSchemasFile(params) {
389
+ const { componentsSchemas, utils } = params;
390
+ const schemaKeyToVarNameFn = (key) => schemaKeyToVarName(key, utils);
391
+ const lines = generateAuxiliarySchemas(
392
+ Object.keys(componentsSchemas),
393
+ componentsSchemas,
394
+ schemaKeyToVarNameFn,
395
+ /* @__PURE__ */ new Set()
396
+ );
397
+ return `import * as z from "zod";
398
+
399
+ ${lines.join("\n\n")}
400
+ `;
401
+ }
402
+ function typeToZodSchemaFallback(typeStr) {
403
+ const t = typeStr.trim();
404
+ if (t === "RequestParams") return "z.any()";
405
+ if (t === "Record<string, any>" || t === "Record<string, unknown>")
406
+ return "z.record(z.string(), z.any())";
407
+ if (/^Record\s*<\s*string\s*,/i.test(t))
408
+ return "z.record(z.string(), z.any())";
409
+ if (t === "string") return "z.string()";
410
+ if (t === "number") return "z.number()";
411
+ if (t === "boolean") return "z.boolean()";
412
+ if (t === "any") return "z.any()";
413
+ if (t === "unknown") return "z.unknown()";
414
+ return "z.any()";
415
+ }
416
+ function typeToZodSchemaWithSchema(typeStr, schemas, utils, typeSuffix) {
417
+ const t = typeStr.trim();
418
+ if (!schemas || Object.keys(schemas).length === 0) {
419
+ return { expr: typeToZodSchemaFallback(t), refs: [] };
420
+ }
421
+ if (t === "RequestParams") return { expr: "z.any()", refs: [] };
422
+ const schemaKey = typeNameToSchemaKey(t, typeSuffix);
423
+ const schema = schemas[schemaKey];
424
+ if (!schema) {
425
+ return { expr: typeToZodSchemaFallback(t), refs: [] };
426
+ }
427
+ const refs = /* @__PURE__ */ new Set();
428
+ collectRefs(schema, schemas, refs);
429
+ const schemaKeyToVarNameFn = (key) => schemaKeyToVarName(key, utils);
430
+ const expr = schemaToZodExpr(
431
+ schema,
432
+ schemas,
433
+ schemaKeyToVarNameFn
434
+ );
435
+ return { expr, refs: [...refs] };
436
+ }
437
+ function schemaKeyToZod(schemaKey, schemas, utils) {
438
+ const schema = schemas[schemaKey];
439
+ if (!schema) return { expr: "z.any()", refs: [] };
440
+ const refs = /* @__PURE__ */ new Set();
441
+ collectRefs(schema, schemas, refs);
442
+ const schemaKeyToVarNameFn = (key) => schemaKeyToVarName(key, utils);
443
+ const expr = schemaToZodExpr(
444
+ schema,
445
+ schemas,
446
+ schemaKeyToVarNameFn
447
+ );
448
+ return { expr, refs: [...refs] };
449
+ }
450
+ function buildEndpointZodContractsCode(params) {
451
+ const {
452
+ routeNameUsage,
453
+ inputParams,
454
+ responseDataTypeName,
455
+ contractsVarName,
456
+ utils,
457
+ componentsSchemas = null,
458
+ typeSuffix = "DC",
459
+ responseSchemaKey,
460
+ useExternalZodSchemas = false
461
+ } = params;
462
+ const _ = utils._;
463
+ const paramsSchemaName = `${_.camelCase(routeNameUsage)}ParamsSchema`;
464
+ const dataSchemaName = `${_.camelCase(routeNameUsage)}DataSchema`;
465
+ const allAuxiliaryKeys = /* @__PURE__ */ new Set();
466
+ const paramParts = [];
467
+ for (const p of inputParams) {
468
+ const { expr, refs: refKeys } = typeToZodSchemaWithSchema(
469
+ p.type,
470
+ componentsSchemas,
471
+ utils,
472
+ typeSuffix
473
+ );
474
+ for (const k of refKeys) allAuxiliaryKeys.add(k);
475
+ const schemaWithOptional = p.optional ? `${expr}.optional()` : expr;
476
+ paramParts.push(`${p.name}: ${schemaWithOptional}`);
477
+ }
478
+ const responseResult = responseSchemaKey && componentsSchemas && responseSchemaKey in componentsSchemas ? schemaKeyToZod(responseSchemaKey, componentsSchemas, utils) : typeToZodSchemaWithSchema(
479
+ responseDataTypeName,
480
+ componentsSchemas,
481
+ utils,
482
+ typeSuffix
483
+ );
484
+ const schemaKeyToVarNameFn = (key) => schemaKeyToVarName(key, utils);
485
+ const useDataSchemaFromCentral = useExternalZodSchemas && responseSchemaKey && componentsSchemas && responseSchemaKey in componentsSchemas;
486
+ if (useDataSchemaFromCentral) {
487
+ allAuxiliaryKeys.add(responseSchemaKey);
488
+ } else {
489
+ for (const k of responseResult.refs) allAuxiliaryKeys.add(k);
490
+ }
491
+ const zodSchemaImportNames = useExternalZodSchemas && allAuxiliaryKeys.size > 0 ? [...allAuxiliaryKeys].map(schemaKeyToVarNameFn) : [];
492
+ const allAuxiliary = useExternalZodSchemas ? [] : generateAuxiliarySchemas(
493
+ [...allAuxiliaryKeys],
494
+ componentsSchemas ?? {},
495
+ schemaKeyToVarNameFn,
496
+ /* @__PURE__ */ new Set()
497
+ );
498
+ const paramsFields = paramParts.join(",\n ");
499
+ const paramsSchemaCode = `export const ${paramsSchemaName} = z.object({
500
+ ${paramsFields},
501
+ });`;
502
+ const dataSchemaCode = useDataSchemaFromCentral ? `export const ${dataSchemaName} = ${schemaKeyToVarNameFn(responseSchemaKey)};` : `export const ${dataSchemaName} = ${responseResult.expr};`;
503
+ const contractsCode = `export const ${contractsVarName} = {
504
+ params: ${paramsSchemaName},
505
+ data: ${dataSchemaName},
506
+ };`;
507
+ const auxiliaryBlock = allAuxiliary.length > 0 ? `${allAuxiliary.join("\n\n")}
508
+
509
+ ` : "";
510
+ const content = `${auxiliaryBlock}${paramsSchemaCode}
511
+
512
+ ${dataSchemaCode}
513
+
514
+ ${contractsCode}`;
515
+ return { content, zodSchemaImportNames };
516
+ }
222
517
  const formatGroupNameEnumKey = (groupName, { _ }) => _.upperFirst(_.camelCase(groupName));
223
518
  const formatTagNameEnumKey = (tagName, utils) => formatGroupNameEnumKey(tagName, utils);
224
519
  const metaInfoTmpl = async ({
@@ -370,8 +665,17 @@ const newEndpointTmpl = ({
370
665
  groupName,
371
666
  metaInfo,
372
667
  filterTypes,
373
- configuration
668
+ configuration,
669
+ zodContracts,
670
+ relativePathZodSchemas
671
+ // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: codegen template, many branches by design
374
672
  }) => {
673
+ const zodContractsIsObject = typeof zodContracts === "object" && zodContracts !== null;
674
+ const hasZodContracts = zodContracts === true || zodContractsIsObject;
675
+ const validateOpt = zodContractsIsObject ? zodContracts.validate : zodContracts === true ? true : void 0;
676
+ const throwOpt = zodContractsIsObject ? zodContracts.throw : void 0;
677
+ const validateOptObj = validateOpt != null && typeof validateOpt === "object" && !Array.isArray(validateOpt) ? validateOpt : null;
678
+ const throwOptObj = throwOpt != null && typeof throwOpt === "object" && !Array.isArray(throwOpt) ? throwOpt : null;
375
679
  const { _ } = utils;
376
680
  const positiveResponseTypes = route.raw.responsesTypes?.filter(
377
681
  (it) => +it.status >= 200 && +it.status < 300 && (!it.typeData || filterTypes(it.typeData))
@@ -484,9 +788,95 @@ const newEndpointTmpl = ({
484
788
  }`
485
789
  });
486
790
  const isAllowedInputType = filterTypes(requestInputTypeDc);
791
+ const defaultOkResponseType = positiveResponseTypes?.[0]?.type ?? "unknown";
792
+ const contractsVarName = hasZodContracts ? `${_.camelCase(route.routeName.usage)}Contracts` : null;
793
+ const swaggerSchema = configuration.config?.swaggerSchema ?? configuration?.swaggerSchema;
794
+ const componentsSchemas = swaggerSchema?.components?.schemas;
795
+ let operationFromSpec = null;
796
+ const pathKeyForSpec = path2?.startsWith("/") ? path2 : `/${path2 || ""}`;
797
+ const methodKey = method?.toLowerCase?.() ?? method;
798
+ if (pathKeyForSpec && methodKey && swaggerSchema?.paths?.[pathKeyForSpec]) {
799
+ operationFromSpec = swaggerSchema.paths[pathKeyForSpec][methodKey] ?? null;
800
+ }
801
+ if (!operationFromSpec && swaggerSchema?.paths && raw?.operationId) {
802
+ for (const pathItem of Object.values(swaggerSchema.paths)) {
803
+ const op = pathItem?.[methodKey];
804
+ if (op?.operationId === raw.operationId) {
805
+ operationFromSpec = op;
806
+ break;
807
+ }
808
+ }
809
+ }
810
+ let responseSchemaKey = getResponseSchemaKeyFromOperation(
811
+ operationFromSpec ?? raw
812
+ );
813
+ if (!responseSchemaKey && componentsSchemas && configuration.modelTypes) {
814
+ const aliasType = configuration.modelTypes.find(
815
+ (m) => m.name === defaultOkResponseType
816
+ );
817
+ if (aliasType?.typeIdentifier === "type" && typeof aliasType.content === "string" && /^[A-Za-z0-9_]+$/.test(aliasType.content.trim())) {
818
+ const resolved = typeNameToSchemaKey(aliasType.content.trim(), "DC");
819
+ if (resolved in componentsSchemas) responseSchemaKey = resolved;
820
+ }
821
+ }
822
+ if (!responseSchemaKey && componentsSchemas) {
823
+ const match = defaultOkResponseType.match(/^Get(.+)DataDC$/);
824
+ if (match) {
825
+ const candidate = match[1];
826
+ if (candidate in componentsSchemas) responseSchemaKey = candidate;
827
+ }
828
+ }
829
+ const contractsCode = hasZodContracts && contractsVarName ? buildEndpointZodContractsCode({
830
+ routeNameUsage: route.routeName.usage,
831
+ inputParams,
832
+ responseDataTypeName: defaultOkResponseType,
833
+ contractsVarName,
834
+ utils,
835
+ componentsSchemas: componentsSchemas ?? void 0,
836
+ typeSuffix: "DC",
837
+ responseSchemaKey: responseSchemaKey ?? void 0,
838
+ useExternalZodSchemas: Boolean(relativePathZodSchemas)
839
+ }) : null;
840
+ const contractsLine = contractsVarName != null ? `contracts: ${contractsVarName},` : "";
841
+ const validateContractsLine = (() => {
842
+ if (validateOpt === void 0) return "";
843
+ if (typeof validateOpt === "string")
844
+ return `validateContracts: ${validateOpt},`;
845
+ if (typeof validateOpt === "boolean")
846
+ return `validateContracts: ${validateOpt},`;
847
+ if (validateOptObj !== null) {
848
+ const parts = [];
849
+ if (validateOptObj.params !== void 0)
850
+ parts.push(
851
+ `params: ${typeof validateOptObj.params === "string" ? validateOptObj.params : validateOptObj.params}`
852
+ );
853
+ if (validateOptObj.data !== void 0)
854
+ parts.push(
855
+ `data: ${typeof validateOptObj.data === "string" ? validateOptObj.data : validateOptObj.data}`
856
+ );
857
+ return parts.length > 0 ? `validateContracts: { ${parts.join(", ")} },` : "";
858
+ }
859
+ return "";
860
+ })();
861
+ const throwContractsLine = (() => {
862
+ if (throwOpt === void 0) return "";
863
+ if (typeof throwOpt === "string") return `throwContracts: ${throwOpt},`;
864
+ if (typeof throwOpt === "boolean") return `throwContracts: ${throwOpt},`;
865
+ if (throwOptObj !== null) {
866
+ const parts = [];
867
+ if (throwOptObj.params !== void 0)
868
+ parts.push(`params: ${throwOptObj.params}`);
869
+ if (throwOptObj.data !== void 0)
870
+ parts.push(`data: ${throwOptObj.data}`);
871
+ return parts.length > 0 ? `throwContracts: { ${parts.join(", ")} },` : "";
872
+ }
873
+ return "";
874
+ })();
487
875
  return {
488
876
  reservedDataContractNames,
489
877
  localModelTypes: isAllowedInputType ? [requestInputTypeDc] : [],
878
+ contractsCode: contractsCode ?? void 0,
879
+ contractsVarName: contractsVarName ?? void 0,
490
880
  content: `
491
881
  new ${importFileParams.endpoint.exportName}<
492
882
  ${getHttpRequestGenerics()},
@@ -519,6 +909,9 @@ new ${importFileParams.endpoint.exportName}<
519
909
  ${groupName ? `group: ${metaInfo ? `Group.${formatGroupNameEnumKey(groupName, utils)}` : `"${groupName}"`},` : ""}
520
910
  ${metaInfo?.namespace ? `namespace,` : ""}
521
911
  meta: ${requestInfoMeta?.tmplData ?? "{} as any"},
912
+ ${contractsLine}
913
+ ${validateContractsLine}
914
+ ${throwContractsLine}
522
915
  },
523
916
  ${importFileParams.queryClient.exportName},
524
917
  ${importFileParams.httpClient.exportName},
@@ -536,7 +929,8 @@ const allEndpointPerFileTmpl = async (params) => {
536
929
  utils,
537
930
  relativePathDataContracts,
538
931
  groupName,
539
- metaInfo
932
+ metaInfo,
933
+ relativePathZodSchemas
540
934
  } = params;
541
935
  const { _ } = utils;
542
936
  const dataContractNamesInThisFile = [];
@@ -548,7 +942,11 @@ const allEndpointPerFileTmpl = async (params) => {
548
942
  const newEndpointTemplates = routes.map((route) => {
549
943
  const newEndpointTemplateData = newEndpointTmpl({
550
944
  ...params,
551
- route
945
+ route,
946
+ groupName,
947
+ metaInfo,
948
+ zodContracts: codegenParams.zodContracts,
949
+ relativePathZodSchemas: relativePathZodSchemas ?? void 0
552
950
  });
553
951
  const { reservedDataContractNames } = newEndpointTemplateData;
554
952
  reservedDataContractNames.forEach((reservedDataContractName) => {
@@ -559,12 +957,27 @@ const allEndpointPerFileTmpl = async (params) => {
559
957
  return { ...newEndpointTemplateData, route };
560
958
  });
561
959
  const extraImportLines = [];
960
+ const hasAnyZodContracts = newEndpointTemplates.some(
961
+ (t) => t.contractsCode != null
962
+ );
963
+ const allZodSchemaImportNames = /* @__PURE__ */ new Set();
964
+ newEndpointTemplates.forEach((t) => {
965
+ const c = t.contractsCode;
966
+ if (c != null && typeof c === "object" && c.zodSchemaImportNames?.length) {
967
+ for (const n of c.zodSchemaImportNames) {
968
+ allZodSchemaImportNames.add(n);
969
+ }
970
+ }
971
+ });
972
+ const zodImportLine = hasAnyZodContracts ? 'import * as z from "zod";' : "";
973
+ const zodSchemasImportLine = allZodSchemaImportNames.size && relativePathZodSchemas ? `import { ${[...allZodSchemaImportNames].sort().join(", ")} } from "${relativePathZodSchemas}";` : "";
562
974
  const endpointTemplates = await Promise.all(
563
975
  newEndpointTemplates.map(
564
976
  async ({
565
977
  content: requestInfoInstanceContent,
566
978
  localModelTypes,
567
- route
979
+ route,
980
+ contractsCode
568
981
  }) => {
569
982
  const requestInfoMeta = codegenParams.getEndpointMeta?.(route, utils);
570
983
  if (requestInfoMeta?.typeNameImportPath && requestInfoMeta.typeName) {
@@ -572,6 +985,12 @@ const allEndpointPerFileTmpl = async (params) => {
572
985
  `import { ${requestInfoMeta.typeName} } from "${requestInfoMeta.typeNameImportPath}";`
573
986
  );
574
987
  }
988
+ const contractsResult = contractsCode != null && typeof contractsCode === "object" ? contractsCode : null;
989
+ const contractsBlock = contractsResult != null ? `
990
+
991
+ ${contractsResult.content}
992
+
993
+ ` : "";
575
994
  return `
576
995
  ${(await Promise.all(
577
996
  localModelTypes.map(async (modelType) => {
@@ -583,7 +1002,7 @@ const allEndpointPerFileTmpl = async (params) => {
583
1002
  return contractType;
584
1003
  })
585
1004
  )).filter(Boolean).join("\n\n")}
586
-
1005
+ ${contractsBlock}
587
1006
  ${endpointJSDocTmpl({
588
1007
  ...params,
589
1008
  route
@@ -610,6 +1029,7 @@ const allEndpointPerFileTmpl = async (params) => {
610
1029
  import { ${importFileParams.httpClient.exportName} } from "${importFileParams.httpClient.path}";
611
1030
  import { ${importFileParams.queryClient.exportName} } from "${importFileParams.queryClient.path}";
612
1031
  ${extraImportLines.join("\n")}
1032
+ ${[zodImportLine, zodSchemasImportLine].filter(Boolean).join("\n")}
613
1033
  ${dataContractImportToken}
614
1034
 
615
1035
  ${(await Promise.all(
@@ -649,11 +1069,12 @@ const allEndpointPerFileTmpl = async (params) => {
649
1069
  const allExportsTmpl = async ({
650
1070
  collectedExportFiles,
651
1071
  metaInfo,
652
- formatTSContent
1072
+ formatTSContent,
1073
+ exportSchemas
653
1074
  }) => {
654
1075
  return await formatTSContent(`${LINTERS_IGNORE}
655
1076
  export * from './data-contracts';
656
- ${collectedExportFiles.map((fileName) => `export * from './${fileName}';`).join("\n")}
1077
+ ${exportSchemas ? " export * from './schemas';\n " : ""}${collectedExportFiles.map((fileName) => `export * from './${fileName}';`).join("\n")}
657
1078
  ${metaInfo ? 'export * from "./meta-info";' : ""}
658
1079
  `);
659
1080
  };
@@ -692,18 +1113,22 @@ const endpointPerFileTmpl = async (params) => {
692
1113
  utils,
693
1114
  relativePathDataContracts,
694
1115
  groupName,
695
- metaInfo
1116
+ metaInfo,
1117
+ relativePathZodSchemas
696
1118
  } = params;
697
1119
  const { _ } = utils;
698
1120
  const {
699
1121
  content: requestInfoInstanceContent,
700
1122
  reservedDataContractNames,
701
- localModelTypes
1123
+ localModelTypes,
1124
+ contractsCode
702
1125
  } = newEndpointTmpl({
703
1126
  ...params,
704
1127
  route,
705
1128
  groupName,
706
- metaInfo
1129
+ metaInfo,
1130
+ zodContracts: codegenParams.zodContracts,
1131
+ relativePathZodSchemas: relativePathZodSchemas ?? void 0
707
1132
  });
708
1133
  const dataContactNames = new Set(
709
1134
  Object.keys(
@@ -729,6 +1154,15 @@ const endpointPerFileTmpl = async (params) => {
729
1154
  );
730
1155
  }
731
1156
  const dataContractImportToken = "/*__DATA_CONTRACT_IMPORTS__*/";
1157
+ const contractsResult = contractsCode != null && typeof contractsCode === "object" ? contractsCode : null;
1158
+ const zodImportLine = contractsResult != null ? 'import * as z from "zod";' : "";
1159
+ const zodSchemasImportLine = contractsResult?.zodSchemaImportNames?.length && relativePathZodSchemas ? `import { ${contractsResult.zodSchemaImportNames.join(", ")} } from "${relativePathZodSchemas}";` : "";
1160
+ const contractsBlock = contractsResult != null ? `
1161
+
1162
+ ${contractsResult.content}
1163
+
1164
+ ` : "";
1165
+ const zodImportsBlock = [zodImportLine, zodSchemasImportLine].filter(Boolean).join("\n");
732
1166
  const contentWithImportToken = await formatTSContent(`${LINTERS_IGNORE}
733
1167
  import {
734
1168
  RequestParams,
@@ -739,6 +1173,7 @@ const endpointPerFileTmpl = async (params) => {
739
1173
  import { ${importFileParams.httpClient.exportName} } from "${importFileParams.httpClient.path}";
740
1174
  import { ${importFileParams.queryClient.exportName} } from "${importFileParams.queryClient.path}";
741
1175
  ${extraImportLines.join("\n")}
1176
+ ${zodImportsBlock}
742
1177
  ${dataContractImportToken}
743
1178
 
744
1179
  ${(await Promise.all(
@@ -768,7 +1203,7 @@ const endpointPerFileTmpl = async (params) => {
768
1203
  return contractType;
769
1204
  })
770
1205
  )).filter(Boolean).join("\n\n")}
771
-
1206
+ ${contractsBlock}
772
1207
  ${endpointJSDocTmpl({
773
1208
  ...params,
774
1209
  route
@@ -816,7 +1251,7 @@ const unpackFilterOption = (option, argsToString, defaultReturnValue = true) =>
816
1251
  const removeUnusedTypesItteration = async ({
817
1252
  directory,
818
1253
  keepTypes
819
- // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: <explanation>
1254
+ // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: iterative AST traversal
820
1255
  }) => {
821
1256
  const project = new tsMorph.Project();
822
1257
  project.addSourceFilesAtPaths([
@@ -1134,6 +1569,8 @@ const generateApi = async (params) => {
1134
1569
  filterTypes
1135
1570
  };
1136
1571
  const reservedDataContractNamesMap = /* @__PURE__ */ new Map();
1572
+ const componentsSchemasForZod = generated.configuration.config?.swaggerSchema?.components?.schemas ?? generated.configuration.swaggerSchema?.components?.schemas;
1573
+ const hasZodSchemasFile = (params.zodContracts === true || typeof params.zodContracts === "object" && params.zodContracts != null) && componentsSchemasForZod && typeof componentsSchemasForZod === "object" && Object.keys(componentsSchemasForZod).length > 0;
1137
1574
  const collectedExportFilesFromIndexFile = [];
1138
1575
  const groupsMap = /* @__PURE__ */ new Map();
1139
1576
  const nonEmptyGroups = /* @__PURE__ */ new Set();
@@ -1155,7 +1592,8 @@ const generateApi = async (params) => {
1155
1592
  metaInfo: params.noMetaInfo ? null : {
1156
1593
  groupNames: [],
1157
1594
  namespace
1158
- }
1595
+ },
1596
+ relativePathZodSchemas: hasZodSchemasFile ? "../schemas" : null
1159
1597
  });
1160
1598
  if (Array.isArray(route.raw.tags)) {
1161
1599
  route.raw.tags.forEach((tag) => {
@@ -1199,7 +1637,8 @@ const generateApi = async (params) => {
1199
1637
  metaInfo: params.noMetaInfo ? null : {
1200
1638
  namespace,
1201
1639
  groupNames: []
1202
- }
1640
+ },
1641
+ relativePathZodSchemas: hasZodSchemasFile ? "./schemas" : null
1203
1642
  });
1204
1643
  reservedDataContractNames.forEach((name) => {
1205
1644
  reservedDataContractNamesMap.set(
@@ -1395,6 +1834,22 @@ export * as ${exportGroupName} from './endpoints';
1395
1834
  withPrefix: false,
1396
1835
  content: dataContractsContent
1397
1836
  });
1837
+ if (hasZodSchemasFile && componentsSchemasForZod) {
1838
+ const schemasTsContent = buildCentralZodSchemasFile({
1839
+ componentsSchemas: componentsSchemasForZod,
1840
+ utils
1841
+ });
1842
+ const formattedSchemasContent = await generated.formatTSContent(
1843
+ `${LINTERS_IGNORE}
1844
+ ${schemasTsContent}`
1845
+ );
1846
+ codegenFs.createFile({
1847
+ path: paths.outputDir,
1848
+ fileName: "schemas.ts",
1849
+ withPrefix: false,
1850
+ content: formattedSchemasContent
1851
+ });
1852
+ }
1398
1853
  if (metaInfo) {
1399
1854
  codegenFs.createFile({
1400
1855
  path: paths.outputDir,
@@ -1414,7 +1869,8 @@ export * as ${exportGroupName} from './endpoints';
1414
1869
  content: await allExportsTmpl({
1415
1870
  ...baseTmplParams,
1416
1871
  collectedExportFiles: collectedExportFilesFromIndexFile,
1417
- metaInfo
1872
+ metaInfo,
1873
+ exportSchemas: hasZodSchemasFile
1418
1874
  })
1419
1875
  });
1420
1876
  if (shouldGenerateBarrelFiles) {
@@ -1436,7 +1892,8 @@ export * as ${namespace} from './__exports';
1436
1892
  content: await allExportsTmpl({
1437
1893
  ...baseTmplParams,
1438
1894
  collectedExportFiles: collectedExportFilesFromIndexFile,
1439
- metaInfo
1895
+ metaInfo,
1896
+ exportSchemas: hasZodSchemasFile
1440
1897
  })
1441
1898
  });
1442
1899
  }