@nullix/zod-mongoose-studio 2.4.0 → 2.4.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.
@@ -5,8 +5,8 @@ import util from 'node:util';
5
5
  import { fileURLToPath } from 'node:url';
6
6
  import { dirname } from 'node:path';
7
7
  import * as zod from 'zod';
8
- import * as mongoose$1 from 'mongoose';
9
- import * as v4$1 from 'zod/v4';
8
+ import * as mongoose from 'mongoose';
9
+ import { z } from 'zod/v4';
10
10
  import 'node:http';
11
11
  import 'node:https';
12
12
  import 'node:events';
@@ -16,1395 +16,1123 @@ import 'node:crypto';
16
16
  import '@iconify/utils';
17
17
  import 'consola';
18
18
 
19
- function _mergeNamespaces(n, m) {
20
- for (var i = 0; i < m.length; i++) {
21
- const e = m[i];
22
- if (typeof e !== 'string' && !Array.isArray(e)) { for (const k in e) {
23
- if (k !== 'default' && !(k in n)) {
24
- const d = Object.getOwnPropertyDescriptor(e, k);
25
- if (d) {
26
- Object.defineProperty(n, k, d.get ? d : {
27
- enumerable: true,
28
- get: function () { return e[k]; }
29
- });
30
- }
31
- }
32
- } }
33
- }
34
- return Object.freeze(Object.defineProperty(n, Symbol.toStringTag, { value: 'Module' }));
35
- }
36
-
37
- function getDefaultExportFromNamespaceIfNotNamed (n) {
38
- return n && Object.prototype.hasOwnProperty.call(n, 'default') && Object.keys(n).length === 1 ? n['default'] : n;
39
- }
40
-
41
- var dist = {};
42
-
43
- const require$$0 = /*@__PURE__*/getDefaultExportFromNamespaceIfNotNamed(v4$1);
44
-
45
- const require$$1 = /*@__PURE__*/getDefaultExportFromNamespaceIfNotNamed(mongoose$1);
46
-
47
- var v4 = require$$0;
48
- var mongoose = require$$1;
49
-
50
- //#region src/utils.ts
51
- function flatHooks(configHooks, hooks = {}, parentName) {
52
- for (const key in configHooks) {
53
- const subHook = configHooks[key];
54
- const name = parentName ? `${parentName}:${key}` : key;
55
- if (typeof subHook === "object" && subHook !== null) flatHooks(subHook, hooks, name);
56
- else if (typeof subHook === "function") hooks[name] = subHook;
57
- }
58
- return hooks;
19
+ var __defProp = Object.defineProperty;
20
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
21
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
22
+ function flatHooks(configHooks, hooks2 = {}, parentName) {
23
+ for (const key in configHooks) {
24
+ const subHook = configHooks[key];
25
+ const name = parentName ? `${parentName}:${key}` : key;
26
+ if (typeof subHook === "object" && subHook !== null) flatHooks(subHook, hooks2, name);
27
+ else if (typeof subHook === "function") hooks2[name] = subHook;
28
+ }
29
+ return hooks2;
59
30
  }
60
31
  const createTask = /* @__PURE__ */ (() => {
61
- if (console.createTask) return console.createTask;
62
- const defaultTask = { run: (fn) => fn() };
63
- return () => defaultTask;
32
+ if (console.createTask) return console.createTask;
33
+ const defaultTask = { run: (fn) => fn() };
34
+ return () => defaultTask;
64
35
  })();
65
- function callHooks(hooks, args, startIndex, task) {
66
- for (let i = startIndex; i < hooks.length; i += 1) try {
67
- const result = task ? task.run(() => hooks[i](...args)) : hooks[i](...args);
68
- if (result instanceof Promise) return result.then(() => callHooks(hooks, args, i + 1, task));
69
- } catch (error) {
70
- return Promise.reject(error);
71
- }
36
+ function callHooks(hooks2, args, startIndex, task) {
37
+ for (let i = startIndex; i < hooks2.length; i += 1) try {
38
+ const result = task ? task.run(() => hooks2[i](...args)) : hooks2[i](...args);
39
+ if (result instanceof Promise) return result.then(() => callHooks(hooks2, args, i + 1, task));
40
+ } catch (error) {
41
+ return Promise.reject(error);
42
+ }
72
43
  }
73
- function serialTaskCaller(hooks, args, name) {
74
- if (hooks.length > 0) return callHooks(hooks, args, 0, createTask(name));
44
+ function serialTaskCaller(hooks2, args, name) {
45
+ if (hooks2.length > 0) return callHooks(hooks2, args, 0, createTask(name));
75
46
  }
76
- function parallelTaskCaller(hooks, args, name) {
77
- if (hooks.length > 0) {
78
- const task = createTask(name);
79
- return Promise.all(hooks.map((hook) => task.run(() => hook(...args))));
80
- }
47
+ function parallelTaskCaller(hooks2, args, name) {
48
+ if (hooks2.length > 0) {
49
+ const task = createTask(name);
50
+ return Promise.all(hooks2.map((hook) => task.run(() => hook(...args))));
51
+ }
81
52
  }
82
53
  function callEachWith(callbacks, arg0) {
83
- for (const callback of [...callbacks]) callback(arg0);
54
+ for (const callback of [...callbacks]) callback(arg0);
84
55
  }
85
- //#endregion
86
- //#region src/hookable.ts
87
56
  var Hookable = class {
88
- _hooks;
89
- _before;
90
- _after;
91
- _deprecatedHooks;
92
- _deprecatedMessages;
93
- constructor() {
94
- this._hooks = {};
95
- this._before = void 0;
96
- this._after = void 0;
97
- this._deprecatedMessages = void 0;
98
- this._deprecatedHooks = {};
99
- this.hook = this.hook.bind(this);
100
- this.callHook = this.callHook.bind(this);
101
- this.callHookWith = this.callHookWith.bind(this);
102
- }
103
- hook(name, function_, options = {}) {
104
- if (!name || typeof function_ !== "function") return () => {};
105
- const originalName = name;
106
- let dep;
107
- while (this._deprecatedHooks[name]) {
108
- dep = this._deprecatedHooks[name];
109
- name = dep.to;
110
- }
111
- if (dep && !options.allowDeprecated) {
112
- let message = dep.message;
113
- if (!message) message = `${originalName} hook has been deprecated` + (dep.to ? `, please use ${dep.to}` : "");
114
- if (!this._deprecatedMessages) this._deprecatedMessages = /* @__PURE__ */ new Set();
115
- if (!this._deprecatedMessages.has(message)) {
116
- console.warn(message);
117
- this._deprecatedMessages.add(message);
118
- }
119
- }
120
- if (!function_.name) try {
121
- Object.defineProperty(function_, "name", {
122
- get: () => "_" + name.replace(/\W+/g, "_") + "_hook_cb",
123
- configurable: true
124
- });
125
- } catch {}
126
- this._hooks[name] = this._hooks[name] || [];
127
- this._hooks[name].push(function_);
128
- return () => {
129
- if (function_) {
130
- this.removeHook(name, function_);
131
- function_ = void 0;
132
- }
133
- };
134
- }
135
- hookOnce(name, function_) {
136
- let _unreg;
137
- let _function = (...arguments_) => {
138
- if (typeof _unreg === "function") _unreg();
139
- _unreg = void 0;
140
- _function = void 0;
141
- return function_(...arguments_);
142
- };
143
- _unreg = this.hook(name, _function);
144
- return _unreg;
145
- }
146
- removeHook(name, function_) {
147
- const hooks = this._hooks[name];
148
- if (hooks) {
149
- const index = hooks.indexOf(function_);
150
- if (index !== -1) hooks.splice(index, 1);
151
- if (hooks.length === 0) this._hooks[name] = void 0;
152
- }
153
- }
154
- clearHook(name) {
155
- this._hooks[name] = void 0;
156
- }
157
- deprecateHook(name, deprecated) {
158
- this._deprecatedHooks[name] = typeof deprecated === "string" ? { to: deprecated } : deprecated;
159
- const _hooks = this._hooks[name] || [];
160
- this._hooks[name] = void 0;
161
- for (const hook of _hooks) this.hook(name, hook);
162
- }
163
- deprecateHooks(deprecatedHooks) {
164
- for (const name in deprecatedHooks) this.deprecateHook(name, deprecatedHooks[name]);
165
- }
166
- addHooks(configHooks) {
167
- const hooks = flatHooks(configHooks);
168
- const removeFns = Object.keys(hooks).map((key) => this.hook(key, hooks[key]));
169
- return () => {
170
- for (const unreg of removeFns) unreg();
171
- removeFns.length = 0;
172
- };
173
- }
174
- removeHooks(configHooks) {
175
- const hooks = flatHooks(configHooks);
176
- for (const key in hooks) this.removeHook(key, hooks[key]);
177
- }
178
- removeAllHooks() {
179
- this._hooks = {};
180
- }
181
- callHook(name, ...args) {
182
- return this.callHookWith(serialTaskCaller, name, args);
183
- }
184
- callHookParallel(name, ...args) {
185
- return this.callHookWith(parallelTaskCaller, name, args);
186
- }
187
- callHookWith(caller, name, args) {
188
- const event = this._before || this._after ? {
189
- name,
190
- args,
191
- context: {}
192
- } : void 0;
193
- if (this._before) callEachWith(this._before, event);
194
- const result = caller(this._hooks[name] ? [...this._hooks[name]] : [], args, name);
195
- if (result instanceof Promise) return result.finally(() => {
196
- if (this._after && event) callEachWith(this._after, event);
197
- });
198
- if (this._after && event) callEachWith(this._after, event);
199
- return result;
200
- }
201
- beforeEach(function_) {
202
- this._before = this._before || [];
203
- this._before.push(function_);
204
- return () => {
205
- if (this._before !== void 0) {
206
- const index = this._before.indexOf(function_);
207
- if (index !== -1) this._before.splice(index, 1);
208
- }
209
- };
210
- }
211
- afterEach(function_) {
212
- this._after = this._after || [];
213
- this._after.push(function_);
214
- return () => {
215
- if (this._after !== void 0) {
216
- const index = this._after.indexOf(function_);
217
- if (index !== -1) this._after.splice(index, 1);
218
- }
219
- };
220
- }
57
+ constructor() {
58
+ __publicField(this, "_hooks");
59
+ __publicField(this, "_before");
60
+ __publicField(this, "_after");
61
+ __publicField(this, "_deprecatedHooks");
62
+ __publicField(this, "_deprecatedMessages");
63
+ this._hooks = {};
64
+ this._before = void 0;
65
+ this._after = void 0;
66
+ this._deprecatedMessages = void 0;
67
+ this._deprecatedHooks = {};
68
+ this.hook = this.hook.bind(this);
69
+ this.callHook = this.callHook.bind(this);
70
+ this.callHookWith = this.callHookWith.bind(this);
71
+ }
72
+ hook(name, function_, options = {}) {
73
+ if (!name || typeof function_ !== "function") return () => {
74
+ };
75
+ const originalName = name;
76
+ let dep;
77
+ while (this._deprecatedHooks[name]) {
78
+ dep = this._deprecatedHooks[name];
79
+ name = dep.to;
80
+ }
81
+ if (dep && !options.allowDeprecated) {
82
+ let message = dep.message;
83
+ if (!message) message = `${originalName} hook has been deprecated` + (dep.to ? `, please use ${dep.to}` : "");
84
+ if (!this._deprecatedMessages) this._deprecatedMessages = /* @__PURE__ */ new Set();
85
+ if (!this._deprecatedMessages.has(message)) {
86
+ console.warn(message);
87
+ this._deprecatedMessages.add(message);
88
+ }
89
+ }
90
+ if (!function_.name) try {
91
+ Object.defineProperty(function_, "name", {
92
+ get: () => "_" + name.replace(/\W+/g, "_") + "_hook_cb",
93
+ configurable: true
94
+ });
95
+ } catch {
96
+ }
97
+ this._hooks[name] = this._hooks[name] || [];
98
+ this._hooks[name].push(function_);
99
+ return () => {
100
+ if (function_) {
101
+ this.removeHook(name, function_);
102
+ function_ = void 0;
103
+ }
104
+ };
105
+ }
106
+ hookOnce(name, function_) {
107
+ let _unreg;
108
+ let _function = (...arguments_) => {
109
+ if (typeof _unreg === "function") _unreg();
110
+ _unreg = void 0;
111
+ _function = void 0;
112
+ return function_(...arguments_);
113
+ };
114
+ _unreg = this.hook(name, _function);
115
+ return _unreg;
116
+ }
117
+ removeHook(name, function_) {
118
+ const hooks2 = this._hooks[name];
119
+ if (hooks2) {
120
+ const index = hooks2.indexOf(function_);
121
+ if (index !== -1) hooks2.splice(index, 1);
122
+ if (hooks2.length === 0) this._hooks[name] = void 0;
123
+ }
124
+ }
125
+ clearHook(name) {
126
+ this._hooks[name] = void 0;
127
+ }
128
+ deprecateHook(name, deprecated) {
129
+ this._deprecatedHooks[name] = typeof deprecated === "string" ? { to: deprecated } : deprecated;
130
+ const _hooks = this._hooks[name] || [];
131
+ this._hooks[name] = void 0;
132
+ for (const hook of _hooks) this.hook(name, hook);
133
+ }
134
+ deprecateHooks(deprecatedHooks) {
135
+ for (const name in deprecatedHooks) this.deprecateHook(name, deprecatedHooks[name]);
136
+ }
137
+ addHooks(configHooks) {
138
+ const hooks2 = flatHooks(configHooks);
139
+ const removeFns = Object.keys(hooks2).map((key) => this.hook(key, hooks2[key]));
140
+ return () => {
141
+ for (const unreg of removeFns) unreg();
142
+ removeFns.length = 0;
143
+ };
144
+ }
145
+ removeHooks(configHooks) {
146
+ const hooks2 = flatHooks(configHooks);
147
+ for (const key in hooks2) this.removeHook(key, hooks2[key]);
148
+ }
149
+ removeAllHooks() {
150
+ this._hooks = {};
151
+ }
152
+ callHook(name, ...args) {
153
+ return this.callHookWith(serialTaskCaller, name, args);
154
+ }
155
+ callHookParallel(name, ...args) {
156
+ return this.callHookWith(parallelTaskCaller, name, args);
157
+ }
158
+ callHookWith(caller, name, args) {
159
+ const event = this._before || this._after ? {
160
+ name,
161
+ args,
162
+ context: {}
163
+ } : void 0;
164
+ if (this._before) callEachWith(this._before, event);
165
+ const result = caller(this._hooks[name] ? [...this._hooks[name]] : [], args, name);
166
+ if (result instanceof Promise) return result.finally(() => {
167
+ if (this._after && event) callEachWith(this._after, event);
168
+ });
169
+ if (this._after && event) callEachWith(this._after, event);
170
+ return result;
171
+ }
172
+ beforeEach(function_) {
173
+ this._before = this._before || [];
174
+ this._before.push(function_);
175
+ return () => {
176
+ if (this._before !== void 0) {
177
+ const index = this._before.indexOf(function_);
178
+ if (index !== -1) this._before.splice(index, 1);
179
+ }
180
+ };
181
+ }
182
+ afterEach(function_) {
183
+ this._after = this._after || [];
184
+ this._after.push(function_);
185
+ return () => {
186
+ if (this._after !== void 0) {
187
+ const index = this._after.indexOf(function_);
188
+ if (index !== -1) this._after.splice(index, 1);
189
+ }
190
+ };
191
+ }
221
192
  };
222
193
  function createHooks() {
223
- return new Hookable();
194
+ return new Hookable();
224
195
  }
225
-
226
196
  const hooks = createHooks();
227
- /**
228
- * Synchronous hook caller for Hookable.
229
- */
230
197
  function callHookSync(name, ...args) {
231
- hooks.callHookWith((callbacks, args) => {
232
- for (const callback of callbacks) {
233
- callback(...args);
234
- }
235
- }, name, args);
198
+ hooks.callHookWith((callbacks, args2) => {
199
+ for (const callback of callbacks) {
200
+ callback(...args2);
201
+ }
202
+ }, name, args);
236
203
  }
237
-
238
- /**
239
- * This securely stores our Mongoose metadata alongside the Zod schema instances
240
- * without polluting the actual validation logic.
241
- */
242
- const mongooseRegistry = v4.z.registry();
243
- /**
244
- * A clean wrapper to attach Mongoose metadata to any Zod schema.
245
- */
204
+ const mongooseRegistry = z.registry();
246
205
  function withMongoose(schema, meta = {}) {
247
- callHookSync('registry:get:before', { schema });
248
- const existing = mongooseRegistry.get(schema) || {};
249
- callHookSync('registry:get', { schema, meta: existing });
250
- const merged = { ...existing, ...meta };
251
- callHookSync('registry:add', { schema, meta: merged });
252
- mongooseRegistry.add(schema, merged);
253
- callHookSync('registry:added', { schema, meta: merged });
254
- return schema;
206
+ callHookSync("registry:get:before", { schema });
207
+ const existing = mongooseRegistry.get(schema) || {};
208
+ callHookSync("registry:get", { schema, meta: existing });
209
+ const merged = { ...existing, ...meta };
210
+ callHookSync("registry:add", { schema, meta: merged });
211
+ mongooseRegistry.add(schema, merged);
212
+ callHookSync("registry:added", { schema, meta: merged });
213
+ return schema;
255
214
  }
256
- /**
257
- * Recursively collect Mongoose metadata from a Zod schema and its wrappers.
258
- */
259
215
  function getMongooseMeta(schema) {
260
- const def = schema._def;
261
- if (!def)
262
- return {};
263
- let meta = mongooseRegistry.get(schema) || {};
264
- // If it has an inner type (Optional, Nullable, Default, etc.), collect from it too
265
- if (def.innerType) {
266
- meta = { ...getMongooseMeta(def.innerType), ...meta };
267
- }
268
- else if (def.schema) {
269
- meta = { ...getMongooseMeta(def.schema), ...meta };
270
- }
271
- // Handle pipes (like z.codec)
272
- if (def.type === 'pipe') {
273
- // Collect from both 'in' and 'out' parts, preferring metadata from 'out' if it exists,
274
- // but the pipe itself usually holds the metadata we want.
275
- meta = { ...getMongooseMeta(def.in), ...getMongooseMeta(def.out), ...meta };
276
- }
277
- return meta;
216
+ const def = schema._def;
217
+ if (!def)
218
+ return {};
219
+ let meta = mongooseRegistry.get(schema) || {};
220
+ if (def.innerType) {
221
+ meta = { ...getMongooseMeta(def.innerType), ...meta };
222
+ } else if (def.schema) {
223
+ meta = { ...getMongooseMeta(def.schema), ...meta };
224
+ }
225
+ if (def.type === "pipe") {
226
+ meta = { ...getMongooseMeta(def.in), ...getMongooseMeta(def.out), ...meta };
227
+ }
228
+ return meta;
278
229
  }
279
-
280
- /**
281
- * Recursively unwrap Zod schemas (Optional, Nullable, Default, Effects, Pipelines)
282
- * using Zod's public API and internal _def.type identifiers.
283
- */
284
- function unwrapZodSchema(schema,
285
- // eslint-disable-next-line unicorn/no-object-as-default-parameter
286
- features = { required: true }, visited = new Set()) {
287
- if (!schema)
288
- return { schema, features };
289
- if (visited.has(schema))
290
- return { schema, features };
291
- const def = schema._def;
292
- if (!def)
293
- return { schema, features };
294
- // Skip visited check for wrappers to allow deep unwrapping
295
- if (!(schema instanceof v4.z.ZodOptional) &&
296
- !(schema instanceof v4.z.ZodNullable) &&
297
- !(schema instanceof v4.z.ZodDefault) &&
298
- def.type !== 'pipe') {
299
- visited.add(schema);
300
- }
301
- if (schema instanceof v4.z.ZodOptional) {
302
- const inner = schema.unwrap();
303
- return unwrapZodSchema(
304
- // @ts-expect-error Zod v4 schema.unwrap() return type mismatch
305
- inner, {
306
- ...features,
307
- required: false,
308
- isOptional: true,
309
- }, visited);
310
- }
311
- if (schema instanceof v4.z.ZodNullable) {
312
- return unwrapZodSchema(
313
- // @ts-expect-error Zod v4 schema.unwrap() return type mismatch
314
- schema.unwrap(), {
315
- ...features,
316
- isNullable: true,
317
- }, visited);
318
- }
319
- if (schema instanceof v4.z.ZodDefault) {
320
- const defaultValue = typeof def.defaultValue === 'function' ? def.defaultValue() : def.defaultValue;
321
- return unwrapZodSchema(def.innerType, {
322
- ...features,
323
- default: defaultValue,
324
- }, visited);
325
- }
326
- const { type } = def;
327
- // In Zod v4, transform, preprocess, and refine are often implemented as pipes.
328
- // For transform: in = schema, out = transformation
329
- // For preprocess: in = preprocessing, out = schema
330
- if (type === 'pipe') {
331
- const inType = def.in?._def?.type;
332
- const outType = def.out?._def?.type;
333
- if (inType === 'transform') {
334
- // It's a preprocess (in is transformation, out is schema)
335
- return unwrapZodSchema(def.out, features, visited);
336
- }
337
- if (outType === 'transform' || outType === 'refinement') {
338
- // It's a transform or refine (in is schema, out is logic)
339
- // We should still collect transformations from the 'out' part
340
- const transformFeatures = { ...features };
341
- const outDef = def.out?._def;
342
- const effects = outDef?.effects || outDef?.transformations || (outType === 'transform' ? [outDef] : []);
343
- if (effects && Array.isArray(effects)) {
344
- transformFeatures.transformations = [
345
- ...(transformFeatures.transformations || []),
346
- ...effects,
347
- ];
348
- }
349
- return unwrapZodSchema(def.in, transformFeatures, visited);
350
- }
351
- // Default pipe behavior (extract the output part)
352
- return unwrapZodSchema(def.out, features, visited);
353
- }
354
- if (type === 'transform' ||
355
- type === 'preprocess' ||
356
- type === 'refinement' ||
357
- type === 'effects') {
358
- const transformFeatures = { ...features };
359
- const effects = def.effects || def.transformations || (def.type === 'transform' || type === 'transform' ? [def] : []);
360
- if (effects && Array.isArray(effects)) {
361
- transformFeatures.transformations = [
362
- ...(transformFeatures.transformations || []),
363
- ...effects,
364
- ];
365
- }
366
- const inner = def.schema || def.innerType;
367
- if (inner) {
368
- const result = unwrapZodSchema(inner, transformFeatures, visited);
369
- return result;
370
- }
230
+ function unwrapZodSchema(schema, features = { required: true }, visited = /* @__PURE__ */ new Set()) {
231
+ var _a, _b, _c, _d, _e;
232
+ if (!schema)
233
+ return { schema, features };
234
+ if (visited.has(schema))
235
+ return { schema, features };
236
+ const def = schema._def;
237
+ if (!def)
238
+ return { schema, features };
239
+ if (!(schema instanceof z.ZodOptional) && !(schema instanceof z.ZodNullable) && !(schema instanceof z.ZodDefault) && def.type !== "pipe") {
240
+ visited.add(schema);
241
+ }
242
+ if (schema instanceof z.ZodOptional) {
243
+ const inner = schema.unwrap();
244
+ return unwrapZodSchema(
245
+ // @ts-expect-error Zod v4 schema.unwrap() return type mismatch
246
+ inner,
247
+ {
248
+ ...features,
249
+ required: false,
250
+ isOptional: true
251
+ },
252
+ visited
253
+ );
254
+ }
255
+ if (schema instanceof z.ZodNullable) {
256
+ return unwrapZodSchema(
257
+ // @ts-expect-error Zod v4 schema.unwrap() return type mismatch
258
+ schema.unwrap(),
259
+ {
260
+ ...features,
261
+ isNullable: true
262
+ },
263
+ visited
264
+ );
265
+ }
266
+ if (schema instanceof z.ZodDefault) {
267
+ const defaultValue = typeof def.defaultValue === "function" ? def.defaultValue() : def.defaultValue;
268
+ return unwrapZodSchema(def.innerType, {
269
+ ...features,
270
+ default: defaultValue
271
+ }, visited);
272
+ }
273
+ const { type } = def;
274
+ if (type === "pipe") {
275
+ const inType = (_b = (_a = def.in) == null ? void 0 : _a._def) == null ? void 0 : _b.type;
276
+ const outType = (_d = (_c = def.out) == null ? void 0 : _c._def) == null ? void 0 : _d.type;
277
+ if (inType === "transform") {
278
+ return unwrapZodSchema(def.out, features, visited);
371
279
  }
372
- if (type === 'lazy') {
373
- // For lazy types, we need to be careful with infinite recursion.
374
- // If we've already seen this specific lazy schema in this unwrapping chain,
375
- // we return it as is to stop recursion.
376
- // NOTE: In Zod v4, getter() might return different objects each time if not careful.
377
- return { schema, features };
280
+ if (outType === "transform" || outType === "refinement") {
281
+ const transformFeatures = { ...features };
282
+ const outDef = (_e = def.out) == null ? void 0 : _e._def;
283
+ const effects = (outDef == null ? void 0 : outDef.effects) || (outDef == null ? void 0 : outDef.transformations) || (outType === "transform" ? [outDef] : []);
284
+ if (effects && Array.isArray(effects)) {
285
+ transformFeatures.transformations = [
286
+ ...transformFeatures.transformations || [],
287
+ ...effects
288
+ ];
289
+ }
290
+ return unwrapZodSchema(def.in, transformFeatures, visited);
378
291
  }
379
- if (type === 'branded' || type === 'readonly') {
380
- return unwrapZodSchema(schema.unwrap(), {
381
- ...features,
382
- ...(type === 'readonly' ? { readOnly: true } : {}),
383
- }, visited);
292
+ return unwrapZodSchema(def.out, features, visited);
293
+ }
294
+ if (type === "transform" || type === "preprocess" || type === "refinement" || type === "effects") {
295
+ const transformFeatures = { ...features };
296
+ const effects = def.effects || def.transformations || (def.type === "transform" || type === "transform" ? [def] : []);
297
+ if (effects && Array.isArray(effects)) {
298
+ transformFeatures.transformations = [
299
+ ...transformFeatures.transformations || [],
300
+ ...effects
301
+ ];
384
302
  }
385
- // Extract checks if present
386
- if (def.checks && Array.isArray(def.checks)) {
387
- features.checks = [...(features.checks || []), ...def.checks];
303
+ const inner = def.schema || def.innerType;
304
+ if (inner) {
305
+ const result = unwrapZodSchema(inner, transformFeatures, visited);
306
+ return result;
388
307
  }
308
+ }
309
+ if (type === "lazy") {
389
310
  return { schema, features };
311
+ }
312
+ if (type === "branded" || type === "readonly") {
313
+ return unwrapZodSchema(schema.unwrap(), {
314
+ ...features,
315
+ ...type === "readonly" ? { readOnly: true } : {}
316
+ }, visited);
317
+ }
318
+ if (def.checks && Array.isArray(def.checks)) {
319
+ features.checks = [...features.checks || [], ...def.checks];
320
+ }
321
+ return { schema, features };
390
322
  }
391
-
392
323
  let mongooseInstance = null;
393
- /**
394
- * Manually set the Mongoose instance.
395
- * Useful in ESM environments where automatic detection via require() might fail.
396
- */
324
+ let isFrontend;
325
+ const setFrontendMode = (enabled) => {
326
+ isFrontend = enabled;
327
+ };
328
+ const getFrontendMode = () => {
329
+ if (isFrontend === void 0 || isFrontend === null) {
330
+ return globalThis.window !== void 0 && globalThis.document !== void 0;
331
+ }
332
+ return isFrontend;
333
+ };
397
334
  const setMongoose = (m) => {
398
- mongooseInstance = m;
335
+ mongooseInstance = m;
399
336
  };
400
- // Helper to get mongoose instance safely
401
337
  const getMongoose = () => {
402
- if (mongooseInstance) {
403
- return mongooseInstance;
404
- }
405
- try {
406
- // eslint-disable-next-line global-require
407
- const m = require('mongoose');
408
- if (m && (m.Schema || m.default?.Schema)) {
409
- return m.default || m;
410
- }
411
- return m;
338
+ var _a;
339
+ if (getFrontendMode()) {
340
+ return null;
341
+ }
342
+ if (mongooseInstance) {
343
+ return mongooseInstance;
344
+ }
345
+ try {
346
+ if (typeof require !== "undefined") {
347
+ const m = require("mongoose");
348
+ if (m && (m.Schema || ((_a = m.default) == null ? void 0 : _a.Schema))) {
349
+ return m.default || m;
350
+ }
351
+ return m;
412
352
  }
413
- catch {
414
- // Try to see if mongoose is globally available (e.g. in some environments)
415
- if (globalThis.mongoose) {
416
- return globalThis.mongoose;
417
- }
418
- return null;
353
+ return null;
354
+ } catch {
355
+ if (globalThis.mongoose) {
356
+ return globalThis.mongoose;
419
357
  }
358
+ return null;
359
+ }
420
360
  };
421
- let isFrontend = false;
422
- /**
423
- * Enable or disable frontend mode.
424
- * In frontend mode, specialized types like ObjectId and Buffer fall back to
425
- * simpler representations (strings/arrays) and do not depend on Mongoose.
426
- */
427
- const setFrontendMode = (enabled) => {
428
- isFrontend = enabled;
429
- };
430
- const getFrontendMode = () => {
431
- // Try to auto-detect if not explicitly set
432
- // This is a simple heuristic: check for window/document
433
- if (isFrontend === undefined || isFrontend === null) {
434
- return globalThis.window !== undefined && globalThis.document !== undefined;
435
- }
436
- return isFrontend;
437
- };
438
-
439
- /**
440
- * Helper to map Zod checks (min, max, regex, etc.) to Mongoose Schema properties.
441
- */
442
361
  function mapZodChecksToMongoose(checks, mongooseProp) {
443
- if (!checks || !Array.isArray(checks))
444
- return;
445
- for (const check of checks) {
446
- const traitSet = check._zod?.traits;
447
- const checkDef = check._zod?.def;
448
- if (!traitSet || !checkDef)
449
- continue;
450
- // String Lengths
451
- if (traitSet.has('$ZodCheckMinLength')) {
452
- mongooseProp.minlength = checkDef.minimum;
453
- }
454
- if (traitSet.has('$ZodCheckMaxLength')) {
455
- mongooseProp.maxlength = checkDef.maximum;
456
- }
457
- if (traitSet.has('$ZodCheckLengthEquals')) {
458
- mongooseProp.minlength = checkDef.length;
459
- mongooseProp.maxlength = checkDef.length;
460
- }
461
- // Numbers and Dates Comparisons
462
- if (traitSet.has('$ZodCheckGreaterThan')) {
463
- mongooseProp.min = checkDef.value;
464
- }
465
- if (traitSet.has('$ZodCheckLessThan')) {
466
- mongooseProp.max = checkDef.value;
467
- }
468
- // Regex / Match
469
- if (traitSet.has('$ZodCheckRegex')) {
470
- mongooseProp.match = checkDef.pattern;
471
- }
472
- // UUID
473
- if (traitSet.has('$ZodUUID')) {
474
- const mongoose = globalThis.mongoose || globalThis.__mongoose;
475
- if (mongoose?.Schema.Types.UUID) {
476
- mongooseProp.type = mongoose.Schema.Types.UUID;
477
- }
478
- }
479
- // ISO Formats
480
- if (traitSet.has('$ZodISODateTime') || traitSet.has('$ZodISODate')) {
481
- mongooseProp.type = Date;
482
- }
483
- // String Transforms (trim, lowercase, uppercase)
484
- if (traitSet.has('$ZodCheckOverwrite') && typeof checkDef.tx === 'function') {
485
- const txStr = checkDef.tx.toString();
486
- if (txStr.includes('.trim()')) {
487
- mongooseProp.trim = true;
488
- }
489
- else if (txStr.includes('.toLowerCase()')) {
490
- mongooseProp.lowercase = true;
491
- }
492
- else if (txStr.includes('.toUpperCase()')) {
493
- mongooseProp.uppercase = true;
494
- }
495
- }
362
+ var _a, _b;
363
+ if (!checks || !Array.isArray(checks))
364
+ return;
365
+ for (const check of checks) {
366
+ const traitSet = (_a = check._zod) == null ? void 0 : _a.traits;
367
+ const checkDef = (_b = check._zod) == null ? void 0 : _b.def;
368
+ if (!traitSet || !checkDef)
369
+ continue;
370
+ if (traitSet.has("$ZodCheckMinLength")) {
371
+ mongooseProp.minlength = checkDef.minimum;
496
372
  }
497
- callHookSync('validation:mappers', { checks, mongooseProp });
498
- }
499
-
500
- /**
501
- * Handles ZodObject conversion to Mongoose Schema definition.
502
- */
503
- function handleObject(unwrapped, mongooseProp, visited, extractMongooseDef, isField = false) {
504
- callHookSync('schema:object:before', { schema: unwrapped, mongooseProp, visited });
505
- const { shape } = unwrapped;
506
- const objDef = {};
507
- // We must ensure recursive calls see the current object to break cycles.
508
- const placeholder = mongooseProp.type ? mongooseProp : objDef;
509
- visited.set(unwrapped, placeholder);
510
- // eslint-disable-next-line no-restricted-syntax
511
- for (const key in shape) {
512
- if (!Object.prototype.hasOwnProperty.call(shape, key))
513
- continue;
514
- // Skip automatic _id mapping unless explicitly requested
515
- if (key === '_id') {
516
- const idMeta = mongooseRegistry.get(shape[key]) || {};
517
- const unwrappedId = unwrapZodSchema(shape[key]).schema;
518
- const unwrappedIdMeta = mongooseRegistry.get(unwrappedId) || {};
519
- if (idMeta.includeId !== true &&
520
- unwrappedIdMeta.includeId !== true &&
521
- mongooseProp.includeId !== true) {
522
- continue;
523
- }
524
- }
525
- const def = extractMongooseDef(shape[key], visited);
526
- if (def && typeof def === 'object' && def.__isDiscriminatorUnion) {
527
- const mongoose = getMongoose();
528
- if (mongoose) {
529
- const baseSchema = new mongoose.Schema(def.baseDef, {
530
- discriminatorKey: def.discriminatorKey,
531
- _id: false,
532
- });
533
- const discriminators = {};
534
- for (const [dKey, dDef] of Object.entries(def.discriminators)) {
535
- discriminators[dKey] = new mongoose.Schema(dDef, { _id: false });
536
- }
537
- objDef[key] = {
538
- type: baseSchema,
539
- discriminators,
540
- };
541
- }
542
- else {
543
- objDef[key] = def;
544
- }
545
- }
546
- else if (typeof def === 'object' && def !== null && !Array.isArray(def)) {
547
- const { includeId, ...cleanDef } = def;
548
- objDef[key] = cleanDef;
549
- }
550
- else {
551
- objDef[key] = def;
552
- }
553
- callHookSync('schema:object:field', { key, schema: shape[key], objDef, visited });
373
+ if (traitSet.has("$ZodCheckMaxLength")) {
374
+ mongooseProp.maxlength = checkDef.maximum;
554
375
  }
555
- // If the developer didn't provide a strict Mongoose type override, return the shape
556
- let result;
557
- // Handle explicit or default subschema request
558
- const shouldBeSubSchema = isField && mongooseProp.schema !== false;
559
- if (shouldBeSubSchema && !mongooseProp.type) {
560
- const mongoose = getMongoose();
561
- if (mongoose) {
562
- const options = typeof mongooseProp.schema === 'object' ? mongooseProp.schema : {};
563
- const { plugins, ...schemaOptions } = options;
564
- const subSchema = new mongoose.Schema(objDef, schemaOptions);
565
- if (plugins && Array.isArray(plugins)) {
566
- for (const plugin of plugins) {
567
- subSchema.plugin(plugin);
568
- }
569
- }
570
- mongooseProp.type = subSchema;
571
- }
376
+ if (traitSet.has("$ZodCheckLengthEquals")) {
377
+ mongooseProp.minlength = checkDef.length;
378
+ mongooseProp.maxlength = checkDef.length;
572
379
  }
573
- if (mongooseProp.type) {
574
- const mongoose = getMongoose();
575
- const isSchema = mongoose && (mongooseProp.type instanceof mongoose.Schema || mongooseProp.type.constructor?.name === 'Schema');
576
- // If there is a type override, merge the object definition into the result unless it's a Schema
577
- if (!isSchema) {
578
- Object.assign(mongooseProp, objDef);
579
- }
580
- result = mongooseProp;
380
+ if (traitSet.has("$ZodCheckGreaterThan")) {
381
+ mongooseProp.min = checkDef.value;
581
382
  }
582
- else {
583
- Object.assign(mongooseProp, objDef);
584
- const topLevelOptions = new Set([
585
- 'collection',
586
- 'versionKey',
587
- 'timestamps',
588
- 'discriminatorKey',
589
- 'strict',
590
- 'id',
591
- '_id',
592
- 'minimize',
593
- 'validateBeforeSave',
594
- 'schema',
595
- ]);
596
- const hasFieldMetadata = Object.keys(mongooseProp).some((k) => {
597
- if (Object.prototype.hasOwnProperty.call(objDef, k))
598
- return false;
599
- if (topLevelOptions.has(k))
600
- return false;
601
- if (k === 'required' && mongooseProp[k] === false)
602
- return false;
603
- return true;
604
- });
605
- result = hasFieldMetadata ? mongooseProp : objDef;
383
+ if (traitSet.has("$ZodCheckLessThan")) {
384
+ mongooseProp.max = checkDef.value;
606
385
  }
607
- callHookSync('schema:object:after', { schema: unwrapped, mongooseProp, objDef, result });
608
- return result;
609
- }
610
- /**
611
- * Handles ZodArray, ZodSet, and ZodTuple conversion.
612
- */
613
- function handleArray(unwrapped, mongooseProp, visited, extractMongooseDef) {
614
- callHookSync('schema:array:before', { schema: unwrapped, mongooseProp, visited });
615
- const element = unwrapped.element ||
616
- unwrapped._def.valueType ||
617
- unwrapped._def.rest ||
618
- unwrapped._def.items?.[0];
619
- const mongoose = getMongoose();
620
- const innerDef = element
621
- ? extractMongooseDef(element, visited)
622
- : mongoose?.Schema.Types.Mixed || 'Mixed';
623
- // If no explicit type override, wrap the inner definition in an array
624
- if (!mongooseProp.type) {
625
- if (innerDef && typeof innerDef === 'object' && innerDef.__isDiscriminatorUnion && mongoose) {
626
- // const baseSchema =
627
- // new mongoose.Schema(innerDef.baseDef, {
628
- // discriminatorKey: innerDef.discriminatorKey,
629
- // _id: false,
630
- // });
631
- const discriminators = {};
632
- for (const [dKey, dDef] of Object.entries(innerDef.discriminators)) {
633
- discriminators[dKey] = new mongoose.Schema(dDef, { _id: false });
634
- }
635
- mongooseProp.type = [
636
- new mongoose.Schema({}, {
637
- discriminatorKey: innerDef.discriminatorKey,
638
- _id: false,
639
- }),
640
- ];
641
- mongooseProp.discriminators = discriminators;
642
- }
643
- else {
644
- const innerType = innerDef.type || innerDef;
645
- mongooseProp.type = [innerType];
646
- // Transfer any metadata from the inner type (like 'ref') to the array definition
647
- if (typeof innerDef === 'object') {
648
- // eslint-disable-next-line sonarjs/no-unused-vars
649
- const { type: _extractedType, ...innerMeta } = innerDef;
650
- Object.assign(mongooseProp, innerMeta);
651
- mongooseProp.type = [innerType]; // Restore type as array
652
- }
653
- }
386
+ if (traitSet.has("$ZodCheckRegex")) {
387
+ mongooseProp.match = checkDef.pattern;
654
388
  }
655
- callHookSync('schema:array:after', { schema: unwrapped, mongooseProp, innerDef });
656
- }
657
- /**
658
- * Handles ZodRecord and ZodMap conversion.
659
- */
660
- function handleRecord(unwrapped, mongooseProp, visited, extractMongooseDef) {
661
- callHookSync('schema:record:before', { schema: unwrapped, mongooseProp, visited });
662
- const type = unwrapped._def?.type;
663
- const isMap = type === 'map';
664
- const valueType = unwrapped.valueType ||
665
- unwrapped.valueSchema ||
666
- unwrapped._def.valueType ||
667
- unwrapped._def.valueSchema ||
668
- unwrapped._def.innerType; // For some Zod versions
669
- let innerDef;
670
- if (!mongooseProp.type || mongooseProp.type === Map || mongooseProp.type === Object) {
671
- // z.record() maps to a POJO (Object/Mixed), while z.map() maps to a Mongoose Map
672
- mongooseProp.type = isMap ? Map : Object;
673
- const finalValueType = valueType || unwrapped.valueSchema || unwrapped._def?.valueSchema;
674
- if (finalValueType) {
675
- innerDef = extractMongooseDef(finalValueType, visited);
676
- mongooseProp.of = innerDef.type || innerDef;
677
- }
678
- }
679
- callHookSync('schema:record:after', { schema: unwrapped, mongooseProp, innerDef });
680
- }
681
-
682
- /**
683
- * THE CONVERTER (Safe AST Walker)
684
- * We extract the Zod type and merge it with any registered Mongoose metadata.
685
- */
686
- function extractMongooseDef(schema, visited = new Map(), isField = false, noWrap = false) {
687
- // Only call converter:before at the very beginning of a run
688
- if (visited.size === 0) {
689
- callHookSync('converter:before', { schema: schema, visited });
389
+ if (traitSet.has("$ZodUUID")) {
390
+ const mongoose = globalThis.mongoose || globalThis.__mongoose;
391
+ if (mongoose == null ? void 0 : mongoose.Schema.Types.UUID) {
392
+ mongooseProp.type = mongoose.Schema.Types.UUID;
393
+ }
690
394
  }
691
- callHookSync('converter:start', { schema: schema, visited });
692
- const { schema: unwrapped, features } = unwrapZodSchema(schema);
693
- // Pull any explicitly registered Mongoose metadata (including from wrappers)
694
- const meta = mongooseRegistry.get(schema) || {};
695
- const mongooseProp = getMongooseMeta(schema);
696
- callHookSync('converter:unwrapped', {
697
- schema: schema,
698
- unwrapped,
699
- features,
700
- meta: mongooseProp,
701
- mongooseProp: mongooseProp,
702
- });
703
- if (features.isOptional === true && mongooseProp.type && mongooseProp.required !== true) {
704
- mongooseProp.required = false;
395
+ if (traitSet.has("$ZodISODateTime") || traitSet.has("$ZodISODate")) {
396
+ mongooseProp.type = Date;
705
397
  }
706
- if (visited.has(schema)) {
707
- const existing = visited.get(schema);
708
- if (existing === mongooseProp) {
709
- return existing;
710
- }
711
- // console.log('Visited CACHE for', (unwrapped as any)._def.type, existing);
712
- if (Object.keys(meta).length > 0) {
713
- Object.assign(existing, mongooseProp);
714
- }
715
- return existing;
398
+ if (traitSet.has("$ZodCheckOverwrite") && typeof checkDef.tx === "function") {
399
+ const txStr = checkDef.tx.toString();
400
+ if (txStr.includes(".trim()")) {
401
+ mongooseProp.trim = true;
402
+ } else if (txStr.includes(".toLowerCase()")) {
403
+ mongooseProp.lowercase = true;
404
+ } else if (txStr.includes(".toUpperCase()")) {
405
+ mongooseProp.uppercase = true;
406
+ }
716
407
  }
717
- visited.set(schema, mongooseProp);
718
- // console.log('Visited set for', (unwrapped as any)._def.type, mongooseProp);
719
- if (features.default !== undefined) {
720
- mongooseProp.default = features.default;
408
+ }
409
+ callHookSync("validation:mappers", { checks, mongooseProp });
410
+ }
411
+ function handleObject(unwrapped, mongooseProp, visited, extractMongooseDef2, isField = false) {
412
+ var _a;
413
+ callHookSync("schema:object:before", { schema: unwrapped, mongooseProp, visited });
414
+ const { shape } = unwrapped;
415
+ const objDef = {};
416
+ const placeholder = mongooseProp.type ? mongooseProp : objDef;
417
+ visited.set(unwrapped, placeholder);
418
+ for (const key in shape) {
419
+ if (!Object.prototype.hasOwnProperty.call(shape, key))
420
+ continue;
421
+ if (key === "_id") {
422
+ const idMeta = mongooseRegistry.get(shape[key]) || {};
423
+ const unwrappedId = unwrapZodSchema(shape[key]).schema;
424
+ const unwrappedIdMeta = mongooseRegistry.get(unwrappedId) || {};
425
+ if (idMeta.includeId !== true && unwrappedIdMeta.includeId !== true && mongooseProp.includeId !== true) {
426
+ continue;
427
+ }
721
428
  }
722
- if (features.required === false) {
723
- mongooseProp.required = false;
429
+ const def = extractMongooseDef2(shape[key], visited);
430
+ if (def && typeof def === "object" && def.__isDiscriminatorUnion) {
431
+ const mongoose = getMongoose();
432
+ if (mongoose) {
433
+ const baseSchema = new mongoose.Schema(def.baseDef, {
434
+ discriminatorKey: def.discriminatorKey,
435
+ _id: false
436
+ });
437
+ const discriminators = {};
438
+ for (const [dKey, dDef] of Object.entries(def.discriminators)) {
439
+ discriminators[dKey] = new mongoose.Schema(dDef, { _id: false });
440
+ }
441
+ objDef[key] = {
442
+ type: baseSchema,
443
+ discriminators
444
+ };
445
+ } else {
446
+ objDef[key] = def;
447
+ }
448
+ } else if (typeof def === "object" && def !== null && !Array.isArray(def)) {
449
+ const { includeId, ...cleanDef } = def;
450
+ objDef[key] = cleanDef;
451
+ } else {
452
+ objDef[key] = def;
724
453
  }
725
- if (features.readOnly === true) {
726
- mongooseProp.readOnly = true;
454
+ callHookSync("schema:object:field", { key, schema: shape[key], objDef, visited });
455
+ }
456
+ let result;
457
+ const shouldBeSubSchema = isField && mongooseProp.schema !== false;
458
+ if (shouldBeSubSchema && !mongooseProp.type) {
459
+ const mongoose = getMongoose();
460
+ if (mongoose) {
461
+ const options = typeof mongooseProp.schema === "object" ? mongooseProp.schema : {};
462
+ const { plugins, ...schemaOptions } = options;
463
+ const subSchema = new mongoose.Schema(objDef, schemaOptions);
464
+ if (plugins && Array.isArray(plugins)) {
465
+ for (const plugin of plugins) {
466
+ subSchema.plugin(plugin);
467
+ }
468
+ }
469
+ mongooseProp.type = subSchema;
727
470
  }
728
- // Map Zod checks to Mongoose options
729
- mapZodChecksToMongoose(features.checks, mongooseProp);
730
- const def = unwrapped._def;
731
- if (!def) {
732
- callHookSync('converter:after', {
733
- schema: schema,
734
- mongooseProp,
735
- });
736
- return mongooseProp;
471
+ }
472
+ if (mongooseProp.type) {
473
+ const mongoose = getMongoose();
474
+ const isSchema = mongoose && (mongooseProp.type instanceof mongoose.Schema || ((_a = mongooseProp.type.constructor) == null ? void 0 : _a.name) === "Schema");
475
+ if (!isSchema) {
476
+ Object.assign(mongooseProp, objDef);
737
477
  }
738
- const { type } = def;
739
- callHookSync('converter:node', {
740
- schema: unwrapped,
741
- mongooseProp,
742
- type,
478
+ result = mongooseProp;
479
+ } else {
480
+ Object.assign(mongooseProp, objDef);
481
+ const topLevelOptions = /* @__PURE__ */ new Set([
482
+ "collection",
483
+ "versionKey",
484
+ "timestamps",
485
+ "discriminatorKey",
486
+ "strict",
487
+ "id",
488
+ "_id",
489
+ "minimize",
490
+ "validateBeforeSave",
491
+ "schema"
492
+ ]);
493
+ const hasFieldMetadata = Object.keys(mongooseProp).some((k) => {
494
+ if (Object.prototype.hasOwnProperty.call(objDef, k))
495
+ return false;
496
+ if (topLevelOptions.has(k))
497
+ return false;
498
+ if (k === "required" && mongooseProp[k] === false)
499
+ return false;
500
+ return true;
743
501
  });
744
- // Handle recursion and specific types via separate handlers
745
- if (type === 'object') {
746
- const wrapperFn = (s, v) => extractMongooseDef(s, v, true);
747
- const result = handleObject(unwrapped, mongooseProp, visited, wrapperFn, isField && !noWrap);
748
- callHookSync('converter:after', {
749
- schema: schema,
750
- mongooseProp: result,
751
- });
752
- if (typeof result === 'object' && result !== null && !Array.isArray(result)) {
753
- delete result.includeId;
754
- }
755
- return result;
502
+ result = hasFieldMetadata ? mongooseProp : objDef;
503
+ }
504
+ callHookSync("schema:object:after", { schema: unwrapped, mongooseProp, objDef, result });
505
+ return result;
506
+ }
507
+ function handleArray(unwrapped, mongooseProp, visited, extractMongooseDef2) {
508
+ var _a;
509
+ callHookSync("schema:array:before", { schema: unwrapped, mongooseProp, visited });
510
+ const element = unwrapped.element || unwrapped._def.valueType || unwrapped._def.rest || ((_a = unwrapped._def.items) == null ? void 0 : _a[0]);
511
+ const mongoose = getMongoose();
512
+ const innerDef = element ? extractMongooseDef2(element, visited) : (mongoose == null ? void 0 : mongoose.Schema.Types.Mixed) || "Mixed";
513
+ if (!mongooseProp.type) {
514
+ if (innerDef && typeof innerDef === "object" && innerDef.__isDiscriminatorUnion && mongoose) {
515
+ const discriminators = {};
516
+ for (const [dKey, dDef] of Object.entries(innerDef.discriminators)) {
517
+ discriminators[dKey] = new mongoose.Schema(dDef, { _id: false });
518
+ }
519
+ mongooseProp.type = [
520
+ new mongoose.Schema({}, {
521
+ discriminatorKey: innerDef.discriminatorKey,
522
+ _id: false
523
+ })
524
+ ];
525
+ mongooseProp.discriminators = discriminators;
526
+ } else {
527
+ const innerType = innerDef.type || innerDef;
528
+ mongooseProp.type = [innerType];
529
+ if (typeof innerDef === "object") {
530
+ const { type: _extractedType, ...innerMeta } = innerDef;
531
+ Object.assign(mongooseProp, innerMeta);
532
+ mongooseProp.type = [innerType];
533
+ }
756
534
  }
757
- if (type === 'array' || type === 'set' || type === 'tuple') {
758
- handleArray(unwrapped, mongooseProp, visited, (s, v) => extractMongooseDef(s, v, true));
535
+ }
536
+ callHookSync("schema:array:after", { schema: unwrapped, mongooseProp, innerDef });
537
+ }
538
+ function handleRecord(unwrapped, mongooseProp, visited, extractMongooseDef2) {
539
+ var _a, _b;
540
+ callHookSync("schema:record:before", { schema: unwrapped, mongooseProp, visited });
541
+ const type = (_a = unwrapped._def) == null ? void 0 : _a.type;
542
+ const isMap = type === "map";
543
+ const valueType = unwrapped.valueType || unwrapped.valueSchema || unwrapped._def.valueType || unwrapped._def.valueSchema || unwrapped._def.innerType;
544
+ let innerDef;
545
+ if (!mongooseProp.type || mongooseProp.type === Map || mongooseProp.type === Object) {
546
+ mongooseProp.type = isMap ? Map : Object;
547
+ const finalValueType = valueType || unwrapped.valueSchema || ((_b = unwrapped._def) == null ? void 0 : _b.valueSchema);
548
+ if (finalValueType) {
549
+ innerDef = extractMongooseDef2(finalValueType, visited);
550
+ mongooseProp.of = innerDef.type || innerDef;
759
551
  }
760
- if (type === 'record' || type === 'map') {
761
- handleRecord(unwrapped, mongooseProp, visited, (s, v) => extractMongooseDef(s, v, true));
552
+ }
553
+ callHookSync("schema:record:after", { schema: unwrapped, mongooseProp, innerDef });
554
+ }
555
+ function extractMongooseDef(schema, visited = /* @__PURE__ */ new Map(), isField = false, noWrap = false) {
556
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
557
+ if (visited.size === 0) {
558
+ callHookSync("converter:before", { schema, visited });
559
+ }
560
+ callHookSync("converter:start", { schema, visited });
561
+ const { schema: unwrapped, features } = unwrapZodSchema(schema);
562
+ const meta = mongooseRegistry.get(schema) || {};
563
+ const mongooseProp = getMongooseMeta(schema);
564
+ callHookSync("converter:unwrapped", {
565
+ schema,
566
+ unwrapped,
567
+ features,
568
+ meta: mongooseProp,
569
+ mongooseProp
570
+ });
571
+ if (features.isOptional === true && mongooseProp.type && mongooseProp.required !== true) {
572
+ mongooseProp.required = false;
573
+ }
574
+ if (visited.has(schema)) {
575
+ const existing = visited.get(schema);
576
+ if (existing === mongooseProp) {
577
+ return existing;
762
578
  }
763
- // Handle Intersections
764
- if (type === 'intersection') {
765
- const left = extractMongooseDef(unwrapped._def.left, visited, isField, true);
766
- const right = extractMongooseDef(unwrapped._def.right, visited, isField, true);
767
- if (typeof left === 'object' && typeof right === 'object') {
768
- Object.assign(mongooseProp, left, right);
769
- if (isField && !noWrap && mongooseProp.schema !== false && !mongooseProp.type) {
770
- const mongoose = getMongoose();
771
- if (mongoose) {
772
- const options = typeof mongooseProp.schema === 'object' ? mongooseProp.schema : {};
773
- const { plugins, ...schemaOptions } = options;
774
- const definition = { ...mongooseProp };
775
- // Remove metadata fields that shouldn't be in the schema definition if they are top-level
776
- delete definition.schema;
777
- const subSchema = new mongoose.Schema(definition, schemaOptions);
778
- if (plugins && Array.isArray(plugins)) {
779
- for (const plugin of plugins) {
780
- subSchema.plugin(plugin);
781
- }
782
- }
783
- mongooseProp.type = subSchema;
784
- // Clear other fields since they are now in subSchema
785
- for (const key of Object.keys(mongooseProp)) {
786
- if (key !== 'type')
787
- delete mongooseProp[key];
788
- }
789
- }
790
- }
791
- }
792
- else if (!mongooseProp.type) {
793
- mongooseProp.type = getMongoose()?.Schema.Types.Mixed || 'Mixed';
794
- }
579
+ if (Object.keys(meta).length > 0) {
580
+ Object.assign(existing, mongooseProp);
795
581
  }
796
- if ((type === 'union' ||
797
- type === 'discriminatedunion' ||
798
- type === 'discriminated_union' ||
799
- type === 'xor') &&
800
- !mongooseProp.type) {
582
+ return existing;
583
+ }
584
+ visited.set(schema, mongooseProp);
585
+ if (features.default !== void 0) {
586
+ mongooseProp.default = features.default;
587
+ }
588
+ if (features.required === false) {
589
+ mongooseProp.required = false;
590
+ }
591
+ if (features.readOnly === true) {
592
+ mongooseProp.readOnly = true;
593
+ }
594
+ mapZodChecksToMongoose(features.checks, mongooseProp);
595
+ const def = unwrapped._def;
596
+ if (!def) {
597
+ callHookSync("converter:after", {
598
+ schema,
599
+ mongooseProp
600
+ });
601
+ return mongooseProp;
602
+ }
603
+ const { type } = def;
604
+ callHookSync("converter:node", {
605
+ schema: unwrapped,
606
+ mongooseProp,
607
+ type
608
+ });
609
+ if (type === "object") {
610
+ const wrapperFn = (s, v) => extractMongooseDef(s, v, true);
611
+ const result = handleObject(unwrapped, mongooseProp, visited, wrapperFn, isField && !noWrap);
612
+ callHookSync("converter:after", {
613
+ schema,
614
+ mongooseProp: result
615
+ });
616
+ if (typeof result === "object" && result !== null && !Array.isArray(result)) {
617
+ delete result.includeId;
618
+ }
619
+ return result;
620
+ }
621
+ if (type === "array" || type === "set" || type === "tuple") {
622
+ handleArray(unwrapped, mongooseProp, visited, (s, v) => extractMongooseDef(s, v, true));
623
+ }
624
+ if (type === "record" || type === "map") {
625
+ handleRecord(unwrapped, mongooseProp, visited, (s, v) => extractMongooseDef(s, v, true));
626
+ }
627
+ if (type === "intersection") {
628
+ const left = extractMongooseDef(unwrapped._def.left, visited, isField, true);
629
+ const right = extractMongooseDef(unwrapped._def.right, visited, isField, true);
630
+ if (typeof left === "object" && typeof right === "object") {
631
+ Object.assign(mongooseProp, left, right);
632
+ if (isField && !noWrap && mongooseProp.schema !== false && !mongooseProp.type) {
801
633
  const mongoose = getMongoose();
802
- const options = unwrapped.options || unwrapped._def.options;
803
- const discriminatorKey = unwrapped._def.discriminator;
804
- const unionCtx = {
805
- isSimpleUnion: false,
806
- isObjectUnion: false,
807
- isXor: type === 'xor' ||
808
- ((unwrapped._def?.inclusive === false ||
809
- schema._def?.inclusive === false) &&
810
- !discriminatorKey &&
811
- !schema._def?.discriminator),
812
- };
813
- if (Array.isArray(options) && options.length > 0) {
814
- unionCtx.isSimpleUnion = options.every((opt) => {
815
- const { type } = unwrapZodSchema(opt).schema._def;
816
- return ['string', 'number', 'boolean', 'date', 'bigint', 'literal'].includes(type);
817
- });
818
- unionCtx.isObjectUnion = options.every((opt) => {
819
- const { type } = unwrapZodSchema(opt).schema._def;
820
- return type === 'object';
821
- });
822
- }
823
- callHookSync('schema:union:before', { schema: unwrapped, mongooseProp, ctx: unionCtx });
824
- if (discriminatorKey && unionCtx.isObjectUnion) {
825
- const discriminators = {};
826
- const allOptionDefs = [];
827
- for (const option of options) {
828
- const { schema: unwrappedOpt } = unwrapZodSchema(option);
829
- const { shape } = unwrappedOpt._def;
830
- const discriminatorProp = shape[discriminatorKey];
831
- // Support both ZodLiteral and ZodOptional/ZodDefault/ZodNullable wrapped literals
832
- const { schema: unwrappedDisc } = unwrapZodSchema(discriminatorProp);
833
- const discriminatorValue = unwrappedDisc._def.value ?? unwrappedDisc._def.values?.[0];
834
- // Use a fresh Map for each option to avoid cross-contamination of visited nodes
835
- const optionDef = extractMongooseDef(option, new Map(), true, true);
836
- if (optionDef && typeof optionDef === 'object' && !Array.isArray(optionDef)) {
837
- const cleanOptionDef = { ...optionDef };
838
- delete cleanOptionDef[discriminatorKey];
839
- discriminators[discriminatorValue] = cleanOptionDef;
840
- allOptionDefs.push(cleanOptionDef);
841
- }
842
- }
843
- // Identify common fields present in ALL options to move to baseDef
844
- const baseDef = {};
845
- if (allOptionDefs.length > 0) {
846
- const firstOption = allOptionDefs[0];
847
- for (const key of Object.keys(firstOption)) {
848
- const isCommon = allOptionDefs.every((def) => {
849
- if (!(key in def))
850
- return false;
851
- // Simple check for equality of definitions (can be improved)
852
- return JSON.stringify(def[key]) === JSON.stringify(firstOption[key]);
853
- });
854
- if (isCommon) {
855
- baseDef[key] = firstOption[key];
856
- // Remove from discriminators to avoid duplication
857
- for (const def of allOptionDefs) {
858
- delete def[key];
859
- }
860
- }
861
- }
862
- }
863
- const result = {
864
- __isDiscriminatorUnion: true,
865
- discriminatorKey,
866
- discriminators,
867
- baseDef,
868
- validate: {
869
- validator(_v) {
870
- try {
871
- // Ensure we include the discriminator key in the object being validated
872
- const mongoose = getMongoose();
873
- const doc = mongoose && this instanceof mongoose.Document ? this.toObject() : this || {};
874
- schema.parse(doc);
875
- return true;
876
- }
877
- catch (err) {
878
- const message = err?.errors?.[0]?.message || err.message;
879
- if (this && typeof this.invalidate === 'function') {
880
- this.invalidate(discriminatorKey, `Zod validation failed: ${message}`);
881
- }
882
- return false;
883
- }
884
- },
885
- message: (props) => `Validation failed for ${props.path}`,
886
- },
887
- };
888
- // If this is wrapped in a meta object, ensure we return the result properly
889
- if (mongooseProp && typeof mongooseProp === 'object' && !Array.isArray(mongooseProp)) {
890
- Object.assign(mongooseProp, result);
891
- callHookSync('schema:union:after', {
892
- schema: unwrapped,
893
- mongooseProp,
894
- ctx: unionCtx,
895
- });
896
- return mongooseProp;
634
+ if (mongoose) {
635
+ const options = typeof mongooseProp.schema === "object" ? mongooseProp.schema : {};
636
+ const { plugins, ...schemaOptions } = options;
637
+ const definition = { ...mongooseProp };
638
+ delete definition.schema;
639
+ const subSchema = new mongoose.Schema(definition, schemaOptions);
640
+ if (plugins && Array.isArray(plugins)) {
641
+ for (const plugin of plugins) {
642
+ subSchema.plugin(plugin);
897
643
  }
898
- callHookSync('schema:union:after', {
899
- schema: unwrapped,
900
- mongooseProp: result,
901
- ctx: unionCtx,
902
- });
903
- return result;
644
+ }
645
+ mongooseProp.type = subSchema;
646
+ for (const key of Object.keys(mongooseProp)) {
647
+ if (key !== "type")
648
+ delete mongooseProp[key];
649
+ }
904
650
  }
905
- if (getMongoose()?.Schema.Types.Union &&
906
- unionCtx.isSimpleUnion &&
907
- options.length > 0 &&
908
- !unionCtx.isXor) {
909
- mongooseProp.type = mongoose.Schema.Types.Union;
910
- mongooseProp.of = options.map((opt) => {
911
- const def = extractMongooseDef(opt, visited, true, true);
912
- return def.type || def;
913
- });
651
+ }
652
+ } else if (!mongooseProp.type) {
653
+ mongooseProp.type = ((_a = getMongoose()) == null ? void 0 : _a.Schema.Types.Mixed) || "Mixed";
654
+ }
655
+ }
656
+ if ((type === "union" || type === "discriminatedunion" || type === "discriminated_union" || type === "xor") && !mongooseProp.type) {
657
+ const mongoose = getMongoose();
658
+ const options = unwrapped.options || unwrapped._def.options;
659
+ const discriminatorKey = unwrapped._def.discriminator;
660
+ const unionCtx = {
661
+ isSimpleUnion: false,
662
+ isObjectUnion: false,
663
+ isXor: type === "xor" || (((_b = unwrapped._def) == null ? void 0 : _b.inclusive) === false || ((_c = schema._def) == null ? void 0 : _c.inclusive) === false) && !discriminatorKey && !((_d = schema._def) == null ? void 0 : _d.discriminator)
664
+ };
665
+ if (Array.isArray(options) && options.length > 0) {
666
+ unionCtx.isSimpleUnion = options.every((opt) => {
667
+ const { type: type2 } = unwrapZodSchema(opt).schema._def;
668
+ return ["string", "number", "boolean", "date", "bigint", "literal"].includes(type2);
669
+ });
670
+ unionCtx.isObjectUnion = options.every((opt) => {
671
+ const { type: type2 } = unwrapZodSchema(opt).schema._def;
672
+ return type2 === "object";
673
+ });
674
+ }
675
+ callHookSync("schema:union:before", { schema: unwrapped, mongooseProp, ctx: unionCtx });
676
+ if (discriminatorKey && unionCtx.isObjectUnion) {
677
+ const discriminators = {};
678
+ const allOptionDefs = [];
679
+ for (const option of options) {
680
+ const { schema: unwrappedOpt } = unwrapZodSchema(option);
681
+ const { shape } = unwrappedOpt._def;
682
+ const discriminatorProp = shape[discriminatorKey];
683
+ const { schema: unwrappedDisc } = unwrapZodSchema(discriminatorProp);
684
+ const discriminatorValue = (_f = unwrappedDisc._def.value) != null ? _f : (_e = unwrappedDisc._def.values) == null ? void 0 : _e[0];
685
+ const optionDef = extractMongooseDef(option, /* @__PURE__ */ new Map(), true, true);
686
+ if (optionDef && typeof optionDef === "object" && !Array.isArray(optionDef)) {
687
+ const cleanOptionDef = { ...optionDef };
688
+ delete cleanOptionDef[discriminatorKey];
689
+ discriminators[discriminatorValue] = cleanOptionDef;
690
+ allOptionDefs.push(cleanOptionDef);
914
691
  }
915
- else if (unionCtx.isObjectUnion && options.length > 0) {
916
- // Merge all object properties into a single schema object
917
- const mergedDef = {};
918
- for (const opt of options) {
919
- const def = extractMongooseDef(opt, new Map(), true, true);
920
- if (typeof def === 'object' && def !== null) {
921
- for (const [key, prop] of Object.entries(def)) {
922
- if (typeof prop === 'object' && prop !== null && !Array.isArray(prop)) {
923
- prop.required = false;
924
- }
925
- if (mergedDef[key] &&
926
- typeof mergedDef[key] === 'object' &&
927
- typeof prop === 'object' &&
928
- !Array.isArray(mergedDef[key]) &&
929
- !Array.isArray(prop)) {
930
- const existingType = mergedDef[key].type ||
931
- mergedDef[key].instance ||
932
- (typeof mergedDef[key] === 'function' ? mergedDef[key] : null);
933
- const newType = prop.type ||
934
- prop.instance ||
935
- (typeof prop === 'function' ? prop : null);
936
- const isMixed = (t) => !t ||
937
- t === 'Mixed' ||
938
- t === 'SchemaMixed' ||
939
- t?.name === 'Mixed' ||
940
- t?.instance === 'Mixed' ||
941
- t?.name === 'SchemaMixed' ||
942
- t?.instance === 'SchemaMixed' ||
943
- (getMongoose()?.Schema.Types.Mixed &&
944
- (t === getMongoose()?.Schema.Types.Mixed ||
945
- t?.instance === 'Mixed' ||
946
- t?.instance === 'SchemaMixed'));
947
- if (isMixed(existingType) && !isMixed(newType)) {
948
- mergedDef[key] = prop;
949
- }
950
- else if (!isMixed(existingType) && isMixed(newType)) ;
951
- else {
952
- Object.assign(mergedDef[key], prop);
953
- }
954
- }
955
- else if (!mergedDef[key] ||
956
- typeof mergedDef[key] !== 'object' ||
957
- Array.isArray(mergedDef[key])) {
958
- mergedDef[key] = prop;
959
- }
960
- }
961
- }
962
- }
963
- if (isField && unionCtx.isXor) {
964
- // For nested XOR, always use Mixed with validator to ensure mutual exclusivity
965
- mongooseProp.type = mongoose?.Schema.Types.Mixed || 'Mixed';
966
- mongooseProp.validate = {
967
- validator(v) {
968
- try {
969
- schema.parse(v);
970
- return true;
971
- }
972
- catch {
973
- return false;
974
- }
975
- },
976
- message: 'XOR validation failed',
977
- };
978
- }
979
- else {
980
- // For root or other object unions, merge properties
981
- if (!mongooseProp.type ||
982
- mongooseProp.type === (getMongoose()?.Schema.Types.Mixed || 'Mixed')) {
983
- delete mongooseProp.type;
984
- }
985
- Object.assign(mongooseProp, mergedDef);
986
- // If the object contains a 'type' property, Mongoose might misinterpret it as a field definition.
987
- // We can hint that it's a nested object by using a Schema if 'type' is present along with other fields.
988
- if (isField &&
989
- Object.prototype.hasOwnProperty.call(mongooseProp, 'type') &&
990
- Object.keys(mongooseProp).length > 1) {
991
- const mongooseInstance = getMongoose();
992
- if (mongooseInstance) {
993
- mongooseProp.type = new mongooseInstance.Schema(mongooseProp, { _id: false });
994
- for (const key of Object.keys(mongooseProp)) {
995
- if (key !== 'type')
996
- delete mongooseProp[key];
997
- }
998
- }
999
- }
692
+ }
693
+ const baseDef = {};
694
+ if (allOptionDefs.length > 0) {
695
+ const firstOption = allOptionDefs[0];
696
+ for (const key of Object.keys(firstOption)) {
697
+ const isCommon = allOptionDefs.every((def2) => {
698
+ if (!(key in def2))
699
+ return false;
700
+ return JSON.stringify(def2[key]) === JSON.stringify(firstOption[key]);
701
+ });
702
+ if (isCommon) {
703
+ baseDef[key] = firstOption[key];
704
+ for (const def2 of allOptionDefs) {
705
+ delete def2[key];
1000
706
  }
707
+ }
1001
708
  }
1002
- else {
1003
- mongooseProp.type = mongoose?.Schema.Types.Mixed || 'Mixed';
1004
- if (isField &&
1005
- (type === 'xor' ||
1006
- type === 'discriminated_union' ||
1007
- type === 'discriminatedunion' ||
1008
- type === 'union') &&
1009
- !mongooseProp.ref && // Skip Zod validation for populated fields
1010
- !Array.isArray(mongooseProp.type) && // Skip Zod validation for arrays
1011
- mongooseProp.type !== Map && // Skip Zod validation for maps
1012
- !mongooseProp.of // Skip Zod validation for collections
1013
- ) {
1014
- mongooseProp.validate = {
1015
- validator(v) {
1016
- try {
1017
- schema.parse(v);
1018
- return true;
1019
- }
1020
- catch (err) {
1021
- return false;
1022
- }
1023
- },
1024
- message: (props) => {
1025
- if (unionCtx.isXor)
1026
- return 'XOR validation failed';
1027
- try {
1028
- schema.parse(props.value);
1029
- }
1030
- catch (err) {
1031
- return `Union validation failed: ${err.message}`;
1032
- }
1033
- return 'Union validation failed';
1034
- },
1035
- };
709
+ }
710
+ const result = {
711
+ __isDiscriminatorUnion: true,
712
+ discriminatorKey,
713
+ discriminators,
714
+ baseDef,
715
+ validate: {
716
+ validator(_v) {
717
+ var _a2, _b2;
718
+ try {
719
+ const mongoose2 = getMongoose();
720
+ const doc = mongoose2 && this instanceof mongoose2.Document ? this.toObject() : this || {};
721
+ schema.parse(doc);
722
+ return true;
723
+ } catch (err) {
724
+ const message = ((_b2 = (_a2 = err == null ? void 0 : err.errors) == null ? void 0 : _a2[0]) == null ? void 0 : _b2.message) || err.message;
725
+ if (this && typeof this.invalidate === "function") {
726
+ this.invalidate(discriminatorKey, `Zod validation failed: ${message}`);
727
+ }
728
+ return false;
1036
729
  }
730
+ },
731
+ message: (props) => `Validation failed for ${props.path}`
1037
732
  }
1038
- callHookSync('schema:union:after', {
1039
- schema: unwrapped,
1040
- mongooseProp,
1041
- ctx: unionCtx,
733
+ };
734
+ if (mongooseProp && typeof mongooseProp === "object" && !Array.isArray(mongooseProp)) {
735
+ Object.assign(mongooseProp, result);
736
+ callHookSync("schema:union:after", {
737
+ schema: unwrapped,
738
+ mongooseProp,
739
+ ctx: unionCtx
1042
740
  });
741
+ return mongooseProp;
742
+ }
743
+ callHookSync("schema:union:after", {
744
+ schema: unwrapped,
745
+ mongooseProp: result,
746
+ ctx: unionCtx
747
+ });
748
+ return result;
1043
749
  }
1044
- if (type === 'literal' && !mongooseProp.type) {
1045
- mongooseProp.type = getMongoose()?.Schema.Types.Mixed || 'Mixed';
1046
- }
1047
- // Handle Primitives
1048
- switch (type) {
1049
- case 'string':
1050
- case 'number':
1051
- case 'boolean':
1052
- case 'date':
1053
- case 'bigint':
1054
- case 'stringbool':
1055
- case 'boolstring':
1056
- case 'booleanstring': {
1057
- if (!mongooseProp.type) {
1058
- if (type === 'bigint') {
1059
- mongooseProp.type = typeof BigInt === 'undefined' ? Number : BigInt;
1060
- }
1061
- else {
1062
- const typeMap = {
1063
- string: String,
1064
- number: Number,
1065
- boolean: Boolean,
1066
- date: Date,
1067
- stringbool: Boolean,
1068
- boolstring: Boolean,
1069
- booleanstring: Boolean,
1070
- };
1071
- mongooseProp.type = typeMap[type];
1072
- // Clever inference: If a transform occurred (which we know if the Zod type
1073
- // is different from the default value type), prefer the default's type.
1074
- if (mongooseProp.default !== undefined) {
1075
- const defaultType = typeof mongooseProp.default;
1076
- if (defaultType === 'boolean' && type !== 'boolean') {
1077
- mongooseProp.type = Boolean;
1078
- }
1079
- else if (defaultType === 'number' && type !== 'number') {
1080
- mongooseProp.type = Number;
1081
- }
1082
- else if (defaultType === 'string' && type !== 'string') {
1083
- mongooseProp.type = String;
1084
- }
1085
- else if (mongooseProp.default instanceof Date && type !== 'date') {
1086
- mongooseProp.type = Date;
1087
- }
1088
- }
1089
- // Even cleverer: Check transformations for clues (e.g., stringbool, boolstring)
1090
- if (mongooseProp.type === String && features.transformations) {
1091
- for (const tx of features.transformations) {
1092
- const txStr = tx.transform?.toString() || tx.toString();
1093
- if (txStr.includes('stringbool') || txStr.includes('boolstring') || txStr.includes('booleanstring')) {
1094
- mongooseProp.type = Boolean;
1095
- break;
1096
- }
1097
- if (txStr.includes('=== "true"') || txStr.includes('=== \'true\'')) {
1098
- mongooseProp.type = Boolean;
1099
- break;
1100
- }
1101
- }
1102
- }
1103
- }
750
+ if (((_g = getMongoose()) == null ? void 0 : _g.Schema.Types.Union) && unionCtx.isSimpleUnion && options.length > 0 && !unionCtx.isXor) {
751
+ mongooseProp.type = mongoose.Schema.Types.Union;
752
+ mongooseProp.of = options.map((opt) => {
753
+ const def2 = extractMongooseDef(opt, visited, true, true);
754
+ return def2.type || def2;
755
+ });
756
+ } else if (unionCtx.isObjectUnion && options.length > 0) {
757
+ const mergedDef = {};
758
+ for (const opt of options) {
759
+ const def2 = extractMongooseDef(opt, /* @__PURE__ */ new Map(), true, true);
760
+ if (typeof def2 === "object" && def2 !== null) {
761
+ for (const [key, prop] of Object.entries(def2)) {
762
+ if (typeof prop === "object" && prop !== null && !Array.isArray(prop)) {
763
+ prop.required = false;
1104
764
  }
1105
- if (mongooseProp.required !== false)
1106
- mongooseProp.required = true;
1107
- break;
1108
- }
1109
- case 'enum':
1110
- case 'nativeenum':
1111
- case 'native_enum': {
1112
- if (!mongooseProp.type)
1113
- mongooseProp.type = String;
1114
- mongooseProp.enum =
1115
- type === 'enum'
1116
- ? unwrapped.options || def.values
1117
- : Object.values(unwrapped.enum || def.values);
1118
- if (mongooseProp.required !== false)
1119
- mongooseProp.required = true;
1120
- break;
765
+ if (mergedDef[key] && typeof mergedDef[key] === "object" && typeof prop === "object" && !Array.isArray(mergedDef[key]) && !Array.isArray(prop)) {
766
+ const existingType = mergedDef[key].type || mergedDef[key].instance || (typeof mergedDef[key] === "function" ? mergedDef[key] : null);
767
+ const newType = prop.type || prop.instance || (typeof prop === "function" ? prop : null);
768
+ const isMixed = (t) => {
769
+ var _a2, _b2;
770
+ return !t || t === "Mixed" || t === "SchemaMixed" || (t == null ? void 0 : t.name) === "Mixed" || (t == null ? void 0 : t.instance) === "Mixed" || (t == null ? void 0 : t.name) === "SchemaMixed" || (t == null ? void 0 : t.instance) === "SchemaMixed" || ((_a2 = getMongoose()) == null ? void 0 : _a2.Schema.Types.Mixed) && (t === ((_b2 = getMongoose()) == null ? void 0 : _b2.Schema.Types.Mixed) || (t == null ? void 0 : t.instance) === "Mixed" || (t == null ? void 0 : t.instance) === "SchemaMixed");
771
+ };
772
+ if (isMixed(existingType) && !isMixed(newType)) {
773
+ mergedDef[key] = prop;
774
+ } else if (!isMixed(existingType) && isMixed(newType)) ;
775
+ else {
776
+ Object.assign(mergedDef[key], prop);
777
+ }
778
+ } else if (!mergedDef[key] || typeof mergedDef[key] !== "object" || Array.isArray(mergedDef[key])) {
779
+ mergedDef[key] = prop;
780
+ }
781
+ }
1121
782
  }
1122
- // Do nothing
1123
- }
1124
- // Handle Specialized Types (Buffer, ObjectId)
1125
- const mongooseInstance = getMongoose();
1126
- if (type === 'any' || type === 'unknown' || type === 'custom') {
1127
- const cls = def.cls || unwrapped.cls;
1128
- if (cls === Buffer || (typeof Uint8Array !== 'undefined' && cls === Uint8Array)) {
1129
- if (!mongooseProp.type)
1130
- mongooseProp.type = mongooseInstance?.Schema.Types.Buffer || 'Buffer';
783
+ }
784
+ if (isField && unionCtx.isXor) {
785
+ mongooseProp.type = (mongoose == null ? void 0 : mongoose.Schema.Types.Mixed) || "Mixed";
786
+ mongooseProp.validate = {
787
+ validator(v) {
788
+ try {
789
+ schema.parse(v);
790
+ return true;
791
+ } catch {
792
+ return false;
793
+ }
794
+ },
795
+ message: "XOR validation failed"
796
+ };
797
+ } else {
798
+ if (!mongooseProp.type || mongooseProp.type === (((_h = getMongoose()) == null ? void 0 : _h.Schema.Types.Mixed) || "Mixed")) {
799
+ delete mongooseProp.type;
1131
800
  }
1132
- else if ((cls?.name === 'ObjectId' || (mongooseInstance && cls === mongooseInstance.Types.ObjectId)) &&
1133
- !mongooseProp.type) {
1134
- mongooseProp.type = mongooseInstance?.Schema.Types.ObjectId || 'ObjectId';
801
+ Object.assign(mongooseProp, mergedDef);
802
+ if (isField && Object.prototype.hasOwnProperty.call(mongooseProp, "type") && Object.keys(mongooseProp).length > 1) {
803
+ const mongooseInstance3 = getMongoose();
804
+ if (mongooseInstance3) {
805
+ mongooseProp.type = new mongooseInstance3.Schema(mongooseProp, { _id: false });
806
+ for (const key of Object.keys(mongooseProp)) {
807
+ if (key !== "type")
808
+ delete mongooseProp[key];
809
+ }
810
+ }
1135
811
  }
812
+ }
813
+ } else {
814
+ mongooseProp.type = (mongoose == null ? void 0 : mongoose.Schema.Types.Mixed) || "Mixed";
815
+ if (isField && (type === "xor" || type === "discriminated_union" || type === "discriminatedunion" || type === "union") && !mongooseProp.ref && // Skip Zod validation for populated fields
816
+ !Array.isArray(mongooseProp.type) && // Skip Zod validation for arrays
817
+ mongooseProp.type !== Map && // Skip Zod validation for maps
818
+ !mongooseProp.of) {
819
+ mongooseProp.validate = {
820
+ validator(v) {
821
+ try {
822
+ schema.parse(v);
823
+ return true;
824
+ } catch (err) {
825
+ return false;
826
+ }
827
+ },
828
+ message: (props) => {
829
+ if (unionCtx.isXor)
830
+ return "XOR validation failed";
831
+ try {
832
+ schema.parse(props.value);
833
+ } catch (err) {
834
+ return `Union validation failed: ${err.message}`;
835
+ }
836
+ return "Union validation failed";
837
+ }
838
+ };
839
+ }
1136
840
  }
1137
- // Handle Lazy (Recursion Support)
1138
- if (type === 'lazy') {
1139
- const inner = def.getter();
1140
- const result = extractMongooseDef(inner, visited, isField);
1141
- if (Object.keys(meta).length > 0 && result !== mongooseProp) {
1142
- if (typeof result === 'object' && !Array.isArray(result)) {
1143
- Object.assign(mongooseProp, result);
841
+ callHookSync("schema:union:after", {
842
+ schema: unwrapped,
843
+ mongooseProp,
844
+ ctx: unionCtx
845
+ });
846
+ }
847
+ if (type === "literal" && !mongooseProp.type) {
848
+ mongooseProp.type = ((_i = getMongoose()) == null ? void 0 : _i.Schema.Types.Mixed) || "Mixed";
849
+ }
850
+ switch (type) {
851
+ case "string":
852
+ case "number":
853
+ case "boolean":
854
+ case "date":
855
+ case "bigint":
856
+ case "stringbool":
857
+ case "boolstring":
858
+ case "booleanstring": {
859
+ if (!mongooseProp.type) {
860
+ if (type === "bigint") {
861
+ mongooseProp.type = typeof BigInt === "undefined" ? Number : BigInt;
862
+ } else {
863
+ const typeMap = {
864
+ string: String,
865
+ number: Number,
866
+ boolean: Boolean,
867
+ date: Date,
868
+ stringbool: Boolean,
869
+ boolstring: Boolean,
870
+ booleanstring: Boolean
871
+ };
872
+ mongooseProp.type = typeMap[type];
873
+ if (mongooseProp.default !== void 0) {
874
+ const defaultType = typeof mongooseProp.default;
875
+ if (defaultType === "boolean" && type !== "boolean") {
876
+ mongooseProp.type = Boolean;
877
+ } else if (defaultType === "number" && type !== "number") {
878
+ mongooseProp.type = Number;
879
+ } else if (defaultType === "string" && type !== "string") {
880
+ mongooseProp.type = String;
881
+ } else if (mongooseProp.default instanceof Date && type !== "date") {
882
+ mongooseProp.type = Date;
1144
883
  }
1145
- else {
1146
- mongooseProp.type = result.type || result;
884
+ }
885
+ if (mongooseProp.type === String && features.transformations) {
886
+ for (const tx of features.transformations) {
887
+ const txStr = ((_j = tx.transform) == null ? void 0 : _j.toString()) || tx.toString();
888
+ if (txStr.includes("stringbool") || txStr.includes("boolstring") || txStr.includes("booleanstring")) {
889
+ mongooseProp.type = Boolean;
890
+ break;
891
+ }
892
+ if (txStr.includes('=== "true"') || txStr.includes("=== 'true'")) {
893
+ mongooseProp.type = Boolean;
894
+ break;
895
+ }
1147
896
  }
1148
- return mongooseProp;
897
+ }
1149
898
  }
1150
- return result;
899
+ }
900
+ if (mongooseProp.required !== false)
901
+ mongooseProp.required = true;
902
+ break;
1151
903
  }
1152
- // Fallback for z.any() or unhandled types
1153
- if (!mongooseProp.type && type !== 'object') {
1154
- mongooseProp.type = getMongoose()?.Schema.Types.Mixed || 'Mixed';
904
+ case "enum":
905
+ case "nativeenum":
906
+ case "native_enum": {
907
+ if (!mongooseProp.type)
908
+ mongooseProp.type = String;
909
+ mongooseProp.enum = type === "enum" ? unwrapped.options || def.values : Object.values(unwrapped.enum || def.values);
910
+ if (mongooseProp.required !== false)
911
+ mongooseProp.required = true;
912
+ break;
1155
913
  }
1156
- callHookSync('converter:after', {
1157
- schema: schema,
1158
- mongooseProp,
1159
- });
1160
- if (typeof mongooseProp === 'object' && mongooseProp !== null && !Array.isArray(mongooseProp)) {
1161
- delete mongooseProp.includeId;
914
+ }
915
+ const mongooseInstance2 = getMongoose();
916
+ if (type === "any" || type === "unknown" || type === "custom") {
917
+ const cls = def.cls || unwrapped.cls;
918
+ if (cls === Buffer || typeof Uint8Array !== "undefined" && cls === Uint8Array) {
919
+ if (!mongooseProp.type)
920
+ mongooseProp.type = (mongooseInstance2 == null ? void 0 : mongooseInstance2.Schema.Types.Buffer) || "Buffer";
921
+ } else if (((cls == null ? void 0 : cls.name) === "ObjectId" || mongooseInstance2 && cls === mongooseInstance2.Types.ObjectId) && !mongooseProp.type) {
922
+ mongooseProp.type = (mongooseInstance2 == null ? void 0 : mongooseInstance2.Schema.Types.ObjectId) || "ObjectId";
1162
923
  }
1163
- return mongooseProp;
924
+ }
925
+ if (type === "lazy") {
926
+ const inner = def.getter();
927
+ const result = extractMongooseDef(inner, visited, isField);
928
+ if (Object.keys(meta).length > 0 && result !== mongooseProp) {
929
+ if (typeof result === "object" && !Array.isArray(result)) {
930
+ Object.assign(mongooseProp, result);
931
+ } else {
932
+ mongooseProp.type = result.type || result;
933
+ }
934
+ return mongooseProp;
935
+ }
936
+ return result;
937
+ }
938
+ if (!mongooseProp.type && type !== "object") {
939
+ mongooseProp.type = ((_k = getMongoose()) == null ? void 0 : _k.Schema.Types.Mixed) || "Mixed";
940
+ }
941
+ callHookSync("converter:after", {
942
+ schema,
943
+ mongooseProp
944
+ });
945
+ if (typeof mongooseProp === "object" && mongooseProp !== null && !Array.isArray(mongooseProp)) {
946
+ delete mongooseProp.includeId;
947
+ }
948
+ return mongooseProp;
1164
949
  }
1165
-
1166
- /**
1167
- * Converts a Zod schema to a Mongoose Schema instance.
1168
- */
1169
950
  function toMongooseSchema(schema, options) {
1170
- const { schema: unwrapped } = unwrapZodSchema(schema);
1171
- const meta = mongooseRegistry.get(schema) ||
1172
- mongooseRegistry.get(unwrapped) ||
1173
- schema.meta?.() ||
1174
- unwrapped.meta?.() ||
1175
- {};
1176
- const { plugins, ...schemaOptions } = options || {};
1177
- const mergedOptions = {
1178
- // Also merge other schema options from meta if they exist
1179
- ...(meta.collection ? { collection: meta.collection } : {}),
1180
- // eslint-disable-next-line unicorn/no-negated-condition
1181
- ...(meta.strict !== undefined ? { strict: meta.strict } : {}),
1182
- // eslint-disable-next-line unicorn/no-negated-condition
1183
- ...(meta.minimize !== undefined ? { minimize: meta.minimize } : {}),
1184
- // eslint-disable-next-line unicorn/no-negated-condition
1185
- ...(meta.validateBeforeSave !== undefined ? { validateBeforeSave: meta.validateBeforeSave } : {}),
1186
- // eslint-disable-next-line unicorn/no-negated-condition
1187
- ...(meta.versionKey !== undefined ? { versionKey: meta.versionKey } : {}),
1188
- ...(meta.id === undefined ? {} : { id: meta.id }),
1189
- ...(meta._id === undefined ? {} : { _id: meta._id }),
1190
- ...(meta.timestamps ? { timestamps: meta.timestamps } : {}),
1191
- ...(meta.discriminatorKey ? { discriminatorKey: meta.discriminatorKey } : {}),
1192
- ...schemaOptions,
1193
- };
1194
- let definition = extractMongooseDef(schema, new Map(), false);
1195
- const mongoose = getMongoose();
1196
- if (!mongoose) {
1197
- throw new Error('Mongoose must be installed to use toMongooseSchema. If you are in an ESM environment, ensure mongoose is loaded.');
951
+ var _a, _b;
952
+ const { schema: unwrapped } = unwrapZodSchema(schema);
953
+ const meta = mongooseRegistry.get(schema) || mongooseRegistry.get(unwrapped) || ((_a = schema.meta) == null ? void 0 : _a.call(schema)) || ((_b = unwrapped.meta) == null ? void 0 : _b.call(unwrapped)) || {};
954
+ const { plugins, ...schemaOptions } = options || {};
955
+ const mergedOptions = {
956
+ // Also merge other schema options from meta if they exist
957
+ ...meta.collection ? { collection: meta.collection } : {},
958
+ // eslint-disable-next-line unicorn/no-negated-condition
959
+ ...meta.strict !== void 0 ? { strict: meta.strict } : {},
960
+ // eslint-disable-next-line unicorn/no-negated-condition
961
+ ...meta.minimize !== void 0 ? { minimize: meta.minimize } : {},
962
+ // eslint-disable-next-line unicorn/no-negated-condition
963
+ ...meta.validateBeforeSave !== void 0 ? { validateBeforeSave: meta.validateBeforeSave } : {},
964
+ // eslint-disable-next-line unicorn/no-negated-condition
965
+ ...meta.versionKey !== void 0 ? { versionKey: meta.versionKey } : {},
966
+ ...meta.id === void 0 ? {} : { id: meta.id },
967
+ ...meta._id === void 0 ? {} : { _id: meta._id },
968
+ ...meta.timestamps ? { timestamps: meta.timestamps } : {},
969
+ ...meta.discriminatorKey ? { discriminatorKey: meta.discriminatorKey } : {},
970
+ ...schemaOptions
971
+ };
972
+ let definition = extractMongooseDef(schema, /* @__PURE__ */ new Map(), false);
973
+ const mongoose = getMongoose();
974
+ if (!mongoose) {
975
+ throw new Error("Mongoose must be installed to use toMongooseSchema. If you are in an ESM environment, ensure mongoose is loaded.");
976
+ }
977
+ let mongooseSchema;
978
+ if (definition && typeof definition === "object" && definition.__isDiscriminatorUnion) {
979
+ const { discriminatorKey, discriminators, baseDef, validate } = definition;
980
+ mongooseSchema = new mongoose.Schema(baseDef, {
981
+ ...mergedOptions,
982
+ discriminatorKey
983
+ });
984
+ if (validate) {
985
+ if (!mongooseSchema.path(discriminatorKey)) {
986
+ mongooseSchema.add({ [discriminatorKey]: { type: String } });
987
+ }
988
+ mongooseSchema.path(discriminatorKey).validate(validate);
1198
989
  }
1199
- let mongooseSchema;
1200
- if (definition && typeof definition === 'object' && definition.__isDiscriminatorUnion) {
1201
- const { discriminatorKey, discriminators, baseDef, validate } = definition;
1202
- mongooseSchema = new mongoose.Schema(baseDef, {
1203
- ...mergedOptions,
1204
- discriminatorKey,
1205
- });
1206
- if (validate) {
1207
- if (!mongooseSchema.path(discriminatorKey)) {
1208
- mongooseSchema.add({ [discriminatorKey]: { type: String } });
1209
- }
1210
- mongooseSchema.path(discriminatorKey).validate(validate);
1211
- }
1212
- for (const [key, dDef] of Object.entries(discriminators)) {
1213
- if (mongooseSchema.discriminators && mongooseSchema.discriminators[key]) {
1214
- continue;
1215
- }
1216
- mongooseSchema.discriminator(key, new mongoose.Schema(dDef, { _id: false }));
1217
- }
990
+ for (const [key, dDef] of Object.entries(discriminators)) {
991
+ if (mongooseSchema.discriminators && mongooseSchema.discriminators[key]) {
992
+ continue;
993
+ }
994
+ mongooseSchema.discriminator(key, new mongoose.Schema(dDef, { _id: false }));
1218
995
  }
1219
- else {
1220
- // Strip internal includeId metadata that might have leaked into the definition
1221
- if (typeof definition === 'object' && definition !== null) {
1222
- // If it's a top-level object, it might have metadata fields directly
1223
- const { includeId, ...cleanDefinition } = definition;
1224
- definition = cleanDefinition;
1225
- // Also clean any top-level field definitions
1226
- for (const value of Object.values(definition)) {
1227
- if (value && typeof value === 'object' && !Array.isArray(value)) {
1228
- delete value.includeId;
1229
- }
1230
- }
996
+ } else {
997
+ if (typeof definition === "object" && definition !== null) {
998
+ const { includeId, ...cleanDefinition } = definition;
999
+ definition = cleanDefinition;
1000
+ for (const value of Object.values(definition)) {
1001
+ if (value && typeof value === "object" && !Array.isArray(value)) {
1002
+ delete value.includeId;
1231
1003
  }
1232
- mongooseSchema = new mongoose.Schema(definition, mergedOptions);
1004
+ }
1233
1005
  }
1234
- // Apply plugins if provided in options
1235
- if (plugins && Array.isArray(plugins)) {
1236
- for (const plugin of plugins) {
1237
- mongooseSchema.plugin(plugin);
1238
- }
1006
+ mongooseSchema = new mongoose.Schema(definition, mergedOptions);
1007
+ }
1008
+ if (plugins && Array.isArray(plugins)) {
1009
+ for (const plugin of plugins) {
1010
+ mongooseSchema.plugin(plugin);
1239
1011
  }
1240
- // Call schema:created hook
1241
- callHookSync('schema:created', {
1242
- schema,
1243
- mongooseSchema,
1244
- options: mergedOptions,
1245
- });
1246
- return mongooseSchema;
1012
+ }
1013
+ callHookSync("schema:created", {
1014
+ schema,
1015
+ mongooseSchema,
1016
+ options: mergedOptions
1017
+ });
1018
+ return mongooseSchema;
1247
1019
  }
1248
-
1249
- // ============================================================================
1250
- // 2. PRIMITIVE TYPES (ObjectId & Buffer)
1251
- // ============================================================================
1252
- const preprocessFn = (val) => (val === null ? undefined : val);
1253
- const zObjectId = (options) => {
1254
- const isFrontend = getFrontendMode();
1255
- if (isFrontend) {
1256
- return withMongoose(v4.z.preprocess(preprocessFn, v4.z.string().regex(/^[\dA-Fa-f]{24}$/, 'Invalid ObjectId')), { type: 'ObjectId', ...options });
1020
+ function populateZodSchema(schema, keys) {
1021
+ const { shape } = schema;
1022
+ const newShape = { ...shape };
1023
+ const keysToPopulate = keys || Object.keys(shape);
1024
+ const populateField = (field) => {
1025
+ const meta = getMongooseMeta(field);
1026
+ const { schema: unwrapped, features } = unwrapZodSchema(field);
1027
+ let result = field;
1028
+ if (meta == null ? void 0 : meta.refSchema) {
1029
+ result = meta.refSchema;
1030
+ } else if (unwrapped instanceof z.ZodArray) {
1031
+ const populatedInner = populateField(unwrapped.element);
1032
+ if (populatedInner !== unwrapped.element) {
1033
+ result = z.array(populatedInner);
1034
+ }
1035
+ } else if (unwrapped instanceof z.ZodObject) {
1036
+ result = populateZodSchema(unwrapped);
1037
+ }
1038
+ if (result !== field && result !== unwrapped) {
1039
+ if (features.isOptional && !(result instanceof z.ZodOptional))
1040
+ result = result.optional();
1041
+ if (features.isNullable && !(result instanceof z.ZodNullable))
1042
+ result = result.nullable();
1043
+ if (features.default !== void 0 && !(result instanceof z.ZodDefault))
1044
+ result = result.default(features.default);
1257
1045
  }
1258
- const mongooseInstance = getMongoose();
1259
- return withMongoose(v4.z.preprocess(preprocessFn, v4.z.custom((val) => (mongooseInstance && val instanceof mongooseInstance.Types.ObjectId) ||
1260
- (typeof val === 'string' && /^[\dA-Fa-f]{24}$/.test(val)))), { type: mongooseInstance?.Schema.Types.ObjectId || 'ObjectId', ...options });
1046
+ return result;
1047
+ };
1048
+ for (const key of keysToPopulate) {
1049
+ newShape[key] = populateField(shape[key]);
1050
+ }
1051
+ return z.object(newShape);
1052
+ }
1053
+ const genTimestampsSchema = (createdAtField = "createdAt", updatedAtField = "updatedAt") => {
1054
+ if (createdAtField != null && updatedAtField != null && createdAtField === updatedAtField) {
1055
+ throw new Error("`createdAt` and `updatedAt` fields must be different");
1056
+ }
1057
+ const shape = {};
1058
+ if (createdAtField != null)
1059
+ shape[createdAtField] = z.date().default(() => /* @__PURE__ */ new Date());
1060
+ if (updatedAtField != null)
1061
+ shape[updatedAtField] = z.date().default(() => /* @__PURE__ */ new Date());
1062
+ return shape;
1063
+ };
1064
+ const bufferMongooseGetter = (value) => value != null && value._bsontype === "Binary" ? value.buffer : value;
1065
+ const preprocessFn = (val) => val === null ? void 0 : val;
1066
+ const zObjectId = (options) => {
1067
+ const mongooseInstance2 = getMongoose();
1068
+ const objectIdSchema = z.custom((val) => mongooseInstance2 && val instanceof mongooseInstance2.Types.ObjectId);
1069
+ const baseUnion = z.preprocess(preprocessFn, z.union([objectIdSchema, z.string().regex(/^[\dA-Fa-f]{24}$/, "Invalid ObjectId")]));
1070
+ const inputSchema = z.codec(baseUnion, objectIdSchema, {
1071
+ decode: (val) => {
1072
+ if (!mongooseInstance2)
1073
+ return val;
1074
+ if (val instanceof mongooseInstance2.Types.ObjectId) {
1075
+ return val;
1076
+ }
1077
+ return new mongooseInstance2.Types.ObjectId(val);
1078
+ },
1079
+ encode: (val) => val.toString()
1080
+ });
1081
+ return withMongoose(inputSchema, {
1082
+ type: (mongooseInstance2 == null ? void 0 : mongooseInstance2.Schema.Types.ObjectId) || "ObjectId",
1083
+ ...options
1084
+ });
1261
1085
  };
1262
1086
  const zBuffer = (options) => {
1263
- if (getFrontendMode()) {
1264
- return withMongoose(v4.z.instanceof(Uint8Array), { type: 'Buffer', ...options });
1265
- }
1266
- const mongooseInstance = getMongoose();
1267
- return withMongoose(v4.z.custom((val) => (mongooseInstance && val instanceof Buffer) || val instanceof Uint8Array), { type: mongooseInstance?.Schema.Types.Buffer || 'Buffer', ...options });
1087
+ const mongooseInstance2 = getMongoose();
1088
+ return withMongoose(z.custom((val) => mongooseInstance2 && val instanceof Buffer || val instanceof Uint8Array), { type: (mongooseInstance2 == null ? void 0 : mongooseInstance2.Schema.Types.Buffer) || "Buffer", ...options });
1268
1089
  };
1269
- // ============================================================================
1270
- // 3. REF SCHEMAS & DYNAMIC POPULATION
1271
- // ============================================================================
1272
1090
  const zRef = (ref, schema, options) => {
1273
- const isFrontend = getFrontendMode();
1274
- const mongooseInstance = getMongoose();
1275
- const objectIdSchema = zObjectId();
1276
- const base = v4.z.codec(v4.z.union([objectIdSchema, schema]), objectIdSchema, {
1277
- decode: (val) => (typeof val === 'object' && val !== null && '_id' in val ? val._id : val),
1278
- encode: (val) => val,
1279
- });
1280
- const result = withMongoose(base, {
1281
- type: isFrontend ? 'ObjectId' : mongooseInstance?.Schema.Types.ObjectId || 'ObjectId',
1282
- ref,
1283
- refSchema: schema,
1284
- ...options,
1285
- });
1286
- return result;
1091
+ const mongooseInstance2 = getMongoose();
1092
+ const objectIdSchema = zObjectId();
1093
+ const base = z.codec(z.union([objectIdSchema, schema]), objectIdSchema, {
1094
+ decode: (val) => typeof val === "object" && val !== null && "_id" in val ? val._id : val,
1095
+ encode: (val) => val
1096
+ });
1097
+ return withMongoose(base, {
1098
+ type: (mongooseInstance2 == null ? void 0 : mongooseInstance2.Schema.Types.ObjectId) || "ObjectId",
1099
+ ref,
1100
+ refSchema: schema,
1101
+ ...options
1102
+ });
1287
1103
  };
1288
- function populateZodSchema(schema, keys) {
1289
- const { shape } = schema;
1290
- const newShape = { ...shape };
1291
- const keysToPopulate = keys || Object.keys(shape);
1292
- const populateField = (field) => {
1293
- const meta = getMongooseMeta(field);
1294
- const { schema: unwrapped, features } = unwrapZodSchema(field);
1295
- let result = field;
1296
- if (meta?.refSchema) {
1297
- result = meta.refSchema;
1298
- }
1299
- else if (unwrapped instanceof v4.z.ZodArray) {
1300
- const populatedInner = populateField(unwrapped.element);
1301
- if (populatedInner !== unwrapped.element) {
1302
- result = v4.z.array(populatedInner);
1303
- }
1304
- }
1305
- else if (unwrapped instanceof v4.z.ZodObject) {
1306
- result = populateZodSchema(unwrapped);
1307
- }
1308
- if (result !== field && result !== unwrapped) {
1309
- if (features.isOptional && !(result instanceof v4.z.ZodOptional))
1310
- result = result.optional();
1311
- if (features.isNullable && !(result instanceof v4.z.ZodNullable))
1312
- result = result.nullable();
1313
- if (features.default !== undefined && !(result instanceof v4.z.ZodDefault))
1314
- result = result.default(features.default);
1315
- }
1316
- return result;
1317
- };
1318
- for (const key of keysToPopulate) {
1319
- newShape[key] = populateField(shape[key]);
1320
- }
1321
- return v4.z.object(newShape);
1322
- }
1323
- // ============================================================================
1324
- // 4. TIMESTAMPS & OUTPUT FORMATTING
1325
- // ============================================================================
1326
- const DateFieldZod = () => v4.z.date().default(() => new Date());
1327
- const genTimestampsSchema = (createdAtField = 'createdAt', updatedAtField = 'updatedAt') => {
1328
- if (createdAtField != null &&
1329
- updatedAtField != null &&
1330
- createdAtField === updatedAtField) {
1331
- throw new Error('`createdAt` and `updatedAt` fields must be different');
1332
- }
1333
- const shape = {};
1334
- if (createdAtField != null)
1335
- shape[createdAtField] = withMongoose(DateFieldZod(), { immutable: true, index: true });
1336
- if (updatedAtField != null)
1337
- shape[updatedAtField] = withMongoose(DateFieldZod(), { index: true });
1338
- return shape;
1339
- };
1340
- const bufferMongooseGetter = (value) => value != null && value._bsontype === 'Binary' ? value.buffer : value;
1341
-
1342
- // ============================================================================
1343
- // 6. INITIALIZATION RUNTIME COMPONENT
1344
- // ============================================================================
1345
- /**
1346
- * Converts a standard Mongoose model into a `StrictModel` with advanced type-safe population.
1347
- *
1348
- * @template UserInferredType The Zod-inferred type of the document (e.g. `z.infer<typeof Schema>`).
1349
- * @param name The model name to register or retrieve from Mongoose.
1350
- * @param mongooseSchema The Mongoose schema instance.
1351
- * @returns A `StrictModel` instance with enhanced type safety for population.
1352
- *
1353
- * @example
1354
- * ```typescript
1355
- * const PostModel = toStrictModel<Post>('Post', postSchema);
1356
- * const post = await PostModel.findOne().populate('author').exec();
1357
- * // post.author is now fully typed
1358
- * ```
1359
- */
1360
1104
  function toStrictModel(name, mongooseSchema) {
1361
- const rawModel = mongoose.model(name, mongooseSchema);
1362
- return rawModel;
1105
+ const m = getMongoose();
1106
+ if (!m) {
1107
+ throw new Error("Mongoose must be installed to use toStrictModel.");
1108
+ }
1109
+ const rawModel = m.model(name, mongooseSchema);
1110
+ return rawModel;
1363
1111
  }
1364
1112
 
1365
- var bufferMongooseGetter_1 = dist.bufferMongooseGetter = bufferMongooseGetter;
1366
- var callHookSync_1 = dist.callHookSync = callHookSync;
1367
- var extractMongooseDef_1 = dist.extractMongooseDef = extractMongooseDef;
1368
- var genTimestampsSchema_1 = dist.genTimestampsSchema = genTimestampsSchema;
1369
- var getFrontendMode_1 = dist.getFrontendMode = getFrontendMode;
1370
- var getMongoose_1 = dist.getMongoose = getMongoose;
1371
- var getMongooseMeta_1 = dist.getMongooseMeta = getMongooseMeta;
1372
- var hooks_1 = dist.hooks = hooks;
1373
- var mongooseRegistry_1 = dist.mongooseRegistry = mongooseRegistry;
1374
- var populateZodSchema_1 = dist.populateZodSchema = populateZodSchema;
1375
- var setFrontendMode_1 = dist.setFrontendMode = setFrontendMode;
1376
- var setMongoose_1 = dist.setMongoose = setMongoose;
1377
- var toMongooseSchema_1 = dist.toMongooseSchema = toMongooseSchema;
1378
- var toStrictModel_1 = dist.toStrictModel = toStrictModel;
1379
- var withMongoose_1 = dist.withMongoose = withMongoose;
1380
- var zBuffer_1 = dist.zBuffer = zBuffer;
1381
- var zObjectId_1 = dist.zObjectId = zObjectId;
1382
- var zRef_1 = dist.zRef = zRef;
1383
-
1384
- const mongooseZod = /*#__PURE__*/_mergeNamespaces({
1385
- __proto__: null,
1386
- bufferMongooseGetter: bufferMongooseGetter_1,
1387
- callHookSync: callHookSync_1,
1388
- default: dist,
1389
- extractMongooseDef: extractMongooseDef_1,
1390
- genTimestampsSchema: genTimestampsSchema_1,
1391
- getFrontendMode: getFrontendMode_1,
1392
- getMongoose: getMongoose_1,
1393
- getMongooseMeta: getMongooseMeta_1,
1394
- hooks: hooks_1,
1395
- mongooseRegistry: mongooseRegistry_1,
1396
- populateZodSchema: populateZodSchema_1,
1397
- setFrontendMode: setFrontendMode_1,
1398
- setMongoose: setMongoose_1,
1399
- toMongooseSchema: toMongooseSchema_1,
1400
- toStrictModel: toStrictModel_1,
1401
- withMongoose: withMongoose_1,
1402
- zBuffer: zBuffer_1,
1403
- zObjectId: zObjectId_1,
1404
- zRef: zRef_1
1405
- }, [dist]);
1113
+ const mongooseZod = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
1114
+ __proto__: null,
1115
+ bufferMongooseGetter: bufferMongooseGetter,
1116
+ callHookSync: callHookSync,
1117
+ extractMongooseDef: extractMongooseDef,
1118
+ genTimestampsSchema: genTimestampsSchema,
1119
+ getFrontendMode: getFrontendMode,
1120
+ getMongoose: getMongoose,
1121
+ getMongooseMeta: getMongooseMeta,
1122
+ hooks: hooks,
1123
+ mongooseRegistry: mongooseRegistry,
1124
+ populateZodSchema: populateZodSchema,
1125
+ setFrontendMode: setFrontendMode,
1126
+ setMongoose: setMongoose,
1127
+ toMongooseSchema: toMongooseSchema,
1128
+ toStrictModel: toStrictModel,
1129
+ withMongoose: withMongoose,
1130
+ zBuffer: zBuffer,
1131
+ zObjectId: zObjectId,
1132
+ zRef: zRef
1133
+ }, Symbol.toStringTag, { value: 'Module' }));
1406
1134
 
1407
- setMongoose_1(mongoose$1.default || mongoose$1);
1135
+ setMongoose(mongoose.default || mongoose);
1408
1136
  let _filename = "/sandbox/main.ts";
1409
1137
  let _dirname = "/sandbox";
1410
1138
  try {
@@ -1447,7 +1175,7 @@ const parse_post = defineEventHandler(async (event) => {
1447
1175
  const sandboxRequire = (moduleName) => {
1448
1176
  if (moduleName === "zod" || moduleName === "zod/v4") return zod;
1449
1177
  if (moduleName === "@nullix/zod-mongoose") return mongooseZod;
1450
- if (moduleName === "mongoose") return mongoose$1.default || mongoose$1;
1178
+ if (moduleName === "mongoose") return mongoose.default || mongoose;
1451
1179
  throw new Error(`Security Exception: Module "${moduleName}" is blocked.`);
1452
1180
  };
1453
1181
  const sandbox = {
@@ -1478,8 +1206,8 @@ const parse_post = defineEventHandler(async (event) => {
1478
1206
  if (!schema || !schema._def) {
1479
1207
  throw new Error("You must `export default` a valid Zod schema.");
1480
1208
  }
1481
- const extractedDef = extractMongooseDef_1(schema);
1482
- const mongooseSchema = toMongooseSchema_1(schema);
1209
+ const extractedDef = extractMongooseDef(schema);
1210
+ const mongooseSchema = toMongooseSchema(schema);
1483
1211
  const formatOpts = { depth: null, showHidden: false, colors: false };
1484
1212
  const formatValue = (val) => {
1485
1213
  if (typeof val === "function") {