@nullix/zod-mongoose-studio 3.3.0 → 3.3.2

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 (119) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/_fonts/57NSSoFy1VLVs2gqly8Ls9awBnZMFyXGrefpmqvdqmc-zJfbBtpgM4cDmcXBsqZNW79_kFnlpPd62b48glgdydA.woff2 +0 -0
  3. package/.output/public/_fonts/8VR2wSMN-3U4NbWAVYXlkRV6hA0jFBXP-0RtL3X7fko-x2gYI4qfmkRdxyQQUPaBZdZdgl1TeVrquF_TxHeM4lM.woff2 +0 -0
  4. package/.output/public/_fonts/GsKUclqeNLJ96g5AU593ug6yanivOiwjW_7zESNPChw-jHA4tBeM1bjF7LATGUpfBuSTyomIFrWBTzjF7txVYfg.woff2 +0 -0
  5. package/.output/public/_fonts/Ld1FnTo3yTIwDyGfTQ5-Fws9AWsCbKfMvgxduXr7JcY-W25bL8NF1fjpLRSOgJb7RoZPHqGQNwMTM7S9tHVoxx8.woff2 +0 -0
  6. package/.output/public/_fonts/NdzqRASp2bovDUhQT1IRE_EMqKJ2KYQdTCfFcBvL8yw-KhwZiS86o3fErOe5GGMExHUemmI_dBfaEFxjISZrBd0.woff2 +0 -0
  7. package/.output/public/_fonts/iTkrULNFJJkTvihIg1Vqi5IODRH_9btXCioVF5l98I8-AndUyau2HR2felA_ra8V2mutQgschhasE5FD1dXGJX8.woff2 +0 -0
  8. package/.output/public/_nuxt/B6lqezyA.js +27 -0
  9. package/.output/public/_nuxt/{IxYCG8hB.js → B7ScFmDB.js} +1 -1
  10. package/.output/public/_nuxt/B8gqXD2U.js +1 -0
  11. package/.output/public/_nuxt/{ikxafTHA.js → BC9tFNFa.js} +180 -184
  12. package/.output/public/_nuxt/{qwxNOyg7.js → Bbi9UBvi.js} +1 -1
  13. package/.output/public/_nuxt/{CNZorjDf.js → BcYnCaqL.js} +1 -1
  14. package/.output/public/_nuxt/{BzhSDy30.js → BlZ0x31M.js} +1 -1
  15. package/.output/public/_nuxt/Bw82IGM8.js +1 -0
  16. package/.output/public/_nuxt/{qQyvCkbV.js → C8xmwXC2.js} +1 -1
  17. package/.output/public/_nuxt/{Ce-T_1aD.js → C919AVYR.js} +1 -1
  18. package/.output/public/_nuxt/{nDZOJ7rN.js → CsQL5F-l.js} +2 -2
  19. package/.output/public/_nuxt/Czp4_2o-.js +33 -0
  20. package/.output/public/_nuxt/{CC3n3Aga.js → DJa7_7Hz.js} +1 -1
  21. package/.output/public/_nuxt/DKK0Mrrg.js +1 -0
  22. package/.output/public/_nuxt/DbUZZZZu.js +6 -0
  23. package/.output/public/_nuxt/{B7P0wQ35.js → DbqvVYbv.js} +1 -1
  24. package/.output/public/_nuxt/{Ick_23I4.js → JkiDMdYG.js} +1 -1
  25. package/.output/public/_nuxt/{81vqh61j.js → OVQ3C2Ge.js} +1 -1
  26. package/.output/public/_nuxt/{Cs8GXJCB.js → PXBhK7S_.js} +1 -1
  27. package/.output/public/_nuxt/{CAd-qHfI.js → YC-RLggm.js} +1 -1
  28. package/.output/public/_nuxt/builds/latest.json +1 -1
  29. package/.output/public/_nuxt/builds/meta/46174b5e-cab6-4a73-95f8-66a1c9b1be2b.json +1 -0
  30. package/.output/public/_nuxt/{tzj4nvDE.js → d1NBz903.js} +2 -2
  31. package/.output/public/_nuxt/{entry.J_CbC0oY.css → entry.DaqrxXuH.css} +1 -1
  32. package/.output/public/_nuxt/error-404.CTSXlFYa.css +1 -0
  33. package/.output/public/_nuxt/error-500.DqEfQnVZ.css +1 -0
  34. package/.output/public/_nuxt/{Bd32GOUy.js → iGzUozbF.js} +1 -1
  35. package/.output/public/_nuxt/{DjPT-NCE.js → iKW_mt0p.js} +1 -1
  36. package/.output/server/chunks/_/error-500.mjs.map +1 -1
  37. package/.output/server/chunks/build/client.precomputed.mjs +1 -1
  38. package/.output/server/chunks/build/{error-404-BN-7rNE4.mjs → error-404-KRkA0DPI.mjs} +10 -4
  39. package/.output/server/chunks/build/error-404-KRkA0DPI.mjs.map +1 -0
  40. package/.output/server/chunks/build/error-404-styles.I0NYw-Bn.mjs +8 -0
  41. package/.output/server/chunks/build/error-404-styles.I0NYw-Bn.mjs.map +1 -0
  42. package/.output/server/chunks/build/{error-500-DhIQ-2yt.mjs → error-500-DIIFf55p.mjs} +10 -4
  43. package/.output/server/chunks/build/error-500-DIIFf55p.mjs.map +1 -0
  44. package/.output/server/chunks/build/error-500-styles.D1cs9hQy.mjs +8 -0
  45. package/.output/server/chunks/build/error-500-styles.D1cs9hQy.mjs.map +1 -0
  46. package/.output/server/chunks/build/index-CB1N4gax.mjs +557 -0
  47. package/.output/server/chunks/build/index-CB1N4gax.mjs.map +1 -0
  48. package/.output/server/chunks/build/server.mjs +326 -248
  49. package/.output/server/chunks/build/server.mjs.map +1 -1
  50. package/.output/server/chunks/build/styles.mjs +4 -4
  51. package/.output/server/chunks/nitro/nitro.mjs +2319 -852
  52. package/.output/server/chunks/nitro/nitro.mjs.map +1 -1
  53. package/.output/server/chunks/routes/api/editor-types.get.mjs +113 -0
  54. package/.output/server/chunks/routes/api/editor-types.get.mjs.map +1 -0
  55. package/.output/server/chunks/routes/api/parse.post.mjs +26 -1448
  56. package/.output/server/chunks/routes/api/parse.post.mjs.map +1 -1
  57. package/.output/server/chunks/routes/api/resolve.get.mjs +6 -0
  58. package/.output/server/chunks/routes/api/resolve.get.mjs.map +1 -1
  59. package/.output/server/chunks/routes/api/studio/run.post.mjs +40 -0
  60. package/.output/server/chunks/routes/api/studio/run.post.mjs.map +1 -0
  61. package/.output/server/chunks/routes/renderer.mjs +1 -1
  62. package/.output/server/chunks/routes/renderer.mjs.map +1 -1
  63. package/.output/server/index.mjs +7 -1
  64. package/.output/server/index.mjs.map +1 -1
  65. package/.output/server/node_modules/acorn/dist/acorn.mjs +6266 -0
  66. package/.output/server/node_modules/acorn/package.json +50 -0
  67. package/.output/server/node_modules/ip-address/dist/common.js +112 -4
  68. package/.output/server/node_modules/ip-address/dist/ipv4.js +322 -87
  69. package/.output/server/node_modules/ip-address/dist/ipv6.js +654 -199
  70. package/.output/server/node_modules/ip-address/dist/v4/constants.js +45 -2
  71. package/.output/server/node_modules/ip-address/dist/v6/constants.js +55 -3
  72. package/.output/server/node_modules/ip-address/dist/v6/helpers.js +12 -3
  73. package/.output/server/node_modules/ip-address/package.json +49 -37
  74. package/.output/server/node_modules/ufo/dist/index.mjs +2 -2
  75. package/.output/server/node_modules/ufo/package.json +9 -9
  76. package/.output/server/package.json +4 -3
  77. package/README.md +65 -20
  78. package/app/assets/css/main.css +1 -0
  79. package/app/assets/css/studio.css +131 -0
  80. package/app/components/StudioConversion.vue +41 -0
  81. package/app/components/StudioDataPanel.vue +21 -0
  82. package/app/components/StudioEditor.vue +78 -102
  83. package/app/components/StudioExpandButton.vue +11 -0
  84. package/app/components/StudioOutput.vue +7 -1
  85. package/app/components/StudioSourcePanel.vue +16 -0
  86. package/app/components/StudioValidation.vue +47 -0
  87. package/app/components/ZodMongooseStudio.vue +216 -198
  88. package/app/composables/useStudioRunner.ts +142 -0
  89. package/app/pages/index.vue +1 -1
  90. package/app/plugins/monaco.client.ts +2 -0
  91. package/bin/index.mjs +5 -0
  92. package/nuxt.config.ts +4 -3
  93. package/package.json +6 -3
  94. package/server/api/editor-types.get.ts +7 -0
  95. package/server/api/parse.post.ts +17 -175
  96. package/server/api/studio/run.post.ts +29 -0
  97. package/server/middleware/security.ts +29 -7
  98. package/server/utils/editor-types.json +1 -0
  99. package/server/utils/example-data.ts +80 -0
  100. package/server/utils/parse-request.ts +28 -0
  101. package/server/utils/runner-client.ts +40 -0
  102. package/server/utils/studio-execution.ts +176 -0
  103. package/.output/public/_nuxt/BD40YYqZ.js +0 -33
  104. package/.output/public/_nuxt/BlQmLjV4.js +0 -1
  105. package/.output/public/_nuxt/CJ4Cv9fY.js +0 -61
  106. package/.output/public/_nuxt/builds/meta/495a8ebb-444d-4414-9b98-c181aa84d817.json +0 -1
  107. package/.output/public/_nuxt/error-404.64pZEiDn.css +0 -1
  108. package/.output/public/_nuxt/error-500.DHOpI0Ir.css +0 -1
  109. package/.output/public/_nuxt/rH_O4qXT.js +0 -1
  110. package/.output/server/chunks/build/error-404-BN-7rNE4.mjs.map +0 -1
  111. package/.output/server/chunks/build/error-404-styles.Byx46oLR.mjs +0 -8
  112. package/.output/server/chunks/build/error-404-styles.Byx46oLR.mjs.map +0 -1
  113. package/.output/server/chunks/build/error-500-DhIQ-2yt.mjs.map +0 -1
  114. package/.output/server/chunks/build/error-500-styles.BL3UT0Wa.mjs +0 -8
  115. package/.output/server/chunks/build/error-500-styles.BL3UT0Wa.mjs.map +0 -1
  116. package/.output/server/chunks/build/index-B4T6zHp0.mjs +0 -1904
  117. package/.output/server/chunks/build/index-B4T6zHp0.mjs.map +0 -1
  118. package/.output/server/node_modules/zod/index.js +0 -4
  119. /package/.output/public/_nuxt/{editor.CdBKkuhR.css → monaco.CdBKkuhR.css} +0 -0
@@ -0,0 +1,80 @@
1
+ import type { ZodType } from "zod/v4";
2
+ import { getMongooseMeta } from "@nullix/zod-mongoose";
3
+
4
+ type Schema = ZodType & { _def: Record<string, any> };
5
+
6
+ function checks(schema: Schema): Record<string, any>[] {
7
+ return (schema._def.checks || []).map((check: any) => check._zod?.def || check.def || {});
8
+ }
9
+
10
+ function sampleString(schema: Schema, key: string): string {
11
+ const rules = checks(schema);
12
+ const format = schema._def.format || rules.find((rule) => rule.format)?.format;
13
+ if (format === "email" || /email/i.test(key)) return "alex@example.com";
14
+ if (format === "uuid") return "123e4567-e89b-42d3-a456-426614174000";
15
+ if (format === "url") return "https://example.com";
16
+ if (format === "datetime") return "2026-01-01T12:00:00.000Z";
17
+ if (format === "date") return "2026-01-01";
18
+
19
+ const minimum = Math.max(1, ...rules.filter((rule) => rule.check === "min_length").map((rule) => rule.minimum));
20
+ const base = /name/i.test(key) ? "Alex Morgan" : /title/i.test(key) ? "Example title" : "example";
21
+ return base.padEnd(Math.min(minimum, 100), "x");
22
+ }
23
+
24
+ function sampleNumber(schema: Schema): number {
25
+ const rules = checks(schema);
26
+ const lower = rules.find((rule) => rule.check === "greater_than");
27
+ const upper = rules.find((rule) => rule.check === "less_than");
28
+ const integer = schema._def.type === "int" || rules.some((rule) => rule.check === "number_format" && rule.format === "safeint");
29
+ const minimum = lower ? Number(lower.value) + (lower.inclusive ? 0 : integer ? 1 : 0.1) : 1;
30
+ const maximum = upper ? Number(upper.value) - (upper.inclusive ? 0 : integer ? 1 : 0.1) : Infinity;
31
+ const candidate = Math.min(Math.max(21, minimum), maximum);
32
+ return integer ? Math.ceil(candidate) : candidate;
33
+ }
34
+
35
+ export function createExample(schema: Schema, key = "value", depth = 0, seen = new Set<Schema>()): unknown {
36
+ if (depth > 8 || seen.has(schema)) throw new Error("This recursive schema needs a handwritten example.");
37
+ const nextSeen = new Set(seen).add(schema);
38
+ const def = schema._def;
39
+ const mongooseType = getMongooseMeta(schema).type as any;
40
+ if (mongooseType === "ObjectId" || mongooseType?.schemaName === "ObjectId") return "507f1f77bcf86cd799439011";
41
+
42
+ switch (def.type) {
43
+ case "optional":
44
+ case "default":
45
+ case "prefault":
46
+ return depth === 0 ? createExample(def.innerType, key, depth + 1, nextSeen) : undefined;
47
+ case "nullable":
48
+ case "nonoptional":
49
+ case "readonly":
50
+ case "catch":
51
+ return createExample(def.innerType, key, depth + 1, nextSeen);
52
+ case "pipe":
53
+ return createExample(def.in, key, depth + 1, nextSeen);
54
+ case "lazy":
55
+ return createExample(def.getter(), key, depth + 1, nextSeen);
56
+ case "object": {
57
+ const result: Record<string, unknown> = {};
58
+ for (const [field, fieldSchema] of Object.entries((schema as any).shape || def.shape || {})) {
59
+ const value = createExample(fieldSchema as Schema, field, depth + 1, nextSeen);
60
+ if (value !== undefined) result[field] = value;
61
+ }
62
+ return result;
63
+ }
64
+ case "array": {
65
+ const minimum = Math.max(0, ...checks(schema).filter((rule) => rule.check === "min_length").map((rule) => rule.minimum));
66
+ return Array.from({ length: Math.min(Math.max(1, minimum), 10) }, () => createExample(def.element, key, depth + 1, nextSeen));
67
+ }
68
+ case "tuple": return def.items.map((item: Schema) => createExample(item, key, depth + 1, nextSeen));
69
+ case "string": return sampleString(schema, key);
70
+ case "number":
71
+ case "int": return sampleNumber(schema);
72
+ case "boolean": return true;
73
+ case "enum": return Object.values(def.entries)[0];
74
+ case "literal": return def.values?.[0];
75
+ case "union": return createExample(def.options[0], key, depth + 1, nextSeen);
76
+ case "record": return { example: createExample(def.valueType, key, depth + 1, nextSeen) };
77
+ case "date": return "2026-01-01T12:00:00.000Z";
78
+ default: throw new Error(`Automatic examples do not yet support ${def.type || "this schema"}.`);
79
+ }
80
+ }
@@ -0,0 +1,28 @@
1
+ import { createError } from "h3";
2
+ import type { H3Event } from "h3";
3
+ import type { ParseBody } from "./studio-execution";
4
+
5
+ const MAX_BODY_BYTES = 160_000;
6
+
7
+ export async function readStudioRequest(event: H3Event): Promise<ParseBody> {
8
+ const chunks: Buffer[] = [];
9
+ let size = 0;
10
+ for await (const chunk of event.node.req) {
11
+ const bytes = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
12
+ size += bytes.length;
13
+ if (size > MAX_BODY_BYTES) throw createError({ statusCode: 413, message: "Studio input is too large." });
14
+ chunks.push(bytes);
15
+ }
16
+ let body: ParseBody;
17
+ try { body = JSON.parse(Buffer.concat(chunks).toString("utf8")); }
18
+ catch { throw createError({ statusCode: 400, message: "Invalid JSON request." }); }
19
+ if (typeof body?.sourceCode !== "string" || !body.sourceCode.trim()) {
20
+ throw createError({ statusCode: 400, message: "Add a Zod schema to the editor first." });
21
+ }
22
+ if (body.sourceCode.length > 50_000 || typeof body.inputData !== "string" || body.inputData.length > 100_000 ||
23
+ (body.selectedSchema !== undefined && typeof body.selectedSchema !== "string") ||
24
+ (body.action !== undefined && body.action !== "run" && body.action !== "example")) {
25
+ throw createError({ statusCode: 400, message: "Invalid or oversized Studio input." });
26
+ }
27
+ return body;
28
+ }
@@ -0,0 +1,40 @@
1
+ import { createError } from "h3";
2
+ import { request } from "node:http";
3
+ import type { ParseBody } from "./studio-execution";
4
+
5
+ const MAX_RESPONSE_BYTES = 1_000_000;
6
+
7
+ export function runInContainer(body: ParseBody, socketPath: string): Promise<unknown> {
8
+ const payload = JSON.stringify(body);
9
+ return new Promise((resolve, reject) => {
10
+ const req = request({
11
+ socketPath,
12
+ path: "/run",
13
+ method: "POST",
14
+ headers: { "content-type": "application/json", "content-length": Buffer.byteLength(payload) },
15
+ }, (res) => {
16
+ const chunks: Buffer[] = [];
17
+ let size = 0;
18
+ res.on("data", (chunk: Buffer) => {
19
+ size += chunk.length;
20
+ if (size > MAX_RESPONSE_BYTES) {
21
+ req.destroy(new Error("Studio result is too large."));
22
+ return;
23
+ }
24
+ chunks.push(chunk);
25
+ });
26
+ res.on("end", () => {
27
+ try {
28
+ const result = JSON.parse(Buffer.concat(chunks).toString("utf8"));
29
+ if (res.statusCode !== 200) {
30
+ reject(createError({ statusCode: res.statusCode === 400 ? 400 : res.statusCode === 504 ? 504 : 503, message: result.error || "Studio runner failed." }));
31
+ } else resolve(result);
32
+ } catch { reject(createError({ statusCode: 502, message: "Invalid response from Studio runner." })); }
33
+ });
34
+ res.on("error", reject);
35
+ });
36
+ req.setTimeout(5000, () => req.destroy(new Error("Studio runner timed out.")));
37
+ req.on("error", reject);
38
+ req.end(payload);
39
+ });
40
+ }
@@ -0,0 +1,176 @@
1
+ import vm from "node:vm";
2
+ import { transformSync } from "esbuild";
3
+ import util from "node:util";
4
+ import { parse } from "acorn";
5
+ import * as zod from "zod/v4";
6
+ import mongoose from "mongoose";
7
+ import * as mongooseZod from "@nullix/zod-mongoose";
8
+ import { createExample } from "./example-data";
9
+
10
+ mongooseZod.setMongoose(mongoose);
11
+
12
+ export class StudioExecutionError extends Error {
13
+ statusCode = 400;
14
+ }
15
+
16
+ function errorMessage(error: unknown): string {
17
+ return error instanceof Error ? error.message || error.name : String(error);
18
+ }
19
+
20
+ function declaredNames(jsCode: string): string[] {
21
+ const file = parse(jsCode, { ecmaVersion: "latest", sourceType: "script" });
22
+ const names: string[] = [];
23
+ for (const statement of file.body) {
24
+ if (statement.type !== "VariableDeclaration") continue;
25
+ for (const declaration of statement.declarations) {
26
+ if (declaration.id.type === "Identifier") names.push(declaration.id.name);
27
+ }
28
+ }
29
+ return names;
30
+ }
31
+
32
+ function displayValue(value: unknown): string {
33
+ const seen = new WeakSet<object>();
34
+ return JSON.stringify(value, (_key, item) => {
35
+ if (typeof item === "bigint") return `${item.toString()}n`;
36
+ if (typeof item === "undefined") return "[undefined]";
37
+ if (typeof item === "number" && !Number.isFinite(item)) return String(item);
38
+ if (typeof item === "object" && item !== null) {
39
+ if (item instanceof Date) return item.toISOString();
40
+ if (typeof item.toHexString === "function") return item.toHexString();
41
+ if (seen.has(item)) return "[Circular]";
42
+ seen.add(item);
43
+ }
44
+ return item;
45
+ }, 2) || "undefined";
46
+ }
47
+
48
+ function formatMongoose(value: any): any {
49
+ if (typeof value === "function") return value.name || value.toString();
50
+ if (Array.isArray(value)) return value.map(formatMongoose);
51
+ if (value !== null && typeof value === "object" && value.constructor === Object) {
52
+ return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, formatMongoose(entry)]));
53
+ }
54
+ return value;
55
+ }
56
+
57
+ export type ParseBody = {
58
+ sourceCode?: string;
59
+ inputData?: string;
60
+ selectedSchema?: string;
61
+ action?: "run" | "example";
62
+ };
63
+
64
+ export function executeStudio(body: ParseBody, timeoutMs: number) {
65
+ const sourceCode = body.sourceCode!;
66
+ mongooseZod.hooks.removeAllHooks();
67
+ try {
68
+ let jsCode: string;
69
+ try {
70
+ jsCode = transformSync(sourceCode, { loader: "ts", format: "cjs", target: "esnext" }).code;
71
+ } catch (error) {
72
+ throw new StudioExecutionError(`Compilation error: ${errorMessage(error)}`);
73
+ }
74
+ const names = declaredNames(jsCode);
75
+
76
+ const sandboxRequire = (moduleName: string) => {
77
+ if (moduleName === "zod" || moduleName === "zod/v4") return zod;
78
+ if (moduleName === "@nullix/zod-mongoose") return mongooseZod;
79
+ if (moduleName === "mongoose") return mongoose;
80
+ throw new Error(`Module "${moduleName}" is unavailable in Studio.`);
81
+ };
82
+ const context = vm.createContext({
83
+ ...mongooseZod,
84
+ z: zod.z,
85
+ mongoose,
86
+ require: sandboxRequire,
87
+ console: { log: () => {}, warn: () => {}, error: () => {} },
88
+ __filename: "/sandbox/main.ts",
89
+ __dirname: "/sandbox",
90
+ });
91
+ const captured = names.map((name) => `${JSON.stringify(name)}: typeof ${name} === "undefined" ? undefined : ${name}`).join(",");
92
+ const script = new vm.Script(`
93
+ (() => {
94
+ let exports = {};
95
+ let module = { exports };
96
+ ${jsCode}
97
+ return { exported: module.exports, declared: { ${captured} } };
98
+ })()
99
+ `);
100
+ const result = script.runInContext(context, { timeout: timeoutMs });
101
+ const choices = new Map<string, zod.ZodType>();
102
+ for (const [name, value] of Object.entries(result.declared)) {
103
+ if (value instanceof zod.ZodType && ![...choices.values()].includes(value)) choices.set(name, value);
104
+ }
105
+ for (const [name, value] of Object.entries(result.exported || {})) {
106
+ if (value instanceof zod.ZodType && ![...choices.values()].includes(value)) choices.set(name, value);
107
+ }
108
+ const defaultExport = result.exported instanceof zod.ZodType ? result.exported : result.exported?.default;
109
+ if (defaultExport instanceof zod.ZodType && ![...choices.values()].includes(defaultExport)) choices.set("default", defaultExport);
110
+ if (!choices.size) throw new Error("Define a Zod schema, such as const UserSchema = z.object({ name: z.string() }).");
111
+
112
+ const selectedSchema = body.selectedSchema && choices.has(body.selectedSchema)
113
+ ? body.selectedSchema : choices.keys().next().value as string;
114
+ const schema = choices.get(selectedSchema)!;
115
+ const schemaNames = [...choices.keys()];
116
+
117
+ let example: string | undefined;
118
+ let exampleError: string | undefined;
119
+ let inputData = body.inputData;
120
+ if (body.action === "example") {
121
+ try {
122
+ const fixture = result.declared.exampleInput;
123
+ const generated = fixture !== undefined ? fixture : createExample(schema as any);
124
+ const exampleResult = schema.safeParse(generated);
125
+ if (!exampleResult.success) throw new Error("The example does not satisfy this schema. Add or update a valid const exampleInput for custom rules.");
126
+ example = displayValue(generated);
127
+ inputData = example;
128
+ } catch (error) {
129
+ exampleError = errorMessage(error);
130
+ }
131
+ }
132
+
133
+ let validation: { status: "valid" | "invalid" | "json-error" | "parse-error" | "empty"; parsed?: string; issues?: { path: string; message: string; code: string }[]; message?: string } = { status: "empty" };
134
+ if (typeof inputData !== "string" || !inputData.trim()) {
135
+ validation = { status: "empty", message: "Add JSON data to try this schema." };
136
+ } else {
137
+ let input: unknown;
138
+ let inputValid = false;
139
+ try {
140
+ input = JSON.parse(inputData);
141
+ inputValid = true;
142
+ } catch (error) {
143
+ validation = { status: "json-error", message: errorMessage(error) };
144
+ }
145
+ if (inputValid) {
146
+ try {
147
+ const parsed = schema.safeParse(input);
148
+ validation = parsed.success
149
+ ? { status: "valid", parsed: displayValue(parsed.data) }
150
+ : { status: "invalid", issues: parsed.error.issues.map((issue) => ({ path: issue.path.length ? issue.path.join(".") : "(root)", message: issue.message, code: issue.code })) };
151
+ } catch (error) {
152
+ validation = { status: "parse-error", message: `Validation could not run: ${errorMessage(error)}` };
153
+ }
154
+ }
155
+ }
156
+
157
+ let conversion: { definition?: string; schemaObj?: string; schemaTree?: string; schemaPaths?: string; error?: string };
158
+ try {
159
+ const extracted = mongooseZod.extractMongooseDef(schema);
160
+ const converted = mongooseZod.toMongooseSchema(schema, { modelName: "ParsedSchema" });
161
+ const inspect = (value: unknown) => util.inspect(formatMongoose(value), { depth: null, colors: false, showHidden: false });
162
+ conversion = {
163
+ definition: inspect(extracted),
164
+ schemaObj: inspect(converted.obj),
165
+ schemaTree: inspect((converted as any).tree),
166
+ schemaPaths: inspect((converted as any).paths),
167
+ };
168
+ } catch (error) {
169
+ conversion = { error: errorMessage(error) };
170
+ }
171
+
172
+ return { schemaNames, selectedSchema, validation, conversion, example, exampleError };
173
+ } finally {
174
+ mongooseZod.hooks.removeAllHooks();
175
+ }
176
+ }