@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/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":"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"}