@chnak/zod-to-markdown 1.0.5 → 1.0.6

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/lib/index.js CHANGED
@@ -1,14 +1,20 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.zodSchemaToMarkdown = exports.zodSchemaToTable = void 0;
4
- const zod_1 = require("zod");
4
+ /**
5
+ * 使用 typeName 检查 Zod 类型,解决跨模块实例化导致的 instanceof 失败问题
6
+ */
7
+ function isZodType(schema, typeName) {
8
+ var _a;
9
+ return ((_a = schema._def) === null || _a === void 0 ? void 0 : _a.typeName) === typeName;
10
+ }
5
11
  /**
6
12
  * 将 Zod schema 转换为表格形式的 Markdown
7
13
  * @param schema - 要转换的 Zod schema
8
14
  * @returns 表格形式的 Markdown 字符串
9
15
  */
10
16
  function zodSchemaToTable(schema) {
11
- if (!(schema instanceof zod_1.z.ZodObject)) {
17
+ if (!isZodType(schema, 'ZodObject')) {
12
18
  return zodSchemaToMarkdown(schema);
13
19
  }
14
20
  // 收集所有嵌套字段
@@ -30,13 +36,13 @@ exports.zodSchemaToTable = zodSchemaToTable;
30
36
  */
31
37
  function collectFields(schema, prefix, fields, wrapperType) {
32
38
  // 处理 Optional - 包装类型
33
- if (schema instanceof zod_1.z.ZodOptional) {
39
+ if (isZodType(schema, 'ZodOptional')) {
34
40
  const inner = schema.unwrap();
35
41
  // 对于简单类型直接包装
36
- if (inner instanceof zod_1.z.ZodObject || inner instanceof zod_1.z.ZodArray) {
42
+ if (isZodType(inner, 'ZodObject') || isZodType(inner, 'ZodArray')) {
37
43
  collectFields(inner, prefix, fields, 'Optional');
38
44
  }
39
- else if (inner instanceof zod_1.z.ZodUnion || inner instanceof zod_1.z.ZodDiscriminatedUnion || inner instanceof zod_1.z.ZodIntersection) {
45
+ else if (isZodType(inner, 'ZodUnion') || isZodType(inner, 'ZodDiscriminatedUnion') || isZodType(inner, 'ZodIntersection')) {
40
46
  // 嵌套的复杂类型也需要展开
41
47
  collectFields(inner, prefix, fields, 'Optional');
42
48
  }
@@ -50,12 +56,12 @@ function collectFields(schema, prefix, fields, wrapperType) {
50
56
  return;
51
57
  }
52
58
  // 处理 Nullable - 包装类型
53
- if (schema instanceof zod_1.z.ZodNullable) {
59
+ if (isZodType(schema, 'ZodNullable')) {
54
60
  const inner = schema.unwrap();
55
- if (inner instanceof zod_1.z.ZodObject || inner instanceof zod_1.z.ZodArray) {
61
+ if (isZodType(inner, 'ZodObject') || isZodType(inner, 'ZodArray')) {
56
62
  collectFields(inner, prefix, fields, 'Nullable');
57
63
  }
58
- else if (inner instanceof zod_1.z.ZodUnion || inner instanceof zod_1.z.ZodDiscriminatedUnion || inner instanceof zod_1.z.ZodIntersection) {
64
+ else if (isZodType(inner, 'ZodUnion') || isZodType(inner, 'ZodDiscriminatedUnion') || isZodType(inner, 'ZodIntersection')) {
59
65
  // 嵌套的复杂类型也需要展开
60
66
  collectFields(inner, prefix, fields, 'Nullable');
61
67
  }
@@ -69,15 +75,15 @@ function collectFields(schema, prefix, fields, wrapperType) {
69
75
  return;
70
76
  }
71
77
  // 处理 Default
72
- if (schema instanceof zod_1.z.ZodDefault) {
78
+ if (isZodType(schema, 'ZodDefault')) {
73
79
  collectFields(schema.removeDefault(), prefix, fields);
74
80
  return;
75
81
  }
76
82
  // 处理 Array - 收集元素类型
77
- if (schema instanceof zod_1.z.ZodArray) {
83
+ if (isZodType(schema, 'ZodArray')) {
78
84
  const element = schema.element;
79
85
  // 如果是对象数组,展开其字段
80
- if (element instanceof zod_1.z.ZodObject) {
86
+ if (isZodType(element, 'ZodObject')) {
81
87
  const innerFields = [];
82
88
  collectFields(element, '', innerFields);
83
89
  innerFields.forEach(field => {
@@ -89,16 +95,20 @@ function collectFields(schema, prefix, fields, wrapperType) {
89
95
  });
90
96
  });
91
97
  }
92
- else if (element instanceof zod_1.z.ZodUnion || element instanceof zod_1.z.ZodDiscriminatedUnion) {
98
+ else if (isZodType(element, 'ZodUnion') || isZodType(element, 'ZodDiscriminatedUnion')) {
93
99
  // 数组元素是 Union 类型时,展开每个选项
94
- element.options.forEach((opt, index) => {
100
+ const unionSchema = element;
101
+ unionSchema.options.forEach((opt, index) => {
95
102
  // 对于 ZodOptional/ZodNullable,保留包装类型信息
96
- if (opt instanceof zod_1.z.ZodOptional || opt instanceof zod_1.z.ZodNullable) {
103
+ if (isZodType(opt, 'ZodOptional') || isZodType(opt, 'ZodNullable')) {
97
104
  const typeStr = getTypeString(opt);
98
- const inner = opt instanceof zod_1.z.ZodOptional ? opt.unwrap() : opt.unwrap();
99
- if (inner instanceof zod_1.z.ZodObject || inner instanceof zod_1.z.ZodIntersection) {
105
+ const innerWrapperType = isZodType(opt, 'ZodOptional') ? 'Optional' : 'Nullable';
106
+ const inner = isZodType(opt, 'ZodOptional')
107
+ ? opt.unwrap()
108
+ : opt.unwrap();
109
+ if (isZodType(inner, 'ZodObject') || isZodType(inner, 'ZodIntersection')) {
100
110
  const innerFields = [];
101
- collectFields(inner, '', innerFields);
111
+ collectFields(inner, '', innerFields, innerWrapperType);
102
112
  innerFields.forEach(field => {
103
113
  fields.push({
104
114
  path: `${prefix}[].${field.path} (option ${index + 1})`,
@@ -115,7 +125,7 @@ function collectFields(schema, prefix, fields, wrapperType) {
115
125
  });
116
126
  }
117
127
  }
118
- else if (opt instanceof zod_1.z.ZodObject || opt instanceof zod_1.z.ZodIntersection) {
128
+ else if (isZodType(opt, 'ZodObject') || isZodType(opt, 'ZodIntersection')) {
119
129
  // 对象类型或交叉类型,递归展开
120
130
  const innerFields = [];
121
131
  collectFields(opt, '', innerFields);
@@ -137,10 +147,10 @@ function collectFields(schema, prefix, fields, wrapperType) {
137
147
  }
138
148
  });
139
149
  }
140
- else if (element instanceof zod_1.z.ZodOptional) {
150
+ else if (isZodType(element, 'ZodOptional')) {
141
151
  // 数组元素是 Optional 类型时,展开内部类型
142
152
  const inner = element.unwrap();
143
- if (inner instanceof zod_1.z.ZodObject) {
153
+ if (isZodType(inner, 'ZodObject')) {
144
154
  const innerFields = [];
145
155
  collectFields(inner, '', innerFields);
146
156
  innerFields.forEach(field => {
@@ -171,7 +181,7 @@ function collectFields(schema, prefix, fields, wrapperType) {
171
181
  return;
172
182
  }
173
183
  // 处理 ZodObject - 递归展开
174
- if (schema instanceof zod_1.z.ZodObject) {
184
+ if (isZodType(schema, 'ZodObject')) {
175
185
  const shape = schema.shape;
176
186
  Object.keys(shape).forEach(key => {
177
187
  const subSchema = shape[key];
@@ -181,15 +191,18 @@ function collectFields(schema, prefix, fields, wrapperType) {
181
191
  return;
182
192
  }
183
193
  // 处理 ZodUnion - 展开每个选项
184
- if (schema instanceof zod_1.z.ZodUnion) {
185
- schema.options.forEach((opt, index) => {
194
+ if (isZodType(schema, 'ZodUnion')) {
195
+ const unionSchema = schema;
196
+ unionSchema.options.forEach((opt, index) => {
186
197
  // 对于 ZodOptional/ZodNullable,保留包装类型信息
187
- if (opt instanceof zod_1.z.ZodOptional || opt instanceof zod_1.z.ZodNullable) {
198
+ if (isZodType(opt, 'ZodOptional') || isZodType(opt, 'ZodNullable')) {
188
199
  const typeStr = getTypeString(opt);
189
- const innerWrapperType = opt instanceof zod_1.z.ZodOptional ? 'Optional' : 'Nullable';
190
- const inner = opt instanceof zod_1.z.ZodOptional ? opt.unwrap() : opt.unwrap();
200
+ const innerWrapperType = isZodType(opt, 'ZodOptional') ? 'Optional' : 'Nullable';
201
+ const inner = isZodType(opt, 'ZodOptional')
202
+ ? opt.unwrap()
203
+ : opt.unwrap();
191
204
  // 只有内部是对象或交叉类型才展开,否则直接使用类型字符串
192
- if (inner instanceof zod_1.z.ZodObject || inner instanceof zod_1.z.ZodIntersection) {
205
+ if (isZodType(inner, 'ZodObject') || isZodType(inner, 'ZodIntersection')) {
193
206
  const innerFields = [];
194
207
  collectFields(inner, '', innerFields, innerWrapperType);
195
208
  innerFields.forEach(field => {
@@ -208,7 +221,7 @@ function collectFields(schema, prefix, fields, wrapperType) {
208
221
  });
209
222
  }
210
223
  }
211
- else if (opt instanceof zod_1.z.ZodObject || opt instanceof zod_1.z.ZodIntersection) {
224
+ else if (isZodType(opt, 'ZodObject') || isZodType(opt, 'ZodIntersection')) {
212
225
  // 对象类型或交叉类型,递归展开
213
226
  const innerFields = [];
214
227
  collectFields(opt, '', innerFields);
@@ -232,14 +245,17 @@ function collectFields(schema, prefix, fields, wrapperType) {
232
245
  return;
233
246
  }
234
247
  // 处理 ZodDiscriminatedUnion - 类似 Union 但有关联键
235
- if (schema instanceof zod_1.z.ZodDiscriminatedUnion) {
236
- schema.options.forEach((opt, index) => {
248
+ if (isZodType(schema, 'ZodDiscriminatedUnion')) {
249
+ const discUnionSchema = schema;
250
+ discUnionSchema.options.forEach((opt, index) => {
237
251
  // 对于 ZodOptional/ZodNullable,保留包装类型信息
238
- if (opt instanceof zod_1.z.ZodOptional || opt instanceof zod_1.z.ZodNullable) {
252
+ if (isZodType(opt, 'ZodOptional') || isZodType(opt, 'ZodNullable')) {
239
253
  const typeStr = getTypeString(opt);
240
- const innerWrapperType = opt instanceof zod_1.z.ZodOptional ? 'Optional' : 'Nullable';
241
- const inner = opt instanceof zod_1.z.ZodOptional ? opt.unwrap() : opt.unwrap();
242
- if (inner instanceof zod_1.z.ZodObject || inner instanceof zod_1.z.ZodIntersection) {
254
+ const innerWrapperType = isZodType(opt, 'ZodOptional') ? 'Optional' : 'Nullable';
255
+ const inner = isZodType(opt, 'ZodOptional')
256
+ ? opt.unwrap()
257
+ : opt.unwrap();
258
+ if (isZodType(inner, 'ZodObject') || isZodType(inner, 'ZodIntersection')) {
243
259
  const innerFields = [];
244
260
  collectFields(inner, '', innerFields, innerWrapperType);
245
261
  innerFields.forEach(field => {
@@ -258,7 +274,7 @@ function collectFields(schema, prefix, fields, wrapperType) {
258
274
  });
259
275
  }
260
276
  }
261
- else if (opt instanceof zod_1.z.ZodObject || opt instanceof zod_1.z.ZodIntersection) {
277
+ else if (isZodType(opt, 'ZodObject') || isZodType(opt, 'ZodIntersection')) {
262
278
  const innerFields = [];
263
279
  collectFields(opt, '', innerFields);
264
280
  innerFields.forEach(field => {
@@ -280,11 +296,12 @@ function collectFields(schema, prefix, fields, wrapperType) {
280
296
  return;
281
297
  }
282
298
  // 处理 ZodIntersection - 展开左右两部分
283
- if (schema instanceof zod_1.z.ZodIntersection) {
299
+ if (isZodType(schema, 'ZodIntersection')) {
300
+ const intSchema = schema;
284
301
  const leftFields = [];
285
302
  const rightFields = [];
286
- collectFields(schema._def.left, '', leftFields);
287
- collectFields(schema._def.right, '', rightFields);
303
+ collectFields(intSchema._def.left, '', leftFields);
304
+ collectFields(intSchema._def.right, '', rightFields);
288
305
  leftFields.forEach(field => {
289
306
  fields.push({
290
307
  path: `${prefix}: ${field.path} (Left)`,
@@ -302,17 +319,19 @@ function collectFields(schema, prefix, fields, wrapperType) {
302
319
  return;
303
320
  }
304
321
  // 处理 Record
305
- if (schema instanceof zod_1.z.ZodRecord) {
322
+ if (isZodType(schema, 'ZodRecord')) {
323
+ const recordSchema = schema;
306
324
  fields.push({
307
325
  path: prefix,
308
- type: `Record<${getTypeString(schema.keySchema)}, ${getTypeString(schema.valueSchema)}>`,
326
+ type: `Record<${getTypeString(recordSchema.keySchema)}, ${getTypeString(recordSchema.valueSchema)}>`,
309
327
  description: schema.description || '-',
310
328
  });
311
329
  return;
312
330
  }
313
331
  // 处理 Tuple
314
- if (schema instanceof zod_1.z.ZodTuple) {
315
- const items = schema.items.map((item) => getTypeString(item)).join(', ');
332
+ if (isZodType(schema, 'ZodTuple')) {
333
+ const tupleSchema = schema;
334
+ const items = tupleSchema.items.map((item) => getTypeString(item)).join(', ');
316
335
  fields.push({
317
336
  path: prefix,
318
337
  type: `Tuple(${items})`,
@@ -321,14 +340,15 @@ function collectFields(schema, prefix, fields, wrapperType) {
321
340
  return;
322
341
  }
323
342
  // 处理 ZodEffects (transform)
324
- if (schema instanceof zod_1.z.ZodEffects) {
343
+ if (isZodType(schema, 'ZodEffects')) {
344
+ const effectsSchema = schema;
325
345
  const innerFields = [];
326
- collectFields(schema.innerType(), prefix, innerFields);
346
+ collectFields(effectsSchema.innerType(), prefix, innerFields);
327
347
  if (innerFields.length > 0) {
328
348
  innerFields.forEach(field => {
329
349
  fields.push({
330
350
  path: field.path,
331
- type: `Effects(${schema._def.effect.type})<${field.type}>`,
351
+ type: `Effects(${effectsSchema._def.effect.type})<${field.type}>`,
332
352
  description: field.description,
333
353
  });
334
354
  });
@@ -336,7 +356,7 @@ function collectFields(schema, prefix, fields, wrapperType) {
336
356
  else {
337
357
  fields.push({
338
358
  path: prefix,
339
- type: `Effects(${schema._def.effect.type})<${getTypeString(schema.innerType())}>`,
359
+ type: `Effects(${effectsSchema._def.effect.type})<${getTypeString(effectsSchema.innerType())}>`,
340
360
  description: schema.description || '-',
341
361
  });
342
362
  }
@@ -360,93 +380,119 @@ function collectFields(schema, prefix, fields, wrapperType) {
360
380
  * 获取类型的字符串描述
361
381
  */
362
382
  function getTypeString(schema) {
363
- if (schema instanceof zod_1.z.ZodOptional) {
383
+ if (isZodType(schema, 'ZodOptional')) {
364
384
  return `Optional<${getTypeString(schema.unwrap())}>`;
365
385
  }
366
- if (schema instanceof zod_1.z.ZodNullable) {
386
+ if (isZodType(schema, 'ZodNullable')) {
367
387
  return `Nullable<${getTypeString(schema.unwrap())}>`;
368
388
  }
369
- if (schema instanceof zod_1.z.ZodDefault) {
389
+ if (isZodType(schema, 'ZodDefault')) {
370
390
  return `Default<${getTypeString(schema.removeDefault())}>`;
371
391
  }
372
- if (schema instanceof zod_1.z.ZodArray) {
392
+ if (isZodType(schema, 'ZodArray')) {
373
393
  return `Array<${getTypeString(schema.element)}>`;
374
394
  }
375
- if (schema instanceof zod_1.z.ZodObject) {
395
+ if (isZodType(schema, 'ZodObject')) {
376
396
  // ZodObject 应该被 collectFields 展开,这里仅作为兜底
377
397
  const keys = Object.keys(schema.shape);
378
398
  return `Object{${keys.join(', ')}}`;
379
399
  }
380
- if (schema instanceof zod_1.z.ZodString) {
400
+ if (isZodType(schema, 'ZodString')) {
401
+ const strSchema = schema;
381
402
  let result = 'String';
382
- if (schema.minLength !== null || schema.maxLength !== null) {
403
+ if (strSchema.minLength !== null || strSchema.maxLength !== null) {
383
404
  const constraints = [];
384
- if (schema.minLength !== null)
385
- constraints.push(`min: ${schema.minLength}`);
386
- if (schema.maxLength !== null)
387
- constraints.push(`max: ${schema.maxLength}`);
405
+ if (strSchema.minLength !== null)
406
+ constraints.push(`min: ${strSchema.minLength}`);
407
+ if (strSchema.maxLength !== null)
408
+ constraints.push(`max: ${strSchema.maxLength}`);
388
409
  result += ` (${constraints.join(', ')})`;
389
410
  }
390
411
  return result;
391
412
  }
392
- if (schema instanceof zod_1.z.ZodNumber) {
413
+ if (isZodType(schema, 'ZodNumber')) {
414
+ const numSchema = schema;
393
415
  let result = 'Number';
394
- if (schema.minValue !== null || schema.maxValue !== null) {
416
+ if (numSchema.minValue !== null || numSchema.maxValue !== null) {
395
417
  const constraints = [];
396
- if (schema.minValue !== null)
397
- constraints.push(`min: ${schema.minValue}`);
398
- if (schema.maxValue !== null)
399
- constraints.push(`max: ${schema.maxValue}`);
418
+ if (numSchema.minValue !== null)
419
+ constraints.push(`min: ${numSchema.minValue}`);
420
+ if (numSchema.maxValue !== null)
421
+ constraints.push(`max: ${numSchema.maxValue}`);
400
422
  result += ` (${constraints.join(', ')})`;
401
423
  }
402
424
  return result;
403
425
  }
404
- if (schema instanceof zod_1.z.ZodEnum) {
405
- return `Enum(${schema.options.join(' | ')})`;
426
+ if (isZodType(schema, 'ZodEnum')) {
427
+ return `Enum(${(schema.options).join(' | ')})`;
406
428
  }
407
- if (schema instanceof zod_1.z.ZodLiteral) {
429
+ if (isZodType(schema, 'ZodLiteral')) {
408
430
  return `Literal(${JSON.stringify(schema.value)})`;
409
431
  }
410
- if (schema instanceof zod_1.z.ZodBoolean)
432
+ if (isZodType(schema, 'ZodBoolean'))
411
433
  return 'Boolean';
412
- if (schema instanceof zod_1.z.ZodBigInt)
434
+ if (isZodType(schema, 'ZodBigInt'))
413
435
  return 'BigInt';
414
- if (schema instanceof zod_1.z.ZodDate)
436
+ if (isZodType(schema, 'ZodDate'))
415
437
  return 'Date';
416
- if (schema instanceof zod_1.z.ZodNaN)
438
+ if (isZodType(schema, 'ZodNaN'))
417
439
  return 'NaN';
418
- if (schema instanceof zod_1.z.ZodNever)
440
+ if (isZodType(schema, 'ZodNever'))
419
441
  return 'Never';
420
- if (schema instanceof zod_1.z.ZodUnknown)
442
+ if (isZodType(schema, 'ZodUnknown'))
421
443
  return 'Unknown';
422
- if (schema instanceof zod_1.z.ZodVoid)
444
+ if (isZodType(schema, 'ZodVoid'))
423
445
  return 'Void';
424
- if (schema instanceof zod_1.z.ZodRecord) {
425
- return `Record<${getTypeString(schema.keySchema)}, ${getTypeString(schema.valueSchema)}>`;
446
+ if (isZodType(schema, 'ZodRecord')) {
447
+ const recSchema = schema;
448
+ return `Record<${getTypeString(recSchema.keySchema)}, ${getTypeString(recSchema.valueSchema)}>`;
426
449
  }
427
- if (schema instanceof zod_1.z.ZodTuple) {
428
- const items = schema.items.map((item) => getTypeString(item)).join(', ');
450
+ if (isZodType(schema, 'ZodTuple')) {
451
+ const tupSchema = schema;
452
+ const items = tupSchema.items.map((item) => getTypeString(item)).join(', ');
429
453
  return `Tuple(${items})`;
430
454
  }
431
- if (schema instanceof zod_1.z.ZodUnion) {
432
- const options = schema.options.map((opt) => getTypeString(opt)).join(' | ');
455
+ if (isZodType(schema, 'ZodUnion')) {
456
+ const unionSchema = schema;
457
+ const options = unionSchema.options.map((opt) => getTypeString(opt)).join(' | ');
433
458
  return `Union(${options})`;
434
459
  }
435
- if (schema instanceof zod_1.z.ZodDiscriminatedUnion) {
460
+ if (isZodType(schema, 'ZodDiscriminatedUnion')) {
436
461
  return `DiscriminatedUnion(${schema.discriminator})`;
437
462
  }
438
- if (schema instanceof zod_1.z.ZodIntersection) {
463
+ if (isZodType(schema, 'ZodIntersection')) {
439
464
  return 'Intersection';
440
465
  }
441
- if (schema instanceof zod_1.z.ZodEffects) {
466
+ if (isZodType(schema, 'ZodEffects')) {
442
467
  return `Effects(${schema._def.effect.type})`;
443
468
  }
444
- return schema.constructor.name;
469
+ if (isZodType(schema, 'ZodMap')) {
470
+ const mapSchema = schema;
471
+ return `Map<${getTypeString(mapSchema.keySchema)}, ${getTypeString(mapSchema.valueSchema)}>`;
472
+ }
473
+ if (isZodType(schema, 'ZodSet')) {
474
+ return `Set<${getTypeString(schema._def.valueType)}>`;
475
+ }
476
+ if (isZodType(schema, 'ZodAny'))
477
+ return 'Any';
478
+ if (isZodType(schema, 'ZodLazy')) {
479
+ return `Lazy(${schema._def.getter().constructor.name || 'unknown'})`;
480
+ }
481
+ if (isZodType(schema, 'ZodFunction')) {
482
+ const fnSchema = schema;
483
+ const args = fnSchema._def.args ? getTypeString(fnSchema._def.args) : 'args';
484
+ const returns = fnSchema._def.returns ? getTypeString(fnSchema._def.returns) : 'returns';
485
+ return `Function(${args} => ${returns})`;
486
+ }
487
+ if (isZodType(schema, 'ZodPromise')) {
488
+ return `Promise<${getTypeString(schema._def.type)}>`;
489
+ }
490
+ return schema._def.typeName || schema.constructor.name;
445
491
  }
446
492
  function zodSchemaToMarkdown(schema, indentLevel = 0) {
447
493
  let markdown = "";
448
494
  const indent = " ".repeat(indentLevel);
449
- if (schema instanceof zod_1.z.ZodObject) {
495
+ if (isZodType(schema, 'ZodObject')) {
450
496
  const shape = schema.shape;
451
497
  Object.keys(shape).forEach((key) => {
452
498
  const subSchema = shape[key];
@@ -455,11 +501,11 @@ function zodSchemaToMarkdown(schema, indentLevel = 0) {
455
501
  markdown += zodSchemaToMarkdown(subSchema, indentLevel + 1);
456
502
  });
457
503
  }
458
- else if (schema instanceof zod_1.z.ZodArray) {
504
+ else if (isZodType(schema, 'ZodArray')) {
459
505
  markdown += `${indent}- Array\n`;
460
506
  markdown += zodSchemaToMarkdown(schema.element, indentLevel + 1);
461
507
  }
462
- else if (schema instanceof zod_1.z.ZodString) {
508
+ else if (isZodType(schema, 'ZodString')) {
463
509
  markdown += `${indent}- String`;
464
510
  if (schema.minLength !== null) {
465
511
  markdown += ` (minLength: ${schema.minLength})`;
@@ -469,7 +515,7 @@ function zodSchemaToMarkdown(schema, indentLevel = 0) {
469
515
  }
470
516
  markdown += "\n";
471
517
  }
472
- else if (schema instanceof zod_1.z.ZodNumber) {
518
+ else if (isZodType(schema, 'ZodNumber')) {
473
519
  markdown += `${indent}- Number`;
474
520
  if (schema.minValue !== null) {
475
521
  markdown += ` (minValue: ${schema.minValue})`;
@@ -479,93 +525,99 @@ function zodSchemaToMarkdown(schema, indentLevel = 0) {
479
525
  }
480
526
  markdown += "\n";
481
527
  }
482
- else if (schema instanceof zod_1.z.ZodEnum) {
528
+ else if (isZodType(schema, 'ZodEnum')) {
483
529
  const values = schema.options.join(", ");
484
530
  markdown += `${indent}- Enum: ${values}\n`;
485
531
  }
486
- else if (schema instanceof zod_1.z.ZodUnion) {
532
+ else if (isZodType(schema, 'ZodUnion')) {
533
+ const unionSchema = schema;
487
534
  markdown += `${indent}- Union\n`;
488
- schema.options.forEach((option, index) => {
535
+ unionSchema.options.forEach((option, index) => {
489
536
  markdown += zodSchemaToMarkdown(option, indentLevel + 1);
490
- if (index < schema.options.length - 1) {
537
+ if (index < unionSchema.options.length - 1) {
491
538
  markdown += `${indent} |\n`;
492
539
  }
493
540
  });
494
541
  }
495
- else if (schema instanceof zod_1.z.ZodBoolean) {
542
+ else if (isZodType(schema, 'ZodBoolean')) {
496
543
  markdown += `${indent}- Boolean\n`;
497
544
  }
498
- else if (schema instanceof zod_1.z.ZodDefault) {
499
- markdown += `${indent}- Default: ${JSON.stringify(schema._def.defaultValue())}\n`;
500
- markdown += zodSchemaToMarkdown(schema.removeDefault(), indentLevel);
545
+ else if (isZodType(schema, 'ZodDefault')) {
546
+ const defSchema = schema;
547
+ markdown += `${indent}- Default: ${JSON.stringify(defSchema._def.defaultValue())}\n`;
548
+ markdown += zodSchemaToMarkdown(defSchema.removeDefault(), indentLevel);
501
549
  }
502
- else if (schema instanceof zod_1.z.ZodOptional) {
550
+ else if (isZodType(schema, 'ZodOptional')) {
503
551
  markdown += `${indent}- Optional\n`;
504
552
  markdown += zodSchemaToMarkdown(schema.unwrap(), indentLevel + 1);
505
553
  }
506
- else if (schema instanceof zod_1.z.ZodNullable) {
554
+ else if (isZodType(schema, 'ZodNullable')) {
507
555
  markdown += `${indent}- Nullable\n`;
508
556
  markdown += zodSchemaToMarkdown(schema.unwrap(), indentLevel + 1);
509
557
  }
510
- else if (schema instanceof zod_1.z.ZodEffects) {
558
+ else if (isZodType(schema, 'ZodEffects')) {
511
559
  const effectType = schema._def.effect.type;
512
560
  markdown += `${indent}- Effects (${effectType})\n`;
513
561
  markdown += zodSchemaToMarkdown(schema.innerType(), indentLevel + 1);
514
562
  }
515
- else if (schema instanceof zod_1.z.ZodDiscriminatedUnion) {
516
- const discriminator = schema.discriminator;
563
+ else if (isZodType(schema, 'ZodDiscriminatedUnion')) {
564
+ const discUnionSchema = schema;
565
+ const discriminator = discUnionSchema.discriminator;
517
566
  markdown += `${indent}- DiscriminatedUnion (key: ${discriminator})\n`;
518
- schema.options.forEach((option, index) => {
567
+ discUnionSchema.options.forEach((option, index) => {
519
568
  markdown += zodSchemaToMarkdown(option, indentLevel + 1);
520
- if (index < schema.options.length - 1) {
569
+ if (index < discUnionSchema.options.length - 1) {
521
570
  markdown += `${indent} |\n`;
522
571
  }
523
572
  });
524
573
  }
525
- else if (schema instanceof zod_1.z.ZodIntersection) {
574
+ else if (isZodType(schema, 'ZodIntersection')) {
575
+ const intSchema = schema;
526
576
  markdown += `${indent}- Intersection\n`;
527
577
  markdown += `${indent} Left:\n`;
528
- markdown += zodSchemaToMarkdown(schema._def.left, indentLevel + 2);
578
+ markdown += zodSchemaToMarkdown(intSchema._def.left, indentLevel + 2);
529
579
  markdown += `${indent} Right:\n`;
530
- markdown += zodSchemaToMarkdown(schema._def.right, indentLevel + 2);
580
+ markdown += zodSchemaToMarkdown(intSchema._def.right, indentLevel + 2);
531
581
  }
532
- else if (schema instanceof zod_1.z.ZodRecord) {
582
+ else if (isZodType(schema, 'ZodRecord')) {
583
+ const recSchema = schema;
533
584
  markdown += `${indent}- Record\n`;
534
585
  markdown += `${indent} Key:\n`;
535
- markdown += zodSchemaToMarkdown(schema.keySchema, indentLevel + 2);
586
+ markdown += zodSchemaToMarkdown(recSchema.keySchema, indentLevel + 2);
536
587
  markdown += `${indent} Value:\n`;
537
- markdown += zodSchemaToMarkdown(schema.valueSchema, indentLevel + 2);
588
+ markdown += zodSchemaToMarkdown(recSchema.valueSchema, indentLevel + 2);
538
589
  }
539
- else if (schema instanceof zod_1.z.ZodTuple) {
590
+ else if (isZodType(schema, 'ZodTuple')) {
591
+ const tupSchema = schema;
540
592
  markdown += `${indent}- Tuple\n`;
541
- schema.items.forEach((item, index) => {
593
+ tupSchema.items.forEach((item, index) => {
542
594
  markdown += `${indent} [${index}]:\n`;
543
595
  markdown += zodSchemaToMarkdown(item, indentLevel + 2);
544
596
  });
545
597
  }
546
- else if (schema instanceof zod_1.z.ZodLiteral) {
598
+ else if (isZodType(schema, 'ZodLiteral')) {
547
599
  markdown += `${indent}- Literal: ${JSON.stringify(schema.value)}\n`;
548
600
  }
549
- else if (schema instanceof zod_1.z.ZodBigInt) {
601
+ else if (isZodType(schema, 'ZodBigInt')) {
550
602
  markdown += `${indent}- BigInt\n`;
551
603
  }
552
- else if (schema instanceof zod_1.z.ZodDate) {
604
+ else if (isZodType(schema, 'ZodDate')) {
553
605
  markdown += `${indent}- Date\n`;
554
606
  }
555
- else if (schema instanceof zod_1.z.ZodNaN) {
607
+ else if (isZodType(schema, 'ZodNaN')) {
556
608
  markdown += `${indent}- NaN\n`;
557
609
  }
558
- else if (schema instanceof zod_1.z.ZodNever) {
610
+ else if (isZodType(schema, 'ZodNever')) {
559
611
  markdown += `${indent}- Never\n`;
560
612
  }
561
- else if (schema instanceof zod_1.z.ZodUnknown) {
613
+ else if (isZodType(schema, 'ZodUnknown')) {
562
614
  markdown += `${indent}- Unknown\n`;
563
615
  }
564
- else if (schema instanceof zod_1.z.ZodVoid) {
616
+ else if (isZodType(schema, 'ZodVoid')) {
565
617
  markdown += `${indent}- Void\n`;
566
618
  }
567
619
  else {
568
- markdown += `${indent}- Type: ${schema.constructor.name}\n`;
620
+ markdown += `${indent}- Type: ${schema._def.typeName || schema.constructor.name}\n`;
569
621
  }
570
622
  return markdown;
571
623
  }
package/lib/index.test.js CHANGED
@@ -309,6 +309,66 @@ describe('zodSchemaToTable', () => {
309
309
  |------|------|------|
310
310
  | items[].a (option 1) | String | - |
311
311
  | items[].b (option 2) | Number | - |
312
+ `;
313
+ expect((0, index_1.zodSchemaToTable)(schema)).toBe(expected);
314
+ });
315
+ it('should convert object schema with ZodMap to table', () => {
316
+ const schema = zod_1.z.object({
317
+ map: zod_1.z.map(zod_1.z.string(), zod_1.z.number()),
318
+ });
319
+ const expected = `| 字段 | 类型 | 描述 |
320
+ |------|------|------|
321
+ | map | Map<String, Number> | - |
322
+ `;
323
+ expect((0, index_1.zodSchemaToTable)(schema)).toBe(expected);
324
+ });
325
+ it('should convert object schema with ZodSet to table', () => {
326
+ const schema = zod_1.z.object({
327
+ set: zod_1.z.set(zod_1.z.string()),
328
+ });
329
+ const expected = `| 字段 | 类型 | 描述 |
330
+ |------|------|------|
331
+ | set | Set<String> | - |
332
+ `;
333
+ expect((0, index_1.zodSchemaToTable)(schema)).toBe(expected);
334
+ });
335
+ it('should convert object schema with ZodAny to table', () => {
336
+ const schema = zod_1.z.object({
337
+ any: zod_1.z.any(),
338
+ });
339
+ const expected = `| 字段 | 类型 | 描述 |
340
+ |------|------|------|
341
+ | any | Any | - |
342
+ `;
343
+ expect((0, index_1.zodSchemaToTable)(schema)).toBe(expected);
344
+ });
345
+ it('should convert object schema with ZodLazy to table', () => {
346
+ const schema = zod_1.z.object({
347
+ lazy: zod_1.z.lazy(() => zod_1.z.string()),
348
+ });
349
+ const expected = `| 字段 | 类型 | 描述 |
350
+ |------|------|------|
351
+ | lazy | Lazy(ZodString) | - |
352
+ `;
353
+ expect((0, index_1.zodSchemaToTable)(schema)).toBe(expected);
354
+ });
355
+ it('should convert object schema with ZodFunction to table', () => {
356
+ const schema = zod_1.z.object({
357
+ fn: zod_1.z.function().args(zod_1.z.string()).returns(zod_1.z.number()),
358
+ });
359
+ const expected = `| 字段 | 类型 | 描述 |
360
+ |------|------|------|
361
+ | fn | Function(Tuple(String) => Number) | - |
362
+ `;
363
+ expect((0, index_1.zodSchemaToTable)(schema)).toBe(expected);
364
+ });
365
+ it('should convert object schema with ZodPromise to table', () => {
366
+ const schema = zod_1.z.object({
367
+ promise: zod_1.z.promise(zod_1.z.string()),
368
+ });
369
+ const expected = `| 字段 | 类型 | 描述 |
370
+ |------|------|------|
371
+ | promise | Promise<String> | - |
312
372
  `;
313
373
  expect((0, index_1.zodSchemaToTable)(schema)).toBe(expected);
314
374
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chnak/zod-to-markdown",
3
- "version": "1.0.5",
3
+ "version": "1.0.6",
4
4
  "description": "A utility function to convert Zod schemas to Markdown documentation",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",