@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 +1898 -60
- package/dist/index.d.cts +3691 -547
- package/dist/index.d.ts +3691 -547
- package/dist/index.js +1796 -61
- package/package.json +4 -2
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
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
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(
|
|
117
|
-
function
|
|
118
|
-
|
|
1045
|
+
__name(ExtendUser, "ExtendUser");
|
|
1046
|
+
function isUserExtension(target) {
|
|
1047
|
+
return Reflect.hasMetadata(EXTEND_USER_METADATA_KEY, target);
|
|
119
1048
|
}
|
|
120
|
-
__name(
|
|
121
|
-
function
|
|
122
|
-
|
|
1049
|
+
__name(isUserExtension, "isUserExtension");
|
|
1050
|
+
function getExtendUserOptions(target) {
|
|
1051
|
+
return Reflect.getMetadata(EXTEND_USER_METADATA_KEY, target);
|
|
123
1052
|
}
|
|
124
|
-
__name(
|
|
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
|
|
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
|
-
|
|
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;
|