@magnet-cms/common 0.1.1 → 0.2.0

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