mobx-tanstack-query-api 0.37.1 → 0.38.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/cli.js CHANGED
@@ -216,6 +216,373 @@ const createShortModelType = (shortModelType) => {
216
216
  description: shortModelType.description || ""
217
217
  };
218
218
  };
219
+ const REF_PREFIX = "#/components/schemas/";
220
+ const REF_PREFIX_PARAMS = "#/components/parameters/";
221
+ function parseRef(ref) {
222
+ if (typeof ref !== "string" || !ref.startsWith(REF_PREFIX)) return null;
223
+ return ref.slice(REF_PREFIX.length);
224
+ }
225
+ function parseParamRef(ref) {
226
+ if (typeof ref !== "string" || !ref.startsWith(REF_PREFIX_PARAMS))
227
+ return null;
228
+ return ref.slice(REF_PREFIX_PARAMS.length);
229
+ }
230
+ function getResponseSchemaKeyFromOperation(rawOperation) {
231
+ const op = rawOperation;
232
+ const responses = op?.responses;
233
+ if (!responses || typeof responses !== "object") return null;
234
+ const successStatus = Object.keys(responses).find((s) => {
235
+ const code = Number.parseInt(s, 10);
236
+ return code >= 200 && code < 300;
237
+ });
238
+ if (!successStatus) return null;
239
+ const successResponse = responses[successStatus];
240
+ const content = successResponse?.content;
241
+ if (!content || typeof content !== "object") return null;
242
+ const jsonContent = content["application/json"] ?? Object.values(content)[0];
243
+ const ref = jsonContent?.schema?.$ref;
244
+ if (typeof ref !== "string") return null;
245
+ return parseRef(ref);
246
+ }
247
+ function typeNameToSchemaKey(typeName, typeSuffix = "DC") {
248
+ const t = typeName.trim();
249
+ if (typeSuffix && t.endsWith(typeSuffix))
250
+ return t.slice(0, -typeSuffix.length);
251
+ return t;
252
+ }
253
+ function schemaToString(schema) {
254
+ let s = "z.string()";
255
+ if (schema.minLength != null) s += `.min(${schema.minLength})`;
256
+ if (schema.maxLength != null) s += `.max(${schema.maxLength})`;
257
+ if (schema.pattern != null)
258
+ s += `.regex(new RegExp(${JSON.stringify(schema.pattern)}))`;
259
+ if (schema.enum != null)
260
+ s = `z.enum([${schema.enum.map((e) => JSON.stringify(e)).join(", ")}])`;
261
+ return s;
262
+ }
263
+ function schemaToNumber(schema) {
264
+ let n = "z.number()";
265
+ if (schema.type === "integer") n += ".int()";
266
+ if (schema.minimum != null) n += `.min(${schema.minimum})`;
267
+ if (schema.maximum != null) n += `.max(${schema.maximum})`;
268
+ return n;
269
+ }
270
+ function schemaToArray(schema, schemas, schemaKeyToVarName2, visited) {
271
+ const items = schema.items ? schemaToZodExpr(schema.items, schemas, schemaKeyToVarName2, visited) : "z.any()";
272
+ let a = `z.array(${items})`;
273
+ if (schema.minItems != null) a += `.min(${schema.minItems})`;
274
+ if (schema.maxItems != null) a += `.max(${schema.maxItems})`;
275
+ return a;
276
+ }
277
+ function schemaToObject(schema, schemas, schemaKeyToVarName2, visited) {
278
+ if (schema.properties && Object.keys(schema.properties).length > 0) {
279
+ const required = new Set(schema.required ?? []);
280
+ const entries = Object.entries(schema.properties).map(
281
+ ([propName, propSchema]) => {
282
+ const expr = schemaToZodExpr(
283
+ propSchema,
284
+ schemas,
285
+ schemaKeyToVarName2,
286
+ visited
287
+ );
288
+ const optional = !required.has(propName);
289
+ const field = optional ? `${expr}.optional()` : expr;
290
+ return ` ${JSON.stringify(propName)}: ${field}`;
291
+ }
292
+ );
293
+ return `z.object({
294
+ ${entries.join(",\n")}
295
+ })`;
296
+ }
297
+ if (schema.additionalProperties === true)
298
+ return "z.record(z.string(), z.any())";
299
+ if (typeof schema.additionalProperties === "object") {
300
+ const value = schemaToZodExpr(
301
+ schema.additionalProperties,
302
+ schemas,
303
+ schemaKeyToVarName2,
304
+ visited
305
+ );
306
+ return `z.record(z.string(), ${value})`;
307
+ }
308
+ return "z.record(z.string(), z.any())";
309
+ }
310
+ function schemaToZodExpr(schema, schemas, schemaKeyToVarName2, visited) {
311
+ if (!schema) return "z.any()";
312
+ if (schema.$ref) {
313
+ const key = parseRef(schema.$ref);
314
+ if (key && key in schemas) {
315
+ const isCycle = visited.has(key);
316
+ return isCycle ? `z.lazy((): z.ZodTypeAny => ${schemaKeyToVarName2(key)})` : `z.lazy(() => ${schemaKeyToVarName2(key)})`;
317
+ }
318
+ return "z.any()";
319
+ }
320
+ if (schema.allOf && schema.allOf.length > 0) {
321
+ const parts = schema.allOf.map(
322
+ (part) => schemaToZodExpr(part, schemas, schemaKeyToVarName2, visited)
323
+ );
324
+ const base2 = parts.length === 1 ? parts[0] : parts.reduce((acc, p) => `z.intersection(${acc}, ${p})`);
325
+ return schema.nullable === true ? `${base2}.nullable()` : base2;
326
+ }
327
+ const nullable = schema.nullable === true;
328
+ let base;
329
+ switch (schema.type) {
330
+ case "string":
331
+ base = schemaToString(schema);
332
+ break;
333
+ case "integer":
334
+ case "number":
335
+ base = schemaToNumber(schema);
336
+ break;
337
+ case "boolean":
338
+ base = "z.boolean()";
339
+ break;
340
+ case "array":
341
+ base = schemaToArray(schema, schemas, schemaKeyToVarName2, visited);
342
+ break;
343
+ case "object":
344
+ base = schemaToObject(schema, schemas, schemaKeyToVarName2, visited);
345
+ break;
346
+ default:
347
+ base = "z.any()";
348
+ }
349
+ return nullable ? `${base}.nullable()` : base;
350
+ }
351
+ function collectRefs(schema, schemas, out) {
352
+ if (!schema) return;
353
+ if (schema.$ref) {
354
+ const key = parseRef(schema.$ref);
355
+ if (key && key in schemas && !out.has(key)) {
356
+ out.add(key);
357
+ collectRefs(schemas[key], schemas, out);
358
+ }
359
+ return;
360
+ }
361
+ if (schema.allOf) {
362
+ for (const part of schema.allOf) collectRefs(part, schemas, out);
363
+ }
364
+ if (schema.properties) {
365
+ for (const v of Object.values(schema.properties)) {
366
+ collectRefs(v, schemas, out);
367
+ }
368
+ }
369
+ if (schema.items) collectRefs(schema.items, schemas, out);
370
+ if (typeof schema.additionalProperties === "object") {
371
+ collectRefs(schema.additionalProperties, schemas, out);
372
+ }
373
+ }
374
+ function schemaKeyToVarName(key, utils) {
375
+ const _ = utils._;
376
+ return `${_.camelCase(key)}Schema`;
377
+ }
378
+ function resolveQueryParameters(operation, componentsParameters) {
379
+ const list = [];
380
+ const params = operation?.parameters;
381
+ if (!Array.isArray(params) || !params.length) return list;
382
+ for (const p of params) {
383
+ let param = p;
384
+ if (p.$ref && componentsParameters) {
385
+ const key = parseParamRef(p.$ref);
386
+ if (key && key in componentsParameters)
387
+ param = componentsParameters[key];
388
+ }
389
+ if (param.in !== "query") continue;
390
+ const name = param.name;
391
+ if (!name) continue;
392
+ const schema = param.schema ?? {
393
+ type: param.type ?? "string",
394
+ format: param.format,
395
+ items: param.items
396
+ };
397
+ list.push({
398
+ name,
399
+ required: param.required === true,
400
+ schema
401
+ });
402
+ }
403
+ return list;
404
+ }
405
+ function queryParamsToZodObject(queryParams, schemas, schemaKeyToVarName2) {
406
+ if (queryParams.length === 0) return "z.object({})";
407
+ const entries = queryParams.map(({ name, required, schema }) => {
408
+ const expr = schemaToZodExpr(
409
+ schema,
410
+ schemas,
411
+ schemaKeyToVarName2,
412
+ /* @__PURE__ */ new Set()
413
+ );
414
+ const field = required ? expr : `${expr}.optional()`;
415
+ return ` ${JSON.stringify(name)}: ${field}`;
416
+ });
417
+ return `z.object({
418
+ ${entries.join(",\n")}
419
+ })`;
420
+ }
421
+ function generateAuxiliarySchemas(schemaKeys, schemas, schemaKeyToVarNameFn, visited) {
422
+ const lines = [];
423
+ for (const key of schemaKeys) {
424
+ if (visited.has(key)) continue;
425
+ visited.add(key);
426
+ const schema = schemas[key];
427
+ if (!schema) continue;
428
+ const varName = schemaKeyToVarNameFn(key);
429
+ const expr = schemaToZodExpr(
430
+ schema,
431
+ schemas,
432
+ schemaKeyToVarNameFn,
433
+ visited
434
+ );
435
+ lines.push(`export const ${varName} = ${expr};`);
436
+ }
437
+ return lines;
438
+ }
439
+ function buildCentralZodSchemasFile(params) {
440
+ const { componentsSchemas, utils } = params;
441
+ const schemaKeyToVarNameFn = (key) => schemaKeyToVarName(key, utils);
442
+ const lines = generateAuxiliarySchemas(
443
+ Object.keys(componentsSchemas),
444
+ componentsSchemas,
445
+ schemaKeyToVarNameFn,
446
+ /* @__PURE__ */ new Set()
447
+ );
448
+ return `import * as z from "zod";
449
+
450
+ ${lines.join("\n\n")}
451
+ `;
452
+ }
453
+ function typeToZodSchemaFallback(typeStr) {
454
+ const t = typeStr.trim();
455
+ if (t === "RequestParams") return "z.any()";
456
+ if (t === "Record<string, any>" || t === "Record<string, unknown>")
457
+ return "z.record(z.string(), z.any())";
458
+ if (/^Record\s*<\s*string\s*,/i.test(t))
459
+ return "z.record(z.string(), z.any())";
460
+ if (t === "string") return "z.string()";
461
+ if (t === "number") return "z.number()";
462
+ if (t === "boolean") return "z.boolean()";
463
+ if (t === "any") return "z.any()";
464
+ if (t === "unknown") return "z.unknown()";
465
+ return "z.any()";
466
+ }
467
+ function typeToZodSchemaWithSchema(typeStr, schemas, utils, typeSuffix) {
468
+ const t = typeStr.trim();
469
+ if (!schemas || Object.keys(schemas).length === 0) {
470
+ return { expr: typeToZodSchemaFallback(t), refs: [] };
471
+ }
472
+ if (t === "RequestParams") return { expr: "z.any()", refs: [] };
473
+ const schemaKey = typeNameToSchemaKey(t, typeSuffix);
474
+ const schema = schemas[schemaKey];
475
+ if (!schema) {
476
+ return { expr: typeToZodSchemaFallback(t), refs: [] };
477
+ }
478
+ const refs = /* @__PURE__ */ new Set();
479
+ collectRefs(schema, schemas, refs);
480
+ const schemaKeyToVarNameFn = (key) => schemaKeyToVarName(key, utils);
481
+ const expr = schemaToZodExpr(
482
+ schema,
483
+ schemas,
484
+ schemaKeyToVarNameFn,
485
+ /* @__PURE__ */ new Set()
486
+ );
487
+ return { expr, refs: [...refs] };
488
+ }
489
+ function schemaKeyToZod(schemaKey, schemas, utils) {
490
+ const schema = schemas[schemaKey];
491
+ if (!schema) return { expr: "z.any()", refs: [] };
492
+ const refs = /* @__PURE__ */ new Set();
493
+ collectRefs(schema, schemas, refs);
494
+ const schemaKeyToVarNameFn = (key) => schemaKeyToVarName(key, utils);
495
+ const expr = schemaToZodExpr(
496
+ schema,
497
+ schemas,
498
+ schemaKeyToVarNameFn,
499
+ /* @__PURE__ */ new Set()
500
+ );
501
+ return { expr, refs: [...refs] };
502
+ }
503
+ function buildEndpointZodContractsCode(params) {
504
+ const {
505
+ routeNameUsage,
506
+ inputParams,
507
+ responseDataTypeName,
508
+ contractsVarName,
509
+ utils,
510
+ componentsSchemas = null,
511
+ typeSuffix = "DC",
512
+ responseSchemaKey,
513
+ useExternalZodSchemas = false,
514
+ openApiOperation = null,
515
+ openApiComponentsParameters = null,
516
+ queryParamName = "query"
517
+ } = params;
518
+ const _ = utils._;
519
+ const paramsSchemaName = `${_.camelCase(routeNameUsage)}ParamsSchema`;
520
+ const dataSchemaName = `${_.camelCase(routeNameUsage)}DataSchema`;
521
+ const allAuxiliaryKeys = /* @__PURE__ */ new Set();
522
+ const paramParts = [];
523
+ const resolvedQueryParams = openApiOperation && (openApiComponentsParameters || openApiOperation.parameters?.length) ? resolveQueryParameters(openApiOperation, openApiComponentsParameters) : [];
524
+ const schemaKeyToVarNameFn = (key) => schemaKeyToVarName(key, utils);
525
+ for (const p of inputParams) {
526
+ let expr;
527
+ let refKeys = [];
528
+ if (p.name === queryParamName && resolvedQueryParams.length > 0 && componentsSchemas) {
529
+ expr = queryParamsToZodObject(
530
+ resolvedQueryParams,
531
+ componentsSchemas,
532
+ schemaKeyToVarNameFn
533
+ );
534
+ } else {
535
+ const result = typeToZodSchemaWithSchema(
536
+ p.type,
537
+ componentsSchemas,
538
+ utils,
539
+ typeSuffix
540
+ );
541
+ expr = result.expr;
542
+ refKeys = result.refs;
543
+ }
544
+ for (const k of refKeys) allAuxiliaryKeys.add(k);
545
+ const schemaWithOptional = p.optional ? `${expr}.optional()` : expr;
546
+ paramParts.push(`${p.name}: ${schemaWithOptional}`);
547
+ }
548
+ const responseResult = responseSchemaKey && componentsSchemas && responseSchemaKey in componentsSchemas ? schemaKeyToZod(responseSchemaKey, componentsSchemas, utils) : typeToZodSchemaWithSchema(
549
+ responseDataTypeName,
550
+ componentsSchemas,
551
+ utils,
552
+ typeSuffix
553
+ );
554
+ const useDataSchemaFromCentral = useExternalZodSchemas && responseSchemaKey && componentsSchemas && responseSchemaKey in componentsSchemas;
555
+ if (useDataSchemaFromCentral) {
556
+ allAuxiliaryKeys.add(responseSchemaKey);
557
+ } else {
558
+ for (const k of responseResult.refs) allAuxiliaryKeys.add(k);
559
+ }
560
+ const zodSchemaImportNames = useExternalZodSchemas && allAuxiliaryKeys.size > 0 ? [...allAuxiliaryKeys].map(schemaKeyToVarNameFn) : [];
561
+ const allAuxiliary = useExternalZodSchemas ? [] : generateAuxiliarySchemas(
562
+ [...allAuxiliaryKeys],
563
+ componentsSchemas ?? {},
564
+ schemaKeyToVarNameFn,
565
+ /* @__PURE__ */ new Set()
566
+ );
567
+ const paramsFields = paramParts.join(",\n ");
568
+ const paramsSchemaCode = `export const ${paramsSchemaName} = z.object({
569
+ ${paramsFields},
570
+ });`;
571
+ const dataSchemaCode = useDataSchemaFromCentral ? `export const ${dataSchemaName} = ${schemaKeyToVarNameFn(responseSchemaKey)};` : `export const ${dataSchemaName} = ${responseResult.expr};`;
572
+ const contractsCode = `export const ${contractsVarName} = {
573
+ params: ${paramsSchemaName},
574
+ data: ${dataSchemaName},
575
+ };`;
576
+ const auxiliaryBlock = allAuxiliary.length > 0 ? `${allAuxiliary.join("\n\n")}
577
+
578
+ ` : "";
579
+ const content = `${auxiliaryBlock}${paramsSchemaCode}
580
+
581
+ ${dataSchemaCode}
582
+
583
+ ${contractsCode}`;
584
+ return { content, zodSchemaImportNames };
585
+ }
219
586
  const formatGroupNameEnumKey = (groupName, { _ }) => _.upperFirst(_.camelCase(groupName));
220
587
  const formatTagNameEnumKey = (tagName, utils) => formatGroupNameEnumKey(tagName, utils);
221
588
  const metaInfoTmpl = async ({
@@ -367,8 +734,17 @@ const newEndpointTmpl = ({
367
734
  groupName,
368
735
  metaInfo,
369
736
  filterTypes,
370
- configuration
737
+ configuration,
738
+ zodContracts,
739
+ relativePathZodSchemas
740
+ // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: codegen template, many branches by design
371
741
  }) => {
742
+ const zodContractsIsObject = typeof zodContracts === "object" && zodContracts !== null;
743
+ const hasZodContracts = zodContracts === true || zodContractsIsObject;
744
+ const validateOpt = zodContractsIsObject ? zodContracts.validate : zodContracts === true ? true : void 0;
745
+ const throwOpt = zodContractsIsObject ? zodContracts.throw : void 0;
746
+ const validateOptObj = validateOpt != null && typeof validateOpt === "object" && !Array.isArray(validateOpt) ? validateOpt : null;
747
+ const throwOptObj = throwOpt != null && typeof throwOpt === "object" && !Array.isArray(throwOpt) ? throwOpt : null;
372
748
  const { _ } = utils;
373
749
  const positiveResponseTypes = route.raw.responsesTypes?.filter(
374
750
  (it) => +it.status >= 200 && +it.status < 300 && (!it.typeData || filterTypes(it.typeData))
@@ -481,9 +857,98 @@ const newEndpointTmpl = ({
481
857
  }`
482
858
  });
483
859
  const isAllowedInputType = filterTypes(requestInputTypeDc);
860
+ const defaultOkResponseType = positiveResponseTypes?.[0]?.type ?? "unknown";
861
+ const contractsVarName = hasZodContracts ? `${_.camelCase(route.routeName.usage)}Contracts` : null;
862
+ const swaggerSchema = configuration.config?.swaggerSchema ?? configuration?.swaggerSchema;
863
+ const componentsSchemas = swaggerSchema?.components?.schemas;
864
+ let operationFromSpec = null;
865
+ const pathKeyForSpec = path2?.startsWith("/") ? path2 : `/${path2 || ""}`;
866
+ const methodKey = method?.toLowerCase?.() ?? method;
867
+ if (pathKeyForSpec && methodKey && swaggerSchema?.paths?.[pathKeyForSpec]) {
868
+ operationFromSpec = swaggerSchema.paths[pathKeyForSpec][methodKey] ?? null;
869
+ }
870
+ if (!operationFromSpec && swaggerSchema?.paths && raw?.operationId) {
871
+ for (const pathItem of Object.values(swaggerSchema.paths)) {
872
+ const op = pathItem?.[methodKey];
873
+ if (op?.operationId === raw.operationId) {
874
+ operationFromSpec = op;
875
+ break;
876
+ }
877
+ }
878
+ }
879
+ let responseSchemaKey = getResponseSchemaKeyFromOperation(
880
+ operationFromSpec ?? raw
881
+ );
882
+ if (!responseSchemaKey && componentsSchemas && configuration.modelTypes) {
883
+ const aliasType = configuration.modelTypes.find(
884
+ (m) => m.name === defaultOkResponseType
885
+ );
886
+ if (aliasType?.typeIdentifier === "type" && typeof aliasType.content === "string" && /^[A-Za-z0-9_]+$/.test(aliasType.content.trim())) {
887
+ const resolved = typeNameToSchemaKey(aliasType.content.trim(), "DC");
888
+ if (resolved in componentsSchemas) responseSchemaKey = resolved;
889
+ }
890
+ }
891
+ if (!responseSchemaKey && componentsSchemas) {
892
+ const match = defaultOkResponseType.match(/^Get(.+)DataDC$/);
893
+ if (match) {
894
+ const candidate = match[1];
895
+ if (candidate in componentsSchemas) responseSchemaKey = candidate;
896
+ }
897
+ }
898
+ const contractsCode = hasZodContracts && contractsVarName ? buildEndpointZodContractsCode({
899
+ routeNameUsage: route.routeName.usage,
900
+ inputParams,
901
+ responseDataTypeName: defaultOkResponseType,
902
+ contractsVarName,
903
+ utils,
904
+ componentsSchemas: componentsSchemas ?? void 0,
905
+ typeSuffix: "DC",
906
+ responseSchemaKey: responseSchemaKey ?? void 0,
907
+ useExternalZodSchemas: Boolean(relativePathZodSchemas),
908
+ openApiOperation: operationFromSpec ?? void 0,
909
+ openApiComponentsParameters: swaggerSchema?.components?.parameters ?? void 0,
910
+ queryParamName: queryName
911
+ }) : null;
912
+ const contractsLine = contractsVarName != null ? `contracts: ${contractsVarName},` : "";
913
+ const validateContractsLine = (() => {
914
+ if (validateOpt === void 0) return "";
915
+ if (typeof validateOpt === "string")
916
+ return `validateContracts: ${validateOpt},`;
917
+ if (typeof validateOpt === "boolean")
918
+ return `validateContracts: ${validateOpt},`;
919
+ if (validateOptObj !== null) {
920
+ const parts = [];
921
+ if (validateOptObj.params !== void 0)
922
+ parts.push(
923
+ `params: ${typeof validateOptObj.params === "string" ? validateOptObj.params : validateOptObj.params}`
924
+ );
925
+ if (validateOptObj.data !== void 0)
926
+ parts.push(
927
+ `data: ${typeof validateOptObj.data === "string" ? validateOptObj.data : validateOptObj.data}`
928
+ );
929
+ return parts.length > 0 ? `validateContracts: { ${parts.join(", ")} },` : "";
930
+ }
931
+ return "";
932
+ })();
933
+ const throwContractsLine = (() => {
934
+ if (throwOpt === void 0) return "";
935
+ if (typeof throwOpt === "string") return `throwContracts: ${throwOpt},`;
936
+ if (typeof throwOpt === "boolean") return `throwContracts: ${throwOpt},`;
937
+ if (throwOptObj !== null) {
938
+ const parts = [];
939
+ if (throwOptObj.params !== void 0)
940
+ parts.push(`params: ${throwOptObj.params}`);
941
+ if (throwOptObj.data !== void 0)
942
+ parts.push(`data: ${throwOptObj.data}`);
943
+ return parts.length > 0 ? `throwContracts: { ${parts.join(", ")} },` : "";
944
+ }
945
+ return "";
946
+ })();
484
947
  return {
485
948
  reservedDataContractNames,
486
949
  localModelTypes: isAllowedInputType ? [requestInputTypeDc] : [],
950
+ contractsCode: contractsCode ?? void 0,
951
+ contractsVarName: contractsVarName ?? void 0,
487
952
  content: `
488
953
  new ${importFileParams.endpoint.exportName}<
489
954
  ${getHttpRequestGenerics()},
@@ -516,6 +981,9 @@ new ${importFileParams.endpoint.exportName}<
516
981
  ${groupName ? `group: ${metaInfo ? `Group.${formatGroupNameEnumKey(groupName, utils)}` : `"${groupName}"`},` : ""}
517
982
  ${metaInfo?.namespace ? `namespace,` : ""}
518
983
  meta: ${requestInfoMeta?.tmplData ?? "{} as any"},
984
+ ${contractsLine}
985
+ ${validateContractsLine}
986
+ ${throwContractsLine}
519
987
  },
520
988
  ${importFileParams.queryClient.exportName},
521
989
  ${importFileParams.httpClient.exportName},
@@ -533,7 +1001,8 @@ const allEndpointPerFileTmpl = async (params) => {
533
1001
  utils,
534
1002
  relativePathDataContracts,
535
1003
  groupName,
536
- metaInfo
1004
+ metaInfo,
1005
+ relativePathZodSchemas
537
1006
  } = params;
538
1007
  const { _ } = utils;
539
1008
  const dataContractNamesInThisFile = [];
@@ -545,7 +1014,11 @@ const allEndpointPerFileTmpl = async (params) => {
545
1014
  const newEndpointTemplates = routes.map((route) => {
546
1015
  const newEndpointTemplateData = newEndpointTmpl({
547
1016
  ...params,
548
- route
1017
+ route,
1018
+ groupName,
1019
+ metaInfo,
1020
+ zodContracts: codegenParams.zodContracts,
1021
+ relativePathZodSchemas: relativePathZodSchemas ?? void 0
549
1022
  });
550
1023
  const { reservedDataContractNames } = newEndpointTemplateData;
551
1024
  reservedDataContractNames.forEach((reservedDataContractName) => {
@@ -556,12 +1029,27 @@ const allEndpointPerFileTmpl = async (params) => {
556
1029
  return { ...newEndpointTemplateData, route };
557
1030
  });
558
1031
  const extraImportLines = [];
1032
+ const hasAnyZodContracts = newEndpointTemplates.some(
1033
+ (t) => t.contractsCode != null
1034
+ );
1035
+ const allZodSchemaImportNames = /* @__PURE__ */ new Set();
1036
+ newEndpointTemplates.forEach((t) => {
1037
+ const c = t.contractsCode;
1038
+ if (c != null && typeof c === "object" && c.zodSchemaImportNames?.length) {
1039
+ for (const n of c.zodSchemaImportNames) {
1040
+ allZodSchemaImportNames.add(n);
1041
+ }
1042
+ }
1043
+ });
1044
+ const zodImportLine = hasAnyZodContracts ? 'import * as z from "zod";' : "";
1045
+ const zodSchemasImportLine = allZodSchemaImportNames.size && relativePathZodSchemas ? `import { ${[...allZodSchemaImportNames].sort().join(", ")} } from "${relativePathZodSchemas}";` : "";
559
1046
  const endpointTemplates = await Promise.all(
560
1047
  newEndpointTemplates.map(
561
1048
  async ({
562
1049
  content: requestInfoInstanceContent,
563
1050
  localModelTypes,
564
- route
1051
+ route,
1052
+ contractsCode
565
1053
  }) => {
566
1054
  const requestInfoMeta = codegenParams.getEndpointMeta?.(route, utils);
567
1055
  if (requestInfoMeta?.typeNameImportPath && requestInfoMeta.typeName) {
@@ -569,6 +1057,12 @@ const allEndpointPerFileTmpl = async (params) => {
569
1057
  `import { ${requestInfoMeta.typeName} } from "${requestInfoMeta.typeNameImportPath}";`
570
1058
  );
571
1059
  }
1060
+ const contractsResult = contractsCode != null && typeof contractsCode === "object" ? contractsCode : null;
1061
+ const contractsBlock = contractsResult != null ? `
1062
+
1063
+ ${contractsResult.content}
1064
+
1065
+ ` : "";
572
1066
  return `
573
1067
  ${(await Promise.all(
574
1068
  localModelTypes.map(async (modelType) => {
@@ -580,7 +1074,7 @@ const allEndpointPerFileTmpl = async (params) => {
580
1074
  return contractType;
581
1075
  })
582
1076
  )).filter(Boolean).join("\n\n")}
583
-
1077
+ ${contractsBlock}
584
1078
  ${endpointJSDocTmpl({
585
1079
  ...params,
586
1080
  route
@@ -607,6 +1101,7 @@ const allEndpointPerFileTmpl = async (params) => {
607
1101
  import { ${importFileParams.httpClient.exportName} } from "${importFileParams.httpClient.path}";
608
1102
  import { ${importFileParams.queryClient.exportName} } from "${importFileParams.queryClient.path}";
609
1103
  ${extraImportLines.join("\n")}
1104
+ ${[zodImportLine, zodSchemasImportLine].filter(Boolean).join("\n")}
610
1105
  ${dataContractImportToken}
611
1106
 
612
1107
  ${(await Promise.all(
@@ -646,11 +1141,12 @@ const allEndpointPerFileTmpl = async (params) => {
646
1141
  const allExportsTmpl = async ({
647
1142
  collectedExportFiles,
648
1143
  metaInfo,
649
- formatTSContent
1144
+ formatTSContent,
1145
+ exportSchemas
650
1146
  }) => {
651
1147
  return await formatTSContent(`${LINTERS_IGNORE}
652
1148
  export * from './data-contracts';
653
- ${collectedExportFiles.map((fileName) => `export * from './${fileName}';`).join("\n")}
1149
+ ${exportSchemas ? " export * from './schemas';\n " : ""}${collectedExportFiles.map((fileName) => `export * from './${fileName}';`).join("\n")}
654
1150
  ${metaInfo ? 'export * from "./meta-info";' : ""}
655
1151
  `);
656
1152
  };
@@ -689,18 +1185,22 @@ const endpointPerFileTmpl = async (params) => {
689
1185
  utils,
690
1186
  relativePathDataContracts,
691
1187
  groupName,
692
- metaInfo
1188
+ metaInfo,
1189
+ relativePathZodSchemas
693
1190
  } = params;
694
1191
  const { _ } = utils;
695
1192
  const {
696
1193
  content: requestInfoInstanceContent,
697
1194
  reservedDataContractNames,
698
- localModelTypes
1195
+ localModelTypes,
1196
+ contractsCode
699
1197
  } = newEndpointTmpl({
700
1198
  ...params,
701
1199
  route,
702
1200
  groupName,
703
- metaInfo
1201
+ metaInfo,
1202
+ zodContracts: codegenParams.zodContracts,
1203
+ relativePathZodSchemas: relativePathZodSchemas ?? void 0
704
1204
  });
705
1205
  const dataContactNames = new Set(
706
1206
  Object.keys(
@@ -726,6 +1226,15 @@ const endpointPerFileTmpl = async (params) => {
726
1226
  );
727
1227
  }
728
1228
  const dataContractImportToken = "/*__DATA_CONTRACT_IMPORTS__*/";
1229
+ const contractsResult = contractsCode != null && typeof contractsCode === "object" ? contractsCode : null;
1230
+ const zodImportLine = contractsResult != null ? 'import * as z from "zod";' : "";
1231
+ const zodSchemasImportLine = contractsResult?.zodSchemaImportNames?.length && relativePathZodSchemas ? `import { ${contractsResult.zodSchemaImportNames.join(", ")} } from "${relativePathZodSchemas}";` : "";
1232
+ const contractsBlock = contractsResult != null ? `
1233
+
1234
+ ${contractsResult.content}
1235
+
1236
+ ` : "";
1237
+ const zodImportsBlock = [zodImportLine, zodSchemasImportLine].filter(Boolean).join("\n");
729
1238
  const contentWithImportToken = await formatTSContent(`${LINTERS_IGNORE}
730
1239
  import {
731
1240
  RequestParams,
@@ -736,6 +1245,7 @@ const endpointPerFileTmpl = async (params) => {
736
1245
  import { ${importFileParams.httpClient.exportName} } from "${importFileParams.httpClient.path}";
737
1246
  import { ${importFileParams.queryClient.exportName} } from "${importFileParams.queryClient.path}";
738
1247
  ${extraImportLines.join("\n")}
1248
+ ${zodImportsBlock}
739
1249
  ${dataContractImportToken}
740
1250
 
741
1251
  ${(await Promise.all(
@@ -765,7 +1275,7 @@ const endpointPerFileTmpl = async (params) => {
765
1275
  return contractType;
766
1276
  })
767
1277
  )).filter(Boolean).join("\n\n")}
768
-
1278
+ ${contractsBlock}
769
1279
  ${endpointJSDocTmpl({
770
1280
  ...params,
771
1281
  route
@@ -813,7 +1323,7 @@ const unpackFilterOption = (option, argsToString, defaultReturnValue = true) =>
813
1323
  const removeUnusedTypesItteration = async ({
814
1324
  directory,
815
1325
  keepTypes
816
- // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: <explanation>
1326
+ // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: iterative AST traversal
817
1327
  }) => {
818
1328
  const project = new Project();
819
1329
  project.addSourceFilesAtPaths([
@@ -1131,6 +1641,8 @@ const generateApi = async (params) => {
1131
1641
  filterTypes
1132
1642
  };
1133
1643
  const reservedDataContractNamesMap = /* @__PURE__ */ new Map();
1644
+ const componentsSchemasForZod = generated.configuration.config?.swaggerSchema?.components?.schemas ?? generated.configuration.swaggerSchema?.components?.schemas;
1645
+ const hasZodSchemasFile = (params.zodContracts === true || typeof params.zodContracts === "object" && params.zodContracts != null) && componentsSchemasForZod && typeof componentsSchemasForZod === "object" && Object.keys(componentsSchemasForZod).length > 0;
1134
1646
  const collectedExportFilesFromIndexFile = [];
1135
1647
  const groupsMap = /* @__PURE__ */ new Map();
1136
1648
  const nonEmptyGroups = /* @__PURE__ */ new Set();
@@ -1152,7 +1664,8 @@ const generateApi = async (params) => {
1152
1664
  metaInfo: params.noMetaInfo ? null : {
1153
1665
  groupNames: [],
1154
1666
  namespace
1155
- }
1667
+ },
1668
+ relativePathZodSchemas: hasZodSchemasFile ? "../schemas" : null
1156
1669
  });
1157
1670
  if (Array.isArray(route.raw.tags)) {
1158
1671
  route.raw.tags.forEach((tag) => {
@@ -1196,7 +1709,8 @@ const generateApi = async (params) => {
1196
1709
  metaInfo: params.noMetaInfo ? null : {
1197
1710
  namespace,
1198
1711
  groupNames: []
1199
- }
1712
+ },
1713
+ relativePathZodSchemas: hasZodSchemasFile ? "./schemas" : null
1200
1714
  });
1201
1715
  reservedDataContractNames.forEach((name) => {
1202
1716
  reservedDataContractNamesMap.set(
@@ -1392,6 +1906,22 @@ export * as ${exportGroupName} from './endpoints';
1392
1906
  withPrefix: false,
1393
1907
  content: dataContractsContent
1394
1908
  });
1909
+ if (hasZodSchemasFile && componentsSchemasForZod) {
1910
+ const schemasTsContent = buildCentralZodSchemasFile({
1911
+ componentsSchemas: componentsSchemasForZod,
1912
+ utils
1913
+ });
1914
+ const formattedSchemasContent = await generated.formatTSContent(
1915
+ `${LINTERS_IGNORE}
1916
+ ${schemasTsContent}`
1917
+ );
1918
+ codegenFs.createFile({
1919
+ path: paths.outputDir,
1920
+ fileName: "schemas.ts",
1921
+ withPrefix: false,
1922
+ content: formattedSchemasContent
1923
+ });
1924
+ }
1395
1925
  if (metaInfo) {
1396
1926
  codegenFs.createFile({
1397
1927
  path: paths.outputDir,
@@ -1411,7 +1941,8 @@ export * as ${exportGroupName} from './endpoints';
1411
1941
  content: await allExportsTmpl({
1412
1942
  ...baseTmplParams,
1413
1943
  collectedExportFiles: collectedExportFilesFromIndexFile,
1414
- metaInfo
1944
+ metaInfo,
1945
+ exportSchemas: hasZodSchemasFile
1415
1946
  })
1416
1947
  });
1417
1948
  if (shouldGenerateBarrelFiles) {
@@ -1433,7 +1964,8 @@ export * as ${namespace} from './__exports';
1433
1964
  content: await allExportsTmpl({
1434
1965
  ...baseTmplParams,
1435
1966
  collectedExportFiles: collectedExportFilesFromIndexFile,
1436
- metaInfo
1967
+ metaInfo,
1968
+ exportSchemas: hasZodSchemasFile
1437
1969
  })
1438
1970
  });
1439
1971
  }