zod-nest 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -38,6 +38,9 @@ interface ZodNestRegistry {
38
38
  * underlying Zod registry is `z.globalRegistry`, which may hold third-party
39
39
  * entries — bulk emission filters its output against this snapshot to keep
40
40
  * only zod-nest-known ids.
41
+ *
42
+ * Includes ids discovered transitively via `.meta({ id })` on descendants
43
+ * of explicitly-registered schemas.
41
44
  */
42
45
  ids(): readonly string[];
43
46
  }
package/dist/index.d.ts CHANGED
@@ -38,6 +38,9 @@ interface ZodNestRegistry {
38
38
  * underlying Zod registry is `z.globalRegistry`, which may hold third-party
39
39
  * entries — bulk emission filters its output against this snapshot to keep
40
40
  * only zod-nest-known ids.
41
+ *
42
+ * Includes ids discovered transitively via `.meta({ id })` on descendants
43
+ * of explicitly-registered schemas.
41
44
  */
42
45
  ids(): readonly string[];
43
46
  }
package/dist/index.js CHANGED
@@ -120,6 +120,7 @@ var overrideJSONSchema = /* @__PURE__ */ __name((schema, arg) => {
120
120
  output: arg
121
121
  });
122
122
  }, "overrideJSONSchema");
123
+ var peekRegistration = /* @__PURE__ */ __name((schema) => customOverrideMap.get(schema), "peekRegistration");
123
124
  var createCustomOverride = /* @__PURE__ */ __name((io) => {
124
125
  return ({ zodSchema, jsonSchema }) => {
125
126
  const record = customOverrideMap.get(zodSchema);
@@ -259,6 +260,18 @@ var isStrictlyUnrepresentable = /* @__PURE__ */ __name((jsonSchema, zodSchema) =
259
260
  }
260
261
  return Object.keys(jsonSchema).length === 0;
261
262
  }, "isStrictlyUnrepresentable");
263
+ var markPipeCoverage = /* @__PURE__ */ __name((schema, io, covered) => {
264
+ const def = schema._zod.def;
265
+ if (def.type !== "pipe" || def.in === void 0 || def.out === void 0) {
266
+ return;
267
+ }
268
+ const target = io === "output" ? def.out : def.in._zod.traits.has("$ZodTransform") ? def.out : def.in;
269
+ if (covered.has(target)) {
270
+ return;
271
+ }
272
+ covered.add(target);
273
+ markPipeCoverage(target, io, covered);
274
+ }, "markPipeCoverage");
262
275
  var buildToJsonSchemaOptions = /* @__PURE__ */ __name((params) => {
263
276
  const strict = params.strict ?? true;
264
277
  const compositionOverride = createCompositionOverride({
@@ -268,8 +281,15 @@ var buildToJsonSchemaOptions = /* @__PURE__ */ __name((params) => {
268
281
  const customOverride = createCustomOverride(params.io);
269
282
  const merged = combine(primitiveOverride, compositionOverride, customOverride, params.override);
270
283
  const unrepresentableHits = [];
284
+ const coveredByPipe = /* @__PURE__ */ new WeakSet();
271
285
  const wrapped = /* @__PURE__ */ __name((ctx) => {
272
286
  merged(ctx);
287
+ if (ctx.zodSchema._zod.def.type === "pipe") {
288
+ const record = peekRegistration(ctx.zodSchema);
289
+ if (record !== void 0 && record[params.io] !== void 0) {
290
+ markPipeCoverage(ctx.zodSchema, params.io, coveredByPipe);
291
+ }
292
+ }
273
293
  if (!strict || !isStrictlyUnrepresentable(ctx.jsonSchema, ctx.zodSchema)) {
274
294
  return;
275
295
  }
@@ -277,7 +297,8 @@ var buildToJsonSchemaOptions = /* @__PURE__ */ __name((params) => {
277
297
  path: [
278
298
  ...ctx.path
279
299
  ],
280
- zodType: ctx.zodSchema._zod.def.type
300
+ zodType: ctx.zodSchema._zod.def.type,
301
+ zodSchema: ctx.zodSchema
281
302
  });
282
303
  }, "wrapped");
283
304
  const options = {
@@ -295,7 +316,7 @@ var buildToJsonSchemaOptions = /* @__PURE__ */ __name((params) => {
295
316
  return {
296
317
  options,
297
318
  consumeUnrepresentable: /* @__PURE__ */ __name(() => {
298
- const firstHit = unrepresentableHits[0];
319
+ const firstHit = unrepresentableHits.find((hit) => !coveredByPipe.has(hit.zodSchema));
299
320
  if (firstHit !== void 0) {
300
321
  throw new ZodNestUnrepresentableError(firstHit.path, firstHit.zodType);
301
322
  }
@@ -324,20 +345,146 @@ var toOpenApi = /* @__PURE__ */ __name((schema, opts) => {
324
345
  }
325
346
  return result;
326
347
  }, "toOpenApi");
348
+ var INNER_TYPE_WRAPPERS = /* @__PURE__ */ new Set([
349
+ "optional",
350
+ "nullable",
351
+ "default",
352
+ "prefault",
353
+ "catch",
354
+ "nonoptional",
355
+ "success",
356
+ "readonly",
357
+ "promise"
358
+ ]);
359
+ var readId = /* @__PURE__ */ __name((schema) => {
360
+ const meta = zod.z.globalRegistry.get(schema);
361
+ if (meta === void 0) {
362
+ return void 0;
363
+ }
364
+ const id = meta.id;
365
+ return typeof id === "string" ? id : void 0;
366
+ }, "readId");
367
+ var collectChildren = /* @__PURE__ */ __name((schema) => {
368
+ const def = schema._zod.def;
369
+ if (def.type === "object") {
370
+ const out = [];
371
+ const shape = def.shape;
372
+ if (shape !== void 0) {
373
+ for (const value of Object.values(shape)) {
374
+ out.push(value);
375
+ }
376
+ }
377
+ if (def.catchall !== void 0) {
378
+ out.push(def.catchall);
379
+ }
380
+ return out;
381
+ }
382
+ if (def.type === "array") {
383
+ return [
384
+ def.element
385
+ ];
386
+ }
387
+ if (def.type === "union") {
388
+ return def.options.map((opt) => opt);
389
+ }
390
+ if (def.type === "intersection") {
391
+ return [
392
+ def.left,
393
+ def.right
394
+ ];
395
+ }
396
+ if (def.type === "tuple") {
397
+ const out = def.items.map((it) => it);
398
+ if (def.rest !== null) {
399
+ out.push(def.rest);
400
+ }
401
+ return out;
402
+ }
403
+ if (def.type === "record" || def.type === "map") {
404
+ return [
405
+ def.keyType,
406
+ def.valueType
407
+ ];
408
+ }
409
+ if (def.type === "set") {
410
+ return [
411
+ def.valueType
412
+ ];
413
+ }
414
+ if (def.type === "pipe") {
415
+ return [
416
+ def.in,
417
+ def.out
418
+ ];
419
+ }
420
+ if (def.type === "lazy") {
421
+ return [
422
+ def.getter()
423
+ ];
424
+ }
425
+ if (INNER_TYPE_WRAPPERS.has(def.type)) {
426
+ return [
427
+ def.innerType
428
+ ];
429
+ }
430
+ return [];
431
+ }, "collectChildren");
432
+ var discoverDependents = /* @__PURE__ */ __name((schema) => {
433
+ const visited = /* @__PURE__ */ new WeakSet();
434
+ const out = [];
435
+ const stack = [
436
+ schema
437
+ ];
438
+ while (stack.length > 0) {
439
+ const current = stack.pop();
440
+ if (visited.has(current)) {
441
+ continue;
442
+ }
443
+ visited.add(current);
444
+ for (const child of collectChildren(current)) {
445
+ if (visited.has(child)) {
446
+ continue;
447
+ }
448
+ const id = readId(child);
449
+ if (id !== void 0) {
450
+ out.push([
451
+ child,
452
+ id
453
+ ]);
454
+ }
455
+ stack.push(child);
456
+ }
457
+ }
458
+ return out;
459
+ }, "discoverDependents");
460
+
461
+ // src/schema/registry.ts
327
462
  var createRegistry = /* @__PURE__ */ __name(() => {
328
463
  const seen = /* @__PURE__ */ new Map();
464
+ const recordOnce = /* @__PURE__ */ __name((schema, id) => {
465
+ let set = seen.get(id);
466
+ if (set === void 0) {
467
+ set = /* @__PURE__ */ new Set();
468
+ seen.set(id, set);
469
+ }
470
+ if (set.has(schema)) {
471
+ return false;
472
+ }
473
+ set.add(schema);
474
+ return true;
475
+ }, "recordOnce");
329
476
  return {
330
477
  zodRegistry: zod.z.globalRegistry,
331
478
  register: /* @__PURE__ */ __name((schema, id) => {
332
479
  zod.z.globalRegistry.add(schema, {
333
480
  id
334
481
  });
335
- let set = seen.get(id);
336
- if (set === void 0) {
337
- set = /* @__PURE__ */ new Set();
338
- seen.set(id, set);
482
+ if (!recordOnce(schema, id)) {
483
+ return;
484
+ }
485
+ for (const [child, childId] of discoverDependents(schema)) {
486
+ recordOnce(child, childId);
339
487
  }
340
- set.add(schema);
341
488
  }, "register"),
342
489
  hasCollision: /* @__PURE__ */ __name((id) => {
343
490
  const set = seen.get(id);
@@ -1279,6 +1426,39 @@ var hintFor = /* @__PURE__ */ __name((ref, collected) => {
1279
1426
  return "no DTO with this id was registered \u2014 check for a meta.id typo or a DTO used without createZodDto";
1280
1427
  }, "hintFor");
1281
1428
 
1429
+ // src/document/expose-closure.ts
1430
+ var extendExposureViaRefs = /* @__PURE__ */ __name((collected, inputSchemas, outputSchemas) => ({
1431
+ ...collected,
1432
+ inputExposedIds: closeOverRefs(collected.inputExposedIds, inputSchemas),
1433
+ outputExposedIds: closeOverRefs(collected.outputExposedIds, outputSchemas)
1434
+ }), "extendExposureViaRefs");
1435
+ var closeOverRefs = /* @__PURE__ */ __name((seed, bodies) => {
1436
+ const out = new Set(seed);
1437
+ const queue = [
1438
+ ...seed
1439
+ ];
1440
+ while (queue.length > 0) {
1441
+ const id = queue.shift();
1442
+ const body = bodies.get(id);
1443
+ if (body === void 0) {
1444
+ continue;
1445
+ }
1446
+ walkRefs(body, (ref) => {
1447
+ if (!ref.startsWith(COMPONENTS_SCHEMAS_PREFIX)) {
1448
+ return void 0;
1449
+ }
1450
+ const target = ref.slice(COMPONENTS_SCHEMAS_PREFIX.length);
1451
+ if (out.has(target)) {
1452
+ return void 0;
1453
+ }
1454
+ out.add(target);
1455
+ queue.push(target);
1456
+ return void 0;
1457
+ });
1458
+ }
1459
+ return out;
1460
+ }, "closeOverRefs");
1461
+
1282
1462
  // src/document/constants.ts
1283
1463
  var OUTPUT_SUFFIX = "Output";
1284
1464
 
@@ -1470,11 +1650,12 @@ var applyZodNest = /* @__PURE__ */ __name((doc, opts) => {
1470
1650
  override: opts.override,
1471
1651
  strict: opts.strict
1472
1652
  });
1653
+ const extended = extendExposureViaRefs(collected, inputSchemas, outputSchemas);
1473
1654
  const { divergentOutputIds, renames } = mergeSchemas({
1474
1655
  doc,
1475
1656
  inputSchemas,
1476
1657
  outputSchemas,
1477
- collected,
1658
+ collected: extended,
1478
1659
  collisions: registry.getCollisions()
1479
1660
  });
1480
1661
  rewriteRefs2({
@@ -1485,7 +1666,7 @@ var applyZodNest = /* @__PURE__ */ __name((doc, opts) => {
1485
1666
  stripMarkers(doc);
1486
1667
  assertNoDanglingRefs({
1487
1668
  doc,
1488
- collected
1669
+ collected: extended
1489
1670
  });
1490
1671
  return doc;
1491
1672
  }, "applyZodNest");