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