@rudderjs/orm 0.0.6
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/LICENSE +21 -0
- package/README.md +604 -0
- package/boost/guidelines.md +234 -0
- package/dist/attribute.d.ts +36 -0
- package/dist/attribute.d.ts.map +1 -0
- package/dist/attribute.js +36 -0
- package/dist/attribute.js.map +1 -0
- package/dist/cast.d.ts +14 -0
- package/dist/cast.d.ts.map +1 -0
- package/dist/cast.js +85 -0
- package/dist/cast.js.map +1 -0
- package/dist/collection.d.ts +73 -0
- package/dist/collection.d.ts.map +1 -0
- package/dist/collection.js +152 -0
- package/dist/collection.js.map +1 -0
- package/dist/factory.d.ts +80 -0
- package/dist/factory.d.ts.map +1 -0
- package/dist/factory.js +129 -0
- package/dist/factory.js.map +1 -0
- package/dist/index.d.ts +195 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +450 -0
- package/dist/index.js.map +1 -0
- package/dist/resource.d.ts +95 -0
- package/dist/resource.d.ts.map +1 -0
- package/dist/resource.js +115 -0
- package/dist/resource.js.map +1 -0
- package/package.json +39 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,450 @@
|
|
|
1
|
+
import { castGet, castSet } from './cast.js';
|
|
2
|
+
export { Attribute } from './attribute.js';
|
|
3
|
+
export { JsonResource, ResourceCollection } from './resource.js';
|
|
4
|
+
export { ModelCollection } from './collection.js';
|
|
5
|
+
export { ModelFactory, sequence } from './factory.js';
|
|
6
|
+
// ─── Global ORM Registry ───────────────────────────────────
|
|
7
|
+
export class ModelRegistry {
|
|
8
|
+
static adapter = null;
|
|
9
|
+
static set(adapter) {
|
|
10
|
+
this.adapter = adapter;
|
|
11
|
+
}
|
|
12
|
+
static get() {
|
|
13
|
+
return this.adapter;
|
|
14
|
+
}
|
|
15
|
+
static getAdapter() {
|
|
16
|
+
if (!this.adapter) {
|
|
17
|
+
throw new Error('[RudderJS ORM] No ORM adapter registered. Did you add a database provider to your providers list?');
|
|
18
|
+
}
|
|
19
|
+
return this.adapter;
|
|
20
|
+
}
|
|
21
|
+
static reset() {
|
|
22
|
+
this.adapter = null;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
// ─── Decorators ────────────────────────────────────────────
|
|
26
|
+
/**
|
|
27
|
+
* Mark an instance property as hidden from JSON output.
|
|
28
|
+
* Equivalent to adding the field name to `static hidden`.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* class User extends Model {
|
|
32
|
+
* @Hidden password = ''
|
|
33
|
+
* }
|
|
34
|
+
*/
|
|
35
|
+
export function Hidden(target, key) {
|
|
36
|
+
const ctor = target.constructor;
|
|
37
|
+
if (!Object.prototype.hasOwnProperty.call(ctor, 'hidden')) {
|
|
38
|
+
ctor.hidden = [...ctor.hidden];
|
|
39
|
+
}
|
|
40
|
+
ctor.hidden.push(String(key));
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Restrict JSON output to only visible properties.
|
|
44
|
+
* Equivalent to setting `static visible`.
|
|
45
|
+
* Applied per-field — all `@Visible` fields form the allowlist.
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* class User extends Model {
|
|
49
|
+
* @Visible id = 0
|
|
50
|
+
* @Visible name = ''
|
|
51
|
+
* password = '' // hidden because visible list is set
|
|
52
|
+
* }
|
|
53
|
+
*/
|
|
54
|
+
export function Visible(target, key) {
|
|
55
|
+
const ctor = target.constructor;
|
|
56
|
+
if (!Object.prototype.hasOwnProperty.call(ctor, 'visible')) {
|
|
57
|
+
ctor.visible = [];
|
|
58
|
+
}
|
|
59
|
+
ctor.visible.push(String(key));
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Always include the named accessor in JSON output.
|
|
63
|
+
* The property must also be defined in `static attributes` with a getter.
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* class User extends Model {
|
|
67
|
+
* @Appends fullName = ''
|
|
68
|
+
* static attributes = {
|
|
69
|
+
* fullName: Attribute.make({ get: (_, a) => `${a['firstName']} ${a['lastName']}` }),
|
|
70
|
+
* }
|
|
71
|
+
* }
|
|
72
|
+
*/
|
|
73
|
+
export function Appends(target, key) {
|
|
74
|
+
const ctor = target.constructor;
|
|
75
|
+
if (!Object.prototype.hasOwnProperty.call(ctor, 'appends')) {
|
|
76
|
+
ctor.appends = [...(ctor.appends ?? [])];
|
|
77
|
+
}
|
|
78
|
+
ctor.appends.push(String(key));
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Apply a cast to an instance property.
|
|
82
|
+
* Equivalent to adding the field to `static casts`.
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* class User extends Model {
|
|
86
|
+
* @Cast('boolean') isAdmin = false
|
|
87
|
+
* @Cast('date') createdAt = new Date()
|
|
88
|
+
* @Cast(MoneyCast) balance = 0
|
|
89
|
+
* }
|
|
90
|
+
*/
|
|
91
|
+
export function Cast(type) {
|
|
92
|
+
return (target, key) => {
|
|
93
|
+
const ctor = target.constructor;
|
|
94
|
+
if (!Object.prototype.hasOwnProperty.call(ctor, 'casts')) {
|
|
95
|
+
ctor.casts = { ...(ctor.casts ?? {}) };
|
|
96
|
+
}
|
|
97
|
+
ctor.casts[String(key)] = type;
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
// ─── Model Base Class ──────────────────────────────────────
|
|
101
|
+
export class Model {
|
|
102
|
+
/** The table name — defaults to lowercase class name + 's' */
|
|
103
|
+
static table;
|
|
104
|
+
/** Primary key column */
|
|
105
|
+
static primaryKey = 'id';
|
|
106
|
+
/** Columns to hide from JSON output */
|
|
107
|
+
static hidden = [];
|
|
108
|
+
/**
|
|
109
|
+
* Columns to exclusively include in JSON output.
|
|
110
|
+
* When set, only these columns (plus appends) appear in toJSON().
|
|
111
|
+
* Takes precedence over `hidden`.
|
|
112
|
+
*/
|
|
113
|
+
static visible = [];
|
|
114
|
+
/**
|
|
115
|
+
* Accessor names (defined in `attributes`) to always append to JSON output.
|
|
116
|
+
* The accessor must have a `get` function.
|
|
117
|
+
*/
|
|
118
|
+
static appends = [];
|
|
119
|
+
/**
|
|
120
|
+
* Attribute casts — map column names to their cast types.
|
|
121
|
+
* Applied both when reading (toJSON) and writing (create/update).
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* static casts = {
|
|
125
|
+
* isAdmin: 'boolean',
|
|
126
|
+
* createdAt: 'date',
|
|
127
|
+
* settings: 'json',
|
|
128
|
+
* balance: MoneyCast, // custom cast class
|
|
129
|
+
* } as const satisfies Record<string, CastDefinition>
|
|
130
|
+
*/
|
|
131
|
+
static casts = {};
|
|
132
|
+
/**
|
|
133
|
+
* Accessors and mutators using `Attribute.make({ get, set })`.
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* static attributes = {
|
|
137
|
+
* firstName: Attribute.make({ get: v => String(v).charAt(0).toUpperCase() + String(v).slice(1) }),
|
|
138
|
+
* fullName: Attribute.make({ get: (_, attrs) => `${attrs['firstName']} ${attrs['lastName']}` }),
|
|
139
|
+
* password: Attribute.make({ set: async v => await bcrypt.hash(String(v), 10) }),
|
|
140
|
+
* }
|
|
141
|
+
*/
|
|
142
|
+
static attributes = {};
|
|
143
|
+
/** Columns that are mass-assignable */
|
|
144
|
+
static fillable = [];
|
|
145
|
+
/**
|
|
146
|
+
* Enable soft deletes for this model. When true:
|
|
147
|
+
* - `delete()` sets `deletedAt` instead of removing the record
|
|
148
|
+
* - Queries automatically exclude records where `deletedAt` is not null
|
|
149
|
+
* - Use `withTrashed()` to include soft-deleted records
|
|
150
|
+
* - Use `onlyTrashed()` to return only soft-deleted records
|
|
151
|
+
* - Use `restore()` to un-delete a record
|
|
152
|
+
* - Use `forceDelete()` to permanently remove a record
|
|
153
|
+
*/
|
|
154
|
+
static softDeletes = false;
|
|
155
|
+
// ── Instance-level serialization overrides ─────────────
|
|
156
|
+
/** @internal */
|
|
157
|
+
_instanceHidden;
|
|
158
|
+
/** @internal */
|
|
159
|
+
_instanceVisible;
|
|
160
|
+
// ── Scopes ─────────────────────────────────────────────
|
|
161
|
+
static globalScopes = {};
|
|
162
|
+
static scopes = {};
|
|
163
|
+
// ── Observers ──────────────────────────────────────────
|
|
164
|
+
/** @internal */
|
|
165
|
+
static _observers = [];
|
|
166
|
+
/** @internal */
|
|
167
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
168
|
+
static _listeners = new Map();
|
|
169
|
+
static observe(ObserverClass) {
|
|
170
|
+
if (!Object.prototype.hasOwnProperty.call(this, '_observers')) {
|
|
171
|
+
this._observers = [];
|
|
172
|
+
}
|
|
173
|
+
this._observers.push(new ObserverClass());
|
|
174
|
+
}
|
|
175
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
176
|
+
static on(event, handler) {
|
|
177
|
+
if (!Object.prototype.hasOwnProperty.call(this, '_listeners')) {
|
|
178
|
+
this._listeners = new Map();
|
|
179
|
+
}
|
|
180
|
+
const list = this._listeners.get(event) ?? [];
|
|
181
|
+
list.push(handler);
|
|
182
|
+
this._listeners.set(event, list);
|
|
183
|
+
}
|
|
184
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
185
|
+
static async _fireEvent(event, ...args) {
|
|
186
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
187
|
+
let result = args[0];
|
|
188
|
+
const observers = Object.prototype.hasOwnProperty.call(this, '_observers') ? this._observers : [];
|
|
189
|
+
for (const obs of observers) {
|
|
190
|
+
const method = obs[event];
|
|
191
|
+
if (method) {
|
|
192
|
+
const ret = await method.call(obs, ...args);
|
|
193
|
+
if (ret === false)
|
|
194
|
+
return false;
|
|
195
|
+
if (ret !== undefined && ret !== null && typeof ret === 'object')
|
|
196
|
+
result = ret;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
const listeners = Object.prototype.hasOwnProperty.call(this, '_listeners')
|
|
200
|
+
? (this._listeners.get(event) ?? [])
|
|
201
|
+
: [];
|
|
202
|
+
for (const fn of listeners) {
|
|
203
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
204
|
+
const ret = await fn(...args);
|
|
205
|
+
if (ret === false)
|
|
206
|
+
return false;
|
|
207
|
+
if (ret !== undefined && ret !== null && typeof ret === 'object')
|
|
208
|
+
result = ret;
|
|
209
|
+
}
|
|
210
|
+
return result;
|
|
211
|
+
}
|
|
212
|
+
static clearObservers() {
|
|
213
|
+
this._observers = [];
|
|
214
|
+
this._listeners = new Map();
|
|
215
|
+
}
|
|
216
|
+
// ── Query Methods ──────────────────────────────────────
|
|
217
|
+
static getTable() {
|
|
218
|
+
return this.table ?? `${this.name.toLowerCase()}s`;
|
|
219
|
+
}
|
|
220
|
+
static query() {
|
|
221
|
+
let q = ModelRegistry.getAdapter().query(this.getTable());
|
|
222
|
+
if (this.softDeletes) {
|
|
223
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
224
|
+
q._enableSoftDeletes?.();
|
|
225
|
+
}
|
|
226
|
+
const globalScopes = this.globalScopes;
|
|
227
|
+
const excludedScopes = new Set();
|
|
228
|
+
for (const [, scopeFn] of Object.entries(globalScopes)) {
|
|
229
|
+
q = scopeFn(q);
|
|
230
|
+
}
|
|
231
|
+
const modelClass = this;
|
|
232
|
+
const localScopes = modelClass.scopes;
|
|
233
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
234
|
+
const enhanced = q;
|
|
235
|
+
enhanced.scope = (name, ...args) => {
|
|
236
|
+
const scopeFn = localScopes[name];
|
|
237
|
+
if (!scopeFn)
|
|
238
|
+
throw new Error(`[RudderJS ORM] Scope "${name}" is not defined on ${modelClass.name}.`);
|
|
239
|
+
return scopeFn(enhanced, ...args);
|
|
240
|
+
};
|
|
241
|
+
enhanced.withoutGlobalScope = (name) => {
|
|
242
|
+
excludedScopes.add(name);
|
|
243
|
+
let rebuilt = ModelRegistry.getAdapter().query(modelClass.getTable());
|
|
244
|
+
if (modelClass.softDeletes) {
|
|
245
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
246
|
+
rebuilt._enableSoftDeletes?.();
|
|
247
|
+
}
|
|
248
|
+
for (const [scopeName, scopeFn] of Object.entries(globalScopes)) {
|
|
249
|
+
if (!excludedScopes.has(scopeName)) {
|
|
250
|
+
rebuilt = scopeFn(rebuilt);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
254
|
+
;
|
|
255
|
+
rebuilt.scope = enhanced.scope;
|
|
256
|
+
rebuilt.withoutGlobalScope = enhanced.withoutGlobalScope;
|
|
257
|
+
return rebuilt;
|
|
258
|
+
};
|
|
259
|
+
return enhanced;
|
|
260
|
+
}
|
|
261
|
+
static _q(self) {
|
|
262
|
+
const q = ModelRegistry.getAdapter().query(self.getTable());
|
|
263
|
+
if (self.softDeletes) {
|
|
264
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
265
|
+
q._enableSoftDeletes?.();
|
|
266
|
+
}
|
|
267
|
+
let result = q;
|
|
268
|
+
for (const [, scopeFn] of Object.entries(self.globalScopes)) {
|
|
269
|
+
result = scopeFn(result);
|
|
270
|
+
}
|
|
271
|
+
return result;
|
|
272
|
+
}
|
|
273
|
+
static find(id) {
|
|
274
|
+
return Model._q(this).find(id);
|
|
275
|
+
}
|
|
276
|
+
static all() {
|
|
277
|
+
return Model._q(this).all();
|
|
278
|
+
}
|
|
279
|
+
static where(column, value) {
|
|
280
|
+
return Model._q(this).where(column, value);
|
|
281
|
+
}
|
|
282
|
+
static async create(data) {
|
|
283
|
+
const self = this;
|
|
284
|
+
let payload = self._applyMutators(data);
|
|
285
|
+
const result = await self._fireEvent('creating', payload);
|
|
286
|
+
if (result === false)
|
|
287
|
+
throw new Error(`[RudderJS ORM] Create cancelled by observer on ${self.name}.`);
|
|
288
|
+
if (result && typeof result === 'object')
|
|
289
|
+
payload = result;
|
|
290
|
+
const record = await Model._q(this).create(payload);
|
|
291
|
+
await self._fireEvent('created', record);
|
|
292
|
+
return record;
|
|
293
|
+
}
|
|
294
|
+
static with(...relations) {
|
|
295
|
+
return Model._q(this).with(...relations);
|
|
296
|
+
}
|
|
297
|
+
static async update(id, data) {
|
|
298
|
+
const self = this;
|
|
299
|
+
let payload = self._applyMutators(data);
|
|
300
|
+
const result = await self._fireEvent('updating', id, payload);
|
|
301
|
+
if (result === false)
|
|
302
|
+
throw new Error(`[RudderJS ORM] Update cancelled by observer on ${self.name}.`);
|
|
303
|
+
if (result && typeof result === 'object')
|
|
304
|
+
payload = result;
|
|
305
|
+
const record = await Model._q(this).update(id, payload);
|
|
306
|
+
await self._fireEvent('updated', record);
|
|
307
|
+
return record;
|
|
308
|
+
}
|
|
309
|
+
static async delete(id) {
|
|
310
|
+
const self = this;
|
|
311
|
+
const result = await self._fireEvent('deleting', id);
|
|
312
|
+
if (result === false)
|
|
313
|
+
throw new Error(`[RudderJS ORM] Delete cancelled by observer on ${self.name}.`);
|
|
314
|
+
await Model._q(this).delete(id);
|
|
315
|
+
await self._fireEvent('deleted', id);
|
|
316
|
+
}
|
|
317
|
+
static async restore(id) {
|
|
318
|
+
const self = this;
|
|
319
|
+
const result = await self._fireEvent('restoring', id);
|
|
320
|
+
if (result === false)
|
|
321
|
+
throw new Error(`[RudderJS ORM] Restore cancelled by observer on ${self.name}.`);
|
|
322
|
+
const record = await Model._q(this).restore(id);
|
|
323
|
+
await self._fireEvent('restored', record);
|
|
324
|
+
return record;
|
|
325
|
+
}
|
|
326
|
+
static async forceDelete(id) {
|
|
327
|
+
const self = this;
|
|
328
|
+
const result = await self._fireEvent('deleting', id);
|
|
329
|
+
if (result === false)
|
|
330
|
+
throw new Error(`[RudderJS ORM] Delete cancelled by observer on ${self.name}.`);
|
|
331
|
+
await Model._q(this).forceDelete(id);
|
|
332
|
+
await self._fireEvent('deleted', id);
|
|
333
|
+
}
|
|
334
|
+
// ── Cast / Mutator helpers ─────────────────────────────
|
|
335
|
+
/** @internal — apply cast setters and attribute mutators to an incoming data payload */
|
|
336
|
+
static _applyMutators(data) {
|
|
337
|
+
const result = {};
|
|
338
|
+
for (const [key, value] of Object.entries(data)) {
|
|
339
|
+
let val = value;
|
|
340
|
+
// Attribute mutator (set side) takes priority
|
|
341
|
+
const attrDef = this.attributes[key];
|
|
342
|
+
if (attrDef?.setter) {
|
|
343
|
+
val = attrDef.setter(val, data);
|
|
344
|
+
}
|
|
345
|
+
else if (this.casts[key] !== undefined) {
|
|
346
|
+
val = castSet(this.casts[key], key, val, data);
|
|
347
|
+
}
|
|
348
|
+
result[key] = val;
|
|
349
|
+
}
|
|
350
|
+
return result;
|
|
351
|
+
}
|
|
352
|
+
// ── Instance serialization controls ───────────────────
|
|
353
|
+
/**
|
|
354
|
+
* Make the given keys visible for this instance's JSON output.
|
|
355
|
+
* Removes them from the instance's hidden list and adds to the visible override.
|
|
356
|
+
* Returns `this` for chaining.
|
|
357
|
+
*/
|
|
358
|
+
makeVisible(keys) {
|
|
359
|
+
const k = Array.isArray(keys) ? keys : [keys];
|
|
360
|
+
this._instanceHidden = (this._instanceHidden ?? this.constructor.hidden)
|
|
361
|
+
.filter(h => !k.includes(h));
|
|
362
|
+
return this;
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Hide the given keys from this instance's JSON output.
|
|
366
|
+
* Returns `this` for chaining.
|
|
367
|
+
*/
|
|
368
|
+
makeHidden(keys) {
|
|
369
|
+
const k = Array.isArray(keys) ? keys : [keys];
|
|
370
|
+
this._instanceHidden = [...(this._instanceHidden ?? this.constructor.hidden), ...k];
|
|
371
|
+
return this;
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Override the visible list for this instance only.
|
|
375
|
+
* Returns `this` for chaining.
|
|
376
|
+
*/
|
|
377
|
+
setVisible(keys) {
|
|
378
|
+
this._instanceVisible = keys;
|
|
379
|
+
return this;
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* Override the hidden list for this instance only.
|
|
383
|
+
* Returns `this` for chaining.
|
|
384
|
+
*/
|
|
385
|
+
setHidden(keys) {
|
|
386
|
+
this._instanceHidden = keys;
|
|
387
|
+
return this;
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* Add keys to the visible list for this instance.
|
|
391
|
+
* Returns `this` for chaining.
|
|
392
|
+
*/
|
|
393
|
+
mergeVisible(keys) {
|
|
394
|
+
const base = this._instanceVisible ?? this.constructor.visible;
|
|
395
|
+
this._instanceVisible = [...base, ...keys];
|
|
396
|
+
return this;
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Add keys to the hidden list for this instance.
|
|
400
|
+
* Returns `this` for chaining.
|
|
401
|
+
*/
|
|
402
|
+
mergeHidden(keys) {
|
|
403
|
+
const base = this._instanceHidden ?? this.constructor.hidden;
|
|
404
|
+
this._instanceHidden = [...base, ...keys];
|
|
405
|
+
return this;
|
|
406
|
+
}
|
|
407
|
+
// ── toJSON ─────────────────────────────────────────────
|
|
408
|
+
toJSON() {
|
|
409
|
+
const ctor = this.constructor;
|
|
410
|
+
const rawEntries = Object.entries(this).filter(([k]) => !k.startsWith('_instance'));
|
|
411
|
+
const raw = {};
|
|
412
|
+
for (const [k, v] of rawEntries) {
|
|
413
|
+
raw[k] = v;
|
|
414
|
+
}
|
|
415
|
+
const result = {};
|
|
416
|
+
// Apply casts (get side) and accessor getters
|
|
417
|
+
for (const [k, v] of Object.entries(raw)) {
|
|
418
|
+
const attrDef = ctor.attributes[k];
|
|
419
|
+
if (attrDef?.getter) {
|
|
420
|
+
result[k] = attrDef.getter(v, raw);
|
|
421
|
+
}
|
|
422
|
+
else if (ctor.casts[k] !== undefined) {
|
|
423
|
+
result[k] = castGet(ctor.casts[k], k, v, raw);
|
|
424
|
+
}
|
|
425
|
+
else {
|
|
426
|
+
result[k] = v;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
// Appends — add computed accessor values that aren't raw properties
|
|
430
|
+
for (const appendKey of ctor.appends) {
|
|
431
|
+
if (!(appendKey in result)) {
|
|
432
|
+
const attrDef = ctor.attributes[appendKey];
|
|
433
|
+
if (attrDef?.getter) {
|
|
434
|
+
result[appendKey] = attrDef.getter(undefined, raw);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
// Determine effective visible / hidden lists
|
|
439
|
+
const effectiveVisible = this._instanceVisible ?? ctor.visible;
|
|
440
|
+
const effectiveHidden = this._instanceHidden ?? ctor.hidden;
|
|
441
|
+
// Apply visible (allowlist) — takes precedence
|
|
442
|
+
if (effectiveVisible.length > 0) {
|
|
443
|
+
const appendKeys = new Set(ctor.appends);
|
|
444
|
+
return Object.fromEntries(Object.entries(result).filter(([k]) => effectiveVisible.includes(k) || appendKeys.has(k)));
|
|
445
|
+
}
|
|
446
|
+
// Apply hidden (denylist)
|
|
447
|
+
return Object.fromEntries(Object.entries(result).filter(([k]) => !effectiveHidden.includes(k)));
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base class for API resource transformations.
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* class UserResource extends JsonResource<User> {
|
|
6
|
+
* toArray() {
|
|
7
|
+
* return {
|
|
8
|
+
* id: this.resource.id,
|
|
9
|
+
* name: this.resource.name,
|
|
10
|
+
* email: this.resource.email,
|
|
11
|
+
* // conditional
|
|
12
|
+
* admin: this.when(this.resource.role === 'admin', true),
|
|
13
|
+
* posts: this.whenLoaded('posts', PostResource.collection(this.resource.posts as Post[])),
|
|
14
|
+
* }
|
|
15
|
+
* }
|
|
16
|
+
* }
|
|
17
|
+
*
|
|
18
|
+
* // In a route handler:
|
|
19
|
+
* res.json(new UserResource(user).toArray())
|
|
20
|
+
* res.json(UserResource.collection(users).toResponse())
|
|
21
|
+
*/
|
|
22
|
+
export declare abstract class JsonResource<T extends Record<string, unknown> = Record<string, unknown>> {
|
|
23
|
+
protected readonly resource: T;
|
|
24
|
+
constructor(resource: T);
|
|
25
|
+
/** Transform the resource into an array/object. Override in subclasses. */
|
|
26
|
+
abstract toArray(req?: unknown): Record<string, unknown> | Promise<Record<string, unknown>>;
|
|
27
|
+
/**
|
|
28
|
+
* Include `value` only when `condition` is true.
|
|
29
|
+
* Returns `fallback` (default `undefined`) when false.
|
|
30
|
+
*
|
|
31
|
+
* Undefined values are stripped from the output object — use `mergeWhen()` for
|
|
32
|
+
* conditional blocks of multiple keys.
|
|
33
|
+
*/
|
|
34
|
+
protected when<V>(condition: boolean, value: V): V | undefined;
|
|
35
|
+
protected when<V>(condition: boolean, value: V, fallback: V): V;
|
|
36
|
+
/**
|
|
37
|
+
* Include `then` only when `value` is not null/undefined.
|
|
38
|
+
* If `then` is a function it receives the non-null value.
|
|
39
|
+
*/
|
|
40
|
+
protected whenNotNull<V, R>(value: V | null | undefined, then: R | ((v: NonNullable<V>) => R), fallback?: R): R | undefined;
|
|
41
|
+
/**
|
|
42
|
+
* Include `value` only when the named relation is loaded on the resource.
|
|
43
|
+
* Falls back to `fallback` (default `undefined`) when not loaded.
|
|
44
|
+
*/
|
|
45
|
+
protected whenLoaded<R>(relation: string): unknown;
|
|
46
|
+
protected whenLoaded<R>(relation: string, value: R): R | undefined;
|
|
47
|
+
protected whenLoaded<R>(relation: string, value: R, fallback: R): R;
|
|
48
|
+
/**
|
|
49
|
+
* Merge `attributes` into the output only when `condition` is true.
|
|
50
|
+
* Returns `{}` when false — spread the result at the call site.
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* toArray() {
|
|
54
|
+
* return {
|
|
55
|
+
* id: this.resource.id,
|
|
56
|
+
* ...this.mergeWhen(this.resource.isAdmin, {
|
|
57
|
+
* permissions: this.resource.permissions,
|
|
58
|
+
* lastLogin: this.resource.lastLogin,
|
|
59
|
+
* }),
|
|
60
|
+
* }
|
|
61
|
+
* }
|
|
62
|
+
*/
|
|
63
|
+
protected mergeWhen(condition: boolean, attributes: Record<string, unknown>): Record<string, unknown>;
|
|
64
|
+
/** Create a `ResourceCollection` from an array of raw items using this resource class. */
|
|
65
|
+
static collection<T extends Record<string, unknown>>(this: new (item: T) => JsonResource<T>, items: T[], meta?: Record<string, unknown>): ResourceCollection<T>;
|
|
66
|
+
toJSON(): Record<string, unknown>;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Wraps multiple `JsonResource` instances for collection responses.
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* class UserResource extends JsonResource<User> { ... }
|
|
73
|
+
*
|
|
74
|
+
* // From a route handler:
|
|
75
|
+
* const collection = UserResource.collection(users)
|
|
76
|
+
* res.json(await collection.toResponse())
|
|
77
|
+
* // → { data: [...] }
|
|
78
|
+
*
|
|
79
|
+
* // With pagination metadata:
|
|
80
|
+
* const collection = UserResource.collection(users, { total: 100, page: 1, perPage: 15 })
|
|
81
|
+
* res.json(await collection.toResponse())
|
|
82
|
+
* // → { data: [...], meta: { total: 100, page: 1, perPage: 15 } }
|
|
83
|
+
*/
|
|
84
|
+
export declare class ResourceCollection<T extends Record<string, unknown> = Record<string, unknown>> {
|
|
85
|
+
private readonly items;
|
|
86
|
+
private readonly meta?;
|
|
87
|
+
constructor(items: JsonResource<T>[], meta?: Record<string, unknown> | undefined);
|
|
88
|
+
static of<T extends Record<string, unknown>>(items: JsonResource<T>[], meta?: Record<string, unknown>): ResourceCollection<T>;
|
|
89
|
+
toArray(req?: unknown): Promise<Record<string, unknown>[]>;
|
|
90
|
+
toResponse(req?: unknown): Promise<{
|
|
91
|
+
data: Record<string, unknown>[];
|
|
92
|
+
meta?: Record<string, unknown>;
|
|
93
|
+
}>;
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=resource.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource.d.ts","sourceRoot":"","sources":["../src/resource.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,8BAAsB,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAChF,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;gBAAX,QAAQ,EAAE,CAAC;IAE1C,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAI3F;;;;;;OAMG;IACH,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,GAAG,SAAS;IAC9D,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,CAAC;IAK/D;;;OAGG;IACH,SAAS,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,EACxB,KAAK,EAAE,CAAC,GAAG,IAAI,GAAG,SAAS,EAC3B,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EACpC,QAAQ,CAAC,EAAE,CAAC,GACX,CAAC,GAAG,SAAS;IAShB;;;OAGG;IACH,SAAS,CAAC,UAAU,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO;IAClD,SAAS,CAAC,UAAU,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,GAAG,SAAS;IAClE,SAAS,CAAC,UAAU,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,CAAC;IASnE;;;;;;;;;;;;;;OAcG;IACH,SAAS,CAAC,SAAS,CAAC,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAIrG,0FAA0F;IAC1F,MAAM,CAAC,UAAU,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjD,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,KAAK,YAAY,CAAC,CAAC,CAAC,EACtC,KAAK,EAAE,CAAC,EAAE,EACV,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,kBAAkB,CAAC,CAAC,CAAC;IAIxB,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CASlC;AAID;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,kBAAkB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAEvF,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;gBADL,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,EACxB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,YAAA;IAGjD,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACzC,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,EACxB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,kBAAkB,CAAC,CAAC,CAAC;IAIlB,OAAO,CAAC,GAAG,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IAI1D,UAAU,CAAC,GAAG,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC;CAI9G"}
|