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
@@ -10,30 +10,27 @@ var isAnyZodType = (zodType) => Boolean(
10
10
  zodType?._def?.typeName
11
11
  );
12
12
 
13
- // src/openapi.ts
14
- var openApiVersions = [
15
- "3.0.0",
16
- "3.0.1",
17
- "3.0.2",
18
- "3.0.3",
19
- "3.1.0"
20
- ];
21
- var satisfiesVersion = (test, against) => openApiVersions.indexOf(test) >= openApiVersions.indexOf(against);
22
- var isReferenceObject = (schemaOrRef) => Boolean("$ref" in schemaOrRef && schemaOrRef.$ref);
23
-
24
13
  // src/create/schema/metadata.ts
25
- var enhanceWithMetadata = (schemaObject, metadata) => {
26
- if (isReferenceObject(schemaObject)) {
14
+ var enhanceWithMetadata = (schema, metadata) => {
15
+ if (schema.type === "ref") {
27
16
  if (Object.values(metadata).every((val) => val === void 0)) {
28
- return schemaObject;
17
+ return schema;
29
18
  }
30
19
  return {
31
- allOf: [schemaObject, metadata]
20
+ type: "schema",
21
+ schema: {
22
+ allOf: [schema.schema, metadata]
23
+ },
24
+ effects: schema.effects
32
25
  };
33
26
  }
34
27
  return {
35
- ...schemaObject,
36
- ...metadata
28
+ type: "schema",
29
+ schema: {
30
+ ...schema.schema,
31
+ ...metadata
32
+ },
33
+ effects: schema.effects
37
34
  };
38
35
  };
39
36
 
@@ -42,17 +39,25 @@ var createArraySchema = (zodArray, state) => {
42
39
  const zodType = zodArray._def.type;
43
40
  const minItems = zodArray._def.exactLength?.value ?? zodArray._def.minLength?.value;
44
41
  const maxItems = zodArray._def.exactLength?.value ?? zodArray._def.maxLength?.value;
42
+ const items = createSchemaObject(zodType, state, ["array items"]);
45
43
  return {
46
- type: "array",
47
- items: createSchemaObject(zodType, state, ["array items"]),
48
- ...minItems !== void 0 && { minItems },
49
- ...maxItems !== void 0 && { maxItems }
44
+ type: "schema",
45
+ schema: {
46
+ type: "array",
47
+ items: items.schema,
48
+ ...minItems !== void 0 && { minItems },
49
+ ...maxItems !== void 0 && { maxItems }
50
+ },
51
+ effects: items.effects
50
52
  };
51
53
  };
52
54
 
53
55
  // src/create/schema/parsers/boolean.ts
54
56
  var createBooleanSchema = (_zodBoolean) => ({
55
- type: "boolean"
57
+ type: "schema",
58
+ schema: {
59
+ type: "boolean"
60
+ }
56
61
  });
57
62
 
58
63
  // src/create/schema/parsers/brand.ts
@@ -63,7 +68,10 @@ var createCatchSchema = (zodCatch, state) => createSchemaObject(zodCatch._def.in
63
68
 
64
69
  // src/create/schema/parsers/date.ts
65
70
  var createDateSchema = (_zodDate) => ({
66
- type: "string"
71
+ type: "schema",
72
+ schema: {
73
+ type: "string"
74
+ }
67
75
  });
68
76
 
69
77
  // src/create/schema/parsers/default.ts
@@ -76,21 +84,186 @@ var createDefaultSchema = (zodDefault, state) => {
76
84
  });
77
85
  };
78
86
 
87
+ // src/create/schema/parsers/transform.ts
88
+ var createTransformSchema = (zodTransform, state) => {
89
+ if (zodTransform._def.openapi?.effectType === "output") {
90
+ return {
91
+ type: "schema",
92
+ schema: createManualOutputTransformSchema(zodTransform, state)
93
+ };
94
+ }
95
+ if (zodTransform._def.openapi?.effectType === "input" || zodTransform._def.openapi?.effectType === "same") {
96
+ return createSchemaObject(zodTransform._def.schema, state, [
97
+ "transform input"
98
+ ]);
99
+ }
100
+ if (state.type === "output") {
101
+ return {
102
+ type: "schema",
103
+ schema: createManualOutputTransformSchema(zodTransform, state)
104
+ };
105
+ }
106
+ const schema = createSchemaObject(zodTransform._def.schema, state, [
107
+ "transform input"
108
+ ]);
109
+ return {
110
+ ...schema,
111
+ effects: flattenEffects([
112
+ [
113
+ {
114
+ type: "schema",
115
+ creationType: "input",
116
+ zodType: zodTransform,
117
+ path: [...state.path]
118
+ }
119
+ ],
120
+ schema.effects
121
+ ])
122
+ };
123
+ };
124
+ var createManualOutputTransformSchema = (zodTransform, state) => {
125
+ if (!zodTransform._def.openapi?.type) {
126
+ const zodType = zodTransform.constructor.name;
127
+ const schemaName = `${zodType} - ${zodTransform._def.effect.type}`;
128
+ throw new Error(
129
+ `Failed to determine a type for ${schemaName} at ${state.path.join(
130
+ " > "
131
+ )}. Please change the 'effectType' to 'input', wrap it in a ZodPipeline or assign it a manual 'type'.`
132
+ );
133
+ }
134
+ return {
135
+ type: zodTransform._def.openapi.type
136
+ };
137
+ };
138
+ var getZodTypeName = (zodType) => {
139
+ if (isZodType(zodType, "ZodEffects")) {
140
+ return `${zodType._def.typeName} - ${zodType._def.effect.type}`;
141
+ }
142
+ return zodType._def.typeName;
143
+ };
144
+ var throwTransformError = (effect) => {
145
+ const typeName = getZodTypeName(effect.zodType);
146
+ const input = effect.creationType;
147
+ const opposite = input === "input" ? "output" : "input";
148
+ throw new Error(
149
+ `The ${typeName} at ${effect.path.join(
150
+ " > "
151
+ )} is used within a registered compoment schema${effect.component ? ` (${effect.component.ref})` : ""} and contains an ${input} transformation${effect.component ? ` (${getZodTypeName(
152
+ effect.component.zodType
153
+ )}) defined at ${effect.component.path.join(" > ")}` : ""} which is also used in an ${opposite} schema.
154
+
155
+ This may cause the schema to render incorrectly and is most likely a mistake. You can resolve this by:
156
+
157
+ 1. Setting an \`effectType\` on one of the transformations to \`same\` (Not applicable for ZodDefault), \`input\` or \`output\` eg. \`.openapi({type: 'same'})\`
158
+ 2. Wrapping the transformation in a ZodPipeline
159
+ 3. Assigning a manual type to the transformation eg. \`.openapi({type: 'string'})\`
160
+ 4. Removing the transformation
161
+ 5. Deregister the component containing the transformation`
162
+ );
163
+ };
164
+ var resolveSingleEffect = (effect, state) => {
165
+ if (effect.type === "schema") {
166
+ return {
167
+ creationType: effect.creationType,
168
+ path: effect.path,
169
+ zodType: effect.zodType
170
+ };
171
+ }
172
+ if (effect.type === "component") {
173
+ if (state.visited.has(effect.zodType)) {
174
+ return;
175
+ }
176
+ const component = state.components.schemas.get(effect.zodType);
177
+ if (component?.type !== "complete") {
178
+ throw new Error("Something went wrong, component schema is not complete");
179
+ }
180
+ if (component.resolvedEffect) {
181
+ return {
182
+ creationType: component.resolvedEffect.creationType,
183
+ path: effect.path,
184
+ zodType: effect.zodType,
185
+ component: {
186
+ ref: component.ref,
187
+ zodType: component.resolvedEffect.zodType,
188
+ path: component.resolvedEffect.path
189
+ }
190
+ };
191
+ }
192
+ if (!component.effects) {
193
+ return void 0;
194
+ }
195
+ state.visited.add(effect.zodType);
196
+ const resolved = resolveEffect(component.effects, state);
197
+ state.visited.delete(effect.zodType);
198
+ if (!resolved) {
199
+ return void 0;
200
+ }
201
+ component.resolvedEffect = resolved;
202
+ return resolved;
203
+ }
204
+ return void 0;
205
+ };
206
+ var resolveEffect = (effects, state) => {
207
+ const { input, output } = effects.reduce(
208
+ (acc, effect) => {
209
+ const resolvedSchemaEffect = resolveSingleEffect(effect, state);
210
+ if (resolvedSchemaEffect?.creationType === "input") {
211
+ acc.input.push(resolvedSchemaEffect);
212
+ }
213
+ if (resolvedSchemaEffect?.creationType === "output") {
214
+ acc.output.push(resolvedSchemaEffect);
215
+ }
216
+ if (resolvedSchemaEffect && acc.input.length > 1 && acc.output.length > 1) {
217
+ throwTransformError(resolvedSchemaEffect);
218
+ }
219
+ return acc;
220
+ },
221
+ { input: [], output: [] }
222
+ );
223
+ if (input.length > 0) {
224
+ return input[0];
225
+ }
226
+ if (output.length > 0) {
227
+ return output[0];
228
+ }
229
+ return void 0;
230
+ };
231
+ var verifyEffects = (effects, state) => {
232
+ const resolved = resolveEffect(effects, state);
233
+ if (resolved?.creationType && resolved.creationType !== state.type) {
234
+ throwTransformError(resolved);
235
+ }
236
+ };
237
+ var flattenEffects = (effects) => {
238
+ const allEffects = effects.reduce((acc, effect) => {
239
+ if (effect) {
240
+ return acc.concat(effect);
241
+ }
242
+ return acc;
243
+ }, []);
244
+ return allEffects.length ? allEffects : void 0;
245
+ };
246
+
79
247
  // src/create/schema/parsers/discriminatedUnion.ts
80
248
  var createDiscriminatedUnionSchema = (zodDiscriminatedUnion, state) => {
81
249
  const options = zodDiscriminatedUnion.options;
82
250
  const schemas = options.map(
83
251
  (option, index) => createSchemaObject(option, state, [`discriminated union option ${index}`])
84
252
  );
253
+ const schemaObjects = schemas.map((schema) => schema.schema);
85
254
  const discriminator = mapDiscriminator(
86
- schemas,
255
+ schemaObjects,
87
256
  options,
88
257
  zodDiscriminatedUnion.discriminator,
89
258
  state
90
259
  );
91
260
  return {
92
- oneOf: schemas,
93
- ...discriminator && { discriminator }
261
+ type: "schema",
262
+ schema: {
263
+ oneOf: schemaObjects,
264
+ ...discriminator && { discriminator }
265
+ },
266
+ effects: flattenEffects(schemas.map((schema) => schema.effects))
94
267
  };
95
268
  };
96
269
  var mapDiscriminator = (schemas, zodObjects, discriminator, state) => {
@@ -129,19 +302,29 @@ var mapDiscriminator = (schemas, zodObjects, discriminator, state) => {
129
302
 
130
303
  // src/create/schema/parsers/enum.ts
131
304
  var createEnumSchema = (zodEnum) => ({
132
- type: "string",
133
- enum: zodEnum._def.values
305
+ type: "schema",
306
+ schema: {
307
+ type: "string",
308
+ enum: zodEnum._def.values
309
+ }
134
310
  });
135
311
 
136
312
  // src/create/schema/parsers/intersection.ts
137
- var createIntersectionSchema = (zodIntersection, state) => ({
138
- allOf: [
139
- createSchemaObject(zodIntersection._def.left, state, ["intersection left"]),
140
- createSchemaObject(zodIntersection._def.right, state, [
141
- "intersection right"
142
- ])
143
- ]
144
- });
313
+ var createIntersectionSchema = (zodIntersection, state) => {
314
+ const left = createSchemaObject(zodIntersection._def.left, state, [
315
+ "intersection left"
316
+ ]);
317
+ const right = createSchemaObject(zodIntersection._def.right, state, [
318
+ "intersection right"
319
+ ]);
320
+ return {
321
+ type: "schema",
322
+ schema: {
323
+ allOf: [left.schema, right.schema]
324
+ },
325
+ effects: flattenEffects([left.effects, right.effects])
326
+ };
327
+ };
145
328
 
146
329
  // src/create/schema/parsers/lazy.ts
147
330
  var createLazySchema = (zodLazy, state) => {
@@ -151,8 +334,11 @@ var createLazySchema = (zodLazy, state) => {
151
334
 
152
335
  // src/create/schema/parsers/literal.ts
153
336
  var createLiteralSchema = (zodLiteral) => ({
154
- type: typeof zodLiteral.value,
155
- enum: [zodLiteral._def.value]
337
+ type: "schema",
338
+ schema: {
339
+ type: typeof zodLiteral.value,
340
+ enum: [zodLiteral._def.value]
341
+ }
156
342
  });
157
343
 
158
344
  // src/create/schema/parsers/manual.ts
@@ -166,10 +352,23 @@ var createManualTypeSchema = (zodSchema, state) => {
166
352
  );
167
353
  }
168
354
  return {
169
- type: zodSchema._def.openapi.type
355
+ type: "schema",
356
+ schema: {
357
+ type: zodSchema._def.openapi.type
358
+ }
170
359
  };
171
360
  };
172
361
 
362
+ // src/openapi.ts
363
+ var openApiVersions = [
364
+ "3.0.0",
365
+ "3.0.1",
366
+ "3.0.2",
367
+ "3.0.3",
368
+ "3.1.0"
369
+ ];
370
+ var satisfiesVersion = (test, against) => openApiVersions.indexOf(test) >= openApiVersions.indexOf(against);
371
+
173
372
  // src/create/schema/parsers/nativeEnum.ts
174
373
  var createNativeEnumSchema = (zodEnum, state) => {
175
374
  const enumValues = getValidEnumValues(zodEnum._def.values);
@@ -177,25 +376,37 @@ var createNativeEnumSchema = (zodEnum, state) => {
177
376
  if (strings.length && numbers.length) {
178
377
  if (satisfiesVersion(state.components.openapi, "3.1.0"))
179
378
  return {
180
- type: ["string", "number"],
181
- enum: [...strings, ...numbers]
379
+ type: "schema",
380
+ schema: {
381
+ type: ["string", "number"],
382
+ enum: [...strings, ...numbers]
383
+ }
182
384
  };
183
385
  return {
184
- oneOf: [
185
- { type: "string", enum: strings },
186
- { type: "number", enum: numbers }
187
- ]
386
+ type: "schema",
387
+ schema: {
388
+ oneOf: [
389
+ { type: "string", enum: strings },
390
+ { type: "number", enum: numbers }
391
+ ]
392
+ }
188
393
  };
189
394
  }
190
395
  if (strings.length) {
191
396
  return {
192
- type: "string",
193
- enum: strings
397
+ type: "schema",
398
+ schema: {
399
+ type: "string",
400
+ enum: strings
401
+ }
194
402
  };
195
403
  }
196
404
  return {
197
- type: "number",
198
- enum: numbers
405
+ type: "schema",
406
+ schema: {
407
+ type: "number",
408
+ enum: numbers
409
+ }
199
410
  };
200
411
  };
201
412
  var getValidEnumValues = (enumValues) => {
@@ -211,7 +422,10 @@ var sortStringsAndNumbers = (values) => ({
211
422
 
212
423
  // src/create/schema/parsers/null.ts
213
424
  var createNullSchema = (_zodNull) => ({
214
- type: "null"
425
+ type: "schema",
426
+ schema: {
427
+ type: "null"
428
+ }
215
429
  });
216
430
 
217
431
  // src/create/schema/parsers/nullable.ts
@@ -220,45 +434,69 @@ var createNullableSchema = (zodNullable, state) => {
220
434
  "nullable"
221
435
  ]);
222
436
  if (satisfiesVersion(state.components.openapi, "3.1.0")) {
223
- if (isReferenceObject(schemaObject) || schemaObject.allOf) {
437
+ if (schemaObject.type === "ref" || schemaObject.schema.allOf) {
224
438
  return {
225
- oneOf: mapNullOf([schemaObject], state.components.openapi)
439
+ type: "schema",
440
+ schema: {
441
+ oneOf: mapNullOf([schemaObject.schema], state.components.openapi)
442
+ },
443
+ effects: schemaObject.effects
226
444
  };
227
445
  }
228
- if (schemaObject.oneOf) {
229
- const { oneOf, ...schema3 } = schemaObject;
446
+ if (schemaObject.schema.oneOf) {
447
+ const { oneOf, ...schema3 } = schemaObject.schema;
230
448
  return {
231
- oneOf: mapNullOf(oneOf, state.components.openapi),
232
- ...schema3
449
+ type: "schema",
450
+ schema: {
451
+ oneOf: mapNullOf(oneOf, state.components.openapi),
452
+ ...schema3
453
+ },
454
+ effects: schemaObject.effects
233
455
  };
234
456
  }
235
- if (schemaObject.anyOf) {
236
- const { anyOf, ...schema3 } = schemaObject;
457
+ if (schemaObject.schema.anyOf) {
458
+ const { anyOf, ...schema3 } = schemaObject.schema;
237
459
  return {
238
- anyOf: mapNullOf(anyOf, state.components.openapi),
239
- ...schema3
460
+ type: "schema",
461
+ schema: {
462
+ anyOf: mapNullOf(anyOf, state.components.openapi),
463
+ ...schema3
464
+ },
465
+ effects: schemaObject.effects
240
466
  };
241
467
  }
242
- const { type: type2, ...schema2 } = schemaObject;
468
+ const { type: type2, ...schema2 } = schemaObject.schema;
243
469
  return {
244
- type: mapNullType(type2),
245
- ...schema2
470
+ type: "schema",
471
+ schema: {
472
+ type: mapNullType(type2),
473
+ ...schema2
474
+ },
475
+ effects: schemaObject.effects
246
476
  };
247
477
  }
248
- if (isReferenceObject(schemaObject)) {
478
+ if (schemaObject.type === "ref") {
249
479
  return {
250
- allOf: [schemaObject],
251
- nullable: true
480
+ type: "schema",
481
+ schema: {
482
+ allOf: [schemaObject.schema],
483
+ nullable: true
484
+ },
485
+ effects: schemaObject.effects
252
486
  };
253
487
  }
254
- const { type, ...schema } = schemaObject;
488
+ const { type, ...schema } = schemaObject.schema;
255
489
  return {
256
- ...type && { type },
257
- nullable: true,
258
- ...schema,
259
- // 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
260
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
261
- ...schema.enum && { enum: [...schema.enum, null] }
490
+ type: "schema",
491
+ schema: {
492
+ ...type && { type },
493
+ nullable: true,
494
+ ...schema,
495
+ // 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
496
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
497
+ ...schema.enum && { enum: [...schema.enum, null] }
498
+ },
499
+ effects: schemaObject.effects
262
500
  };
263
501
  };
264
502
  var mapNullType = (type) => {
@@ -283,10 +521,13 @@ var createNumberSchema = (zodNumber, state) => {
283
521
  const minimum = mapMinimum(zodNumberChecks, state.components.openapi);
284
522
  const maximum = mapMaximum(zodNumberChecks, state.components.openapi);
285
523
  return {
286
- type: mapNumberType(zodNumberChecks),
287
- ...minimum && minimum,
288
- // Union types are not easy to tame
289
- ...maximum && maximum
524
+ type: "schema",
525
+ schema: {
526
+ type: mapNumberType(zodNumberChecks),
527
+ ...minimum && minimum,
528
+ // Union types are not easy to tame
529
+ ...maximum && maximum
530
+ }
290
531
  };
291
532
  };
292
533
  var mapMaximum = (zodNumberCheck, openapi) => {
@@ -322,16 +563,29 @@ var getZodNumberChecks = (zodNumber) => zodNumber._def.checks.reduce((acc, check
322
563
  var mapNumberType = (zodNumberChecks) => zodNumberChecks.int ? "integer" : "number";
323
564
 
324
565
  // src/create/schema/parsers/optional.ts
325
- var createOptionalSchema = (zodOptional, state) => (
326
- // Optional doesn't change OpenAPI schema
327
- createSchemaObject(zodOptional.unwrap(), state, ["optional"])
328
- );
566
+ var createOptionalSchema = (zodOptional, state) => createSchemaObject(zodOptional.unwrap(), state, ["optional"]);
329
567
  var isOptionalSchema = (zodSchema, state) => {
330
568
  if (isZodType(zodSchema, "ZodOptional") || isZodType(zodSchema, "ZodNever") || isZodType(zodSchema, "ZodUndefined")) {
331
- return true;
569
+ return { optional: true };
332
570
  }
333
571
  if (isZodType(zodSchema, "ZodDefault")) {
334
- return state.type === "input";
572
+ if (zodSchema._def.openapi?.effectType === "input") {
573
+ return { optional: true };
574
+ }
575
+ if (zodSchema._def.openapi?.effectType === "output") {
576
+ return { optional: false };
577
+ }
578
+ return {
579
+ optional: state.type === "input",
580
+ effects: [
581
+ {
582
+ type: "schema",
583
+ creationType: state.type,
584
+ zodType: zodSchema,
585
+ path: [...state.path]
586
+ }
587
+ ]
588
+ };
335
589
  }
336
590
  if (isZodType(zodSchema, "ZodNullable") || isZodType(zodSchema, "ZodCatch")) {
337
591
  return isOptionalSchema(zodSchema._def.innerType, state);
@@ -340,27 +594,42 @@ var isOptionalSchema = (zodSchema, state) => {
340
594
  return isOptionalSchema(zodSchema._def.schema, state);
341
595
  }
342
596
  if (isZodType(zodSchema, "ZodUnion") || isZodType(zodSchema, "ZodDiscriminatedUnion")) {
343
- return zodSchema._def.options.some(
597
+ const results = zodSchema._def.options.map(
344
598
  (schema) => isOptionalSchema(schema, state)
345
599
  );
600
+ return results.reduce(
601
+ (acc, result) => ({
602
+ optional: acc.optional || result.optional,
603
+ effects: flattenEffects([acc.effects, result.effects])
604
+ }),
605
+ { optional: false }
606
+ );
346
607
  }
347
608
  if (isZodType(zodSchema, "ZodIntersection")) {
348
- return [zodSchema._def.left, zodSchema._def.right].some(
609
+ const results = [zodSchema._def.left, zodSchema._def.right].map(
349
610
  (schema) => isOptionalSchema(schema, state)
350
611
  );
612
+ return results.reduce(
613
+ (acc, result) => ({
614
+ optional: acc.optional || result.optional,
615
+ effects: flattenEffects([acc.effects, result.effects])
616
+ }),
617
+ { optional: false }
618
+ );
351
619
  }
352
620
  if (isZodType(zodSchema, "ZodPipeline")) {
353
- if (state.effectType === "input" || state.type === "input" && state.effectType !== "output") {
621
+ const type = zodSchema._def.openapi?.effectType ?? state.type;
622
+ if (type === "input") {
354
623
  return isOptionalSchema(zodSchema._def.in, state);
355
624
  }
356
- if (state.effectType === "output" || state.type === "output" && state.effectType !== "input") {
625
+ if (type === "output") {
357
626
  return isOptionalSchema(zodSchema._def.out, state);
358
627
  }
359
628
  }
360
629
  if (isZodType(zodSchema, "ZodLazy")) {
361
630
  return isOptionalSchema(zodSchema._def.getter(), state);
362
631
  }
363
- return zodSchema.isOptional();
632
+ return { optional: zodSchema.isOptional() };
364
633
  };
365
634
 
366
635
  // src/create/schema/parsers/object.ts
@@ -414,9 +683,28 @@ var createExtendedSchema = (zodObject, baseZodObject, state) => {
414
683
  if (!diffShape) {
415
684
  return void 0;
416
685
  }
686
+ const extendedSchema = createObjectSchemaFromShape(
687
+ diffShape,
688
+ diffOpts,
689
+ state
690
+ );
417
691
  return {
418
- allOf: [{ $ref: createComponentSchemaRef(completeComponent.ref) }],
419
- ...createObjectSchemaFromShape(diffShape, diffOpts, state)
692
+ type: "schema",
693
+ schema: {
694
+ allOf: [{ $ref: createComponentSchemaRef(completeComponent.ref) }],
695
+ ...extendedSchema.schema
696
+ },
697
+ effects: flattenEffects([
698
+ completeComponent.type === "complete" ? completeComponent.effects : [],
699
+ completeComponent.type === "in-progress" ? [
700
+ {
701
+ type: "component",
702
+ zodType: zodObject,
703
+ path: [...state.path]
704
+ }
705
+ ] : [],
706
+ extendedSchema.effects
707
+ ])
420
708
  };
421
709
  };
422
710
  var createDiffOpts = (baseOpts, extendedOpts) => {
@@ -446,50 +734,114 @@ var createShapeDiff = (baseObj, extendedObj) => {
446
734
  var createObjectSchemaFromShape = (shape, { unknownKeys, catchAll }, state) => {
447
735
  const properties = mapProperties(shape, state);
448
736
  const required = mapRequired(shape, state);
737
+ const additionalProperties = !isZodType(catchAll, "ZodNever") ? createSchemaObject(catchAll, state, ["additional properties"]) : void 0;
449
738
  return {
450
- type: "object",
451
- ...properties && { properties },
452
- ...required && { required },
453
- ...unknownKeys === "strict" && { additionalProperties: false },
454
- ...!isZodType(catchAll, "ZodNever") && {
455
- additionalProperties: createSchemaObject(catchAll, state, [
456
- "additional properties"
457
- ])
458
- }
739
+ type: "schema",
740
+ schema: {
741
+ type: "object",
742
+ ...properties && { properties: properties.properties },
743
+ ...required?.required.length && { required: required.required },
744
+ ...unknownKeys === "strict" && { additionalProperties: false },
745
+ ...additionalProperties && {
746
+ additionalProperties: additionalProperties.schema
747
+ }
748
+ },
749
+ effects: flattenEffects([
750
+ ...properties?.effects ?? [],
751
+ additionalProperties?.effects,
752
+ required?.effects
753
+ ])
459
754
  };
460
755
  };
461
756
  var mapRequired = (shape, state) => {
462
- const required = Object.entries(shape).filter(([_key, zodSchema]) => !isOptionalSchema(zodSchema, state)).map(([key]) => key);
463
- if (!required.length) {
757
+ const { required, effects: allEffects } = Object.entries(shape).reduce(
758
+ (acc, [key, zodSchema]) => {
759
+ state.path.push(`property: ${key}`);
760
+ const { optional, effects } = isOptionalSchema(zodSchema, state);
761
+ state.path.pop();
762
+ if (!optional) {
763
+ acc.required.push(key);
764
+ }
765
+ if (effects) {
766
+ acc.effects.push(effects);
767
+ }
768
+ return acc;
769
+ },
770
+ {
771
+ required: [],
772
+ effects: []
773
+ }
774
+ );
775
+ return { required, effects: flattenEffects(allEffects) };
776
+ };
777
+ var mapProperties = (shape, state) => {
778
+ const shapeEntries = Object.entries(shape);
779
+ if (!shapeEntries.length) {
464
780
  return void 0;
465
781
  }
466
- return required;
467
- };
468
- var mapProperties = (shape, state) => Object.entries(shape).reduce(
469
- (acc, [key, zodSchema]) => {
470
- if (isZodType(zodSchema, "ZodNever") || isZodType(zodSchema, "ZodUndefined")) {
782
+ return shapeEntries.reduce(
783
+ (acc, [key, zodSchema]) => {
784
+ if (isZodType(zodSchema, "ZodNever") || isZodType(zodSchema, "ZodUndefined")) {
785
+ return acc;
786
+ }
787
+ const property = createSchemaObject(zodSchema, state, [
788
+ `property: ${key}`
789
+ ]);
790
+ acc.properties[key] = property.schema;
791
+ acc.effects.push(property.effects);
471
792
  return acc;
793
+ },
794
+ {
795
+ properties: {},
796
+ effects: []
472
797
  }
473
- acc[key] = createSchemaObject(zodSchema, state, [`property: ${key}`]);
474
- return acc;
475
- },
476
- {}
477
- );
798
+ );
799
+ };
478
800
 
479
801
  // src/create/schema/parsers/pipeline.ts
480
802
  var createPipelineSchema = (zodPipeline, state) => {
481
- if (zodPipeline._def.openapi?.effectType === "input") {
803
+ if (zodPipeline._def.openapi?.effectType === "input" || zodPipeline._def.openapi?.effectType === "same") {
482
804
  return createSchemaObject(zodPipeline._def.in, state, ["pipeline input"]);
483
805
  }
484
806
  if (zodPipeline._def.openapi?.effectType === "output") {
485
807
  return createSchemaObject(zodPipeline._def.out, state, ["pipeline output"]);
486
808
  }
487
809
  if (state.type === "input") {
488
- state.effectType = "input";
489
- return createSchemaObject(zodPipeline._def.in, state, ["pipeline input"]);
810
+ const schema2 = createSchemaObject(zodPipeline._def.in, state, [
811
+ "pipeline input"
812
+ ]);
813
+ return {
814
+ ...schema2,
815
+ effects: flattenEffects([
816
+ [
817
+ {
818
+ type: "schema",
819
+ creationType: "input",
820
+ path: [...state.path],
821
+ zodType: zodPipeline
822
+ }
823
+ ],
824
+ schema2.effects
825
+ ])
826
+ };
490
827
  }
491
- state.effectType = "output";
492
- return createSchemaObject(zodPipeline._def.out, state, ["pipeline output"]);
828
+ const schema = createSchemaObject(zodPipeline._def.out, state, [
829
+ "pipeline output"
830
+ ]);
831
+ return {
832
+ ...schema,
833
+ effects: flattenEffects([
834
+ [
835
+ {
836
+ type: "schema",
837
+ creationType: "output",
838
+ path: [...state.path],
839
+ zodType: zodPipeline
840
+ }
841
+ ],
842
+ schema.effects
843
+ ])
844
+ };
493
845
  };
494
846
 
495
847
  // src/create/schema/parsers/preprocess.ts
@@ -511,29 +863,50 @@ var createRecordSchema = (zodRecord, state) => {
511
863
  const keySchema = createSchemaObject(zodRecord.keySchema, state, [
512
864
  "record key"
513
865
  ]);
514
- const maybeComponent = "$ref" in keySchema && state.components.schemas.get(zodRecord.keySchema);
515
- const maybeSchema = maybeComponent && maybeComponent.type === "complete" && maybeComponent.schemaObject;
516
- const renderedKeySchema = maybeSchema || keySchema;
866
+ const maybeComponent = state.components.schemas.get(zodRecord.keySchema);
867
+ const isComplete = maybeComponent && maybeComponent.type === "complete";
868
+ const maybeSchema = isComplete && maybeComponent.schemaObject;
869
+ const maybeEffects = isComplete && maybeComponent.effects || void 0;
870
+ const renderedKeySchema = maybeSchema || keySchema.schema;
517
871
  if ("enum" in renderedKeySchema && renderedKeySchema.enum) {
518
872
  return {
519
- type: "object",
520
- properties: renderedKeySchema.enum.reduce((acc, key) => {
521
- acc[key] = additionalProperties;
522
- return acc;
523
- }, {}),
524
- additionalProperties: false
873
+ type: "schema",
874
+ schema: {
875
+ type: "object",
876
+ properties: renderedKeySchema.enum.reduce((acc, key) => {
877
+ acc[key] = additionalProperties.schema;
878
+ return acc;
879
+ }, {}),
880
+ additionalProperties: false
881
+ },
882
+ effects: flattenEffects([
883
+ keySchema.effects,
884
+ additionalProperties.effects,
885
+ maybeEffects
886
+ ])
525
887
  };
526
888
  }
527
889
  if (satisfiesVersion(state.components.openapi, "3.1.0") && "type" in renderedKeySchema && renderedKeySchema.type === "string" && Object.keys(renderedKeySchema).length > 1) {
528
890
  return {
529
- type: "object",
530
- propertyNames: keySchema,
531
- additionalProperties
891
+ type: "schema",
892
+ schema: {
893
+ type: "object",
894
+ propertyNames: keySchema.schema,
895
+ additionalProperties: additionalProperties.schema
896
+ },
897
+ effects: flattenEffects([
898
+ keySchema.effects,
899
+ additionalProperties.effects
900
+ ])
532
901
  };
533
902
  }
534
903
  return {
535
- type: "object",
536
- additionalProperties
904
+ type: "schema",
905
+ schema: {
906
+ type: "object",
907
+ additionalProperties: additionalProperties.schema
908
+ },
909
+ effects: additionalProperties.effects
537
910
  };
538
911
  };
539
912
 
@@ -545,12 +918,17 @@ var createSetSchema = (zodSet, state) => {
545
918
  const schema = zodSet._def.valueType;
546
919
  const minItems = zodSet._def.minSize?.value;
547
920
  const maxItems = zodSet._def.maxSize?.value;
921
+ const itemSchema = createSchemaObject(schema, state, ["set items"]);
548
922
  return {
549
- type: "array",
550
- items: createSchemaObject(schema, state, ["set items"]),
551
- uniqueItems: true,
552
- ...minItems !== void 0 && { minItems },
553
- ...maxItems !== void 0 && { maxItems }
923
+ type: "schema",
924
+ schema: {
925
+ type: "array",
926
+ items: itemSchema.schema,
927
+ uniqueItems: true,
928
+ ...minItems !== void 0 && { minItems },
929
+ ...maxItems !== void 0 && { maxItems }
930
+ },
931
+ effects: itemSchema.effects
554
932
  };
555
933
  };
556
934
 
@@ -563,29 +941,35 @@ var createStringSchema = (zodString) => {
563
941
  const maxLength = zodStringChecks.length?.[0]?.value ?? zodStringChecks.max?.[0]?.value;
564
942
  if (patterns.length <= 1) {
565
943
  return {
566
- type: "string",
567
- ...format && { format },
568
- ...patterns[0] && { pattern: patterns[0] },
569
- ...minLength !== void 0 && { minLength },
570
- ...maxLength !== void 0 && { maxLength }
571
- };
572
- }
573
- return {
574
- allOf: [
575
- {
944
+ type: "schema",
945
+ schema: {
576
946
  type: "string",
577
947
  ...format && { format },
578
948
  ...patterns[0] && { pattern: patterns[0] },
579
949
  ...minLength !== void 0 && { minLength },
580
950
  ...maxLength !== void 0 && { maxLength }
581
- },
582
- ...patterns.slice(1).map(
583
- (pattern) => ({
951
+ }
952
+ };
953
+ }
954
+ return {
955
+ type: "schema",
956
+ schema: {
957
+ allOf: [
958
+ {
584
959
  type: "string",
585
- pattern
586
- })
587
- )
588
- ]
960
+ ...format && { format },
961
+ ...patterns[0] && { pattern: patterns[0] },
962
+ ...minLength !== void 0 && { minLength },
963
+ ...maxLength !== void 0 && { maxLength }
964
+ },
965
+ ...patterns.slice(1).map(
966
+ (pattern) => ({
967
+ type: "string",
968
+ pattern
969
+ })
970
+ )
971
+ ]
972
+ }
589
973
  };
590
974
  };
591
975
  var getZodStringChecks = (zodString) => zodString._def.checks.reduce(
@@ -651,96 +1035,88 @@ var mapStringFormat = (zodStringChecks) => {
651
1035
  return void 0;
652
1036
  };
653
1037
 
654
- // src/create/schema/parsers/transform.ts
655
- var createTransformSchema = (zodTransform, state) => {
656
- if (zodTransform._def.openapi?.effectType === "output") {
657
- return createManualOutputTransformSchema(zodTransform, state);
658
- }
659
- if (zodTransform._def.openapi?.effectType === "input") {
660
- return createSchemaObject(zodTransform._def.schema, state, [
661
- "transform input"
662
- ]);
663
- }
664
- if (state.type === "output") {
665
- return createManualOutputTransformSchema(zodTransform, state);
666
- }
667
- state.effectType = "input";
668
- return createSchemaObject(zodTransform._def.schema, state, [
669
- "transform input"
670
- ]);
671
- };
672
- var createManualOutputTransformSchema = (zodTransform, state) => {
673
- if (!zodTransform._def.openapi?.type) {
674
- const zodType = zodTransform.constructor.name;
675
- const schemaName = `${zodType} - ${zodTransform._def.effect.type}`;
676
- throw new Error(
677
- `Failed to determine a type for ${schemaName} at ${state.path.join(
678
- " > "
679
- )}. Please change the 'effectType' to 'input', wrap it in a ZodPipeline or assign it a manual 'type'.`
680
- );
681
- }
682
- return {
683
- type: zodTransform._def.openapi.type
684
- };
685
- };
686
- var throwTransformError = (zodType, state) => {
687
- throw new Error(
688
- `${JSON.stringify(zodType)} at ${state.path.join(
689
- " > "
690
- )} 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`
691
- );
692
- };
693
-
694
1038
  // src/create/schema/parsers/tuple.ts
695
1039
  var createTupleSchema = (zodTuple, state) => {
696
1040
  const items = zodTuple.items;
697
1041
  const rest = zodTuple._def.rest;
698
- return {
699
- type: "array",
700
- ...mapItemProperties(items, rest, state)
701
- };
702
- };
703
- var mapPrefixItems = (items, state) => {
704
- if (items.length) {
705
- return items.map(
706
- (item, index) => createSchemaObject(item, state, [`tuple item ${index}`])
707
- );
708
- }
709
- return void 0;
710
- };
711
- var mapItemProperties = (items, rest, state) => {
712
1042
  const prefixItems = mapPrefixItems(items, state);
713
1043
  if (satisfiesVersion(state.components.openapi, "3.1.0")) {
714
1044
  if (!rest) {
715
1045
  return {
716
- maxItems: items.length,
717
- minItems: items.length,
718
- ...prefixItems && { prefixItems }
1046
+ type: "schema",
1047
+ schema: {
1048
+ type: "array",
1049
+ maxItems: items.length,
1050
+ minItems: items.length,
1051
+ ...prefixItems && {
1052
+ prefixItems: prefixItems.schemas.map((item) => item.schema)
1053
+ }
1054
+ },
1055
+ effects: prefixItems?.effects
719
1056
  };
720
1057
  }
1058
+ const itemSchema = createSchemaObject(rest, state, ["tuple items"]);
721
1059
  return {
722
- items: createSchemaObject(rest, state, ["tuple items"]),
723
- ...prefixItems && { prefixItems }
1060
+ type: "schema",
1061
+ schema: {
1062
+ type: "array",
1063
+ items: itemSchema.schema,
1064
+ ...prefixItems && {
1065
+ prefixItems: prefixItems.schemas.map((item) => item.schema)
1066
+ }
1067
+ },
1068
+ effects: flattenEffects([prefixItems?.effects, itemSchema.effects])
724
1069
  };
725
1070
  }
726
1071
  if (!rest) {
727
1072
  return {
728
- maxItems: items.length,
729
- minItems: items.length,
730
- ...prefixItems && { items: { oneOf: prefixItems } }
1073
+ type: "schema",
1074
+ schema: {
1075
+ type: "array",
1076
+ maxItems: items.length,
1077
+ minItems: items.length,
1078
+ ...prefixItems && {
1079
+ items: { oneOf: prefixItems.schemas.map((item) => item.schema) }
1080
+ }
1081
+ },
1082
+ effects: prefixItems?.effects
1083
+ };
1084
+ }
1085
+ if (prefixItems) {
1086
+ const restSchema = createSchemaObject(rest, state, ["tuple items"]);
1087
+ return {
1088
+ type: "schema",
1089
+ schema: {
1090
+ type: "array",
1091
+ items: {
1092
+ oneOf: [
1093
+ ...prefixItems.schemas.map((item) => item.schema),
1094
+ restSchema.schema
1095
+ ]
1096
+ }
1097
+ },
1098
+ effects: flattenEffects([restSchema.effects, prefixItems.effects])
731
1099
  };
732
1100
  }
733
1101
  return {
734
- ...prefixItems && {
735
- items: {
736
- oneOf: [
737
- ...prefixItems,
738
- createSchemaObject(rest, state, ["tuple items"])
739
- ]
740
- }
1102
+ type: "schema",
1103
+ schema: {
1104
+ type: "array"
741
1105
  }
742
1106
  };
743
1107
  };
1108
+ var mapPrefixItems = (items, state) => {
1109
+ if (items.length) {
1110
+ const schemas = items.map(
1111
+ (item, index) => createSchemaObject(item, state, [`tuple item ${index}`])
1112
+ );
1113
+ return {
1114
+ effects: flattenEffects(schemas.map((s) => s.effects)),
1115
+ schemas
1116
+ };
1117
+ }
1118
+ return void 0;
1119
+ };
744
1120
 
745
1121
  // src/create/schema/parsers/union.ts
746
1122
  var createUnionSchema = (zodUnion, state) => {
@@ -749,16 +1125,27 @@ var createUnionSchema = (zodUnion, state) => {
749
1125
  );
750
1126
  if (zodUnion._def.openapi?.unionOneOf) {
751
1127
  return {
752
- oneOf: schemas
1128
+ type: "schema",
1129
+ schema: {
1130
+ oneOf: schemas.map((s) => s.schema)
1131
+ },
1132
+ effects: flattenEffects(schemas.map((s) => s.effects))
753
1133
  };
754
1134
  }
755
1135
  return {
756
- anyOf: schemas
1136
+ type: "schema",
1137
+ schema: {
1138
+ anyOf: schemas.map((s) => s.schema)
1139
+ },
1140
+ effects: flattenEffects(schemas.map((s) => s.effects))
757
1141
  };
758
1142
  };
759
1143
 
760
1144
  // src/create/schema/parsers/unknown.ts
761
- var createUnknownSchema = (_zodUnknown) => ({});
1145
+ var createUnknownSchema = (_zodUnknown) => ({
1146
+ type: "schema",
1147
+ schema: {}
1148
+ });
762
1149
 
763
1150
  // src/create/schema/parsers/index.ts
764
1151
  var createSchemaSwitch = (zodSchema, state) => {
@@ -856,22 +1243,16 @@ var createSchemaSwitch = (zodSchema, state) => {
856
1243
  };
857
1244
 
858
1245
  // src/create/schema/index.ts
859
- var newSchemaState = (state) => ({
860
- type: state.type,
861
- components: state.components,
862
- path: [...state.path],
863
- visited: new Set(state.visited)
864
- });
865
- var createNewSchema = (zodSchema, newState, subpath) => {
866
- newState.path.push(...subpath);
867
- if (newState.visited.has(zodSchema)) {
1246
+ var isDescriptionEqual = (schema, zodSchema) => schema.type === "ref" && zodSchema.description === schema.zodType.description;
1247
+ var createNewSchema = (zodSchema, state) => {
1248
+ if (state.visited.has(zodSchema)) {
868
1249
  throw new Error(
869
- `The schema at ${newState.path.join(
1250
+ `The schema at ${state.path.join(
870
1251
  " > "
871
1252
  )} needs to be registered because it's circularly referenced`
872
1253
  );
873
1254
  }
874
- newState.visited.add(zodSchema);
1255
+ state.visited.add(zodSchema);
875
1256
  const {
876
1257
  effectType,
877
1258
  param,
@@ -881,99 +1262,112 @@ var createNewSchema = (zodSchema, newState, subpath) => {
881
1262
  unionOneOf,
882
1263
  ...additionalMetadata
883
1264
  } = zodSchema._def.openapi ?? {};
884
- const schema = createSchemaSwitch(zodSchema, newState);
885
- const description = zodSchema.description;
1265
+ const schema = createSchemaSwitch(zodSchema, state);
1266
+ const description = zodSchema.description && !isDescriptionEqual(schema, zodSchema) ? zodSchema.description : void 0;
886
1267
  const schemaWithMetadata = enhanceWithMetadata(schema, {
887
1268
  ...description && { description },
888
1269
  ...additionalMetadata
889
1270
  });
890
- return {
891
- schema: schemaWithMetadata,
892
- newState
893
- };
1271
+ state.visited.delete(zodSchema);
1272
+ return schemaWithMetadata;
894
1273
  };
895
- var createNewRef = (ref, zodSchema, state, subpath) => {
1274
+ var createNewRef = (ref, zodSchema, state) => {
896
1275
  state.components.schemas.set(zodSchema, {
897
1276
  type: "in-progress",
898
1277
  ref
899
1278
  });
900
- const newSchema = createNewSchema(
901
- zodSchema,
902
- newSchemaState({ ...state, visited: /* @__PURE__ */ new Set() }),
903
- subpath
904
- );
1279
+ const newSchema = createNewSchema(zodSchema, {
1280
+ ...state,
1281
+ visited: /* @__PURE__ */ new Set()
1282
+ });
905
1283
  state.components.schemas.set(zodSchema, {
906
1284
  type: "complete",
907
1285
  ref,
908
1286
  schemaObject: newSchema.schema,
909
- creationType: newSchema.newState?.effectType
1287
+ effects: newSchema.effects
910
1288
  });
911
1289
  return {
1290
+ type: "ref",
912
1291
  schema: { $ref: createComponentSchemaRef(ref) },
913
- newState: newSchema.newState
1292
+ effects: newSchema.effects ? [
1293
+ {
1294
+ type: "component",
1295
+ zodType: zodSchema,
1296
+ path: [...state.path]
1297
+ }
1298
+ ] : void 0,
1299
+ zodType: zodSchema
914
1300
  };
915
1301
  };
916
- var createExistingRef = (zodSchema, component, state, subpath) => {
917
- const newState = newSchemaState(state);
918
- newState.path.push(...subpath);
1302
+ var createExistingRef = (zodSchema, component, state) => {
919
1303
  if (component && component.type === "complete") {
920
- if (component.creationType && component.creationType !== state.type) {
921
- throwTransformError(zodSchema, newState);
922
- }
923
1304
  return {
1305
+ type: "ref",
924
1306
  schema: { $ref: createComponentSchemaRef(component.ref) },
925
- newState: {
926
- ...newState,
927
- effectType: component.creationType
928
- }
1307
+ effects: component.effects ? [
1308
+ {
1309
+ type: "component",
1310
+ zodType: zodSchema,
1311
+ path: [...state.path]
1312
+ }
1313
+ ] : void 0,
1314
+ zodType: zodSchema
929
1315
  };
930
1316
  }
931
1317
  if (component && component.type === "in-progress") {
932
1318
  return {
1319
+ type: "ref",
933
1320
  schema: { $ref: createComponentSchemaRef(component.ref) },
934
- newState
1321
+ effects: [
1322
+ {
1323
+ type: "component",
1324
+ zodType: zodSchema,
1325
+ path: [...state.path]
1326
+ }
1327
+ ],
1328
+ zodType: zodSchema
935
1329
  };
936
1330
  }
937
1331
  return;
938
1332
  };
939
- var createSchemaOrRef = (zodSchema, state, subpath) => {
1333
+ var createSchemaOrRef = (zodSchema, state) => {
940
1334
  const component = state.components.schemas.get(zodSchema);
941
- const existingRef = createExistingRef(zodSchema, component, state, subpath);
1335
+ const existingRef = createExistingRef(zodSchema, component, state);
942
1336
  if (existingRef) {
943
1337
  return existingRef;
944
1338
  }
945
1339
  const ref = zodSchema._def.openapi?.ref ?? component?.ref;
946
1340
  if (ref) {
947
- return createNewRef(ref, zodSchema, state, subpath);
1341
+ return createNewRef(ref, zodSchema, state);
948
1342
  }
949
- return createNewSchema(zodSchema, newSchemaState(state), subpath);
1343
+ return createNewSchema(zodSchema, state);
950
1344
  };
951
1345
  var createSchemaObject = (zodSchema, state, subpath) => {
952
- const { schema, newState } = createSchemaOrRef(zodSchema, state, subpath);
953
- if (newState?.effectType) {
954
- if (state.type !== newState?.effectType || state.effectType && newState.effectType !== state.effectType) {
955
- throwTransformError(zodSchema, newState);
956
- }
957
- state.effectType = newState.effectType;
958
- }
1346
+ state.path.push(...subpath);
1347
+ const schema = createSchemaOrRef(zodSchema, state);
1348
+ state.path.pop();
959
1349
  return schema;
960
1350
  };
1351
+ var createSchema = (zodSchema, state, subpath) => {
1352
+ const schema = createSchemaObject(zodSchema, state, subpath);
1353
+ if (schema.effects) {
1354
+ verifyEffects(schema.effects, state);
1355
+ }
1356
+ return schema.schema;
1357
+ };
961
1358
 
962
1359
  // src/create/parameters.ts
963
1360
  var createComponentParamRef = (ref) => `#/components/parameters/${ref}`;
964
1361
  var createBaseParameter = (schema, components, subpath) => {
965
1362
  const { ref, ...rest } = schema._def.openapi?.param ?? {};
966
- const state = newSchemaState({
1363
+ const state = {
967
1364
  components,
968
1365
  type: "input",
969
1366
  path: [],
970
1367
  visited: /* @__PURE__ */ new Set()
971
- });
972
- const schemaObject = createSchemaObject(schema, state, [
973
- ...subpath,
974
- "schema"
975
- ]);
976
- const required = !isOptionalSchema(schema, state);
1368
+ };
1369
+ const schemaObject = createSchema(schema, state, [...subpath, "schema"]);
1370
+ const required = !isOptionalSchema(schema, state)?.optional;
977
1371
  const description = schema._def.openapi?.description ?? schema._def.description;
978
1372
  return {
979
1373
  ...description && { description },
@@ -993,7 +1387,7 @@ var createParamOrRef = (zodSchema, components, subpath, type, name) => {
993
1387
  throw new Error("Parameter name missing");
994
1388
  }
995
1389
  if (component && component.type === "complete") {
996
- if (!("$ref" in component.paramObject) && (component.in !== type || component.name !== name)) {
1390
+ if (!("$ref" in component.paramObject) && (component.in !== paramType || component.name !== paramName)) {
997
1391
  throw new Error(`parameterRef "${component.ref}" is already registered`);
998
1392
  }
999
1393
  return {
@@ -1024,11 +1418,12 @@ var createParamOrRef = (zodSchema, components, subpath, type, name) => {
1024
1418
  }
1025
1419
  return paramObject;
1026
1420
  };
1027
- var createParameters = (type, zodObject, components, subpath) => {
1028
- if (!zodObject) {
1421
+ var createParameters = (type, zodObjectType, components, subpath) => {
1422
+ if (!zodObjectType) {
1029
1423
  return [];
1030
1424
  }
1031
- return Object.entries(zodObject.shape).map(
1425
+ const zodObject = getZodObject(zodObjectType, "input").shape;
1426
+ return Object.entries(zodObject).map(
1032
1427
  ([key, zodSchema]) => createParamOrRef(zodSchema, components, [...subpath, key], type, key)
1033
1428
  );
1034
1429
  };
@@ -1082,6 +1477,27 @@ var createParametersObject = (parameters, requestParams, components, subpath) =>
1082
1477
  ];
1083
1478
  return combinedParameters.length ? combinedParameters : void 0;
1084
1479
  };
1480
+ var getZodObject = (schema, type) => {
1481
+ if (isZodType(schema, "ZodObject")) {
1482
+ return schema;
1483
+ }
1484
+ if (isZodType(schema, "ZodLazy")) {
1485
+ return getZodObject(schema.schema, type);
1486
+ }
1487
+ if (isZodType(schema, "ZodEffects")) {
1488
+ return getZodObject(schema.innerType(), type);
1489
+ }
1490
+ if (isZodType(schema, "ZodBranded")) {
1491
+ return getZodObject(schema.unwrap(), type);
1492
+ }
1493
+ if (isZodType(schema, "ZodPipeline")) {
1494
+ if (type === "input") {
1495
+ return getZodObject(schema._def.in, type);
1496
+ }
1497
+ return getZodObject(schema._def.out, type);
1498
+ }
1499
+ throw new Error("failed to find ZodObject in schema");
1500
+ };
1085
1501
 
1086
1502
  // src/create/content.ts
1087
1503
  var createMediaTypeSchema = (schemaObject, components, type, subpath) => {
@@ -1091,14 +1507,14 @@ var createMediaTypeSchema = (schemaObject, components, type, subpath) => {
1091
1507
  if (!isAnyZodType(schemaObject)) {
1092
1508
  return schemaObject;
1093
1509
  }
1094
- return createSchemaObject(
1510
+ return createSchema(
1095
1511
  schemaObject,
1096
- newSchemaState({
1512
+ {
1097
1513
  components,
1098
1514
  type,
1099
1515
  path: [],
1100
1516
  visited: /* @__PURE__ */ new Set()
1101
- }),
1517
+ },
1102
1518
  subpath
1103
1519
  );
1104
1520
  };
@@ -1172,14 +1588,14 @@ var createHeaderOrRef = (schema, components) => {
1172
1588
  };
1173
1589
  var createBaseHeader = (schema, components) => {
1174
1590
  const { ref, ...rest } = schema._def.openapi?.header ?? {};
1175
- const state = newSchemaState({
1591
+ const state = {
1176
1592
  components,
1177
1593
  type: "output",
1178
1594
  path: [],
1179
1595
  visited: /* @__PURE__ */ new Set()
1180
- });
1181
- const schemaObject = createSchemaObject(schema, state, ["header"]);
1182
- const required = !isOptionalSchema(schema, state);
1596
+ };
1597
+ const schemaObject = createSchema(schema, state, ["header"]);
1598
+ const required = !isOptionalSchema(schema, state)?.optional;
1183
1599
  return {
1184
1600
  ...rest,
1185
1601
  ...schema && { schema: schemaObject },
@@ -1470,13 +1886,13 @@ var createComponents = (componentsObject, components) => {
1470
1886
  var createSchemaComponents = (componentsObject, components) => {
1471
1887
  Array.from(components.schemas).forEach(([schema, { type }], index) => {
1472
1888
  if (type === "manual") {
1473
- const state = newSchemaState({
1889
+ const state = {
1474
1890
  components,
1475
1891
  type: schema._def.openapi?.refType ?? "output",
1476
1892
  path: [],
1477
1893
  visited: /* @__PURE__ */ new Set()
1478
- });
1479
- createSchemaObject(schema, state, [`component schema index ${index}`]);
1894
+ };
1895
+ createSchema(schema, state, [`component schema index ${index}`]);
1480
1896
  }
1481
1897
  });
1482
1898
  const customComponents = Object.entries(