zod-openapi 2.12.0 → 2.14.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.
Files changed (41) hide show
  1. package/README.md +13 -11
  2. package/lib-commonjs/index.js +708 -292
  3. package/lib-esm/{index.js → index.mjs} +708 -292
  4. package/lib-types/create/components.d.ts +25 -2
  5. package/lib-types/create/document.d.ts +3 -2
  6. package/lib-types/create/parameters.d.ts +3 -2
  7. package/lib-types/create/schema/index.d.ts +19 -12
  8. package/lib-types/create/schema/metadata.d.ts +2 -1
  9. package/lib-types/create/schema/parsers/array.d.ts +2 -3
  10. package/lib-types/create/schema/parsers/boolean.d.ts +2 -2
  11. package/lib-types/create/schema/parsers/brand.d.ts +2 -3
  12. package/lib-types/create/schema/parsers/catch.d.ts +2 -3
  13. package/lib-types/create/schema/parsers/date.d.ts +2 -2
  14. package/lib-types/create/schema/parsers/default.d.ts +2 -3
  15. package/lib-types/create/schema/parsers/discriminatedUnion.d.ts +2 -2
  16. package/lib-types/create/schema/parsers/enum.d.ts +2 -2
  17. package/lib-types/create/schema/parsers/index.d.ts +2 -3
  18. package/lib-types/create/schema/parsers/intersection.d.ts +2 -3
  19. package/lib-types/create/schema/parsers/lazy.d.ts +2 -3
  20. package/lib-types/create/schema/parsers/literal.d.ts +2 -2
  21. package/lib-types/create/schema/parsers/manual.d.ts +2 -3
  22. package/lib-types/create/schema/parsers/nativeEnum.d.ts +2 -3
  23. package/lib-types/create/schema/parsers/null.d.ts +2 -2
  24. package/lib-types/create/schema/parsers/nullable.d.ts +2 -3
  25. package/lib-types/create/schema/parsers/number.d.ts +2 -2
  26. package/lib-types/create/schema/parsers/object.d.ts +14 -6
  27. package/lib-types/create/schema/parsers/optional.d.ts +9 -4
  28. package/lib-types/create/schema/parsers/pipeline.d.ts +2 -3
  29. package/lib-types/create/schema/parsers/preprocess.d.ts +2 -3
  30. package/lib-types/create/schema/parsers/readonly.d.ts +2 -3
  31. package/lib-types/create/schema/parsers/record.d.ts +2 -3
  32. package/lib-types/create/schema/parsers/refine.d.ts +2 -3
  33. package/lib-types/create/schema/parsers/set.d.ts +2 -3
  34. package/lib-types/create/schema/parsers/string.d.ts +2 -2
  35. package/lib-types/create/schema/parsers/transform.d.ts +8 -4
  36. package/lib-types/create/schema/parsers/tuple.d.ts +2 -3
  37. package/lib-types/create/schema/parsers/union.d.ts +2 -3
  38. package/lib-types/create/schema/parsers/unknown.d.ts +2 -2
  39. package/lib-types/extendZod.d.ts +26 -7
  40. package/lib-types/openapi3-ts/dist/model/openapi31.d.ts +1 -1
  41. package/package.json +17 -11
@@ -34,30 +34,27 @@ var isAnyZodType = (zodType) => Boolean(
34
34
  zodType?._def?.typeName
35
35
  );
36
36
 
37
- // src/openapi.ts
38
- var openApiVersions = [
39
- "3.0.0",
40
- "3.0.1",
41
- "3.0.2",
42
- "3.0.3",
43
- "3.1.0"
44
- ];
45
- var satisfiesVersion = (test, against) => openApiVersions.indexOf(test) >= openApiVersions.indexOf(against);
46
- var isReferenceObject = (schemaOrRef) => Boolean("$ref" in schemaOrRef && schemaOrRef.$ref);
47
-
48
37
  // src/create/schema/metadata.ts
49
- var enhanceWithMetadata = (schemaObject, metadata) => {
50
- if (isReferenceObject(schemaObject)) {
38
+ var enhanceWithMetadata = (schema, metadata) => {
39
+ if (schema.type === "ref") {
51
40
  if (Object.values(metadata).every((val) => val === void 0)) {
52
- return schemaObject;
41
+ return schema;
53
42
  }
54
43
  return {
55
- allOf: [schemaObject, metadata]
44
+ type: "schema",
45
+ schema: {
46
+ allOf: [schema.schema, metadata]
47
+ },
48
+ effects: schema.effects
56
49
  };
57
50
  }
58
51
  return {
59
- ...schemaObject,
60
- ...metadata
52
+ type: "schema",
53
+ schema: {
54
+ ...schema.schema,
55
+ ...metadata
56
+ },
57
+ effects: schema.effects
61
58
  };
62
59
  };
63
60
 
@@ -66,17 +63,25 @@ var createArraySchema = (zodArray, state) => {
66
63
  const zodType = zodArray._def.type;
67
64
  const minItems = zodArray._def.exactLength?.value ?? zodArray._def.minLength?.value;
68
65
  const maxItems = zodArray._def.exactLength?.value ?? zodArray._def.maxLength?.value;
66
+ const items = createSchemaObject(zodType, state, ["array items"]);
69
67
  return {
70
- type: "array",
71
- items: createSchemaObject(zodType, state, ["array items"]),
72
- ...minItems !== void 0 && { minItems },
73
- ...maxItems !== void 0 && { maxItems }
68
+ type: "schema",
69
+ schema: {
70
+ type: "array",
71
+ items: items.schema,
72
+ ...minItems !== void 0 && { minItems },
73
+ ...maxItems !== void 0 && { maxItems }
74
+ },
75
+ effects: items.effects
74
76
  };
75
77
  };
76
78
 
77
79
  // src/create/schema/parsers/boolean.ts
78
80
  var createBooleanSchema = (_zodBoolean) => ({
79
- type: "boolean"
81
+ type: "schema",
82
+ schema: {
83
+ type: "boolean"
84
+ }
80
85
  });
81
86
 
82
87
  // src/create/schema/parsers/brand.ts
@@ -87,7 +92,10 @@ var createCatchSchema = (zodCatch, state) => createSchemaObject(zodCatch._def.in
87
92
 
88
93
  // src/create/schema/parsers/date.ts
89
94
  var createDateSchema = (_zodDate) => ({
90
- type: "string"
95
+ type: "schema",
96
+ schema: {
97
+ type: "string"
98
+ }
91
99
  });
92
100
 
93
101
  // src/create/schema/parsers/default.ts
@@ -100,21 +108,186 @@ var createDefaultSchema = (zodDefault, state) => {
100
108
  });
101
109
  };
102
110
 
111
+ // src/create/schema/parsers/transform.ts
112
+ var createTransformSchema = (zodTransform, state) => {
113
+ if (zodTransform._def.openapi?.effectType === "output") {
114
+ return {
115
+ type: "schema",
116
+ schema: createManualOutputTransformSchema(zodTransform, state)
117
+ };
118
+ }
119
+ if (zodTransform._def.openapi?.effectType === "input" || zodTransform._def.openapi?.effectType === "same") {
120
+ return createSchemaObject(zodTransform._def.schema, state, [
121
+ "transform input"
122
+ ]);
123
+ }
124
+ if (state.type === "output") {
125
+ return {
126
+ type: "schema",
127
+ schema: createManualOutputTransformSchema(zodTransform, state)
128
+ };
129
+ }
130
+ const schema = createSchemaObject(zodTransform._def.schema, state, [
131
+ "transform input"
132
+ ]);
133
+ return {
134
+ ...schema,
135
+ effects: flattenEffects([
136
+ [
137
+ {
138
+ type: "schema",
139
+ creationType: "input",
140
+ zodType: zodTransform,
141
+ path: [...state.path]
142
+ }
143
+ ],
144
+ schema.effects
145
+ ])
146
+ };
147
+ };
148
+ var createManualOutputTransformSchema = (zodTransform, state) => {
149
+ if (!zodTransform._def.openapi?.type) {
150
+ const zodType = zodTransform.constructor.name;
151
+ const schemaName = `${zodType} - ${zodTransform._def.effect.type}`;
152
+ throw new Error(
153
+ `Failed to determine a type for ${schemaName} at ${state.path.join(
154
+ " > "
155
+ )}. Please change the 'effectType' to 'input', wrap it in a ZodPipeline or assign it a manual 'type'.`
156
+ );
157
+ }
158
+ return {
159
+ type: zodTransform._def.openapi.type
160
+ };
161
+ };
162
+ var getZodTypeName = (zodType) => {
163
+ if (isZodType(zodType, "ZodEffects")) {
164
+ return `${zodType._def.typeName} - ${zodType._def.effect.type}`;
165
+ }
166
+ return zodType._def.typeName;
167
+ };
168
+ var throwTransformError = (effect) => {
169
+ const typeName = getZodTypeName(effect.zodType);
170
+ const input = effect.creationType;
171
+ const opposite = input === "input" ? "output" : "input";
172
+ throw new Error(
173
+ `The ${typeName} at ${effect.path.join(
174
+ " > "
175
+ )} is used within a registered compoment schema${effect.component ? ` (${effect.component.ref})` : ""} and contains an ${input} transformation${effect.component ? ` (${getZodTypeName(
176
+ effect.component.zodType
177
+ )}) defined at ${effect.component.path.join(" > ")}` : ""} which is also used in an ${opposite} schema.
178
+
179
+ This may cause the schema to render incorrectly and is most likely a mistake. You can resolve this by:
180
+
181
+ 1. Setting an \`effectType\` on one of the transformations to \`same\` (Not applicable for ZodDefault), \`input\` or \`output\` eg. \`.openapi({type: 'same'})\`
182
+ 2. Wrapping the transformation in a ZodPipeline
183
+ 3. Assigning a manual type to the transformation eg. \`.openapi({type: 'string'})\`
184
+ 4. Removing the transformation
185
+ 5. Deregister the component containing the transformation`
186
+ );
187
+ };
188
+ var resolveSingleEffect = (effect, state) => {
189
+ if (effect.type === "schema") {
190
+ return {
191
+ creationType: effect.creationType,
192
+ path: effect.path,
193
+ zodType: effect.zodType
194
+ };
195
+ }
196
+ if (effect.type === "component") {
197
+ if (state.visited.has(effect.zodType)) {
198
+ return;
199
+ }
200
+ const component = state.components.schemas.get(effect.zodType);
201
+ if (component?.type !== "complete") {
202
+ throw new Error("Something went wrong, component schema is not complete");
203
+ }
204
+ if (component.resolvedEffect) {
205
+ return {
206
+ creationType: component.resolvedEffect.creationType,
207
+ path: effect.path,
208
+ zodType: effect.zodType,
209
+ component: {
210
+ ref: component.ref,
211
+ zodType: component.resolvedEffect.zodType,
212
+ path: component.resolvedEffect.path
213
+ }
214
+ };
215
+ }
216
+ if (!component.effects) {
217
+ return void 0;
218
+ }
219
+ state.visited.add(effect.zodType);
220
+ const resolved = resolveEffect(component.effects, state);
221
+ state.visited.delete(effect.zodType);
222
+ if (!resolved) {
223
+ return void 0;
224
+ }
225
+ component.resolvedEffect = resolved;
226
+ return resolved;
227
+ }
228
+ return void 0;
229
+ };
230
+ var resolveEffect = (effects, state) => {
231
+ const { input, output } = effects.reduce(
232
+ (acc, effect) => {
233
+ const resolvedSchemaEffect = resolveSingleEffect(effect, state);
234
+ if (resolvedSchemaEffect?.creationType === "input") {
235
+ acc.input.push(resolvedSchemaEffect);
236
+ }
237
+ if (resolvedSchemaEffect?.creationType === "output") {
238
+ acc.output.push(resolvedSchemaEffect);
239
+ }
240
+ if (resolvedSchemaEffect && acc.input.length > 1 && acc.output.length > 1) {
241
+ throwTransformError(resolvedSchemaEffect);
242
+ }
243
+ return acc;
244
+ },
245
+ { input: [], output: [] }
246
+ );
247
+ if (input.length > 0) {
248
+ return input[0];
249
+ }
250
+ if (output.length > 0) {
251
+ return output[0];
252
+ }
253
+ return void 0;
254
+ };
255
+ var verifyEffects = (effects, state) => {
256
+ const resolved = resolveEffect(effects, state);
257
+ if (resolved?.creationType && resolved.creationType !== state.type) {
258
+ throwTransformError(resolved);
259
+ }
260
+ };
261
+ var flattenEffects = (effects) => {
262
+ const allEffects = effects.reduce((acc, effect) => {
263
+ if (effect) {
264
+ return acc.concat(effect);
265
+ }
266
+ return acc;
267
+ }, []);
268
+ return allEffects.length ? allEffects : void 0;
269
+ };
270
+
103
271
  // src/create/schema/parsers/discriminatedUnion.ts
104
272
  var createDiscriminatedUnionSchema = (zodDiscriminatedUnion, state) => {
105
273
  const options = zodDiscriminatedUnion.options;
106
274
  const schemas = options.map(
107
275
  (option, index) => createSchemaObject(option, state, [`discriminated union option ${index}`])
108
276
  );
277
+ const schemaObjects = schemas.map((schema) => schema.schema);
109
278
  const discriminator = mapDiscriminator(
110
- schemas,
279
+ schemaObjects,
111
280
  options,
112
281
  zodDiscriminatedUnion.discriminator,
113
282
  state
114
283
  );
115
284
  return {
116
- oneOf: schemas,
117
- ...discriminator && { discriminator }
285
+ type: "schema",
286
+ schema: {
287
+ oneOf: schemaObjects,
288
+ ...discriminator && { discriminator }
289
+ },
290
+ effects: flattenEffects(schemas.map((schema) => schema.effects))
118
291
  };
119
292
  };
120
293
  var mapDiscriminator = (schemas, zodObjects, discriminator, state) => {
@@ -153,19 +326,29 @@ var mapDiscriminator = (schemas, zodObjects, discriminator, state) => {
153
326
 
154
327
  // src/create/schema/parsers/enum.ts
155
328
  var createEnumSchema = (zodEnum) => ({
156
- type: "string",
157
- enum: zodEnum._def.values
329
+ type: "schema",
330
+ schema: {
331
+ type: "string",
332
+ enum: zodEnum._def.values
333
+ }
158
334
  });
159
335
 
160
336
  // src/create/schema/parsers/intersection.ts
161
- var createIntersectionSchema = (zodIntersection, state) => ({
162
- allOf: [
163
- createSchemaObject(zodIntersection._def.left, state, ["intersection left"]),
164
- createSchemaObject(zodIntersection._def.right, state, [
165
- "intersection right"
166
- ])
167
- ]
168
- });
337
+ var createIntersectionSchema = (zodIntersection, state) => {
338
+ const left = createSchemaObject(zodIntersection._def.left, state, [
339
+ "intersection left"
340
+ ]);
341
+ const right = createSchemaObject(zodIntersection._def.right, state, [
342
+ "intersection right"
343
+ ]);
344
+ return {
345
+ type: "schema",
346
+ schema: {
347
+ allOf: [left.schema, right.schema]
348
+ },
349
+ effects: flattenEffects([left.effects, right.effects])
350
+ };
351
+ };
169
352
 
170
353
  // src/create/schema/parsers/lazy.ts
171
354
  var createLazySchema = (zodLazy, state) => {
@@ -175,8 +358,11 @@ var createLazySchema = (zodLazy, state) => {
175
358
 
176
359
  // src/create/schema/parsers/literal.ts
177
360
  var createLiteralSchema = (zodLiteral) => ({
178
- type: typeof zodLiteral.value,
179
- enum: [zodLiteral._def.value]
361
+ type: "schema",
362
+ schema: {
363
+ type: typeof zodLiteral.value,
364
+ enum: [zodLiteral._def.value]
365
+ }
180
366
  });
181
367
 
182
368
  // src/create/schema/parsers/manual.ts
@@ -190,10 +376,23 @@ var createManualTypeSchema = (zodSchema, state) => {
190
376
  );
191
377
  }
192
378
  return {
193
- type: zodSchema._def.openapi.type
379
+ type: "schema",
380
+ schema: {
381
+ type: zodSchema._def.openapi.type
382
+ }
194
383
  };
195
384
  };
196
385
 
386
+ // src/openapi.ts
387
+ var openApiVersions = [
388
+ "3.0.0",
389
+ "3.0.1",
390
+ "3.0.2",
391
+ "3.0.3",
392
+ "3.1.0"
393
+ ];
394
+ var satisfiesVersion = (test, against) => openApiVersions.indexOf(test) >= openApiVersions.indexOf(against);
395
+
197
396
  // src/create/schema/parsers/nativeEnum.ts
198
397
  var createNativeEnumSchema = (zodEnum, state) => {
199
398
  const enumValues = getValidEnumValues(zodEnum._def.values);
@@ -201,25 +400,37 @@ var createNativeEnumSchema = (zodEnum, state) => {
201
400
  if (strings.length && numbers.length) {
202
401
  if (satisfiesVersion(state.components.openapi, "3.1.0"))
203
402
  return {
204
- type: ["string", "number"],
205
- enum: [...strings, ...numbers]
403
+ type: "schema",
404
+ schema: {
405
+ type: ["string", "number"],
406
+ enum: [...strings, ...numbers]
407
+ }
206
408
  };
207
409
  return {
208
- oneOf: [
209
- { type: "string", enum: strings },
210
- { type: "number", enum: numbers }
211
- ]
410
+ type: "schema",
411
+ schema: {
412
+ oneOf: [
413
+ { type: "string", enum: strings },
414
+ { type: "number", enum: numbers }
415
+ ]
416
+ }
212
417
  };
213
418
  }
214
419
  if (strings.length) {
215
420
  return {
216
- type: "string",
217
- enum: strings
421
+ type: "schema",
422
+ schema: {
423
+ type: "string",
424
+ enum: strings
425
+ }
218
426
  };
219
427
  }
220
428
  return {
221
- type: "number",
222
- enum: numbers
429
+ type: "schema",
430
+ schema: {
431
+ type: "number",
432
+ enum: numbers
433
+ }
223
434
  };
224
435
  };
225
436
  var getValidEnumValues = (enumValues) => {
@@ -235,7 +446,10 @@ var sortStringsAndNumbers = (values) => ({
235
446
 
236
447
  // src/create/schema/parsers/null.ts
237
448
  var createNullSchema = (_zodNull) => ({
238
- type: "null"
449
+ type: "schema",
450
+ schema: {
451
+ type: "null"
452
+ }
239
453
  });
240
454
 
241
455
  // src/create/schema/parsers/nullable.ts
@@ -244,45 +458,69 @@ var createNullableSchema = (zodNullable, state) => {
244
458
  "nullable"
245
459
  ]);
246
460
  if (satisfiesVersion(state.components.openapi, "3.1.0")) {
247
- if (isReferenceObject(schemaObject) || schemaObject.allOf) {
461
+ if (schemaObject.type === "ref" || schemaObject.schema.allOf) {
248
462
  return {
249
- oneOf: mapNullOf([schemaObject], state.components.openapi)
463
+ type: "schema",
464
+ schema: {
465
+ oneOf: mapNullOf([schemaObject.schema], state.components.openapi)
466
+ },
467
+ effects: schemaObject.effects
250
468
  };
251
469
  }
252
- if (schemaObject.oneOf) {
253
- const { oneOf, ...schema3 } = schemaObject;
470
+ if (schemaObject.schema.oneOf) {
471
+ const { oneOf, ...schema3 } = schemaObject.schema;
254
472
  return {
255
- oneOf: mapNullOf(oneOf, state.components.openapi),
256
- ...schema3
473
+ type: "schema",
474
+ schema: {
475
+ oneOf: mapNullOf(oneOf, state.components.openapi),
476
+ ...schema3
477
+ },
478
+ effects: schemaObject.effects
257
479
  };
258
480
  }
259
- if (schemaObject.anyOf) {
260
- const { anyOf, ...schema3 } = schemaObject;
481
+ if (schemaObject.schema.anyOf) {
482
+ const { anyOf, ...schema3 } = schemaObject.schema;
261
483
  return {
262
- anyOf: mapNullOf(anyOf, state.components.openapi),
263
- ...schema3
484
+ type: "schema",
485
+ schema: {
486
+ anyOf: mapNullOf(anyOf, state.components.openapi),
487
+ ...schema3
488
+ },
489
+ effects: schemaObject.effects
264
490
  };
265
491
  }
266
- const { type: type2, ...schema2 } = schemaObject;
492
+ const { type: type2, ...schema2 } = schemaObject.schema;
267
493
  return {
268
- type: mapNullType(type2),
269
- ...schema2
494
+ type: "schema",
495
+ schema: {
496
+ type: mapNullType(type2),
497
+ ...schema2
498
+ },
499
+ effects: schemaObject.effects
270
500
  };
271
501
  }
272
- if (isReferenceObject(schemaObject)) {
502
+ if (schemaObject.type === "ref") {
273
503
  return {
274
- allOf: [schemaObject],
275
- nullable: true
504
+ type: "schema",
505
+ schema: {
506
+ allOf: [schemaObject.schema],
507
+ nullable: true
508
+ },
509
+ effects: schemaObject.effects
276
510
  };
277
511
  }
278
- const { type, ...schema } = schemaObject;
512
+ const { type, ...schema } = schemaObject.schema;
279
513
  return {
280
- ...type && { type },
281
- nullable: true,
282
- ...schema,
283
- // https://github.com/OAI/OpenAPI-Specification/blob/main/proposals/2019-10-31-Clarify-Nullable.md#if-a-schema-specifies-nullable-true-and-enum-1-2-3-does-that-schema-allow-null-values-see-1900
284
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
285
- ...schema.enum && { enum: [...schema.enum, null] }
514
+ type: "schema",
515
+ schema: {
516
+ ...type && { type },
517
+ nullable: true,
518
+ ...schema,
519
+ // https://github.com/OAI/OpenAPI-Specification/blob/main/proposals/2019-10-31-Clarify-Nullable.md#if-a-schema-specifies-nullable-true-and-enum-1-2-3-does-that-schema-allow-null-values-see-1900
520
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
521
+ ...schema.enum && { enum: [...schema.enum, null] }
522
+ },
523
+ effects: schemaObject.effects
286
524
  };
287
525
  };
288
526
  var mapNullType = (type) => {
@@ -307,10 +545,13 @@ var createNumberSchema = (zodNumber, state) => {
307
545
  const minimum = mapMinimum(zodNumberChecks, state.components.openapi);
308
546
  const maximum = mapMaximum(zodNumberChecks, state.components.openapi);
309
547
  return {
310
- type: mapNumberType(zodNumberChecks),
311
- ...minimum && minimum,
312
- // Union types are not easy to tame
313
- ...maximum && maximum
548
+ type: "schema",
549
+ schema: {
550
+ type: mapNumberType(zodNumberChecks),
551
+ ...minimum && minimum,
552
+ // Union types are not easy to tame
553
+ ...maximum && maximum
554
+ }
314
555
  };
315
556
  };
316
557
  var mapMaximum = (zodNumberCheck, openapi) => {
@@ -346,16 +587,29 @@ var getZodNumberChecks = (zodNumber) => zodNumber._def.checks.reduce((acc, check
346
587
  var mapNumberType = (zodNumberChecks) => zodNumberChecks.int ? "integer" : "number";
347
588
 
348
589
  // src/create/schema/parsers/optional.ts
349
- var createOptionalSchema = (zodOptional, state) => (
350
- // Optional doesn't change OpenAPI schema
351
- createSchemaObject(zodOptional.unwrap(), state, ["optional"])
352
- );
590
+ var createOptionalSchema = (zodOptional, state) => createSchemaObject(zodOptional.unwrap(), state, ["optional"]);
353
591
  var isOptionalSchema = (zodSchema, state) => {
354
592
  if (isZodType(zodSchema, "ZodOptional") || isZodType(zodSchema, "ZodNever") || isZodType(zodSchema, "ZodUndefined")) {
355
- return true;
593
+ return { optional: true };
356
594
  }
357
595
  if (isZodType(zodSchema, "ZodDefault")) {
358
- return state.type === "input";
596
+ if (zodSchema._def.openapi?.effectType === "input") {
597
+ return { optional: true };
598
+ }
599
+ if (zodSchema._def.openapi?.effectType === "output") {
600
+ return { optional: false };
601
+ }
602
+ return {
603
+ optional: state.type === "input",
604
+ effects: [
605
+ {
606
+ type: "schema",
607
+ creationType: state.type,
608
+ zodType: zodSchema,
609
+ path: [...state.path]
610
+ }
611
+ ]
612
+ };
359
613
  }
360
614
  if (isZodType(zodSchema, "ZodNullable") || isZodType(zodSchema, "ZodCatch")) {
361
615
  return isOptionalSchema(zodSchema._def.innerType, state);
@@ -364,27 +618,42 @@ var isOptionalSchema = (zodSchema, state) => {
364
618
  return isOptionalSchema(zodSchema._def.schema, state);
365
619
  }
366
620
  if (isZodType(zodSchema, "ZodUnion") || isZodType(zodSchema, "ZodDiscriminatedUnion")) {
367
- return zodSchema._def.options.some(
621
+ const results = zodSchema._def.options.map(
368
622
  (schema) => isOptionalSchema(schema, state)
369
623
  );
624
+ return results.reduce(
625
+ (acc, result) => ({
626
+ optional: acc.optional || result.optional,
627
+ effects: flattenEffects([acc.effects, result.effects])
628
+ }),
629
+ { optional: false }
630
+ );
370
631
  }
371
632
  if (isZodType(zodSchema, "ZodIntersection")) {
372
- return [zodSchema._def.left, zodSchema._def.right].some(
633
+ const results = [zodSchema._def.left, zodSchema._def.right].map(
373
634
  (schema) => isOptionalSchema(schema, state)
374
635
  );
636
+ return results.reduce(
637
+ (acc, result) => ({
638
+ optional: acc.optional || result.optional,
639
+ effects: flattenEffects([acc.effects, result.effects])
640
+ }),
641
+ { optional: false }
642
+ );
375
643
  }
376
644
  if (isZodType(zodSchema, "ZodPipeline")) {
377
- if (state.effectType === "input" || state.type === "input" && state.effectType !== "output") {
645
+ const type = zodSchema._def.openapi?.effectType ?? state.type;
646
+ if (type === "input") {
378
647
  return isOptionalSchema(zodSchema._def.in, state);
379
648
  }
380
- if (state.effectType === "output" || state.type === "output" && state.effectType !== "input") {
649
+ if (type === "output") {
381
650
  return isOptionalSchema(zodSchema._def.out, state);
382
651
  }
383
652
  }
384
653
  if (isZodType(zodSchema, "ZodLazy")) {
385
654
  return isOptionalSchema(zodSchema._def.getter(), state);
386
655
  }
387
- return zodSchema.isOptional();
656
+ return { optional: zodSchema.isOptional() };
388
657
  };
389
658
 
390
659
  // src/create/schema/parsers/object.ts
@@ -438,9 +707,28 @@ var createExtendedSchema = (zodObject, baseZodObject, state) => {
438
707
  if (!diffShape) {
439
708
  return void 0;
440
709
  }
710
+ const extendedSchema = createObjectSchemaFromShape(
711
+ diffShape,
712
+ diffOpts,
713
+ state
714
+ );
441
715
  return {
442
- allOf: [{ $ref: createComponentSchemaRef(completeComponent.ref) }],
443
- ...createObjectSchemaFromShape(diffShape, diffOpts, state)
716
+ type: "schema",
717
+ schema: {
718
+ allOf: [{ $ref: createComponentSchemaRef(completeComponent.ref) }],
719
+ ...extendedSchema.schema
720
+ },
721
+ effects: flattenEffects([
722
+ completeComponent.type === "complete" ? completeComponent.effects : [],
723
+ completeComponent.type === "in-progress" ? [
724
+ {
725
+ type: "component",
726
+ zodType: zodObject,
727
+ path: [...state.path]
728
+ }
729
+ ] : [],
730
+ extendedSchema.effects
731
+ ])
444
732
  };
445
733
  };
446
734
  var createDiffOpts = (baseOpts, extendedOpts) => {
@@ -470,50 +758,114 @@ var createShapeDiff = (baseObj, extendedObj) => {
470
758
  var createObjectSchemaFromShape = (shape, { unknownKeys, catchAll }, state) => {
471
759
  const properties = mapProperties(shape, state);
472
760
  const required = mapRequired(shape, state);
761
+ const additionalProperties = !isZodType(catchAll, "ZodNever") ? createSchemaObject(catchAll, state, ["additional properties"]) : void 0;
473
762
  return {
474
- type: "object",
475
- ...properties && { properties },
476
- ...required && { required },
477
- ...unknownKeys === "strict" && { additionalProperties: false },
478
- ...!isZodType(catchAll, "ZodNever") && {
479
- additionalProperties: createSchemaObject(catchAll, state, [
480
- "additional properties"
481
- ])
482
- }
763
+ type: "schema",
764
+ schema: {
765
+ type: "object",
766
+ ...properties && { properties: properties.properties },
767
+ ...required?.required.length && { required: required.required },
768
+ ...unknownKeys === "strict" && { additionalProperties: false },
769
+ ...additionalProperties && {
770
+ additionalProperties: additionalProperties.schema
771
+ }
772
+ },
773
+ effects: flattenEffects([
774
+ ...properties?.effects ?? [],
775
+ additionalProperties?.effects,
776
+ required?.effects
777
+ ])
483
778
  };
484
779
  };
485
780
  var mapRequired = (shape, state) => {
486
- const required = Object.entries(shape).filter(([_key, zodSchema]) => !isOptionalSchema(zodSchema, state)).map(([key]) => key);
487
- if (!required.length) {
781
+ const { required, effects: allEffects } = Object.entries(shape).reduce(
782
+ (acc, [key, zodSchema]) => {
783
+ state.path.push(`property: ${key}`);
784
+ const { optional, effects } = isOptionalSchema(zodSchema, state);
785
+ state.path.pop();
786
+ if (!optional) {
787
+ acc.required.push(key);
788
+ }
789
+ if (effects) {
790
+ acc.effects.push(effects);
791
+ }
792
+ return acc;
793
+ },
794
+ {
795
+ required: [],
796
+ effects: []
797
+ }
798
+ );
799
+ return { required, effects: flattenEffects(allEffects) };
800
+ };
801
+ var mapProperties = (shape, state) => {
802
+ const shapeEntries = Object.entries(shape);
803
+ if (!shapeEntries.length) {
488
804
  return void 0;
489
805
  }
490
- return required;
491
- };
492
- var mapProperties = (shape, state) => Object.entries(shape).reduce(
493
- (acc, [key, zodSchema]) => {
494
- if (isZodType(zodSchema, "ZodNever") || isZodType(zodSchema, "ZodUndefined")) {
806
+ return shapeEntries.reduce(
807
+ (acc, [key, zodSchema]) => {
808
+ if (isZodType(zodSchema, "ZodNever") || isZodType(zodSchema, "ZodUndefined")) {
809
+ return acc;
810
+ }
811
+ const property = createSchemaObject(zodSchema, state, [
812
+ `property: ${key}`
813
+ ]);
814
+ acc.properties[key] = property.schema;
815
+ acc.effects.push(property.effects);
495
816
  return acc;
817
+ },
818
+ {
819
+ properties: {},
820
+ effects: []
496
821
  }
497
- acc[key] = createSchemaObject(zodSchema, state, [`property: ${key}`]);
498
- return acc;
499
- },
500
- {}
501
- );
822
+ );
823
+ };
502
824
 
503
825
  // src/create/schema/parsers/pipeline.ts
504
826
  var createPipelineSchema = (zodPipeline, state) => {
505
- if (zodPipeline._def.openapi?.effectType === "input") {
827
+ if (zodPipeline._def.openapi?.effectType === "input" || zodPipeline._def.openapi?.effectType === "same") {
506
828
  return createSchemaObject(zodPipeline._def.in, state, ["pipeline input"]);
507
829
  }
508
830
  if (zodPipeline._def.openapi?.effectType === "output") {
509
831
  return createSchemaObject(zodPipeline._def.out, state, ["pipeline output"]);
510
832
  }
511
833
  if (state.type === "input") {
512
- state.effectType = "input";
513
- return createSchemaObject(zodPipeline._def.in, state, ["pipeline input"]);
834
+ const schema2 = createSchemaObject(zodPipeline._def.in, state, [
835
+ "pipeline input"
836
+ ]);
837
+ return {
838
+ ...schema2,
839
+ effects: flattenEffects([
840
+ [
841
+ {
842
+ type: "schema",
843
+ creationType: "input",
844
+ path: [...state.path],
845
+ zodType: zodPipeline
846
+ }
847
+ ],
848
+ schema2.effects
849
+ ])
850
+ };
514
851
  }
515
- state.effectType = "output";
516
- return createSchemaObject(zodPipeline._def.out, state, ["pipeline output"]);
852
+ const schema = createSchemaObject(zodPipeline._def.out, state, [
853
+ "pipeline output"
854
+ ]);
855
+ return {
856
+ ...schema,
857
+ effects: flattenEffects([
858
+ [
859
+ {
860
+ type: "schema",
861
+ creationType: "output",
862
+ path: [...state.path],
863
+ zodType: zodPipeline
864
+ }
865
+ ],
866
+ schema.effects
867
+ ])
868
+ };
517
869
  };
518
870
 
519
871
  // src/create/schema/parsers/preprocess.ts
@@ -535,29 +887,50 @@ var createRecordSchema = (zodRecord, state) => {
535
887
  const keySchema = createSchemaObject(zodRecord.keySchema, state, [
536
888
  "record key"
537
889
  ]);
538
- const maybeComponent = "$ref" in keySchema && state.components.schemas.get(zodRecord.keySchema);
539
- const maybeSchema = maybeComponent && maybeComponent.type === "complete" && maybeComponent.schemaObject;
540
- const renderedKeySchema = maybeSchema || keySchema;
890
+ const maybeComponent = state.components.schemas.get(zodRecord.keySchema);
891
+ const isComplete = maybeComponent && maybeComponent.type === "complete";
892
+ const maybeSchema = isComplete && maybeComponent.schemaObject;
893
+ const maybeEffects = isComplete && maybeComponent.effects || void 0;
894
+ const renderedKeySchema = maybeSchema || keySchema.schema;
541
895
  if ("enum" in renderedKeySchema && renderedKeySchema.enum) {
542
896
  return {
543
- type: "object",
544
- properties: renderedKeySchema.enum.reduce((acc, key) => {
545
- acc[key] = additionalProperties;
546
- return acc;
547
- }, {}),
548
- additionalProperties: false
897
+ type: "schema",
898
+ schema: {
899
+ type: "object",
900
+ properties: renderedKeySchema.enum.reduce((acc, key) => {
901
+ acc[key] = additionalProperties.schema;
902
+ return acc;
903
+ }, {}),
904
+ additionalProperties: false
905
+ },
906
+ effects: flattenEffects([
907
+ keySchema.effects,
908
+ additionalProperties.effects,
909
+ maybeEffects
910
+ ])
549
911
  };
550
912
  }
551
913
  if (satisfiesVersion(state.components.openapi, "3.1.0") && "type" in renderedKeySchema && renderedKeySchema.type === "string" && Object.keys(renderedKeySchema).length > 1) {
552
914
  return {
553
- type: "object",
554
- propertyNames: keySchema,
555
- additionalProperties
915
+ type: "schema",
916
+ schema: {
917
+ type: "object",
918
+ propertyNames: keySchema.schema,
919
+ additionalProperties: additionalProperties.schema
920
+ },
921
+ effects: flattenEffects([
922
+ keySchema.effects,
923
+ additionalProperties.effects
924
+ ])
556
925
  };
557
926
  }
558
927
  return {
559
- type: "object",
560
- additionalProperties
928
+ type: "schema",
929
+ schema: {
930
+ type: "object",
931
+ additionalProperties: additionalProperties.schema
932
+ },
933
+ effects: additionalProperties.effects
561
934
  };
562
935
  };
563
936
 
@@ -569,12 +942,17 @@ var createSetSchema = (zodSet, state) => {
569
942
  const schema = zodSet._def.valueType;
570
943
  const minItems = zodSet._def.minSize?.value;
571
944
  const maxItems = zodSet._def.maxSize?.value;
945
+ const itemSchema = createSchemaObject(schema, state, ["set items"]);
572
946
  return {
573
- type: "array",
574
- items: createSchemaObject(schema, state, ["set items"]),
575
- uniqueItems: true,
576
- ...minItems !== void 0 && { minItems },
577
- ...maxItems !== void 0 && { maxItems }
947
+ type: "schema",
948
+ schema: {
949
+ type: "array",
950
+ items: itemSchema.schema,
951
+ uniqueItems: true,
952
+ ...minItems !== void 0 && { minItems },
953
+ ...maxItems !== void 0 && { maxItems }
954
+ },
955
+ effects: itemSchema.effects
578
956
  };
579
957
  };
580
958
 
@@ -587,29 +965,35 @@ var createStringSchema = (zodString) => {
587
965
  const maxLength = zodStringChecks.length?.[0]?.value ?? zodStringChecks.max?.[0]?.value;
588
966
  if (patterns.length <= 1) {
589
967
  return {
590
- type: "string",
591
- ...format && { format },
592
- ...patterns[0] && { pattern: patterns[0] },
593
- ...minLength !== void 0 && { minLength },
594
- ...maxLength !== void 0 && { maxLength }
595
- };
596
- }
597
- return {
598
- allOf: [
599
- {
968
+ type: "schema",
969
+ schema: {
600
970
  type: "string",
601
971
  ...format && { format },
602
972
  ...patterns[0] && { pattern: patterns[0] },
603
973
  ...minLength !== void 0 && { minLength },
604
974
  ...maxLength !== void 0 && { maxLength }
605
- },
606
- ...patterns.slice(1).map(
607
- (pattern) => ({
975
+ }
976
+ };
977
+ }
978
+ return {
979
+ type: "schema",
980
+ schema: {
981
+ allOf: [
982
+ {
608
983
  type: "string",
609
- pattern
610
- })
611
- )
612
- ]
984
+ ...format && { format },
985
+ ...patterns[0] && { pattern: patterns[0] },
986
+ ...minLength !== void 0 && { minLength },
987
+ ...maxLength !== void 0 && { maxLength }
988
+ },
989
+ ...patterns.slice(1).map(
990
+ (pattern) => ({
991
+ type: "string",
992
+ pattern
993
+ })
994
+ )
995
+ ]
996
+ }
613
997
  };
614
998
  };
615
999
  var getZodStringChecks = (zodString) => zodString._def.checks.reduce(
@@ -675,96 +1059,88 @@ var mapStringFormat = (zodStringChecks) => {
675
1059
  return void 0;
676
1060
  };
677
1061
 
678
- // src/create/schema/parsers/transform.ts
679
- var createTransformSchema = (zodTransform, state) => {
680
- if (zodTransform._def.openapi?.effectType === "output") {
681
- return createManualOutputTransformSchema(zodTransform, state);
682
- }
683
- if (zodTransform._def.openapi?.effectType === "input") {
684
- return createSchemaObject(zodTransform._def.schema, state, [
685
- "transform input"
686
- ]);
687
- }
688
- if (state.type === "output") {
689
- return createManualOutputTransformSchema(zodTransform, state);
690
- }
691
- state.effectType = "input";
692
- return createSchemaObject(zodTransform._def.schema, state, [
693
- "transform input"
694
- ]);
695
- };
696
- var createManualOutputTransformSchema = (zodTransform, state) => {
697
- if (!zodTransform._def.openapi?.type) {
698
- const zodType = zodTransform.constructor.name;
699
- const schemaName = `${zodType} - ${zodTransform._def.effect.type}`;
700
- throw new Error(
701
- `Failed to determine a type for ${schemaName} at ${state.path.join(
702
- " > "
703
- )}. Please change the 'effectType' to 'input', wrap it in a ZodPipeline or assign it a manual 'type'.`
704
- );
705
- }
706
- return {
707
- type: zodTransform._def.openapi.type
708
- };
709
- };
710
- var throwTransformError = (zodType, state) => {
711
- throw new Error(
712
- `${JSON.stringify(zodType)} at ${state.path.join(
713
- " > "
714
- )} contains a transformation but is used in both an input and an output. This is likely a mistake. Set an \`effectType\`, wrap it in a ZodPipeline or assign it a manual type to resolve`
715
- );
716
- };
717
-
718
1062
  // src/create/schema/parsers/tuple.ts
719
1063
  var createTupleSchema = (zodTuple, state) => {
720
1064
  const items = zodTuple.items;
721
1065
  const rest = zodTuple._def.rest;
722
- return {
723
- type: "array",
724
- ...mapItemProperties(items, rest, state)
725
- };
726
- };
727
- var mapPrefixItems = (items, state) => {
728
- if (items.length) {
729
- return items.map(
730
- (item, index) => createSchemaObject(item, state, [`tuple item ${index}`])
731
- );
732
- }
733
- return void 0;
734
- };
735
- var mapItemProperties = (items, rest, state) => {
736
1066
  const prefixItems = mapPrefixItems(items, state);
737
1067
  if (satisfiesVersion(state.components.openapi, "3.1.0")) {
738
1068
  if (!rest) {
739
1069
  return {
740
- maxItems: items.length,
741
- minItems: items.length,
742
- ...prefixItems && { prefixItems }
1070
+ type: "schema",
1071
+ schema: {
1072
+ type: "array",
1073
+ maxItems: items.length,
1074
+ minItems: items.length,
1075
+ ...prefixItems && {
1076
+ prefixItems: prefixItems.schemas.map((item) => item.schema)
1077
+ }
1078
+ },
1079
+ effects: prefixItems?.effects
743
1080
  };
744
1081
  }
1082
+ const itemSchema = createSchemaObject(rest, state, ["tuple items"]);
745
1083
  return {
746
- items: createSchemaObject(rest, state, ["tuple items"]),
747
- ...prefixItems && { prefixItems }
1084
+ type: "schema",
1085
+ schema: {
1086
+ type: "array",
1087
+ items: itemSchema.schema,
1088
+ ...prefixItems && {
1089
+ prefixItems: prefixItems.schemas.map((item) => item.schema)
1090
+ }
1091
+ },
1092
+ effects: flattenEffects([prefixItems?.effects, itemSchema.effects])
748
1093
  };
749
1094
  }
750
1095
  if (!rest) {
751
1096
  return {
752
- maxItems: items.length,
753
- minItems: items.length,
754
- ...prefixItems && { items: { oneOf: prefixItems } }
1097
+ type: "schema",
1098
+ schema: {
1099
+ type: "array",
1100
+ maxItems: items.length,
1101
+ minItems: items.length,
1102
+ ...prefixItems && {
1103
+ items: { oneOf: prefixItems.schemas.map((item) => item.schema) }
1104
+ }
1105
+ },
1106
+ effects: prefixItems?.effects
1107
+ };
1108
+ }
1109
+ if (prefixItems) {
1110
+ const restSchema = createSchemaObject(rest, state, ["tuple items"]);
1111
+ return {
1112
+ type: "schema",
1113
+ schema: {
1114
+ type: "array",
1115
+ items: {
1116
+ oneOf: [
1117
+ ...prefixItems.schemas.map((item) => item.schema),
1118
+ restSchema.schema
1119
+ ]
1120
+ }
1121
+ },
1122
+ effects: flattenEffects([restSchema.effects, prefixItems.effects])
755
1123
  };
756
1124
  }
757
1125
  return {
758
- ...prefixItems && {
759
- items: {
760
- oneOf: [
761
- ...prefixItems,
762
- createSchemaObject(rest, state, ["tuple items"])
763
- ]
764
- }
1126
+ type: "schema",
1127
+ schema: {
1128
+ type: "array"
765
1129
  }
766
1130
  };
767
1131
  };
1132
+ var mapPrefixItems = (items, state) => {
1133
+ if (items.length) {
1134
+ const schemas = items.map(
1135
+ (item, index) => createSchemaObject(item, state, [`tuple item ${index}`])
1136
+ );
1137
+ return {
1138
+ effects: flattenEffects(schemas.map((s) => s.effects)),
1139
+ schemas
1140
+ };
1141
+ }
1142
+ return void 0;
1143
+ };
768
1144
 
769
1145
  // src/create/schema/parsers/union.ts
770
1146
  var createUnionSchema = (zodUnion, state) => {
@@ -773,16 +1149,27 @@ var createUnionSchema = (zodUnion, state) => {
773
1149
  );
774
1150
  if (zodUnion._def.openapi?.unionOneOf) {
775
1151
  return {
776
- oneOf: schemas
1152
+ type: "schema",
1153
+ schema: {
1154
+ oneOf: schemas.map((s) => s.schema)
1155
+ },
1156
+ effects: flattenEffects(schemas.map((s) => s.effects))
777
1157
  };
778
1158
  }
779
1159
  return {
780
- anyOf: schemas
1160
+ type: "schema",
1161
+ schema: {
1162
+ anyOf: schemas.map((s) => s.schema)
1163
+ },
1164
+ effects: flattenEffects(schemas.map((s) => s.effects))
781
1165
  };
782
1166
  };
783
1167
 
784
1168
  // src/create/schema/parsers/unknown.ts
785
- var createUnknownSchema = (_zodUnknown) => ({});
1169
+ var createUnknownSchema = (_zodUnknown) => ({
1170
+ type: "schema",
1171
+ schema: {}
1172
+ });
786
1173
 
787
1174
  // src/create/schema/parsers/index.ts
788
1175
  var createSchemaSwitch = (zodSchema, state) => {
@@ -880,22 +1267,16 @@ var createSchemaSwitch = (zodSchema, state) => {
880
1267
  };
881
1268
 
882
1269
  // src/create/schema/index.ts
883
- var newSchemaState = (state) => ({
884
- type: state.type,
885
- components: state.components,
886
- path: [...state.path],
887
- visited: new Set(state.visited)
888
- });
889
- var createNewSchema = (zodSchema, newState, subpath) => {
890
- newState.path.push(...subpath);
891
- if (newState.visited.has(zodSchema)) {
1270
+ var isDescriptionEqual = (schema, zodSchema) => schema.type === "ref" && zodSchema.description === schema.zodType.description;
1271
+ var createNewSchema = (zodSchema, state) => {
1272
+ if (state.visited.has(zodSchema)) {
892
1273
  throw new Error(
893
- `The schema at ${newState.path.join(
1274
+ `The schema at ${state.path.join(
894
1275
  " > "
895
1276
  )} needs to be registered because it's circularly referenced`
896
1277
  );
897
1278
  }
898
- newState.visited.add(zodSchema);
1279
+ state.visited.add(zodSchema);
899
1280
  const {
900
1281
  effectType,
901
1282
  param,
@@ -905,99 +1286,112 @@ var createNewSchema = (zodSchema, newState, subpath) => {
905
1286
  unionOneOf,
906
1287
  ...additionalMetadata
907
1288
  } = zodSchema._def.openapi ?? {};
908
- const schema = createSchemaSwitch(zodSchema, newState);
909
- const description = zodSchema.description;
1289
+ const schema = createSchemaSwitch(zodSchema, state);
1290
+ const description = zodSchema.description && !isDescriptionEqual(schema, zodSchema) ? zodSchema.description : void 0;
910
1291
  const schemaWithMetadata = enhanceWithMetadata(schema, {
911
1292
  ...description && { description },
912
1293
  ...additionalMetadata
913
1294
  });
914
- return {
915
- schema: schemaWithMetadata,
916
- newState
917
- };
1295
+ state.visited.delete(zodSchema);
1296
+ return schemaWithMetadata;
918
1297
  };
919
- var createNewRef = (ref, zodSchema, state, subpath) => {
1298
+ var createNewRef = (ref, zodSchema, state) => {
920
1299
  state.components.schemas.set(zodSchema, {
921
1300
  type: "in-progress",
922
1301
  ref
923
1302
  });
924
- const newSchema = createNewSchema(
925
- zodSchema,
926
- newSchemaState({ ...state, visited: /* @__PURE__ */ new Set() }),
927
- subpath
928
- );
1303
+ const newSchema = createNewSchema(zodSchema, {
1304
+ ...state,
1305
+ visited: /* @__PURE__ */ new Set()
1306
+ });
929
1307
  state.components.schemas.set(zodSchema, {
930
1308
  type: "complete",
931
1309
  ref,
932
1310
  schemaObject: newSchema.schema,
933
- creationType: newSchema.newState?.effectType
1311
+ effects: newSchema.effects
934
1312
  });
935
1313
  return {
1314
+ type: "ref",
936
1315
  schema: { $ref: createComponentSchemaRef(ref) },
937
- newState: newSchema.newState
1316
+ effects: newSchema.effects ? [
1317
+ {
1318
+ type: "component",
1319
+ zodType: zodSchema,
1320
+ path: [...state.path]
1321
+ }
1322
+ ] : void 0,
1323
+ zodType: zodSchema
938
1324
  };
939
1325
  };
940
- var createExistingRef = (zodSchema, component, state, subpath) => {
941
- const newState = newSchemaState(state);
942
- newState.path.push(...subpath);
1326
+ var createExistingRef = (zodSchema, component, state) => {
943
1327
  if (component && component.type === "complete") {
944
- if (component.creationType && component.creationType !== state.type) {
945
- throwTransformError(zodSchema, newState);
946
- }
947
1328
  return {
1329
+ type: "ref",
948
1330
  schema: { $ref: createComponentSchemaRef(component.ref) },
949
- newState: {
950
- ...newState,
951
- effectType: component.creationType
952
- }
1331
+ effects: component.effects ? [
1332
+ {
1333
+ type: "component",
1334
+ zodType: zodSchema,
1335
+ path: [...state.path]
1336
+ }
1337
+ ] : void 0,
1338
+ zodType: zodSchema
953
1339
  };
954
1340
  }
955
1341
  if (component && component.type === "in-progress") {
956
1342
  return {
1343
+ type: "ref",
957
1344
  schema: { $ref: createComponentSchemaRef(component.ref) },
958
- newState
1345
+ effects: [
1346
+ {
1347
+ type: "component",
1348
+ zodType: zodSchema,
1349
+ path: [...state.path]
1350
+ }
1351
+ ],
1352
+ zodType: zodSchema
959
1353
  };
960
1354
  }
961
1355
  return;
962
1356
  };
963
- var createSchemaOrRef = (zodSchema, state, subpath) => {
1357
+ var createSchemaOrRef = (zodSchema, state) => {
964
1358
  const component = state.components.schemas.get(zodSchema);
965
- const existingRef = createExistingRef(zodSchema, component, state, subpath);
1359
+ const existingRef = createExistingRef(zodSchema, component, state);
966
1360
  if (existingRef) {
967
1361
  return existingRef;
968
1362
  }
969
1363
  const ref = zodSchema._def.openapi?.ref ?? component?.ref;
970
1364
  if (ref) {
971
- return createNewRef(ref, zodSchema, state, subpath);
1365
+ return createNewRef(ref, zodSchema, state);
972
1366
  }
973
- return createNewSchema(zodSchema, newSchemaState(state), subpath);
1367
+ return createNewSchema(zodSchema, state);
974
1368
  };
975
1369
  var createSchemaObject = (zodSchema, state, subpath) => {
976
- const { schema, newState } = createSchemaOrRef(zodSchema, state, subpath);
977
- if (newState?.effectType) {
978
- if (state.type !== newState?.effectType || state.effectType && newState.effectType !== state.effectType) {
979
- throwTransformError(zodSchema, newState);
980
- }
981
- state.effectType = newState.effectType;
982
- }
1370
+ state.path.push(...subpath);
1371
+ const schema = createSchemaOrRef(zodSchema, state);
1372
+ state.path.pop();
983
1373
  return schema;
984
1374
  };
1375
+ var createSchema = (zodSchema, state, subpath) => {
1376
+ const schema = createSchemaObject(zodSchema, state, subpath);
1377
+ if (schema.effects) {
1378
+ verifyEffects(schema.effects, state);
1379
+ }
1380
+ return schema.schema;
1381
+ };
985
1382
 
986
1383
  // src/create/parameters.ts
987
1384
  var createComponentParamRef = (ref) => `#/components/parameters/${ref}`;
988
1385
  var createBaseParameter = (schema, components, subpath) => {
989
1386
  const { ref, ...rest } = schema._def.openapi?.param ?? {};
990
- const state = newSchemaState({
1387
+ const state = {
991
1388
  components,
992
1389
  type: "input",
993
1390
  path: [],
994
1391
  visited: /* @__PURE__ */ new Set()
995
- });
996
- const schemaObject = createSchemaObject(schema, state, [
997
- ...subpath,
998
- "schema"
999
- ]);
1000
- const required = !isOptionalSchema(schema, state);
1392
+ };
1393
+ const schemaObject = createSchema(schema, state, [...subpath, "schema"]);
1394
+ const required = !isOptionalSchema(schema, state)?.optional;
1001
1395
  const description = schema._def.openapi?.description ?? schema._def.description;
1002
1396
  return {
1003
1397
  ...description && { description },
@@ -1017,7 +1411,7 @@ var createParamOrRef = (zodSchema, components, subpath, type, name) => {
1017
1411
  throw new Error("Parameter name missing");
1018
1412
  }
1019
1413
  if (component && component.type === "complete") {
1020
- if (!("$ref" in component.paramObject) && (component.in !== type || component.name !== name)) {
1414
+ if (!("$ref" in component.paramObject) && (component.in !== paramType || component.name !== paramName)) {
1021
1415
  throw new Error(`parameterRef "${component.ref}" is already registered`);
1022
1416
  }
1023
1417
  return {
@@ -1048,11 +1442,12 @@ var createParamOrRef = (zodSchema, components, subpath, type, name) => {
1048
1442
  }
1049
1443
  return paramObject;
1050
1444
  };
1051
- var createParameters = (type, zodObject, components, subpath) => {
1052
- if (!zodObject) {
1445
+ var createParameters = (type, zodObjectType, components, subpath) => {
1446
+ if (!zodObjectType) {
1053
1447
  return [];
1054
1448
  }
1055
- return Object.entries(zodObject.shape).map(
1449
+ const zodObject = getZodObject(zodObjectType, "input").shape;
1450
+ return Object.entries(zodObject).map(
1056
1451
  ([key, zodSchema]) => createParamOrRef(zodSchema, components, [...subpath, key], type, key)
1057
1452
  );
1058
1453
  };
@@ -1106,6 +1501,27 @@ var createParametersObject = (parameters, requestParams, components, subpath) =>
1106
1501
  ];
1107
1502
  return combinedParameters.length ? combinedParameters : void 0;
1108
1503
  };
1504
+ var getZodObject = (schema, type) => {
1505
+ if (isZodType(schema, "ZodObject")) {
1506
+ return schema;
1507
+ }
1508
+ if (isZodType(schema, "ZodLazy")) {
1509
+ return getZodObject(schema.schema, type);
1510
+ }
1511
+ if (isZodType(schema, "ZodEffects")) {
1512
+ return getZodObject(schema.innerType(), type);
1513
+ }
1514
+ if (isZodType(schema, "ZodBranded")) {
1515
+ return getZodObject(schema.unwrap(), type);
1516
+ }
1517
+ if (isZodType(schema, "ZodPipeline")) {
1518
+ if (type === "input") {
1519
+ return getZodObject(schema._def.in, type);
1520
+ }
1521
+ return getZodObject(schema._def.out, type);
1522
+ }
1523
+ throw new Error("failed to find ZodObject in schema");
1524
+ };
1109
1525
 
1110
1526
  // src/create/content.ts
1111
1527
  var createMediaTypeSchema = (schemaObject, components, type, subpath) => {
@@ -1115,14 +1531,14 @@ var createMediaTypeSchema = (schemaObject, components, type, subpath) => {
1115
1531
  if (!isAnyZodType(schemaObject)) {
1116
1532
  return schemaObject;
1117
1533
  }
1118
- return createSchemaObject(
1534
+ return createSchema(
1119
1535
  schemaObject,
1120
- newSchemaState({
1536
+ {
1121
1537
  components,
1122
1538
  type,
1123
1539
  path: [],
1124
1540
  visited: /* @__PURE__ */ new Set()
1125
- }),
1541
+ },
1126
1542
  subpath
1127
1543
  );
1128
1544
  };
@@ -1196,14 +1612,14 @@ var createHeaderOrRef = (schema, components) => {
1196
1612
  };
1197
1613
  var createBaseHeader = (schema, components) => {
1198
1614
  const { ref, ...rest } = schema._def.openapi?.header ?? {};
1199
- const state = newSchemaState({
1615
+ const state = {
1200
1616
  components,
1201
1617
  type: "output",
1202
1618
  path: [],
1203
1619
  visited: /* @__PURE__ */ new Set()
1204
- });
1205
- const schemaObject = createSchemaObject(schema, state, ["header"]);
1206
- const required = !isOptionalSchema(schema, state);
1620
+ };
1621
+ const schemaObject = createSchema(schema, state, ["header"]);
1622
+ const required = !isOptionalSchema(schema, state)?.optional;
1207
1623
  return {
1208
1624
  ...rest,
1209
1625
  ...schema && { schema: schemaObject },
@@ -1494,13 +1910,13 @@ var createComponents = (componentsObject, components) => {
1494
1910
  var createSchemaComponents = (componentsObject, components) => {
1495
1911
  Array.from(components.schemas).forEach(([schema, { type }], index) => {
1496
1912
  if (type === "manual") {
1497
- const state = newSchemaState({
1913
+ const state = {
1498
1914
  components,
1499
1915
  type: schema._def.openapi?.refType ?? "output",
1500
1916
  path: [],
1501
1917
  visited: /* @__PURE__ */ new Set()
1502
- });
1503
- createSchemaObject(schema, state, [`component schema index ${index}`]);
1918
+ };
1919
+ createSchema(schema, state, [`component schema index ${index}`]);
1504
1920
  }
1505
1921
  });
1506
1922
  const customComponents = Object.entries(