@magnet-cms/common 0.1.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,9 +1,9 @@
1
1
  'use strict';
2
2
 
3
3
  require('reflect-metadata');
4
+ var common = require('@nestjs/common');
4
5
  var fs = require('fs');
5
6
  var path = require('path');
6
- var common = require('@nestjs/common');
7
7
 
8
8
  var __defProp = Object.defineProperty;
9
9
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
@@ -13,6 +13,21 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
13
13
  if (typeof require !== "undefined") return require.apply(this, arguments);
14
14
  throw Error('Dynamic require of "' + x + '" is not supported');
15
15
  });
16
+ var EVENT_HANDLER_METADATA = "magnet:event_handler";
17
+ function OnEvent(event, options = {}) {
18
+ return (target, propertyKey, descriptor) => {
19
+ const metadata = {
20
+ event,
21
+ options
22
+ };
23
+ common.SetMetadata(EVENT_HANDLER_METADATA, metadata)(target, propertyKey, descriptor);
24
+ return descriptor;
25
+ };
26
+ }
27
+ __name(OnEvent, "OnEvent");
28
+ var Validators = /* @__PURE__ */ __name((...validators) => {
29
+ return common.applyDecorators(...validators);
30
+ }, "Validators");
16
31
 
17
32
  // src/constants.ts
18
33
  var RESOLVER_METADATA_KEY = "magnet:resolver";
@@ -22,13 +37,936 @@ var SCHEMA_OPTIONS_METADATA_KEY = "magnet:schema:options";
22
37
  var BASE_SCHEMA_METADATA_KEY = "magnet:schema:base";
23
38
  var PROP_METADATA_KEY = "magnet:schema:prop";
24
39
  var UI_METADATA_KEY = "magnet:schema:ui";
40
+ var FIELD_METADATA_KEY = "magnet:schema:field";
25
41
  var SETTING_METADATA_KEY = "magnet:setting";
42
+ var SETTINGS_OPTIONS_METADATA_KEY = "magnet:settings:options";
43
+ var SETTING_FIELD_METADATA_KEY = "magnet:settings:field";
44
+ var EXTEND_USER_METADATA_KEY = "magnet:extend:user";
45
+ var PERMISSION_METADATA_KEY = "magnet:permission";
46
+ var PERMISSION_OPTIONS_METADATA_KEY = "magnet:permission:options";
47
+ var RESOLVED_PERMISSION_KEY = "magnet:permission:resolved";
26
48
  var INJECT_MODEL = "magnet:inject:model";
27
49
  var DESIGN_TYPE = "design:type";
28
50
  var DESIGN_META = "design:metadata";
29
51
  var DESIGN_PARAM_TYPES = "design:paramtypes";
30
52
  var DESIGN_RETURN_TYPE = "design:returntype";
31
53
 
54
+ // src/utils/database-adapter-singleton-for-feature.util.ts
55
+ var GETTER_KEY = Symbol.for("@magnet-cms/common/database-adapter-singleton-for-feature");
56
+ function getGetterSlot() {
57
+ const g = globalThis;
58
+ return g[GETTER_KEY] ?? null;
59
+ }
60
+ __name(getGetterSlot, "getGetterSlot");
61
+ function setGetterSlot(getter) {
62
+ const g = globalThis;
63
+ g[GETTER_KEY] = getter;
64
+ }
65
+ __name(setGetterSlot, "setGetterSlot");
66
+ function registerDatabaseAdapterSingletonForFeature(getter) {
67
+ setGetterSlot(getter);
68
+ }
69
+ __name(registerDatabaseAdapterSingletonForFeature, "registerDatabaseAdapterSingletonForFeature");
70
+ function getDatabaseAdapterSingletonForFeature() {
71
+ const databaseAdapterSingletonGetter = getGetterSlot();
72
+ if (!databaseAdapterSingletonGetter) return null;
73
+ try {
74
+ return databaseAdapterSingletonGetter();
75
+ } catch {
76
+ return null;
77
+ }
78
+ }
79
+ __name(getDatabaseAdapterSingletonForFeature, "getDatabaseAdapterSingletonForFeature");
80
+ function clearDatabaseAdapterSingletonForFeature() {
81
+ setGetterSlot(null);
82
+ }
83
+ __name(clearDatabaseAdapterSingletonForFeature, "clearDatabaseAdapterSingletonForFeature");
84
+ var cachedAdapter = null;
85
+ function isPackageInstalled(packageName) {
86
+ try {
87
+ return fs.existsSync(path.join(__require.resolve(packageName), "../../"));
88
+ } catch {
89
+ return false;
90
+ }
91
+ }
92
+ __name(isPackageInstalled, "isPackageInstalled");
93
+ function detectDatabaseAdapter(dbConfig) {
94
+ if (dbConfig) {
95
+ if ("connectionString" in dbConfig || "dialect" in dbConfig) {
96
+ cachedAdapter = "drizzle";
97
+ return cachedAdapter;
98
+ }
99
+ if ("uri" in dbConfig) {
100
+ cachedAdapter = "mongoose";
101
+ return cachedAdapter;
102
+ }
103
+ }
104
+ if (cachedAdapter) return cachedAdapter;
105
+ if (isPackageInstalled("@magnet-cms/adapter-db-mongoose")) {
106
+ cachedAdapter = "mongoose";
107
+ } else if (isPackageInstalled("@magnet-cms/adapter-db-drizzle")) {
108
+ cachedAdapter = "drizzle";
109
+ } else {
110
+ throw new Error("\u274C No supported database adapter found. Install @magnet-cms/adapter-db-mongoose or @magnet-cms/adapter-db-drizzle.");
111
+ }
112
+ return cachedAdapter;
113
+ }
114
+ __name(detectDatabaseAdapter, "detectDatabaseAdapter");
115
+ function setDatabaseAdapter(adapter) {
116
+ cachedAdapter = adapter;
117
+ }
118
+ __name(setDatabaseAdapter, "setDatabaseAdapter");
119
+ function clearAdapterCache() {
120
+ cachedAdapter = null;
121
+ }
122
+ __name(clearAdapterCache, "clearAdapterCache");
123
+
124
+ // src/utils/get-model-token.util.ts
125
+ function getModelToken(schema) {
126
+ const name = typeof schema === "string" ? schema : schema.name;
127
+ return `MAGNET_MODEL_${name.toUpperCase()}`;
128
+ }
129
+ __name(getModelToken, "getModelToken");
130
+ function getAdapterToken() {
131
+ return "MAGNET_DATABASE_ADAPTER";
132
+ }
133
+ __name(getAdapterToken, "getAdapterToken");
134
+ var globalModelRegistry = /* @__PURE__ */ new Map();
135
+ function registerModel(token, model) {
136
+ globalModelRegistry.set(token, model);
137
+ }
138
+ __name(registerModel, "registerModel");
139
+ function getRegisteredModel(token) {
140
+ return globalModelRegistry.get(token);
141
+ }
142
+ __name(getRegisteredModel, "getRegisteredModel");
143
+
144
+ // src/utils/get-schema-token.util.ts
145
+ var getSchemaToken = /* @__PURE__ */ __name((schema) => {
146
+ return `${schema.name}Schema`;
147
+ }, "getSchemaToken");
148
+ var getSettingToken = /* @__PURE__ */ __name((setting) => {
149
+ return `${setting.name}Setting`;
150
+ }, "getSettingToken");
151
+
152
+ // src/utils/type-guards.ts
153
+ function isObject(value) {
154
+ return typeof value === "object" && value !== null && !Array.isArray(value);
155
+ }
156
+ __name(isObject, "isObject");
157
+ function hasProperty(value, key) {
158
+ return isObject(value) && key in value;
159
+ }
160
+ __name(hasProperty, "hasProperty");
161
+ function hasProperties(value, keys) {
162
+ return isObject(value) && keys.every((key) => key in value);
163
+ }
164
+ __name(hasProperties, "hasProperties");
165
+ function isString(value) {
166
+ return typeof value === "string";
167
+ }
168
+ __name(isString, "isString");
169
+ function isNumber(value) {
170
+ return typeof value === "number" && !Number.isNaN(value);
171
+ }
172
+ __name(isNumber, "isNumber");
173
+ function isBoolean(value) {
174
+ return typeof value === "boolean";
175
+ }
176
+ __name(isBoolean, "isBoolean");
177
+ function isArray(value) {
178
+ return Array.isArray(value);
179
+ }
180
+ __name(isArray, "isArray");
181
+ function isStringArray(value) {
182
+ return Array.isArray(value) && value.every((item) => typeof item === "string");
183
+ }
184
+ __name(isStringArray, "isStringArray");
185
+ function isFunction(value) {
186
+ return typeof value === "function";
187
+ }
188
+ __name(isFunction, "isFunction");
189
+ function isDocument(value) {
190
+ return isObject(value) && hasProperty(value, "id") && typeof value.id === "string";
191
+ }
192
+ __name(isDocument, "isDocument");
193
+ function isCastError(error) {
194
+ return isObject(error) && hasProperty(error, "name") && error.name === "CastError" && hasProperty(error, "path") && typeof error.path === "string";
195
+ }
196
+ __name(isCastError, "isCastError");
197
+ function isDuplicateKeyError(error) {
198
+ return isObject(error) && hasProperty(error, "code") && error.code === 11e3;
199
+ }
200
+ __name(isDuplicateKeyError, "isDuplicateKeyError");
201
+ function isValidationError(error) {
202
+ return isObject(error) && hasProperty(error, "name") && error.name === "ValidationError" && hasProperty(error, "errors");
203
+ }
204
+ __name(isValidationError, "isValidationError");
205
+ function isPostgresUniqueError(error) {
206
+ return isObject(error) && hasProperty(error, "code") && error.code === "23505";
207
+ }
208
+ __name(isPostgresUniqueError, "isPostgresUniqueError");
209
+ function hasMethod(value, methodName) {
210
+ return isObject(value) && hasProperty(value, methodName) && typeof value[methodName] === "function";
211
+ }
212
+ __name(hasMethod, "hasMethod");
213
+ function hasSetLocale(value) {
214
+ return isObject(value) && hasMethod(value, "setLocale");
215
+ }
216
+ __name(hasSetLocale, "hasSetLocale");
217
+ function hasToString(value) {
218
+ return isObject(value) && hasMethod(value, "toString");
219
+ }
220
+ __name(hasToString, "hasToString");
221
+ function assertDefined(value, message) {
222
+ if (value === null || value === void 0) {
223
+ throw new Error(message ?? "Value is null or undefined");
224
+ }
225
+ }
226
+ __name(assertDefined, "assertDefined");
227
+ function assert(condition, message) {
228
+ if (!condition) {
229
+ throw new Error(message ?? "Assertion failed");
230
+ }
231
+ }
232
+ __name(assert, "assert");
233
+ function getDocumentId(doc) {
234
+ if (!isObject(doc)) return void 0;
235
+ if (hasProperty(doc, "id") && typeof doc.id === "string") {
236
+ return doc.id;
237
+ }
238
+ if (hasProperty(doc, "_id")) {
239
+ if (typeof doc._id === "string") {
240
+ return doc._id;
241
+ }
242
+ if (hasToString(doc._id)) {
243
+ return doc._id.toString();
244
+ }
245
+ }
246
+ return void 0;
247
+ }
248
+ __name(getDocumentId, "getDocumentId");
249
+ function isStringRecord(value) {
250
+ if (!isObject(value)) return false;
251
+ return Object.values(value).every((v) => typeof v === "string");
252
+ }
253
+ __name(isStringRecord, "isStringRecord");
254
+ function isVersionDocument(value) {
255
+ return isObject(value) && hasProperty(value, "documentId") && typeof value.documentId === "string" && hasProperty(value, "versionId") && typeof value.versionId === "string" && hasProperty(value, "schemaName") && typeof value.schemaName === "string" && hasProperty(value, "status") && hasProperty(value, "data") && isObject(value.data);
256
+ }
257
+ __name(isVersionDocument, "isVersionDocument");
258
+
259
+ // src/decorators/field/field.prop-mapper.ts
260
+ function isPropDefaultValue(value) {
261
+ if (value === null) return true;
262
+ if (typeof value === "string") return true;
263
+ if (typeof value === "number") return true;
264
+ if (typeof value === "boolean") return true;
265
+ if (typeof value === "function") return true;
266
+ if (Array.isArray(value)) return true;
267
+ if (typeof value === "object") return true;
268
+ return false;
269
+ }
270
+ __name(isPropDefaultValue, "isPropDefaultValue");
271
+ function mapFieldTypeToProp(type, options) {
272
+ const propOptions = {
273
+ required: options.required,
274
+ unique: options.unique,
275
+ default: isPropDefaultValue(options.default) ? options.default : void 0,
276
+ hidden: options.hidden,
277
+ readonly: options.readonly,
278
+ description: options.description
279
+ };
280
+ switch (type) {
281
+ case "text":
282
+ case "email":
283
+ case "url":
284
+ case "phone":
285
+ case "address":
286
+ case "color":
287
+ case "slug":
288
+ case "textarea":
289
+ case "markdown":
290
+ case "code":
291
+ propOptions.type = String;
292
+ break;
293
+ case "number":
294
+ propOptions.type = Number;
295
+ break;
296
+ case "boolean":
297
+ propOptions.type = Boolean;
298
+ break;
299
+ case "date":
300
+ case "datetime":
301
+ propOptions.type = Date;
302
+ break;
303
+ case "richtext":
304
+ propOptions.type = String;
305
+ break;
306
+ case "json":
307
+ case "object":
308
+ propOptions.type = Object;
309
+ break;
310
+ case "select":
311
+ case "enum":
312
+ propOptions.type = String;
313
+ break;
314
+ case "tags":
315
+ propOptions.type = [
316
+ String
317
+ ];
318
+ break;
319
+ case "image":
320
+ case "file":
321
+ propOptions.type = String;
322
+ break;
323
+ case "gallery":
324
+ propOptions.type = [
325
+ String
326
+ ];
327
+ break;
328
+ case "array":
329
+ propOptions.type = Array;
330
+ break;
331
+ case "blocks":
332
+ propOptions.type = Array;
333
+ break;
334
+ case "relationship": {
335
+ const relOptions = options;
336
+ propOptions.ref = relOptions.ref;
337
+ if (relOptions.multiple) {
338
+ propOptions.type = [
339
+ String
340
+ ];
341
+ } else {
342
+ propOptions.type = String;
343
+ }
344
+ break;
345
+ }
346
+ default: {
347
+ const _exhaustiveCheck = type;
348
+ throw new Error(`Unknown field type: ${_exhaustiveCheck}`);
349
+ }
350
+ }
351
+ return Object.fromEntries(Object.entries(propOptions).filter(([, value]) => value !== void 0));
352
+ }
353
+ __name(mapFieldTypeToProp, "mapFieldTypeToProp");
354
+
355
+ // src/decorators/field/field.ui-mapper.ts
356
+ function mapFieldTypeToUIType(type) {
357
+ const typeMap = {
358
+ text: "text",
359
+ number: "number",
360
+ boolean: "switch",
361
+ date: "date",
362
+ datetime: "date",
363
+ richtext: "richText",
364
+ markdown: "textarea",
365
+ code: "code",
366
+ json: "json",
367
+ select: "select",
368
+ enum: "select",
369
+ tags: "multiSelect",
370
+ image: "upload",
371
+ file: "fileUpload",
372
+ gallery: "upload",
373
+ slug: "text",
374
+ email: "email",
375
+ url: "text",
376
+ phone: "phone",
377
+ address: "text",
378
+ color: "text",
379
+ object: "json",
380
+ array: "array",
381
+ blocks: "blocks",
382
+ relationship: "relationship",
383
+ textarea: "textarea"
384
+ };
385
+ return typeMap[type];
386
+ }
387
+ __name(mapFieldTypeToUIType, "mapFieldTypeToUIType");
388
+ function convertToUISelectItems(options) {
389
+ return options.map((opt) => {
390
+ if (typeof opt === "object" && opt !== null && "label" in opt && "value" in opt) {
391
+ return {
392
+ key: String(opt.value),
393
+ value: opt.label
394
+ };
395
+ }
396
+ return {
397
+ key: String(opt),
398
+ value: String(opt)
399
+ };
400
+ });
401
+ }
402
+ __name(convertToUISelectItems, "convertToUISelectItems");
403
+ function convertEnumToUISelectItems(enumObj) {
404
+ return Object.entries(enumObj).filter(([key]) => Number.isNaN(Number(key))).map(([key, value]) => ({
405
+ key: String(value),
406
+ value: key
407
+ }));
408
+ }
409
+ __name(convertEnumToUISelectItems, "convertEnumToUISelectItems");
410
+ function toUIDecoratorOptions(internal) {
411
+ if (internal.side) {
412
+ return {
413
+ type: internal.type,
414
+ label: internal.label,
415
+ description: internal.description,
416
+ side: true,
417
+ options: internal.options
418
+ };
419
+ }
420
+ const result = {
421
+ type: internal.type,
422
+ label: internal.label,
423
+ description: internal.description,
424
+ tab: internal.tab ?? "General"
425
+ };
426
+ if (internal.options) {
427
+ result.options = internal.options;
428
+ }
429
+ return result;
430
+ }
431
+ __name(toUIDecoratorOptions, "toUIDecoratorOptions");
432
+ function mapFieldTypeToUI(type, options) {
433
+ const uiType = mapFieldTypeToUIType(type);
434
+ const internal = {
435
+ type: uiType,
436
+ label: options.label,
437
+ description: options.description,
438
+ tab: options.tab,
439
+ side: options.side ? true : void 0
440
+ };
441
+ switch (type) {
442
+ case "select": {
443
+ const selectOpts = options;
444
+ return toUIDecoratorOptions({
445
+ ...internal,
446
+ type: selectOpts.multiple ? "multiSelect" : "select",
447
+ options: convertToUISelectItems(selectOpts.options)
448
+ });
449
+ }
450
+ case "enum": {
451
+ const enumOpts = options;
452
+ return toUIDecoratorOptions({
453
+ ...internal,
454
+ type: enumOpts.multiple ? "multiSelect" : "select",
455
+ options: convertEnumToUISelectItems(enumOpts.enum)
456
+ });
457
+ }
458
+ case "boolean": {
459
+ const boolOpts = options;
460
+ return toUIDecoratorOptions({
461
+ ...internal,
462
+ type: boolOpts.style === "checkbox" ? "checkbox" : "switch"
463
+ });
464
+ }
465
+ case "richtext": {
466
+ return toUIDecoratorOptions({
467
+ ...internal,
468
+ type: "richText"
469
+ });
470
+ }
471
+ case "code": {
472
+ return toUIDecoratorOptions({
473
+ ...internal,
474
+ type: "code"
475
+ });
476
+ }
477
+ case "tags": {
478
+ const tagsOpts = options;
479
+ return toUIDecoratorOptions({
480
+ ...internal,
481
+ type: "multiSelect",
482
+ options: tagsOpts.suggestions?.map((s) => ({
483
+ key: s,
484
+ value: s
485
+ })) ?? []
486
+ });
487
+ }
488
+ default:
489
+ return toUIDecoratorOptions(internal);
490
+ }
491
+ }
492
+ __name(mapFieldTypeToUI, "mapFieldTypeToUI");
493
+
494
+ // src/decorators/field/field.factory.ts
495
+ function createFieldDecorator(type, defaultOptions = {}) {
496
+ return (options) => {
497
+ const mergedOptions = {
498
+ ...defaultOptions,
499
+ ...options
500
+ };
501
+ return (target, propertyKey) => {
502
+ const designType = Reflect.getMetadata(DESIGN_TYPE, target, propertyKey);
503
+ const metadata = {
504
+ type,
505
+ options: mergedOptions,
506
+ propertyKey,
507
+ target: target.constructor,
508
+ designType
509
+ };
510
+ const existingFields = Reflect.getMetadata(FIELD_METADATA_KEY, target.constructor) ?? [];
511
+ const filteredFields = existingFields.filter((f) => f.propertyKey !== propertyKey);
512
+ Reflect.defineMetadata(FIELD_METADATA_KEY, [
513
+ ...filteredFields,
514
+ metadata
515
+ ], target.constructor);
516
+ emitLegacyPropMetadata(target, propertyKey, type, mergedOptions);
517
+ emitLegacyUIMetadata(target, propertyKey, type, mergedOptions, designType);
518
+ applyAdapterProp(target, propertyKey, type, mergedOptions);
519
+ };
520
+ };
521
+ }
522
+ __name(createFieldDecorator, "createFieldDecorator");
523
+ function emitLegacyPropMetadata(target, propertyKey, type, options) {
524
+ const propOptions = mapFieldTypeToProp(type, options);
525
+ const existingProps = Reflect.getMetadata(PROP_METADATA_KEY, target) ?? [];
526
+ const filteredProps = existingProps.filter((p) => p.propertyKey !== propertyKey);
527
+ Reflect.defineMetadata(PROP_METADATA_KEY, [
528
+ ...filteredProps,
529
+ {
530
+ propertyKey,
531
+ options: propOptions
532
+ }
533
+ ], target);
534
+ }
535
+ __name(emitLegacyPropMetadata, "emitLegacyPropMetadata");
536
+ function emitLegacyUIMetadata(target, propertyKey, type, options, designType) {
537
+ const uiOptions = mapFieldTypeToUI(type, options);
538
+ const existingUI = Reflect.getMetadata(UI_METADATA_KEY, target) ?? [];
539
+ const filteredUI = existingUI.filter((u) => u.propertyKey !== propertyKey);
540
+ Reflect.defineMetadata(UI_METADATA_KEY, [
541
+ ...filteredUI,
542
+ {
543
+ propertyKey,
544
+ options: {
545
+ ...uiOptions,
546
+ designType
547
+ }
548
+ }
549
+ ], target);
550
+ }
551
+ __name(emitLegacyUIMetadata, "emitLegacyUIMetadata");
552
+ function applyAdapterProp(target, propertyKey, type, options) {
553
+ try {
554
+ const adapter = detectDatabaseAdapter();
555
+ const propOptions = mapFieldTypeToProp(type, options);
556
+ const { Prop: Prop2 } = __require(`@magnet-cms/adapter-db-${adapter}`);
557
+ Prop2(propOptions)(target, propertyKey);
558
+ } catch {
559
+ }
560
+ }
561
+ __name(applyAdapterProp, "applyAdapterProp");
562
+ function getFieldMetadata(target) {
563
+ return Reflect.getMetadata(FIELD_METADATA_KEY, target) ?? [];
564
+ }
565
+ __name(getFieldMetadata, "getFieldMetadata");
566
+ function getFieldMetadataForProperty(target, propertyKey) {
567
+ const fields = getFieldMetadata(target);
568
+ return fields.find((f) => f.propertyKey === propertyKey);
569
+ }
570
+ __name(getFieldMetadataForProperty, "getFieldMetadataForProperty");
571
+
572
+ // src/types/field.types.ts
573
+ function isFieldMetadata(value) {
574
+ if (typeof value !== "object" || value === null) {
575
+ return false;
576
+ }
577
+ const metadata = value;
578
+ return typeof metadata.type === "string" && typeof metadata.options === "object" && metadata.options !== null && "propertyKey" in metadata;
579
+ }
580
+ __name(isFieldMetadata, "isFieldMetadata");
581
+ function isValidFieldType(type) {
582
+ const validTypes = [
583
+ "text",
584
+ "number",
585
+ "boolean",
586
+ "date",
587
+ "datetime",
588
+ "richtext",
589
+ "markdown",
590
+ "code",
591
+ "json",
592
+ "select",
593
+ "enum",
594
+ "tags",
595
+ "image",
596
+ "file",
597
+ "gallery",
598
+ "slug",
599
+ "email",
600
+ "url",
601
+ "phone",
602
+ "address",
603
+ "color",
604
+ "object",
605
+ "array",
606
+ "blocks",
607
+ "relationship",
608
+ "textarea"
609
+ ];
610
+ return typeof type === "string" && validTypes.includes(type);
611
+ }
612
+ __name(isValidFieldType, "isValidFieldType");
613
+
614
+ // src/decorators/field/index.ts
615
+ var Field = {
616
+ // ============================================
617
+ // PRIMITIVES
618
+ // ============================================
619
+ /**
620
+ * Text field - single line text input
621
+ *
622
+ * @example
623
+ * ```typescript
624
+ * @Field.Text({ required: true, maxLength: 200 })
625
+ * title: string
626
+ * ```
627
+ */
628
+ Text: createFieldDecorator("text"),
629
+ /**
630
+ * Number field - numeric input
631
+ *
632
+ * @example
633
+ * ```typescript
634
+ * @Field.Number({ min: 0, max: 100, integer: true })
635
+ * quantity: number
636
+ * ```
637
+ */
638
+ Number: createFieldDecorator("number"),
639
+ /**
640
+ * Boolean field - true/false toggle
641
+ *
642
+ * @example
643
+ * ```typescript
644
+ * @Field.Boolean({ default: false, style: 'switch' })
645
+ * isPublished: boolean
646
+ * ```
647
+ */
648
+ Boolean: createFieldDecorator("boolean", {
649
+ style: "switch"
650
+ }),
651
+ /**
652
+ * Date field - date picker (without time)
653
+ *
654
+ * @example
655
+ * ```typescript
656
+ * @Field.Date({ min: '2024-01-01' })
657
+ * publishDate: Date
658
+ * ```
659
+ */
660
+ Date: createFieldDecorator("date"),
661
+ /**
662
+ * DateTime field - date and time picker
663
+ *
664
+ * @example
665
+ * ```typescript
666
+ * @Field.DateTime({ timezone: 'UTC' })
667
+ * scheduledAt: Date
668
+ * ```
669
+ */
670
+ DateTime: createFieldDecorator("datetime"),
671
+ // ============================================
672
+ // RICH CONTENT
673
+ // ============================================
674
+ /**
675
+ * RichText field - WYSIWYG editor
676
+ *
677
+ * @example
678
+ * ```typescript
679
+ * @Field.RichText({ toolbar: 'full' })
680
+ * content: string
681
+ * ```
682
+ */
683
+ RichText: createFieldDecorator("richtext", {
684
+ toolbar: "standard"
685
+ }),
686
+ /**
687
+ * Markdown field - markdown editor with preview
688
+ *
689
+ * @example
690
+ * ```typescript
691
+ * @Field.Markdown({ preview: true })
692
+ * description: string
693
+ * ```
694
+ */
695
+ Markdown: createFieldDecorator("markdown", {
696
+ preview: true
697
+ }),
698
+ /**
699
+ * Code field - code editor with syntax highlighting
700
+ *
701
+ * @example
702
+ * ```typescript
703
+ * @Field.Code({ language: 'typescript' })
704
+ * snippet: string
705
+ * ```
706
+ */
707
+ Code: createFieldDecorator("code"),
708
+ /**
709
+ * JSON field - JSON editor
710
+ *
711
+ * @example
712
+ * ```typescript
713
+ * @Field.JSON()
714
+ * metadata: Record<string, unknown>
715
+ * ```
716
+ */
717
+ JSON: createFieldDecorator("json"),
718
+ /**
719
+ * Textarea field - multi-line text input
720
+ *
721
+ * @example
722
+ * ```typescript
723
+ * @Field.Textarea({ rows: 5 })
724
+ * summary: string
725
+ * ```
726
+ */
727
+ Textarea: createFieldDecorator("textarea"),
728
+ // ============================================
729
+ // SELECTION
730
+ // ============================================
731
+ /**
732
+ * Select field - dropdown selection
733
+ *
734
+ * @example
735
+ * ```typescript
736
+ * @Field.Select({
737
+ * options: [
738
+ * { label: 'Draft', value: 'draft' },
739
+ * { label: 'Published', value: 'published' }
740
+ * ],
741
+ * default: 'draft'
742
+ * })
743
+ * status: string
744
+ * ```
745
+ */
746
+ Select: /* @__PURE__ */ __name((options) => createFieldDecorator("select")(options), "Select"),
747
+ /**
748
+ * Enum field - dropdown from TypeScript enum
749
+ *
750
+ * @example
751
+ * ```typescript
752
+ * enum Status { Draft = 'draft', Published = 'published' }
753
+ *
754
+ * @Field.Enum({ enum: Status, default: Status.Draft })
755
+ * status: Status
756
+ * ```
757
+ */
758
+ Enum: /* @__PURE__ */ __name((options) => createFieldDecorator("enum")(options), "Enum"),
759
+ /**
760
+ * Tags field - multi-value tag input
761
+ *
762
+ * @example
763
+ * ```typescript
764
+ * @Field.Tags({ suggestions: ['tech', 'news'], maxTags: 5 })
765
+ * tags: string[]
766
+ * ```
767
+ */
768
+ Tags: createFieldDecorator("tags"),
769
+ // ============================================
770
+ // MEDIA
771
+ // ============================================
772
+ /**
773
+ * Image field - single image upload
774
+ *
775
+ * @example
776
+ * ```typescript
777
+ * @Field.Image({ folder: 'covers', formats: ['jpg', 'png', 'webp'] })
778
+ * coverImage: string
779
+ * ```
780
+ */
781
+ Image: createFieldDecorator("image"),
782
+ /**
783
+ * File field - single file upload
784
+ *
785
+ * @example
786
+ * ```typescript
787
+ * @Field.File({ folder: 'documents', accept: ['application/pdf'] })
788
+ * attachment: string
789
+ * ```
790
+ */
791
+ File: createFieldDecorator("file"),
792
+ /**
793
+ * Gallery field - multiple image upload
794
+ *
795
+ * @example
796
+ * ```typescript
797
+ * @Field.Gallery({ maxItems: 10 })
798
+ * images: string[]
799
+ * ```
800
+ */
801
+ Gallery: createFieldDecorator("gallery"),
802
+ // ============================================
803
+ // SPECIAL
804
+ // ============================================
805
+ /**
806
+ * Slug field - auto-generated URL-friendly string
807
+ *
808
+ * @example
809
+ * ```typescript
810
+ * @Field.Slug({ from: 'title', unique: true })
811
+ * slug: string
812
+ * ```
813
+ */
814
+ Slug: createFieldDecorator("slug"),
815
+ /**
816
+ * Email field - email input with validation pattern
817
+ *
818
+ * @example
819
+ * ```typescript
820
+ * @Field.Email({ required: true })
821
+ * @Field.Validators(IsEmail())
822
+ * email: string
823
+ * ```
824
+ */
825
+ Email: createFieldDecorator("email", {
826
+ pattern: "^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$"
827
+ }),
828
+ /**
829
+ * URL field - URL input
830
+ *
831
+ * @example
832
+ * ```typescript
833
+ * @Field.URL({ protocols: ['https'] })
834
+ * @Field.Validators(IsUrl())
835
+ * website: string
836
+ * ```
837
+ */
838
+ URL: createFieldDecorator("url"),
839
+ /**
840
+ * Phone field - phone number input
841
+ *
842
+ * @example
843
+ * ```typescript
844
+ * @Field.Phone({ defaultCountry: 'US' })
845
+ * phone: string
846
+ * ```
847
+ */
848
+ Phone: createFieldDecorator("phone"),
849
+ /**
850
+ * Address field - address input with optional geocoding
851
+ *
852
+ * @example
853
+ * ```typescript
854
+ * @Field.Address({ provider: 'google' })
855
+ * address: string
856
+ * ```
857
+ */
858
+ Address: createFieldDecorator("address"),
859
+ /**
860
+ * Color field - color picker
861
+ *
862
+ * @example
863
+ * ```typescript
864
+ * @Field.Color({ format: 'hex', presets: ['#ff0000', '#00ff00'] })
865
+ * brandColor: string
866
+ * ```
867
+ */
868
+ Color: createFieldDecorator("color", {
869
+ format: "hex"
870
+ }),
871
+ // ============================================
872
+ // COMPOSITION
873
+ // ============================================
874
+ /**
875
+ * Object field - nested object structure
876
+ *
877
+ * @example
878
+ * ```typescript
879
+ * @Field.Object()
880
+ * metadata: { key: string; value: string }
881
+ * ```
882
+ */
883
+ Object: createFieldDecorator("object"),
884
+ /**
885
+ * Array field - array of items
886
+ *
887
+ * @example
888
+ * ```typescript
889
+ * @Field.Array({ of: { type: 'text' }, maxItems: 10 })
890
+ * items: string[]
891
+ * ```
892
+ */
893
+ Array: /* @__PURE__ */ __name((options) => createFieldDecorator("array")(options), "Array"),
894
+ /**
895
+ * Blocks field - flexible content blocks
896
+ *
897
+ * @example
898
+ * ```typescript
899
+ * @Field.Blocks({ types: ['paragraph', 'image', 'quote'] })
900
+ * content: Block[]
901
+ * ```
902
+ */
903
+ Blocks: createFieldDecorator("blocks"),
904
+ /**
905
+ * Relationship field - reference to another schema
906
+ *
907
+ * @example
908
+ * ```typescript
909
+ * @Field.Relationship({ ref: 'users', multiple: false })
910
+ * author: string
911
+ *
912
+ * @Field.Relationship({ ref: 'categories', multiple: true })
913
+ * categories: string[]
914
+ * ```
915
+ */
916
+ Relationship: createFieldDecorator("relationship"),
917
+ // ============================================
918
+ // VALIDATION
919
+ // ============================================
920
+ /**
921
+ * Validators - apply class-validator decorators
922
+ *
923
+ * This is an alias for the existing @Validators decorator,
924
+ * keeping validation explicit and using familiar class-validator syntax.
925
+ *
926
+ * @example
927
+ * ```typescript
928
+ * @Field.Text({ required: true })
929
+ * @Field.Validators(IsString(), Length(1, 200), IsNotEmpty())
930
+ * title: string
931
+ * ```
932
+ */
933
+ Validators
934
+ };
935
+ function RequirePermission(options) {
936
+ return (target, propertyKey, descriptor) => {
937
+ common.SetMetadata(PERMISSION_METADATA_KEY, options)(target, propertyKey, descriptor);
938
+ return descriptor;
939
+ };
940
+ }
941
+ __name(RequirePermission, "RequirePermission");
942
+ function HasPermission(permission) {
943
+ return (target, propertyKey, descriptor) => {
944
+ const options = {
945
+ id: permission,
946
+ name: permission.split(".").pop() ?? permission,
947
+ description: `Requires ${permission} permission`
948
+ };
949
+ common.SetMetadata(PERMISSION_METADATA_KEY, options)(target, propertyKey, descriptor);
950
+ return descriptor;
951
+ };
952
+ }
953
+ __name(HasPermission, "HasPermission");
954
+ function PermissionMeta(options) {
955
+ return (target, propertyKey, descriptor) => {
956
+ common.SetMetadata(PERMISSION_OPTIONS_METADATA_KEY, options)(target, propertyKey, descriptor);
957
+ return descriptor;
958
+ };
959
+ }
960
+ __name(PermissionMeta, "PermissionMeta");
961
+ function getPermissionMetadata(target, propertyKey) {
962
+ return Reflect.getMetadata(PERMISSION_METADATA_KEY, target, propertyKey);
963
+ }
964
+ __name(getPermissionMetadata, "getPermissionMetadata");
965
+ function hasPermissionDecorator(target, propertyKey) {
966
+ return Reflect.hasMetadata(PERMISSION_METADATA_KEY, target, propertyKey);
967
+ }
968
+ __name(hasPermissionDecorator, "hasPermissionDecorator");
969
+
32
970
  // src/decorators/resolver/resolver.decorator.ts
33
971
  function Resolver(optionsOrFn) {
34
972
  return (target) => {
@@ -83,59 +1021,36 @@ function Resolve(optionsOrFn) {
83
1021
  };
84
1022
  }
85
1023
  __name(Resolve, "Resolve");
86
- var cachedAdapter = null;
87
- function isPackageInstalled(packageName) {
88
- try {
89
- return fs.existsSync(path.join(__require.resolve(packageName), "../../"));
90
- } catch {
91
- return false;
92
- }
93
- }
94
- __name(isPackageInstalled, "isPackageInstalled");
95
- function detectDatabaseAdapter(dbConfig) {
96
- if (dbConfig) {
97
- if ("connectionString" in dbConfig || "dialect" in dbConfig) {
98
- cachedAdapter = "drizzle";
99
- return cachedAdapter;
100
- }
101
- if ("uri" in dbConfig) {
102
- cachedAdapter = "mongoose";
103
- return cachedAdapter;
1024
+
1025
+ // src/decorators/schema/extend-user.decorator.ts
1026
+ function ExtendUser(options = {}) {
1027
+ const mergedOptions = {
1028
+ timestamps: true,
1029
+ ...options
1030
+ };
1031
+ return (target) => {
1032
+ Reflect.defineMetadata(EXTEND_USER_METADATA_KEY, mergedOptions, target);
1033
+ Reflect.defineMetadata(SCHEMA_METADATA_KEY, true, target);
1034
+ try {
1035
+ const adapter = detectDatabaseAdapter();
1036
+ const { Schema: Schema2 } = __require(`@magnet-cms/adapter-db-${adapter}`);
1037
+ Schema2({
1038
+ collection: "users",
1039
+ timestamps: mergedOptions.timestamps
1040
+ })(target);
1041
+ } catch {
104
1042
  }
105
- }
106
- if (cachedAdapter) return cachedAdapter;
107
- if (isPackageInstalled("@magnet-cms/adapter-mongoose")) {
108
- cachedAdapter = "mongoose";
109
- } else if (isPackageInstalled("@magnet-cms/adapter-drizzle")) {
110
- cachedAdapter = "drizzle";
111
- } else {
112
- throw new Error("\u274C No supported database adapter found. Install @magnet-cms/adapter-mongoose or @magnet-cms/adapter-drizzle.");
113
- }
114
- return cachedAdapter;
1043
+ };
115
1044
  }
116
- __name(detectDatabaseAdapter, "detectDatabaseAdapter");
117
- function setDatabaseAdapter(adapter) {
118
- cachedAdapter = adapter;
1045
+ __name(ExtendUser, "ExtendUser");
1046
+ function isUserExtension(target) {
1047
+ return Reflect.hasMetadata(EXTEND_USER_METADATA_KEY, target);
119
1048
  }
120
- __name(setDatabaseAdapter, "setDatabaseAdapter");
121
- function clearAdapterCache() {
122
- cachedAdapter = null;
1049
+ __name(isUserExtension, "isUserExtension");
1050
+ function getExtendUserOptions(target) {
1051
+ return Reflect.getMetadata(EXTEND_USER_METADATA_KEY, target);
123
1052
  }
124
- __name(clearAdapterCache, "clearAdapterCache");
125
-
126
- // src/utils/get-model-token.util.ts
127
- function getModelToken(schema) {
128
- return `Magnet${schema.name}Model`;
129
- }
130
- __name(getModelToken, "getModelToken");
131
-
132
- // src/utils/get-schema-token.util.ts
133
- var getSchemaToken = /* @__PURE__ */ __name((schema) => {
134
- return `${schema.name}Schema`;
135
- }, "getSchemaToken");
136
- var getSettingToken = /* @__PURE__ */ __name((setting) => {
137
- return `${setting.name}Setting`;
138
- }, "getSettingToken");
1053
+ __name(getExtendUserOptions, "getExtendUserOptions");
139
1054
 
140
1055
  // src/decorators/schema/prop.decorator.ts
141
1056
  function Prop(options) {
@@ -149,7 +1064,7 @@ function Prop(options) {
149
1064
  options
150
1065
  }
151
1066
  ], target);
152
- const { Prop: Prop2 } = __require(`@magnet-cms/adapter-${adapter}`);
1067
+ const { Prop: Prop2 } = __require(`@magnet-cms/adapter-db-${adapter}`);
153
1068
  return Prop2(options)(target, propertyKey);
154
1069
  };
155
1070
  }
@@ -158,7 +1073,8 @@ __name(Prop, "Prop");
158
1073
  // src/decorators/schema/schema.decorator.ts
159
1074
  var defaultSchemaOptions = {
160
1075
  versioning: true,
161
- i18n: true
1076
+ i18n: true,
1077
+ visible: true
162
1078
  };
163
1079
  function Schema(options = {}) {
164
1080
  return (target) => {
@@ -169,7 +1085,7 @@ function Schema(options = {}) {
169
1085
  };
170
1086
  Reflect.defineMetadata(SCHEMA_METADATA_KEY, true, target);
171
1087
  Reflect.defineMetadata(SCHEMA_OPTIONS_METADATA_KEY, mergedOptions, target);
172
- const { Schema: Schema2 } = __require(`@magnet-cms/adapter-${adapter}`);
1088
+ const { Schema: Schema2 } = __require(`@magnet-cms/adapter-db-${adapter}`);
173
1089
  return Schema2()(target);
174
1090
  };
175
1091
  }
@@ -187,6 +1103,81 @@ function Setting() {
187
1103
  }
188
1104
  __name(Setting, "Setting");
189
1105
 
1106
+ // src/decorators/schema/settings.decorator.ts
1107
+ function Settings(options) {
1108
+ return (target) => {
1109
+ Reflect.defineMetadata(SETTING_METADATA_KEY, true, target);
1110
+ Reflect.defineMetadata(SETTINGS_OPTIONS_METADATA_KEY, options, target);
1111
+ };
1112
+ }
1113
+ __name(Settings, "Settings");
1114
+ function getSettingsOptions(target) {
1115
+ return Reflect.getMetadata(SETTINGS_OPTIONS_METADATA_KEY, target);
1116
+ }
1117
+ __name(getSettingsOptions, "getSettingsOptions");
1118
+ function getSettingFields(target) {
1119
+ return Reflect.getMetadata(SETTING_FIELD_METADATA_KEY, target) ?? [];
1120
+ }
1121
+ __name(getSettingFields, "getSettingFields");
1122
+ function createSettingFieldDecorator(type, defaultOptions = {}) {
1123
+ return (options) => {
1124
+ const mergedOptions = {
1125
+ ...defaultOptions,
1126
+ ...options
1127
+ };
1128
+ return (target, propertyKey) => {
1129
+ const metadata = {
1130
+ type,
1131
+ options: mergedOptions,
1132
+ propertyKey
1133
+ };
1134
+ const existingFields = Reflect.getMetadata(SETTING_FIELD_METADATA_KEY, target.constructor) ?? [];
1135
+ const filteredFields = existingFields.filter((f) => f.propertyKey !== propertyKey);
1136
+ Reflect.defineMetadata(SETTING_FIELD_METADATA_KEY, [
1137
+ ...filteredFields,
1138
+ metadata
1139
+ ], target.constructor);
1140
+ };
1141
+ };
1142
+ }
1143
+ __name(createSettingFieldDecorator, "createSettingFieldDecorator");
1144
+ var SettingField = {
1145
+ /**
1146
+ * Text setting field
1147
+ */
1148
+ Text: createSettingFieldDecorator("text"),
1149
+ /**
1150
+ * Number setting field
1151
+ */
1152
+ Number: createSettingFieldDecorator("number"),
1153
+ /**
1154
+ * Boolean setting field (toggle/switch)
1155
+ */
1156
+ Boolean: createSettingFieldDecorator("boolean"),
1157
+ /**
1158
+ * Select setting field (dropdown)
1159
+ */
1160
+ Select: createSettingFieldDecorator("select"),
1161
+ /**
1162
+ * Secret setting field (encrypted, masked in UI)
1163
+ */
1164
+ Secret: createSettingFieldDecorator("secret", {
1165
+ masked: true
1166
+ }),
1167
+ /**
1168
+ * Image setting field
1169
+ */
1170
+ Image: createSettingFieldDecorator("image"),
1171
+ /**
1172
+ * JSON setting field
1173
+ */
1174
+ JSON: createSettingFieldDecorator("json"),
1175
+ /**
1176
+ * Textarea setting field (multi-line text)
1177
+ */
1178
+ Textarea: createSettingFieldDecorator("textarea")
1179
+ };
1180
+
190
1181
  // src/decorators/schema/ui.decorator.ts
191
1182
  function UI(options) {
192
1183
  return (target, propertyKey) => {
@@ -205,9 +1196,6 @@ function UI(options) {
205
1196
  };
206
1197
  }
207
1198
  __name(UI, "UI");
208
- var Validators = /* @__PURE__ */ __name((...validators) => {
209
- return common.applyDecorators(...validators);
210
- }, "Validators");
211
1199
 
212
1200
  // src/decorators/schema/version.decorator.ts
213
1201
  var VERSION_METADATA_KEY = "version:metadata";
@@ -225,12 +1213,643 @@ function InjectModel(model) {
225
1213
  if (propertyKey !== void 0) {
226
1214
  Reflect.defineMetadata(INJECT_MODEL, model, target, propertyKey);
227
1215
  }
228
- const { InjectModel: InjectModel2 } = __require(`@magnet-cms/adapter-${adapter}`);
1216
+ const { InjectModel: InjectModel2 } = __require(`@magnet-cms/adapter-db-${adapter}`);
229
1217
  return InjectModel2(model)(target, propertyKey, parameterIndex);
230
1218
  };
231
1219
  }
232
1220
  __name(InjectModel, "InjectModel");
233
1221
 
1222
+ // src/errors/base.error.ts
1223
+ var ErrorCode = /* @__PURE__ */ function(ErrorCode2) {
1224
+ ErrorCode2[ErrorCode2["VALIDATION_FAILED"] = 1e3] = "VALIDATION_FAILED";
1225
+ ErrorCode2[ErrorCode2["REQUIRED_FIELD_MISSING"] = 1001] = "REQUIRED_FIELD_MISSING";
1226
+ ErrorCode2[ErrorCode2["INVALID_FORMAT"] = 1002] = "INVALID_FORMAT";
1227
+ ErrorCode2[ErrorCode2["VALUE_OUT_OF_RANGE"] = 1003] = "VALUE_OUT_OF_RANGE";
1228
+ ErrorCode2[ErrorCode2["UNIQUE_CONSTRAINT_VIOLATION"] = 1004] = "UNIQUE_CONSTRAINT_VIOLATION";
1229
+ ErrorCode2[ErrorCode2["AUTHENTICATION_REQUIRED"] = 2e3] = "AUTHENTICATION_REQUIRED";
1230
+ ErrorCode2[ErrorCode2["INVALID_CREDENTIALS"] = 2001] = "INVALID_CREDENTIALS";
1231
+ ErrorCode2[ErrorCode2["TOKEN_EXPIRED"] = 2002] = "TOKEN_EXPIRED";
1232
+ ErrorCode2[ErrorCode2["TOKEN_INVALID"] = 2003] = "TOKEN_INVALID";
1233
+ ErrorCode2[ErrorCode2["ACCOUNT_LOCKED"] = 2004] = "ACCOUNT_LOCKED";
1234
+ ErrorCode2[ErrorCode2["EMAIL_NOT_VERIFIED"] = 2005] = "EMAIL_NOT_VERIFIED";
1235
+ ErrorCode2[ErrorCode2["PERMISSION_DENIED"] = 3e3] = "PERMISSION_DENIED";
1236
+ ErrorCode2[ErrorCode2["INSUFFICIENT_PERMISSIONS"] = 3001] = "INSUFFICIENT_PERMISSIONS";
1237
+ ErrorCode2[ErrorCode2["ROLE_NOT_FOUND"] = 3002] = "ROLE_NOT_FOUND";
1238
+ ErrorCode2[ErrorCode2["PERMISSION_NOT_FOUND"] = 3003] = "PERMISSION_NOT_FOUND";
1239
+ ErrorCode2[ErrorCode2["RESOURCE_NOT_FOUND"] = 4e3] = "RESOURCE_NOT_FOUND";
1240
+ ErrorCode2[ErrorCode2["SCHEMA_NOT_FOUND"] = 4001] = "SCHEMA_NOT_FOUND";
1241
+ ErrorCode2[ErrorCode2["DOCUMENT_NOT_FOUND"] = 4002] = "DOCUMENT_NOT_FOUND";
1242
+ ErrorCode2[ErrorCode2["USER_NOT_FOUND"] = 4003] = "USER_NOT_FOUND";
1243
+ ErrorCode2[ErrorCode2["FILE_NOT_FOUND"] = 4004] = "FILE_NOT_FOUND";
1244
+ ErrorCode2[ErrorCode2["VERSION_NOT_FOUND"] = 4005] = "VERSION_NOT_FOUND";
1245
+ ErrorCode2[ErrorCode2["DATABASE_ERROR"] = 5e3] = "DATABASE_ERROR";
1246
+ ErrorCode2[ErrorCode2["CONNECTION_FAILED"] = 5001] = "CONNECTION_FAILED";
1247
+ ErrorCode2[ErrorCode2["QUERY_FAILED"] = 5002] = "QUERY_FAILED";
1248
+ ErrorCode2[ErrorCode2["TRANSACTION_FAILED"] = 5003] = "TRANSACTION_FAILED";
1249
+ ErrorCode2[ErrorCode2["DUPLICATE_KEY"] = 5004] = "DUPLICATE_KEY";
1250
+ ErrorCode2[ErrorCode2["PLUGIN_ERROR"] = 6e3] = "PLUGIN_ERROR";
1251
+ ErrorCode2[ErrorCode2["PLUGIN_NOT_FOUND"] = 6001] = "PLUGIN_NOT_FOUND";
1252
+ ErrorCode2[ErrorCode2["PLUGIN_INITIALIZATION_FAILED"] = 6002] = "PLUGIN_INITIALIZATION_FAILED";
1253
+ ErrorCode2[ErrorCode2["HOOK_EXECUTION_FAILED"] = 6003] = "HOOK_EXECUTION_FAILED";
1254
+ ErrorCode2[ErrorCode2["EXTERNAL_SERVICE_ERROR"] = 7e3] = "EXTERNAL_SERVICE_ERROR";
1255
+ ErrorCode2[ErrorCode2["STORAGE_ERROR"] = 7001] = "STORAGE_ERROR";
1256
+ ErrorCode2[ErrorCode2["EMAIL_SERVICE_ERROR"] = 7002] = "EMAIL_SERVICE_ERROR";
1257
+ ErrorCode2[ErrorCode2["WEBHOOK_DELIVERY_FAILED"] = 7003] = "WEBHOOK_DELIVERY_FAILED";
1258
+ ErrorCode2[ErrorCode2["INTERNAL_ERROR"] = 9e3] = "INTERNAL_ERROR";
1259
+ ErrorCode2[ErrorCode2["CONFIGURATION_ERROR"] = 9001] = "CONFIGURATION_ERROR";
1260
+ ErrorCode2[ErrorCode2["UNEXPECTED_ERROR"] = 9999] = "UNEXPECTED_ERROR";
1261
+ return ErrorCode2;
1262
+ }({});
1263
+ var MagnetError = class extends Error {
1264
+ static {
1265
+ __name(this, "MagnetError");
1266
+ }
1267
+ timestamp;
1268
+ metadata;
1269
+ constructor(message, metadata = {}) {
1270
+ super(message);
1271
+ this.name = this.constructor.name;
1272
+ this.timestamp = /* @__PURE__ */ new Date();
1273
+ this.metadata = metadata;
1274
+ if (Error.captureStackTrace) {
1275
+ Error.captureStackTrace(this, this.constructor);
1276
+ }
1277
+ }
1278
+ /**
1279
+ * Convert to API response format
1280
+ */
1281
+ toResponse() {
1282
+ return {
1283
+ error: {
1284
+ code: this.code,
1285
+ message: this.message,
1286
+ name: this.name,
1287
+ timestamp: this.timestamp.toISOString(),
1288
+ metadata: this.metadata
1289
+ }
1290
+ };
1291
+ }
1292
+ /**
1293
+ * Convert to JSON for logging
1294
+ */
1295
+ toJSON() {
1296
+ return {
1297
+ name: this.name,
1298
+ code: this.code,
1299
+ message: this.message,
1300
+ httpStatus: this.httpStatus,
1301
+ timestamp: this.timestamp.toISOString(),
1302
+ metadata: this.metadata,
1303
+ stack: this.stack
1304
+ };
1305
+ }
1306
+ };
1307
+
1308
+ // src/errors/validation.error.ts
1309
+ var ValidationError = class _ValidationError extends MagnetError {
1310
+ static {
1311
+ __name(this, "ValidationError");
1312
+ }
1313
+ code = ErrorCode.VALIDATION_FAILED;
1314
+ httpStatus = 400;
1315
+ details;
1316
+ constructor(message, details, metadata) {
1317
+ super(message, metadata);
1318
+ this.details = details;
1319
+ }
1320
+ /**
1321
+ * Create ValidationError from class-validator errors
1322
+ */
1323
+ static fromClassValidator(errors) {
1324
+ const details = errors.flatMap((error) => Object.entries(error.constraints ?? {}).map(([constraint, message]) => ({
1325
+ field: error.property,
1326
+ message,
1327
+ constraint,
1328
+ value: error.value
1329
+ })));
1330
+ return new _ValidationError(`Validation failed for ${details.length} field(s)`, details);
1331
+ }
1332
+ toResponse() {
1333
+ return {
1334
+ error: {
1335
+ ...super.toResponse().error,
1336
+ details: this.details
1337
+ }
1338
+ };
1339
+ }
1340
+ };
1341
+ var RequiredFieldError = class extends MagnetError {
1342
+ static {
1343
+ __name(this, "RequiredFieldError");
1344
+ }
1345
+ code = ErrorCode.REQUIRED_FIELD_MISSING;
1346
+ httpStatus = 400;
1347
+ constructor(field, metadata) {
1348
+ super(`Required field '${field}' is missing`, {
1349
+ ...metadata,
1350
+ field
1351
+ });
1352
+ }
1353
+ };
1354
+ var InvalidFormatError = class extends MagnetError {
1355
+ static {
1356
+ __name(this, "InvalidFormatError");
1357
+ }
1358
+ code = ErrorCode.INVALID_FORMAT;
1359
+ httpStatus = 400;
1360
+ constructor(field, expectedFormat, metadata) {
1361
+ super(`Field '${field}' has invalid format. Expected: ${expectedFormat}`, {
1362
+ ...metadata,
1363
+ field
1364
+ });
1365
+ }
1366
+ };
1367
+ var ValueOutOfRangeError = class extends MagnetError {
1368
+ static {
1369
+ __name(this, "ValueOutOfRangeError");
1370
+ }
1371
+ code = ErrorCode.VALUE_OUT_OF_RANGE;
1372
+ httpStatus = 400;
1373
+ constructor(field, min, max, metadata) {
1374
+ const rangeMsg = min !== void 0 && max !== void 0 ? `between ${min} and ${max}` : min !== void 0 ? `at least ${min}` : max !== void 0 ? `at most ${max}` : "within valid range";
1375
+ super(`Field '${field}' must be ${rangeMsg}`, {
1376
+ ...metadata,
1377
+ field
1378
+ });
1379
+ }
1380
+ };
1381
+
1382
+ // src/errors/auth.error.ts
1383
+ var AuthenticationRequiredError = class extends MagnetError {
1384
+ static {
1385
+ __name(this, "AuthenticationRequiredError");
1386
+ }
1387
+ code = ErrorCode.AUTHENTICATION_REQUIRED;
1388
+ httpStatus = 401;
1389
+ constructor(message = "Authentication required", metadata) {
1390
+ super(message, metadata);
1391
+ }
1392
+ };
1393
+ var InvalidCredentialsError = class extends MagnetError {
1394
+ static {
1395
+ __name(this, "InvalidCredentialsError");
1396
+ }
1397
+ code = ErrorCode.INVALID_CREDENTIALS;
1398
+ httpStatus = 401;
1399
+ constructor(message = "Invalid email or password", metadata) {
1400
+ super(message, metadata);
1401
+ }
1402
+ };
1403
+ var TokenExpiredError = class extends MagnetError {
1404
+ static {
1405
+ __name(this, "TokenExpiredError");
1406
+ }
1407
+ code = ErrorCode.TOKEN_EXPIRED;
1408
+ httpStatus = 401;
1409
+ constructor(message = "Token has expired", metadata) {
1410
+ super(message, metadata);
1411
+ }
1412
+ };
1413
+ var TokenInvalidError = class extends MagnetError {
1414
+ static {
1415
+ __name(this, "TokenInvalidError");
1416
+ }
1417
+ code = ErrorCode.TOKEN_INVALID;
1418
+ httpStatus = 401;
1419
+ constructor(message = "Token is invalid", metadata) {
1420
+ super(message, metadata);
1421
+ }
1422
+ };
1423
+ var AccountLockedError = class extends MagnetError {
1424
+ static {
1425
+ __name(this, "AccountLockedError");
1426
+ }
1427
+ code = ErrorCode.ACCOUNT_LOCKED;
1428
+ httpStatus = 423;
1429
+ unlockAt;
1430
+ constructor(message = "Account is temporarily locked", unlockAt, metadata) {
1431
+ super(message, metadata);
1432
+ this.unlockAt = unlockAt;
1433
+ }
1434
+ };
1435
+ var EmailNotVerifiedError = class extends MagnetError {
1436
+ static {
1437
+ __name(this, "EmailNotVerifiedError");
1438
+ }
1439
+ code = ErrorCode.EMAIL_NOT_VERIFIED;
1440
+ httpStatus = 403;
1441
+ constructor(message = "Email address not verified", metadata) {
1442
+ super(message, metadata);
1443
+ }
1444
+ };
1445
+ var PermissionDeniedError = class extends MagnetError {
1446
+ static {
1447
+ __name(this, "PermissionDeniedError");
1448
+ }
1449
+ code = ErrorCode.PERMISSION_DENIED;
1450
+ httpStatus = 403;
1451
+ requiredPermission;
1452
+ constructor(message = "You do not have permission to perform this action", requiredPermission, metadata) {
1453
+ super(message, metadata);
1454
+ this.requiredPermission = requiredPermission;
1455
+ }
1456
+ };
1457
+ var InsufficientPermissionsError = class extends MagnetError {
1458
+ static {
1459
+ __name(this, "InsufficientPermissionsError");
1460
+ }
1461
+ code = ErrorCode.INSUFFICIENT_PERMISSIONS;
1462
+ httpStatus = 403;
1463
+ requiredPermissions;
1464
+ constructor(requiredPermissions, metadata) {
1465
+ super(`Insufficient permissions. Required: ${requiredPermissions.join(", ")}`, metadata);
1466
+ this.requiredPermissions = requiredPermissions;
1467
+ }
1468
+ };
1469
+ var RoleNotFoundError = class extends MagnetError {
1470
+ static {
1471
+ __name(this, "RoleNotFoundError");
1472
+ }
1473
+ code = ErrorCode.ROLE_NOT_FOUND;
1474
+ httpStatus = 404;
1475
+ constructor(roleName, metadata) {
1476
+ super(`Role '${roleName}' not found`, metadata);
1477
+ }
1478
+ };
1479
+ var PermissionNotFoundError = class extends MagnetError {
1480
+ static {
1481
+ __name(this, "PermissionNotFoundError");
1482
+ }
1483
+ code = ErrorCode.PERMISSION_NOT_FOUND;
1484
+ httpStatus = 400;
1485
+ invalidPermissionIds;
1486
+ constructor(invalidPermissionIds, metadata) {
1487
+ super(`Invalid permission(s): ${invalidPermissionIds.join(", ")}. These permissions are not registered in the system.`, {
1488
+ ...metadata,
1489
+ context: {
1490
+ ...metadata?.context,
1491
+ invalidPermissionIds
1492
+ }
1493
+ });
1494
+ this.invalidPermissionIds = invalidPermissionIds;
1495
+ }
1496
+ };
1497
+
1498
+ // src/errors/resource.error.ts
1499
+ var ResourceNotFoundError = class extends MagnetError {
1500
+ static {
1501
+ __name(this, "ResourceNotFoundError");
1502
+ }
1503
+ code = ErrorCode.RESOURCE_NOT_FOUND;
1504
+ httpStatus = 404;
1505
+ constructor(resourceType, identifier, metadata) {
1506
+ super(`${resourceType} with identifier '${identifier}' not found`, {
1507
+ ...metadata,
1508
+ resourceId: identifier
1509
+ });
1510
+ }
1511
+ };
1512
+ var SchemaNotFoundError = class extends MagnetError {
1513
+ static {
1514
+ __name(this, "SchemaNotFoundError");
1515
+ }
1516
+ code = ErrorCode.SCHEMA_NOT_FOUND;
1517
+ httpStatus = 404;
1518
+ constructor(schemaName, metadata) {
1519
+ super(`Schema '${schemaName}' not found`, {
1520
+ ...metadata,
1521
+ schema: schemaName
1522
+ });
1523
+ }
1524
+ };
1525
+ var DocumentNotFoundError = class extends MagnetError {
1526
+ static {
1527
+ __name(this, "DocumentNotFoundError");
1528
+ }
1529
+ code = ErrorCode.DOCUMENT_NOT_FOUND;
1530
+ httpStatus = 404;
1531
+ constructor(schema, id, metadata) {
1532
+ super(`Document '${id}' not found in ${schema}`, {
1533
+ ...metadata,
1534
+ schema,
1535
+ resourceId: id
1536
+ });
1537
+ }
1538
+ };
1539
+ var UserNotFoundError = class extends MagnetError {
1540
+ static {
1541
+ __name(this, "UserNotFoundError");
1542
+ }
1543
+ code = ErrorCode.USER_NOT_FOUND;
1544
+ httpStatus = 404;
1545
+ constructor(identifier, metadata) {
1546
+ super(`User '${identifier}' not found`, {
1547
+ ...metadata,
1548
+ resourceId: identifier
1549
+ });
1550
+ }
1551
+ };
1552
+ var FileNotFoundError = class extends MagnetError {
1553
+ static {
1554
+ __name(this, "FileNotFoundError");
1555
+ }
1556
+ code = ErrorCode.FILE_NOT_FOUND;
1557
+ httpStatus = 404;
1558
+ constructor(path, metadata) {
1559
+ super(`File '${path}' not found`, {
1560
+ ...metadata,
1561
+ resourceId: path
1562
+ });
1563
+ }
1564
+ };
1565
+ var VersionNotFoundError = class extends MagnetError {
1566
+ static {
1567
+ __name(this, "VersionNotFoundError");
1568
+ }
1569
+ code = ErrorCode.VERSION_NOT_FOUND;
1570
+ httpStatus = 404;
1571
+ constructor(schema, documentId, versionId, metadata) {
1572
+ super(`Version '${versionId}' not found for document '${documentId}' in ${schema}`, {
1573
+ ...metadata,
1574
+ schema,
1575
+ resourceId: documentId,
1576
+ context: {
1577
+ versionId
1578
+ }
1579
+ });
1580
+ }
1581
+ };
1582
+
1583
+ // src/errors/database.error.ts
1584
+ var DatabaseError = class extends MagnetError {
1585
+ static {
1586
+ __name(this, "DatabaseError");
1587
+ }
1588
+ code = ErrorCode.DATABASE_ERROR;
1589
+ httpStatus = 500;
1590
+ originalError;
1591
+ constructor(message, originalError, metadata) {
1592
+ super(message, metadata);
1593
+ this.originalError = originalError;
1594
+ }
1595
+ };
1596
+ var ConnectionFailedError = class extends MagnetError {
1597
+ static {
1598
+ __name(this, "ConnectionFailedError");
1599
+ }
1600
+ code = ErrorCode.CONNECTION_FAILED;
1601
+ httpStatus = 503;
1602
+ constructor(message = "Database connection failed", metadata) {
1603
+ super(message, metadata);
1604
+ }
1605
+ };
1606
+ var QueryFailedError = class extends MagnetError {
1607
+ static {
1608
+ __name(this, "QueryFailedError");
1609
+ }
1610
+ code = ErrorCode.QUERY_FAILED;
1611
+ httpStatus = 500;
1612
+ query;
1613
+ constructor(message, query, metadata) {
1614
+ super(message, metadata);
1615
+ this.query = query;
1616
+ }
1617
+ };
1618
+ var TransactionFailedError = class extends MagnetError {
1619
+ static {
1620
+ __name(this, "TransactionFailedError");
1621
+ }
1622
+ code = ErrorCode.TRANSACTION_FAILED;
1623
+ httpStatus = 500;
1624
+ constructor(message = "Transaction failed", metadata) {
1625
+ super(message, metadata);
1626
+ }
1627
+ };
1628
+ var DuplicateKeyError = class extends MagnetError {
1629
+ static {
1630
+ __name(this, "DuplicateKeyError");
1631
+ }
1632
+ code = ErrorCode.DUPLICATE_KEY;
1633
+ httpStatus = 409;
1634
+ constructor(field, value, metadata) {
1635
+ super(`A record with ${field} '${String(value)}' already exists`, {
1636
+ ...metadata,
1637
+ field
1638
+ });
1639
+ }
1640
+ };
1641
+
1642
+ // src/errors/plugin.error.ts
1643
+ var PluginError = class extends MagnetError {
1644
+ static {
1645
+ __name(this, "PluginError");
1646
+ }
1647
+ code = ErrorCode.PLUGIN_ERROR;
1648
+ httpStatus = 500;
1649
+ constructor(pluginName, message, metadata) {
1650
+ super(`Plugin '${pluginName}': ${message}`, metadata);
1651
+ }
1652
+ };
1653
+ var PluginNotFoundError = class extends MagnetError {
1654
+ static {
1655
+ __name(this, "PluginNotFoundError");
1656
+ }
1657
+ code = ErrorCode.PLUGIN_NOT_FOUND;
1658
+ httpStatus = 404;
1659
+ constructor(pluginName, metadata) {
1660
+ super(`Plugin '${pluginName}' not found`, metadata);
1661
+ }
1662
+ };
1663
+ var PluginInitializationError = class extends MagnetError {
1664
+ static {
1665
+ __name(this, "PluginInitializationError");
1666
+ }
1667
+ code = ErrorCode.PLUGIN_INITIALIZATION_FAILED;
1668
+ httpStatus = 500;
1669
+ constructor(pluginName, reason, metadata) {
1670
+ super(`Failed to initialize plugin '${pluginName}': ${reason}`, metadata);
1671
+ }
1672
+ };
1673
+ var HookExecutionError = class extends MagnetError {
1674
+ static {
1675
+ __name(this, "HookExecutionError");
1676
+ }
1677
+ code = ErrorCode.HOOK_EXECUTION_FAILED;
1678
+ httpStatus = 500;
1679
+ constructor(hookName, pluginName, reason, metadata) {
1680
+ super(`Hook '${hookName}' in plugin '${pluginName}' failed: ${reason}`, metadata);
1681
+ }
1682
+ };
1683
+
1684
+ // src/errors/external.error.ts
1685
+ var ExternalServiceError = class extends MagnetError {
1686
+ static {
1687
+ __name(this, "ExternalServiceError");
1688
+ }
1689
+ code = ErrorCode.EXTERNAL_SERVICE_ERROR;
1690
+ httpStatus = 502;
1691
+ constructor(serviceName, message, metadata) {
1692
+ super(`External service '${serviceName}' error: ${message}`, metadata);
1693
+ }
1694
+ };
1695
+ var StorageError = class extends MagnetError {
1696
+ static {
1697
+ __name(this, "StorageError");
1698
+ }
1699
+ code = ErrorCode.STORAGE_ERROR;
1700
+ httpStatus = 502;
1701
+ constructor(message, metadata) {
1702
+ super(`Storage error: ${message}`, metadata);
1703
+ }
1704
+ };
1705
+ var EmailServiceError = class extends MagnetError {
1706
+ static {
1707
+ __name(this, "EmailServiceError");
1708
+ }
1709
+ code = ErrorCode.EMAIL_SERVICE_ERROR;
1710
+ httpStatus = 502;
1711
+ constructor(message, metadata) {
1712
+ super(`Email service error: ${message}`, metadata);
1713
+ }
1714
+ };
1715
+ var WebhookDeliveryError = class extends MagnetError {
1716
+ static {
1717
+ __name(this, "WebhookDeliveryError");
1718
+ }
1719
+ code = ErrorCode.WEBHOOK_DELIVERY_FAILED;
1720
+ httpStatus = 502;
1721
+ webhookUrl;
1722
+ statusCode;
1723
+ constructor(webhookUrl, reason, statusCode, metadata) {
1724
+ super(`Webhook delivery to '${webhookUrl}' failed: ${reason}`, metadata);
1725
+ this.webhookUrl = webhookUrl;
1726
+ this.statusCode = statusCode;
1727
+ }
1728
+ };
1729
+
1730
+ // src/errors/internal.error.ts
1731
+ var InternalError = class extends MagnetError {
1732
+ static {
1733
+ __name(this, "InternalError");
1734
+ }
1735
+ code = ErrorCode.INTERNAL_ERROR;
1736
+ httpStatus = 500;
1737
+ constructor(message = "An internal error occurred", metadata) {
1738
+ super(message, metadata);
1739
+ }
1740
+ };
1741
+ var ConfigurationError = class extends MagnetError {
1742
+ static {
1743
+ __name(this, "ConfigurationError");
1744
+ }
1745
+ code = ErrorCode.CONFIGURATION_ERROR;
1746
+ httpStatus = 500;
1747
+ constructor(message, metadata) {
1748
+ super(`Configuration error: ${message}`, metadata);
1749
+ }
1750
+ };
1751
+ var UnexpectedError = class extends MagnetError {
1752
+ static {
1753
+ __name(this, "UnexpectedError");
1754
+ }
1755
+ code = ErrorCode.UNEXPECTED_ERROR;
1756
+ httpStatus = 500;
1757
+ originalError;
1758
+ constructor(message = "An unexpected error occurred", originalError, metadata) {
1759
+ super(message, metadata);
1760
+ this.originalError = originalError;
1761
+ }
1762
+ };
1763
+
1764
+ // src/errors/factory.ts
1765
+ function fromMongooseError(error, context) {
1766
+ if (isCastError(error) && error.path === "_id") {
1767
+ return new DocumentNotFoundError(context?.schema ?? "document", String(error.value), {
1768
+ operation: context?.operation
1769
+ });
1770
+ }
1771
+ if (isDuplicateKeyError(error)) {
1772
+ const keyValue = error.keyValue;
1773
+ const field = Object.keys(keyValue)[0] ?? "field";
1774
+ const value = keyValue[field];
1775
+ return new DuplicateKeyError(field, value, {
1776
+ schema: context?.schema
1777
+ });
1778
+ }
1779
+ if (isValidationError(error)) {
1780
+ const details = Object.entries(error.errors).map(([field, err]) => {
1781
+ const errorObj = err;
1782
+ return {
1783
+ field,
1784
+ message: String(errorObj.message ?? "Validation failed")
1785
+ };
1786
+ });
1787
+ return new ValidationError("Validation failed", details, {
1788
+ schema: context?.schema
1789
+ });
1790
+ }
1791
+ return new DatabaseError(error instanceof Error ? error.message : "Database operation failed", error, {
1792
+ schema: context?.schema
1793
+ });
1794
+ }
1795
+ __name(fromMongooseError, "fromMongooseError");
1796
+ function extractPostgresUniqueInfo(error) {
1797
+ if (!error.detail) {
1798
+ return null;
1799
+ }
1800
+ const match = error.detail.match(/Key \((\w+)\)=\(([^)]+)\)/);
1801
+ const field = match?.[1];
1802
+ const value = match?.[2];
1803
+ if (field && value) {
1804
+ return {
1805
+ field,
1806
+ value
1807
+ };
1808
+ }
1809
+ return null;
1810
+ }
1811
+ __name(extractPostgresUniqueInfo, "extractPostgresUniqueInfo");
1812
+ function fromDrizzleError(error, context) {
1813
+ if (isPostgresUniqueError(error)) {
1814
+ const info = extractPostgresUniqueInfo(error);
1815
+ if (info) {
1816
+ return new DuplicateKeyError(info.field, info.value, {
1817
+ schema: context?.schema
1818
+ });
1819
+ }
1820
+ }
1821
+ if (error instanceof Error && error.message.includes("unique constraint")) {
1822
+ const match = error.message.match(/Key \((\w+)\)=\(([^)]+)\)/);
1823
+ const field = match?.[1];
1824
+ const value = match?.[2];
1825
+ if (field && value) {
1826
+ return new DuplicateKeyError(field, value, {
1827
+ schema: context?.schema
1828
+ });
1829
+ }
1830
+ }
1831
+ if (error instanceof Error && error.message.includes("no result")) {
1832
+ return new DocumentNotFoundError(context?.schema ?? "document", "unknown", {
1833
+ operation: "read"
1834
+ });
1835
+ }
1836
+ return new DatabaseError(error instanceof Error ? error.message : "Database operation failed", error, {
1837
+ schema: context?.schema
1838
+ });
1839
+ }
1840
+ __name(fromDrizzleError, "fromDrizzleError");
1841
+ function isMagnetError(error) {
1842
+ return error instanceof MagnetError;
1843
+ }
1844
+ __name(isMagnetError, "isMagnetError");
1845
+ function wrapError(error, fallbackMessage = "An error occurred") {
1846
+ if (isMagnetError(error)) {
1847
+ return error;
1848
+ }
1849
+ return new DatabaseError(error instanceof Error ? error.message : fallbackMessage, error);
1850
+ }
1851
+ __name(wrapError, "wrapError");
1852
+
234
1853
  // src/exceptions/validation.exception.ts
235
1854
  var ValidationException = class extends Error {
236
1855
  static {
@@ -248,13 +1867,35 @@ var Model = class {
248
1867
  __name(this, "Model");
249
1868
  }
250
1869
  /**
1870
+ * Get current locale
1871
+ */
1872
+ getLocale() {
1873
+ return "en";
1874
+ }
1875
+ /**
251
1876
  * Set the version for subsequent operations
252
1877
  * @param versionId The version ID or status ('draft', 'published', 'archived')
1878
+ * @returns Same instance (chainable)
253
1879
  */
254
1880
  version(versionId) {
255
1881
  return this;
256
1882
  }
257
1883
  /**
1884
+ * Check if versioning is enabled for this model
1885
+ */
1886
+ isVersioningEnabled() {
1887
+ return false;
1888
+ }
1889
+ /**
1890
+ * Create a version snapshot of a document
1891
+ * @param documentId The document ID
1892
+ * @param data The data to version
1893
+ * @returns Version record or null if versioning disabled
1894
+ */
1895
+ createVersion(documentId, data) {
1896
+ return Promise.resolve(null);
1897
+ }
1898
+ /**
258
1899
  * Find all versions of a document
259
1900
  * @param documentId The document ID
260
1901
  */
@@ -269,12 +1910,13 @@ var Model = class {
269
1910
  return Promise.resolve(null);
270
1911
  }
271
1912
  /**
272
- * Restore a version
1913
+ * Restore a document to a specific version
273
1914
  * @param versionId The version ID to restore
274
1915
  */
275
1916
  restoreVersion(versionId) {
276
1917
  return Promise.resolve(null);
277
1918
  }
1919
+ // ============= Query Builder =============
278
1920
  /**
279
1921
  * Create a query builder for advanced queries with sorting, pagination, and operators.
280
1922
  * The query builder inherits the current locale/version context.
@@ -291,15 +1933,29 @@ var Model = class {
291
1933
  query() {
292
1934
  throw new Error("QueryBuilder not implemented by this adapter");
293
1935
  }
1936
+ // ============= Native Access =============
294
1937
  /**
295
1938
  * Get access to the native database model/collection.
296
1939
  * Use with caution - bypasses Magnet abstractions like locale and versioning.
297
1940
  *
298
- * @returns The underlying database model (e.g., Mongoose Model)
1941
+ * @returns Typed native access object
299
1942
  */
300
1943
  native() {
301
1944
  throw new Error("Native access not implemented by this adapter");
302
1945
  }
1946
+ // ============= Metadata =============
1947
+ /**
1948
+ * Get schema name
1949
+ */
1950
+ getSchemaName() {
1951
+ throw new Error("getSchemaName not implemented by this adapter");
1952
+ }
1953
+ /**
1954
+ * Get schema metadata
1955
+ */
1956
+ getMetadata() {
1957
+ throw new Error("getMetadata not implemented by this adapter");
1958
+ }
303
1959
  };
304
1960
 
305
1961
  // src/model/mixed.model.ts
@@ -316,6 +1972,17 @@ var QueryBuilder = class {
316
1972
  static {
317
1973
  __name(this, "QueryBuilder");
318
1974
  }
1975
+ /**
1976
+ * Exclude specific fields from results
1977
+ * @param fields Array of field names to exclude
1978
+ */
1979
+ exclude(fields) {
1980
+ const projection = {};
1981
+ for (const field of fields) {
1982
+ projection[field] = 0;
1983
+ }
1984
+ return this.select(projection);
1985
+ }
319
1986
  };
320
1987
 
321
1988
  // src/types/auth.types.ts
@@ -332,6 +1999,13 @@ var AuthStrategy = class {
332
1999
  }
333
2000
  };
334
2001
 
2002
+ // src/types/email.types.ts
2003
+ var EmailAdapter = class {
2004
+ static {
2005
+ __name(this, "EmailAdapter");
2006
+ }
2007
+ };
2008
+
335
2009
  // src/types/config.types.ts
336
2010
  var MagnetModuleOptions = class {
337
2011
  static {
@@ -347,17 +2021,54 @@ var MagnetModuleOptions = class {
347
2021
  playground;
348
2022
  storage;
349
2023
  /**
2024
+ * Email adapter configuration
2025
+ * @example
2026
+ * email: { adapter: 'nodemailer', nodemailer: { host: 'smtp.example.com', port: 587, auth: { user: 'user', pass: 'pass' } } }
2027
+ */
2028
+ email;
2029
+ /**
350
2030
  * Plugins to load with the Magnet module
351
2031
  */
352
2032
  plugins;
353
- constructor({ db, jwt, auth, internationalization, playground, storage, plugins }) {
2033
+ /**
2034
+ * Admin panel configuration (enabled by default when omitted).
2035
+ * @example
2036
+ * // Explicit enable (same as omitting `admin`)
2037
+ * admin: true
2038
+ *
2039
+ * // Custom path
2040
+ * admin: { enabled: true, path: '/dashboard' }
2041
+ *
2042
+ * // Disable (for API-only mode)
2043
+ * admin: false
2044
+ */
2045
+ admin;
2046
+ /**
2047
+ * RBAC (Role-Based Access Control) configuration
2048
+ * @example
2049
+ * rbac: { enabled: true, defaultRole: 'authenticated' }
2050
+ */
2051
+ rbac;
2052
+ /**
2053
+ * Vault configuration for encrypted secrets management.
2054
+ * Uses the built-in DB adapter by default (requires VAULT_MASTER_KEY env var).
2055
+ * @example
2056
+ * vault: { adapter: 'db' }
2057
+ * vault: { adapter: 'hashicorp', hashicorp: { url: 'https://vault.example.com:8200' } }
2058
+ */
2059
+ vault;
2060
+ constructor({ db, jwt, auth, internationalization, playground, storage, email, plugins, admin, rbac, vault }) {
354
2061
  this.db = db;
355
2062
  this.jwt = jwt;
356
2063
  this.auth = auth;
357
2064
  this.internationalization = internationalization;
358
2065
  this.playground = playground;
359
2066
  this.storage = storage;
2067
+ this.email = email;
360
2068
  this.plugins = plugins;
2069
+ this.admin = admin;
2070
+ this.rbac = rbac;
2071
+ this.vault = vault;
361
2072
  }
362
2073
  };
363
2074
 
@@ -368,6 +2079,16 @@ var DatabaseAdapter = class {
368
2079
  }
369
2080
  };
370
2081
 
2082
+ // src/types/settings.types.ts
2083
+ function isSettingFieldMetadata(value) {
2084
+ if (typeof value !== "object" || value === null) {
2085
+ return false;
2086
+ }
2087
+ const metadata = value;
2088
+ return typeof metadata.type === "string" && typeof metadata.options === "object" && metadata.options !== null && "propertyKey" in metadata;
2089
+ }
2090
+ __name(isSettingFieldMetadata, "isSettingFieldMetadata");
2091
+
371
2092
  // src/types/storage.types.ts
372
2093
  var StorageAdapter = class {
373
2094
  static {
@@ -375,41 +2096,158 @@ var StorageAdapter = class {
375
2096
  }
376
2097
  };
377
2098
 
2099
+ // src/types/vault.types.ts
2100
+ var VaultAdapter = class {
2101
+ static {
2102
+ __name(this, "VaultAdapter");
2103
+ }
2104
+ };
2105
+
2106
+ // src/types/cache.types.ts
2107
+ var CacheAdapter = class {
2108
+ static {
2109
+ __name(this, "CacheAdapter");
2110
+ }
2111
+ };
2112
+
2113
+ exports.AccountLockedError = AccountLockedError;
378
2114
  exports.AuthStrategy = AuthStrategy;
2115
+ exports.AuthenticationRequiredError = AuthenticationRequiredError;
379
2116
  exports.BASE_SCHEMA_METADATA_KEY = BASE_SCHEMA_METADATA_KEY;
2117
+ exports.CacheAdapter = CacheAdapter;
2118
+ exports.ConfigurationError = ConfigurationError;
2119
+ exports.ConnectionFailedError = ConnectionFailedError;
380
2120
  exports.DESIGN_META = DESIGN_META;
381
2121
  exports.DESIGN_PARAM_TYPES = DESIGN_PARAM_TYPES;
382
2122
  exports.DESIGN_RETURN_TYPE = DESIGN_RETURN_TYPE;
383
2123
  exports.DESIGN_TYPE = DESIGN_TYPE;
384
2124
  exports.DatabaseAdapter = DatabaseAdapter;
2125
+ exports.DatabaseError = DatabaseError;
2126
+ exports.DocumentNotFoundError = DocumentNotFoundError;
2127
+ exports.DuplicateKeyError = DuplicateKeyError;
2128
+ exports.EVENT_HANDLER_METADATA = EVENT_HANDLER_METADATA;
2129
+ exports.EXTEND_USER_METADATA_KEY = EXTEND_USER_METADATA_KEY;
2130
+ exports.EmailAdapter = EmailAdapter;
2131
+ exports.EmailNotVerifiedError = EmailNotVerifiedError;
2132
+ exports.EmailServiceError = EmailServiceError;
2133
+ exports.ErrorCode = ErrorCode;
2134
+ exports.ExtendUser = ExtendUser;
2135
+ exports.ExternalServiceError = ExternalServiceError;
2136
+ exports.FIELD_METADATA_KEY = FIELD_METADATA_KEY;
2137
+ exports.Field = Field;
2138
+ exports.FileNotFoundError = FileNotFoundError;
2139
+ exports.HasPermission = HasPermission;
2140
+ exports.HookExecutionError = HookExecutionError;
385
2141
  exports.INJECT_MODEL = INJECT_MODEL;
386
2142
  exports.InjectModel = InjectModel;
2143
+ exports.InsufficientPermissionsError = InsufficientPermissionsError;
2144
+ exports.InternalError = InternalError;
2145
+ exports.InvalidCredentialsError = InvalidCredentialsError;
2146
+ exports.InvalidFormatError = InvalidFormatError;
2147
+ exports.MagnetError = MagnetError;
387
2148
  exports.MagnetModuleOptions = MagnetModuleOptions;
388
2149
  exports.Mixed = Mixed;
389
2150
  exports.Model = Model;
2151
+ exports.OnEvent = OnEvent;
2152
+ exports.PERMISSION_METADATA_KEY = PERMISSION_METADATA_KEY;
2153
+ exports.PERMISSION_OPTIONS_METADATA_KEY = PERMISSION_OPTIONS_METADATA_KEY;
390
2154
  exports.PROP_METADATA_KEY = PROP_METADATA_KEY;
2155
+ exports.PermissionDeniedError = PermissionDeniedError;
2156
+ exports.PermissionMeta = PermissionMeta;
2157
+ exports.PermissionNotFoundError = PermissionNotFoundError;
2158
+ exports.PluginError = PluginError;
2159
+ exports.PluginInitializationError = PluginInitializationError;
2160
+ exports.PluginNotFoundError = PluginNotFoundError;
391
2161
  exports.Prop = Prop;
392
2162
  exports.QueryBuilder = QueryBuilder;
2163
+ exports.QueryFailedError = QueryFailedError;
2164
+ exports.RESOLVED_PERMISSION_KEY = RESOLVED_PERMISSION_KEY;
393
2165
  exports.RESOLVER_METADATA_KEY = RESOLVER_METADATA_KEY;
394
2166
  exports.RESOLVE_METADATA_KEY = RESOLVE_METADATA_KEY;
2167
+ exports.RequirePermission = RequirePermission;
2168
+ exports.RequiredFieldError = RequiredFieldError;
395
2169
  exports.Resolve = Resolve;
396
2170
  exports.Resolver = Resolver;
2171
+ exports.ResourceNotFoundError = ResourceNotFoundError;
2172
+ exports.RoleNotFoundError = RoleNotFoundError;
397
2173
  exports.SCHEMA_METADATA_KEY = SCHEMA_METADATA_KEY;
398
2174
  exports.SCHEMA_OPTIONS_METADATA_KEY = SCHEMA_OPTIONS_METADATA_KEY;
2175
+ exports.SETTINGS_OPTIONS_METADATA_KEY = SETTINGS_OPTIONS_METADATA_KEY;
2176
+ exports.SETTING_FIELD_METADATA_KEY = SETTING_FIELD_METADATA_KEY;
399
2177
  exports.SETTING_METADATA_KEY = SETTING_METADATA_KEY;
400
2178
  exports.Schema = Schema;
2179
+ exports.SchemaNotFoundError = SchemaNotFoundError;
401
2180
  exports.Setting = Setting;
2181
+ exports.SettingField = SettingField;
2182
+ exports.Settings = Settings;
402
2183
  exports.StorageAdapter = StorageAdapter;
2184
+ exports.StorageError = StorageError;
2185
+ exports.TokenExpiredError = TokenExpiredError;
2186
+ exports.TokenInvalidError = TokenInvalidError;
2187
+ exports.TransactionFailedError = TransactionFailedError;
403
2188
  exports.UI = UI;
404
2189
  exports.UI_METADATA_KEY = UI_METADATA_KEY;
2190
+ exports.UnexpectedError = UnexpectedError;
2191
+ exports.UserNotFoundError = UserNotFoundError;
405
2192
  exports.VERSION_METADATA_KEY = VERSION_METADATA_KEY;
2193
+ exports.ValidationError = ValidationError;
406
2194
  exports.ValidationException = ValidationException;
407
2195
  exports.Validators = Validators;
2196
+ exports.ValueOutOfRangeError = ValueOutOfRangeError;
2197
+ exports.VaultAdapter = VaultAdapter;
408
2198
  exports.Version = Version;
2199
+ exports.VersionNotFoundError = VersionNotFoundError;
2200
+ exports.WebhookDeliveryError = WebhookDeliveryError;
2201
+ exports.assert = assert;
2202
+ exports.assertDefined = assertDefined;
409
2203
  exports.clearAdapterCache = clearAdapterCache;
2204
+ exports.clearDatabaseAdapterSingletonForFeature = clearDatabaseAdapterSingletonForFeature;
2205
+ exports.createFieldDecorator = createFieldDecorator;
410
2206
  exports.detectDatabaseAdapter = detectDatabaseAdapter;
2207
+ exports.fromDrizzleError = fromDrizzleError;
2208
+ exports.fromMongooseError = fromMongooseError;
2209
+ exports.getAdapterToken = getAdapterToken;
2210
+ exports.getDatabaseAdapterSingletonForFeature = getDatabaseAdapterSingletonForFeature;
2211
+ exports.getDocumentId = getDocumentId;
2212
+ exports.getExtendUserOptions = getExtendUserOptions;
2213
+ exports.getFieldMetadata = getFieldMetadata;
2214
+ exports.getFieldMetadataForProperty = getFieldMetadataForProperty;
411
2215
  exports.getModelToken = getModelToken;
2216
+ exports.getPermissionMetadata = getPermissionMetadata;
2217
+ exports.getRegisteredModel = getRegisteredModel;
412
2218
  exports.getSchemaOptions = getSchemaOptions;
413
2219
  exports.getSchemaToken = getSchemaToken;
2220
+ exports.getSettingFields = getSettingFields;
414
2221
  exports.getSettingToken = getSettingToken;
2222
+ exports.getSettingsOptions = getSettingsOptions;
2223
+ exports.hasMethod = hasMethod;
2224
+ exports.hasPermissionDecorator = hasPermissionDecorator;
2225
+ exports.hasProperties = hasProperties;
2226
+ exports.hasProperty = hasProperty;
2227
+ exports.hasSetLocale = hasSetLocale;
2228
+ exports.hasToString = hasToString;
2229
+ exports.isArray = isArray;
2230
+ exports.isBoolean = isBoolean;
2231
+ exports.isCastError = isCastError;
2232
+ exports.isDocument = isDocument;
2233
+ exports.isDuplicateKeyError = isDuplicateKeyError;
2234
+ exports.isFieldMetadata = isFieldMetadata;
2235
+ exports.isFunction = isFunction;
2236
+ exports.isMagnetError = isMagnetError;
2237
+ exports.isNumber = isNumber;
2238
+ exports.isObject = isObject;
2239
+ exports.isPostgresUniqueError = isPostgresUniqueError;
2240
+ exports.isSettingFieldMetadata = isSettingFieldMetadata;
2241
+ exports.isString = isString;
2242
+ exports.isStringArray = isStringArray;
2243
+ exports.isStringRecord = isStringRecord;
2244
+ exports.isUserExtension = isUserExtension;
2245
+ exports.isValidFieldType = isValidFieldType;
2246
+ exports.isValidationError = isValidationError;
2247
+ exports.isVersionDocument = isVersionDocument;
2248
+ exports.mapFieldTypeToProp = mapFieldTypeToProp;
2249
+ exports.mapFieldTypeToUI = mapFieldTypeToUI;
2250
+ exports.registerDatabaseAdapterSingletonForFeature = registerDatabaseAdapterSingletonForFeature;
2251
+ exports.registerModel = registerModel;
415
2252
  exports.setDatabaseAdapter = setDatabaseAdapter;
2253
+ exports.wrapError = wrapError;