@c9up/atlas 0.1.3 → 0.1.4

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.
Files changed (143) hide show
  1. package/db.darwin-arm64.node +0 -0
  2. package/db.darwin-x64.node +0 -0
  3. package/db.linux-arm64-gnu.node +0 -0
  4. package/db.linux-x64-gnu.node +0 -0
  5. package/db.win32-x64-msvc.node +0 -0
  6. package/dist/AtlasProvider.d.ts +106 -0
  7. package/dist/AtlasProvider.d.ts.map +1 -0
  8. package/dist/AtlasProvider.js +190 -0
  9. package/dist/AtlasProvider.js.map +1 -0
  10. package/dist/BaseEntity.d.ts +255 -0
  11. package/dist/BaseEntity.d.ts.map +1 -0
  12. package/dist/BaseEntity.js +420 -0
  13. package/dist/BaseEntity.js.map +1 -0
  14. package/dist/BaseRepository.d.ts +175 -0
  15. package/dist/BaseRepository.d.ts.map +1 -0
  16. package/dist/BaseRepository.js +1394 -0
  17. package/dist/BaseRepository.js.map +1 -0
  18. package/dist/ModelQuery.d.ts +338 -0
  19. package/dist/ModelQuery.d.ts.map +1 -0
  20. package/dist/ModelQuery.js +1598 -0
  21. package/dist/ModelQuery.js.map +1 -0
  22. package/dist/Transaction.d.ts +15 -0
  23. package/dist/Transaction.d.ts.map +1 -0
  24. package/dist/Transaction.js +67 -0
  25. package/dist/Transaction.js.map +1 -0
  26. package/dist/adapters/NapiDbAdapter.d.ts +34 -0
  27. package/dist/adapters/NapiDbAdapter.d.ts.map +1 -0
  28. package/dist/adapters/NapiDbAdapter.js +96 -0
  29. package/dist/adapters/NapiDbAdapter.js.map +1 -0
  30. package/dist/config.d.ts +4 -0
  31. package/dist/config.d.ts.map +1 -0
  32. package/dist/config.js +4 -0
  33. package/dist/config.js.map +1 -0
  34. package/dist/configure.d.ts +10 -0
  35. package/dist/configure.d.ts.map +1 -0
  36. package/dist/configure.js +25 -0
  37. package/dist/configure.js.map +1 -0
  38. package/dist/decorators/entity.d.ts +235 -0
  39. package/dist/decorators/entity.d.ts.map +1 -0
  40. package/dist/decorators/entity.js +264 -0
  41. package/dist/decorators/entity.js.map +1 -0
  42. package/dist/decorators/hooks.d.ts +70 -0
  43. package/dist/decorators/hooks.d.ts.map +1 -0
  44. package/dist/decorators/hooks.js +107 -0
  45. package/dist/decorators/hooks.js.map +1 -0
  46. package/dist/decorators/scope.d.ts +35 -0
  47. package/dist/decorators/scope.d.ts.map +1 -0
  48. package/dist/decorators/scope.js +29 -0
  49. package/dist/decorators/scope.js.map +1 -0
  50. package/dist/errors.d.ts +54 -0
  51. package/dist/errors.d.ts.map +1 -0
  52. package/dist/errors.js +82 -0
  53. package/dist/errors.js.map +1 -0
  54. package/dist/index.d.ts +39 -0
  55. package/dist/index.d.ts.map +1 -0
  56. package/dist/index.js +28 -0
  57. package/dist/index.js.map +1 -0
  58. package/dist/naming/NamingStrategy.d.ts +52 -0
  59. package/dist/naming/NamingStrategy.d.ts.map +1 -0
  60. package/dist/naming/NamingStrategy.js +65 -0
  61. package/dist/naming/NamingStrategy.js.map +1 -0
  62. package/dist/query/QueryBuilder.d.ts +95 -0
  63. package/dist/query/QueryBuilder.d.ts.map +1 -0
  64. package/dist/query/QueryBuilder.js +310 -0
  65. package/dist/query/QueryBuilder.js.map +1 -0
  66. package/dist/query/native.d.ts +18 -0
  67. package/dist/query/native.d.ts.map +1 -0
  68. package/dist/query/native.js +49 -0
  69. package/dist/query/native.js.map +1 -0
  70. package/dist/schema/Migration.d.ts +55 -0
  71. package/dist/schema/Migration.d.ts.map +1 -0
  72. package/dist/schema/Migration.js +68 -0
  73. package/dist/schema/Migration.js.map +1 -0
  74. package/dist/schema/MigrationRunner.d.ts +115 -0
  75. package/dist/schema/MigrationRunner.d.ts.map +1 -0
  76. package/dist/schema/MigrationRunner.js +402 -0
  77. package/dist/schema/MigrationRunner.js.map +1 -0
  78. package/dist/schema/Schema.d.ts +22 -0
  79. package/dist/schema/Schema.d.ts.map +1 -0
  80. package/dist/schema/Schema.js +51 -0
  81. package/dist/schema/Schema.js.map +1 -0
  82. package/dist/schema/SchemaBuilder.d.ts +14 -0
  83. package/dist/schema/SchemaBuilder.d.ts.map +1 -0
  84. package/dist/schema/SchemaBuilder.js +13 -0
  85. package/dist/schema/SchemaBuilder.js.map +1 -0
  86. package/dist/schema/Seeder.d.ts +54 -0
  87. package/dist/schema/Seeder.d.ts.map +1 -0
  88. package/dist/schema/Seeder.js +89 -0
  89. package/dist/schema/Seeder.js.map +1 -0
  90. package/dist/schema/TableBuilder.d.ts +86 -0
  91. package/dist/schema/TableBuilder.d.ts.map +1 -0
  92. package/dist/schema/TableBuilder.js +211 -0
  93. package/dist/schema/TableBuilder.js.map +1 -0
  94. package/dist/schema/types.d.ts +28 -0
  95. package/dist/schema/types.d.ts.map +1 -0
  96. package/dist/schema/types.js +19 -0
  97. package/dist/schema/types.js.map +1 -0
  98. package/dist/services/db.d.ts +22 -0
  99. package/dist/services/db.d.ts.map +1 -0
  100. package/dist/services/db.js +37 -0
  101. package/dist/services/db.js.map +1 -0
  102. package/dist/testing/DatabaseCleanup.d.ts +19 -0
  103. package/dist/testing/DatabaseCleanup.d.ts.map +1 -0
  104. package/dist/testing/DatabaseCleanup.js +40 -0
  105. package/dist/testing/DatabaseCleanup.js.map +1 -0
  106. package/dist/testing/Factory.d.ts +59 -0
  107. package/dist/testing/Factory.d.ts.map +1 -0
  108. package/dist/testing/Factory.js +105 -0
  109. package/dist/testing/Factory.js.map +1 -0
  110. package/dist/testing/TestDatabase.d.ts +25 -0
  111. package/dist/testing/TestDatabase.d.ts.map +1 -0
  112. package/dist/testing/TestDatabase.js +52 -0
  113. package/dist/testing/TestDatabase.js.map +1 -0
  114. package/dist/testing/index.d.ts +4 -0
  115. package/dist/testing/index.d.ts.map +1 -0
  116. package/dist/testing/index.js +4 -0
  117. package/dist/testing/index.js.map +1 -0
  118. package/dist/utils/casing.d.ts +5 -0
  119. package/dist/utils/casing.d.ts.map +1 -0
  120. package/dist/utils/casing.js +9 -0
  121. package/dist/utils/casing.js.map +1 -0
  122. package/dist/utils/dialectFromUrl.d.ts +10 -0
  123. package/dist/utils/dialectFromUrl.d.ts.map +1 -0
  124. package/dist/utils/dialectFromUrl.js +8 -0
  125. package/dist/utils/dialectFromUrl.js.map +1 -0
  126. package/dist/utils/identifier.d.ts +19 -0
  127. package/dist/utils/identifier.d.ts.map +1 -0
  128. package/dist/utils/identifier.js +27 -0
  129. package/dist/utils/identifier.js.map +1 -0
  130. package/dist/utils/safePath.d.ts +22 -0
  131. package/dist/utils/safePath.d.ts.map +1 -0
  132. package/dist/utils/safePath.js +46 -0
  133. package/dist/utils/safePath.js.map +1 -0
  134. package/dist/utils/transactionBrand.d.ts +5 -0
  135. package/dist/utils/transactionBrand.d.ts.map +1 -0
  136. package/dist/utils/transactionBrand.js +5 -0
  137. package/dist/utils/transactionBrand.js.map +1 -0
  138. package/index.darwin-arm64.node +0 -0
  139. package/index.darwin-x64.node +0 -0
  140. package/index.linux-arm64-gnu.node +0 -0
  141. package/index.linux-x64-gnu.node +0 -0
  142. package/index.win32-x64-msvc.node +0 -0
  143. package/package.json +1 -1
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Lifecycle hook decorators — Lucid-compatible hook surface.
3
+ *
4
+ * Decorate a static method on an entity with one of the hooks below; Atlas
5
+ * fires it at the matching point in the BaseRepository CRUD pipeline. Hooks
6
+ * are inherited from the prototype chain — a hook on a parent entity also
7
+ * fires for subclasses.
8
+ *
9
+ * class User extends BaseEntity {
10
+ * @beforeSave()
11
+ * static async hashPassword(user: User) {
12
+ * if (user.isDirty('password')) {
13
+ * user.password = await hash(user.password)
14
+ * }
15
+ * }
16
+ * }
17
+ *
18
+ * @implements Story 32.1
19
+ */
20
+ import "reflect-metadata";
21
+ const HOOKS_KEY = Symbol.for("atlas:hooks");
22
+ function getOwnRegistry(target) {
23
+ const existing = Reflect.getOwnMetadata(HOOKS_KEY, target);
24
+ if (isHookRegistry(existing))
25
+ return existing;
26
+ const registry = {};
27
+ Reflect.defineMetadata(HOOKS_KEY, registry, target);
28
+ return registry;
29
+ }
30
+ function isHookRegistry(value) {
31
+ if (typeof value !== "object" || value === null)
32
+ return false;
33
+ for (const v of Object.values(value)) {
34
+ if (v !== undefined && !Array.isArray(v))
35
+ return false;
36
+ }
37
+ return true;
38
+ }
39
+ function isHookHandler(value) {
40
+ return typeof value === "function";
41
+ }
42
+ /** Register a static method on the class as a hook handler. */
43
+ function register(kind) {
44
+ return (target, propertyKey) => {
45
+ // target is the constructor for static methods, the prototype for instance methods
46
+ const ctor = typeof target === "function" ? target : target.constructor;
47
+ const handler = Reflect.get(ctor, propertyKey);
48
+ if (!isHookHandler(handler)) {
49
+ throw new Error(`@${kind} must decorate a static method, got ${String(propertyKey)}`);
50
+ }
51
+ const registry = getOwnRegistry(ctor);
52
+ if (!registry[kind])
53
+ registry[kind] = [];
54
+ registry[kind]?.push(handler);
55
+ };
56
+ }
57
+ // ─── Decorators (one per hook kind) ───────────────────────────
58
+ export const beforeSave = () => register("beforeSave");
59
+ export const afterSave = () => register("afterSave");
60
+ export const beforeCreate = () => register("beforeCreate");
61
+ export const afterCreate = () => register("afterCreate");
62
+ export const beforeUpdate = () => register("beforeUpdate");
63
+ export const afterUpdate = () => register("afterUpdate");
64
+ export const beforeDelete = () => register("beforeDelete");
65
+ export const afterDelete = () => register("afterDelete");
66
+ export const beforeFind = () => register("beforeFind");
67
+ export const afterFind = () => register("afterFind");
68
+ export const beforeFetch = () => register("beforeFetch");
69
+ export const afterFetch = () => register("afterFetch");
70
+ export const beforePaginate = () => register("beforePaginate");
71
+ export const afterPaginate = () => register("afterPaginate");
72
+ /**
73
+ * Walk the prototype chain and collect every handler registered for `kind`.
74
+ * Parent-class hooks fire BEFORE child-class hooks (so a base entity can set
75
+ * up scoping that the child then refines).
76
+ */
77
+ export function collectHooks(entityClass, kind) {
78
+ const handlers = [];
79
+ let ctor = entityClass;
80
+ const chain = [];
81
+ while (ctor &&
82
+ ctor !== Function.prototype &&
83
+ ctor.name) {
84
+ chain.push(ctor);
85
+ ctor = Object.getPrototypeOf(ctor);
86
+ }
87
+ // Walk parent → child so the most-base hook fires first
88
+ for (const c of chain.reverse()) {
89
+ const registry = Reflect.getOwnMetadata(HOOKS_KEY, c);
90
+ const list = registry?.[kind];
91
+ if (list)
92
+ handlers.push(...list);
93
+ }
94
+ return handlers;
95
+ }
96
+ /**
97
+ * Fire every handler for `kind` sequentially. Awaits each one so a hook can
98
+ * mutate the entity before the next hook (or the persistence step) sees it.
99
+ * If any hook throws, the whole operation aborts and the error propagates.
100
+ */
101
+ export async function fireHooks(entityClass, kind, arg) {
102
+ const handlers = collectHooks(entityClass, kind);
103
+ for (const handler of handlers) {
104
+ await handler(arg);
105
+ }
106
+ }
107
+ //# sourceMappingURL=hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/decorators/hooks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * `scope()` — typed identity helper for declaring entity query scopes.
3
+ *
4
+ * Entity classes expose reusable filter/sort logic via `static scopes = {...}`.
5
+ * TypeScript can't infer the scope type on the naked object form, so this
6
+ * helper lets callers pin the argument types explicitly:
7
+ *
8
+ * class User extends BaseEntity {
9
+ * static scopes = {
10
+ * active: scope((q: ModelQuery<User>) => q.where('status', 'active')),
11
+ * forOrg: scope((q: ModelQuery<User>, org: Org) => q.where('org_id', org.id)),
12
+ * }
13
+ * }
14
+ *
15
+ * The runtime is an identity pass-through — `scope` returns its argument
16
+ * unchanged. Its only purpose is to give TS enough information to infer the
17
+ * scope's parameter types (and, by extension, the return type of
18
+ * `repo.query().apply(s => s.forOrg(...))` call sites).
19
+ *
20
+ * @implements Story 29.8 (scope helper)
21
+ */
22
+ import type { BaseEntity } from "../BaseEntity.js";
23
+ import type { ModelQuery } from "../ModelQuery.js";
24
+ /**
25
+ * A query scope function — takes the current query as first argument and
26
+ * an arbitrary list of extra arguments. Returns the query for chaining
27
+ * (or `void` — the chain is applied in place).
28
+ */
29
+ export type ScopeFn<TEntity extends BaseEntity, Args extends unknown[] = []> = (query: ModelQuery<TEntity>, ...args: Args) => ModelQuery<TEntity> | undefined;
30
+ /**
31
+ * Typed identity helper. Pass any scope function through `scope()` to get
32
+ * TS inference without changing the runtime behaviour.
33
+ */
34
+ export declare function scope<TEntity extends BaseEntity, Args extends unknown[] = []>(fn: ScopeFn<TEntity, Args>): ScopeFn<TEntity, Args>;
35
+ //# sourceMappingURL=scope.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../../src/decorators/scope.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD;;;;GAIG;AACH,MAAM,MAAM,OAAO,CAAC,OAAO,SAAS,UAAU,EAAE,IAAI,SAAS,OAAO,EAAE,GAAG,EAAE,IAAI,CAC9E,KAAK,EAAE,UAAU,CAAC,OAAO,CAAC,EAC1B,GAAG,IAAI,EAAE,IAAI,KACT,UAAU,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC;AAErC;;;GAGG;AACH,wBAAgB,KAAK,CAAC,OAAO,SAAS,UAAU,EAAE,IAAI,SAAS,OAAO,EAAE,GAAG,EAAE,EAC5E,EAAE,EAAE,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,GACxB,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAExB"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * `scope()` — typed identity helper for declaring entity query scopes.
3
+ *
4
+ * Entity classes expose reusable filter/sort logic via `static scopes = {...}`.
5
+ * TypeScript can't infer the scope type on the naked object form, so this
6
+ * helper lets callers pin the argument types explicitly:
7
+ *
8
+ * class User extends BaseEntity {
9
+ * static scopes = {
10
+ * active: scope((q: ModelQuery<User>) => q.where('status', 'active')),
11
+ * forOrg: scope((q: ModelQuery<User>, org: Org) => q.where('org_id', org.id)),
12
+ * }
13
+ * }
14
+ *
15
+ * The runtime is an identity pass-through — `scope` returns its argument
16
+ * unchanged. Its only purpose is to give TS enough information to infer the
17
+ * scope's parameter types (and, by extension, the return type of
18
+ * `repo.query().apply(s => s.forOrg(...))` call sites).
19
+ *
20
+ * @implements Story 29.8 (scope helper)
21
+ */
22
+ /**
23
+ * Typed identity helper. Pass any scope function through `scope()` to get
24
+ * TS inference without changing the runtime behaviour.
25
+ */
26
+ export function scope(fn) {
27
+ return fn;
28
+ }
29
+ //# sourceMappingURL=scope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scope.js","sourceRoot":"","sources":["../../src/decorators/scope.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAeH;;;GAGG;AACH,MAAM,UAAU,KAAK,CACpB,EAA0B;IAE1B,OAAO,EAAE,CAAC;AACX,CAAC"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Atlas error hierarchy — structured errors for the ORM layer.
3
+ *
4
+ * Every error extends {@link AtlasError} with a stable code (prefixed `ATLAS_`),
5
+ * a human-readable message, and an optional hint. Specialised subclasses allow
6
+ * callers to catch by type (`catch (e) { if (e instanceof OptimisticLockError) ... }`)
7
+ * without string-matching on codes.
8
+ *
9
+ * @implements Story 32.10
10
+ */
11
+ export declare class AtlasError extends Error {
12
+ readonly code: string;
13
+ readonly hint?: string;
14
+ constructor(code: string, message: string, options?: {
15
+ hint?: string;
16
+ });
17
+ }
18
+ /**
19
+ * Thrown when an entity cannot be found (find, findOrFail, firstOrFail).
20
+ */
21
+ export declare class EntityNotFoundError extends AtlasError {
22
+ readonly entityClass: string;
23
+ readonly criteria: unknown;
24
+ constructor(entityClass: string, criteria: unknown, hint?: string);
25
+ }
26
+ /**
27
+ * Thrown when an optimistic lock check fails on save — the row was modified
28
+ * by another transaction since we read it. Requires `@Version()` column on the entity.
29
+ */
30
+ export declare class OptimisticLockError extends AtlasError {
31
+ readonly entityClass: string;
32
+ readonly primaryKey: unknown;
33
+ readonly expectedVersion: number;
34
+ constructor(entityClass: string, primaryKey: unknown, expectedVersion: number);
35
+ }
36
+ /**
37
+ * Thrown when accessing a relation that was not eager-loaded AND has no lazy
38
+ * loader available on the entity. Forces callers to be explicit about loading.
39
+ */
40
+ export declare class RelationNotLoadedError extends AtlasError {
41
+ readonly entityClass: string;
42
+ readonly relationName: string;
43
+ constructor(entityClass: string, relationName: string);
44
+ }
45
+ /**
46
+ * Thrown when mass-assignment (`fill` / `merge` / `create`) tries to set a
47
+ * field that is not in the `fillable` list or is in the `guarded` list.
48
+ */
49
+ export declare class MassAssignmentError extends AtlasError {
50
+ readonly entityClass: string;
51
+ readonly attribute: string;
52
+ constructor(entityClass: string, attribute: string);
53
+ }
54
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,qBAAa,UAAW,SAAQ,KAAK;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;gBAEX,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE;CAMtE;AAED;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,UAAU;IAClD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;gBAEf,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,MAAM;CAUjE;AAED;;;GAGG;AACH,qBAAa,mBAAoB,SAAQ,UAAU;IAClD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;gBAGhC,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,OAAO,EACnB,eAAe,EAAE,MAAM;CAYxB;AAED;;;GAGG;AACH,qBAAa,sBAAuB,SAAQ,UAAU;IACrD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;gBAElB,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM;CAYrD;AAED;;;GAGG;AACH,qBAAa,mBAAoB,SAAQ,UAAU;IAClD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;gBAEf,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;CAYlD"}
package/dist/errors.js ADDED
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Atlas error hierarchy — structured errors for the ORM layer.
3
+ *
4
+ * Every error extends {@link AtlasError} with a stable code (prefixed `ATLAS_`),
5
+ * a human-readable message, and an optional hint. Specialised subclasses allow
6
+ * callers to catch by type (`catch (e) { if (e instanceof OptimisticLockError) ... }`)
7
+ * without string-matching on codes.
8
+ *
9
+ * @implements Story 32.10
10
+ */
11
+ export class AtlasError extends Error {
12
+ code;
13
+ hint;
14
+ constructor(code, message, options) {
15
+ super(message);
16
+ this.name = "AtlasError";
17
+ this.code = code.startsWith("ATLAS_") ? code : `ATLAS_${code}`;
18
+ this.hint = options?.hint;
19
+ }
20
+ }
21
+ /**
22
+ * Thrown when an entity cannot be found (find, findOrFail, firstOrFail).
23
+ */
24
+ export class EntityNotFoundError extends AtlasError {
25
+ entityClass;
26
+ criteria;
27
+ constructor(entityClass, criteria, hint) {
28
+ super("E_ENTITY_NOT_FOUND", `${entityClass} not found with ${JSON.stringify(criteria)}`, { hint });
29
+ this.name = "EntityNotFoundError";
30
+ this.entityClass = entityClass;
31
+ this.criteria = criteria;
32
+ }
33
+ }
34
+ /**
35
+ * Thrown when an optimistic lock check fails on save — the row was modified
36
+ * by another transaction since we read it. Requires `@Version()` column on the entity.
37
+ */
38
+ export class OptimisticLockError extends AtlasError {
39
+ entityClass;
40
+ primaryKey;
41
+ expectedVersion;
42
+ constructor(entityClass, primaryKey, expectedVersion) {
43
+ super("E_OPTIMISTIC_LOCK", `Optimistic lock failure saving ${entityClass}#${String(primaryKey)}: the row was modified by another transaction (expected version ${expectedVersion}).`, { hint: "Reload the entity, reapply your changes, and try again." });
44
+ this.name = "OptimisticLockError";
45
+ this.entityClass = entityClass;
46
+ this.primaryKey = primaryKey;
47
+ this.expectedVersion = expectedVersion;
48
+ }
49
+ }
50
+ /**
51
+ * Thrown when accessing a relation that was not eager-loaded AND has no lazy
52
+ * loader available on the entity. Forces callers to be explicit about loading.
53
+ */
54
+ export class RelationNotLoadedError extends AtlasError {
55
+ entityClass;
56
+ relationName;
57
+ constructor(entityClass, relationName) {
58
+ super("E_RELATION_NOT_LOADED", `Relation '${relationName}' on ${entityClass} was not loaded.`, {
59
+ hint: `Call .preload('${relationName}') on the query or .load('${relationName}') on the instance.`,
60
+ });
61
+ this.name = "RelationNotLoadedError";
62
+ this.entityClass = entityClass;
63
+ this.relationName = relationName;
64
+ }
65
+ }
66
+ /**
67
+ * Thrown when mass-assignment (`fill` / `merge` / `create`) tries to set a
68
+ * field that is not in the `fillable` list or is in the `guarded` list.
69
+ */
70
+ export class MassAssignmentError extends AtlasError {
71
+ entityClass;
72
+ attribute;
73
+ constructor(entityClass, attribute) {
74
+ super("E_MASS_ASSIGNMENT", `Attribute '${attribute}' on ${entityClass} is not mass-assignable.`, {
75
+ hint: `Add '${attribute}' to the static 'fillable' array or remove it from 'guarded'.`,
76
+ });
77
+ this.name = "MassAssignmentError";
78
+ this.entityClass = entityClass;
79
+ this.attribute = attribute;
80
+ }
81
+ }
82
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,OAAO,UAAW,SAAQ,KAAK;IAC3B,IAAI,CAAS;IACb,IAAI,CAAU;IAEvB,YAAY,IAAY,EAAE,OAAe,EAAE,OAA2B;QACrE,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;QACzB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,IAAI,EAAE,CAAC;QAC/D,IAAI,CAAC,IAAI,GAAG,OAAO,EAAE,IAAI,CAAC;IAC3B,CAAC;CACD;AAED;;GAEG;AACH,MAAM,OAAO,mBAAoB,SAAQ,UAAU;IACzC,WAAW,CAAS;IACpB,QAAQ,CAAU;IAE3B,YAAY,WAAmB,EAAE,QAAiB,EAAE,IAAa;QAChE,KAAK,CACJ,oBAAoB,EACpB,GAAG,WAAW,mBAAmB,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,EAC3D,EAAE,IAAI,EAAE,CACR,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;QAClC,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC1B,CAAC;CACD;AAED;;;GAGG;AACH,MAAM,OAAO,mBAAoB,SAAQ,UAAU;IACzC,WAAW,CAAS;IACpB,UAAU,CAAU;IACpB,eAAe,CAAS;IAEjC,YACC,WAAmB,EACnB,UAAmB,EACnB,eAAuB;QAEvB,KAAK,CACJ,mBAAmB,EACnB,kCAAkC,WAAW,IAAI,MAAM,CAAC,UAAU,CAAC,mEAAmE,eAAe,IAAI,EACzJ,EAAE,IAAI,EAAE,yDAAyD,EAAE,CACnE,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;QAClC,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,eAAe,GAAG,eAAe,CAAC;IACxC,CAAC;CACD;AAED;;;GAGG;AACH,MAAM,OAAO,sBAAuB,SAAQ,UAAU;IAC5C,WAAW,CAAS;IACpB,YAAY,CAAS;IAE9B,YAAY,WAAmB,EAAE,YAAoB;QACpD,KAAK,CACJ,uBAAuB,EACvB,aAAa,YAAY,QAAQ,WAAW,kBAAkB,EAC9D;YACC,IAAI,EAAE,kBAAkB,YAAY,6BAA6B,YAAY,qBAAqB;SAClG,CACD,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;QACrC,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IAClC,CAAC;CACD;AAED;;;GAGG;AACH,MAAM,OAAO,mBAAoB,SAAQ,UAAU;IACzC,WAAW,CAAS;IACpB,SAAS,CAAS;IAE3B,YAAY,WAAmB,EAAE,SAAiB;QACjD,KAAK,CACJ,mBAAmB,EACnB,cAAc,SAAS,QAAQ,WAAW,0BAA0B,EACpE;YACC,IAAI,EAAE,QAAQ,SAAS,+DAA+D;SACtF,CACD,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;QAClC,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC5B,CAAC;CACD"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * @module @c9up/atlas
3
+ * @description Atlas — Data Mapper ORM for the Ream framework
4
+ * @implements FR29, FR30, FR31, FR34, FR35, FR37
5
+ */
6
+ import "reflect-metadata";
7
+ export { SQLITE_PROD_PRAGMAS } from "./AtlasProvider.js";
8
+ export type { AsyncDatabaseConnection } from "./adapters/NapiDbAdapter.js";
9
+ export { createNapiConnection } from "./adapters/NapiDbAdapter.js";
10
+ export type { DomainEvent } from "./BaseEntity.js";
11
+ export { BaseEntity } from "./BaseEntity.js";
12
+ export type { DatabaseConnection } from "./BaseRepository.js";
13
+ export { BaseRepository } from "./BaseRepository.js";
14
+ export { defineConfig } from "./config.js";
15
+ export { configure } from "./configure.js";
16
+ export type { ColumnAdapter, ColumnMetadata, ColumnOptions, DateColumnConfig, DateTimeColumnOptions, EntityMetadata, ManyToManyOptions, RelationMetadata, } from "./decorators/entity.js";
17
+ export { BelongsTo, Column, column, computed, Entity, getColumnMetadata, getDateColumnConfig, getEntityMetadata, getPrimaryKey, getRelationMetadata, HasMany, HasManyThrough, HasOne, HasOneThrough, hasSoftDeletes, ManyToMany, PrimaryKey, SoftDeletes, } from "./decorators/entity.js";
18
+ export { afterCreate, afterDelete, afterFetch, afterFind, afterPaginate, afterSave, afterUpdate, beforeCreate, beforeDelete, beforeFetch, beforeFind, beforePaginate, beforeSave, beforeUpdate, } from "./decorators/hooks.js";
19
+ export type { ScopeFn } from "./decorators/scope.js";
20
+ export { scope } from "./decorators/scope.js";
21
+ export { AtlasError, EntityNotFoundError, MassAssignmentError, OptimisticLockError, RelationNotLoadedError, } from "./errors.js";
22
+ export { isAtlasStrictMode, ModelQuery, setAtlasStrictMode, } from "./ModelQuery.js";
23
+ export type { NamingStrategy } from "./naming/NamingStrategy.js";
24
+ export { CamelCaseNamingStrategy, defaultNamingStrategy, getNamingStrategy, } from "./naming/NamingStrategy.js";
25
+ export type { AtlasDialect } from "./query/native.js";
26
+ export { getAtlasDialect, setAtlasDialect } from "./query/native.js";
27
+ export type { CteDefinition, ExistsClause, OrderByClause, QueryResult, WhereClause, WhereOperator, } from "./query/QueryBuilder.js";
28
+ export { QueryBuilder, RawSql } from "./query/QueryBuilder.js";
29
+ export { Migration } from "./schema/Migration.js";
30
+ export type { DatabaseAdapter, MigrationRecord, MigrationState, MigrationStatus, } from "./schema/MigrationRunner.js";
31
+ export { MigrationRunner } from "./schema/MigrationRunner.js";
32
+ export type { ColumnDefinition, ColumnType } from "./schema/SchemaBuilder.js";
33
+ export { Schema, TableBuilder } from "./schema/SchemaBuilder.js";
34
+ export { BaseSeeder, runSeederDirectory, runSeeders, Seeder, } from "./schema/Seeder.js";
35
+ export type { TransactionClient } from "./Transaction.js";
36
+ export { transaction } from "./Transaction.js";
37
+ export { truncateAll, useTransaction } from "./testing/DatabaseCleanup.js";
38
+ export { factory } from "./testing/Factory.js";
39
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,kBAAkB,CAAC;AAE1B,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,YAAY,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AAC3E,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,YAAY,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,YAAY,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,YAAY,EACX,aAAa,EACb,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,qBAAqB,EACrB,cAAc,EACd,iBAAiB,EACjB,gBAAgB,GAChB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACN,SAAS,EACT,MAAM,EACN,MAAM,EACN,QAAQ,EACR,MAAM,EACN,iBAAiB,EACjB,mBAAmB,EACnB,iBAAiB,EACjB,aAAa,EACb,mBAAmB,EACnB,OAAO,EACP,cAAc,EACd,MAAM,EACN,aAAa,EACb,cAAc,EACd,UAAU,EACV,UAAU,EACV,WAAW,GACX,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACN,WAAW,EACX,WAAW,EACX,UAAU,EACV,SAAS,EACT,aAAa,EACb,SAAS,EACT,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,UAAU,EACV,cAAc,EACd,UAAU,EACV,YAAY,GACZ,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EACN,UAAU,EACV,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,sBAAsB,GACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,iBAAiB,EACjB,UAAU,EACV,kBAAkB,GAClB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EACN,uBAAuB,EACvB,qBAAqB,EACrB,iBAAiB,GACjB,MAAM,4BAA4B,CAAC;AACpC,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACrE,YAAY,EACX,aAAa,EACb,YAAY,EACZ,aAAa,EACb,WAAW,EACX,WAAW,EACX,aAAa,GACb,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,YAAY,EACX,eAAe,EACf,eAAe,EACf,cAAc,EACd,eAAe,GACf,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,YAAY,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAC9E,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EACN,UAAU,EACV,kBAAkB,EAClB,UAAU,EACV,MAAM,GACN,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC3E,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,28 @@
1
+ /**
2
+ * @module @c9up/atlas
3
+ * @description Atlas — Data Mapper ORM for the Ream framework
4
+ * @implements FR29, FR30, FR31, FR34, FR35, FR37
5
+ */
6
+ import "reflect-metadata";
7
+ export { SQLITE_PROD_PRAGMAS } from "./AtlasProvider.js";
8
+ export { createNapiConnection } from "./adapters/NapiDbAdapter.js";
9
+ export { BaseEntity } from "./BaseEntity.js";
10
+ export { BaseRepository } from "./BaseRepository.js";
11
+ export { defineConfig } from "./config.js";
12
+ export { configure } from "./configure.js";
13
+ export { BelongsTo, Column, column, computed, Entity, getColumnMetadata, getDateColumnConfig, getEntityMetadata, getPrimaryKey, getRelationMetadata, HasMany, HasManyThrough, HasOne, HasOneThrough, hasSoftDeletes, ManyToMany, PrimaryKey, SoftDeletes, } from "./decorators/entity.js";
14
+ export { afterCreate, afterDelete, afterFetch, afterFind, afterPaginate, afterSave, afterUpdate, beforeCreate, beforeDelete, beforeFetch, beforeFind, beforePaginate, beforeSave, beforeUpdate, } from "./decorators/hooks.js";
15
+ export { scope } from "./decorators/scope.js";
16
+ export { AtlasError, EntityNotFoundError, MassAssignmentError, OptimisticLockError, RelationNotLoadedError, } from "./errors.js";
17
+ export { isAtlasStrictMode, ModelQuery, setAtlasStrictMode, } from "./ModelQuery.js";
18
+ export { CamelCaseNamingStrategy, defaultNamingStrategy, getNamingStrategy, } from "./naming/NamingStrategy.js";
19
+ export { getAtlasDialect, setAtlasDialect } from "./query/native.js";
20
+ export { QueryBuilder, RawSql } from "./query/QueryBuilder.js";
21
+ export { Migration } from "./schema/Migration.js";
22
+ export { MigrationRunner } from "./schema/MigrationRunner.js";
23
+ export { Schema, TableBuilder } from "./schema/SchemaBuilder.js";
24
+ export { BaseSeeder, runSeederDirectory, runSeeders, Seeder, } from "./schema/Seeder.js";
25
+ export { transaction } from "./Transaction.js";
26
+ export { truncateAll, useTransaction } from "./testing/DatabaseCleanup.js";
27
+ export { factory } from "./testing/Factory.js";
28
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,kBAAkB,CAAC;AAE1B,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAEnE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAW3C,OAAO,EACN,SAAS,EACT,MAAM,EACN,MAAM,EACN,QAAQ,EACR,MAAM,EACN,iBAAiB,EACjB,mBAAmB,EACnB,iBAAiB,EACjB,aAAa,EACb,mBAAmB,EACnB,OAAO,EACP,cAAc,EACd,MAAM,EACN,aAAa,EACb,cAAc,EACd,UAAU,EACV,UAAU,EACV,WAAW,GACX,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACN,WAAW,EACX,WAAW,EACX,UAAU,EACV,SAAS,EACT,aAAa,EACb,SAAS,EACT,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,UAAU,EACV,cAAc,EACd,UAAU,EACV,YAAY,GACZ,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EACN,UAAU,EACV,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,sBAAsB,GACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,iBAAiB,EACjB,UAAU,EACV,kBAAkB,GAClB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACN,uBAAuB,EACvB,qBAAqB,EACrB,iBAAiB,GACjB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AASrE,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAOlD,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAE9D,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EACN,UAAU,EACV,kBAAkB,EAClB,UAAU,EACV,MAAM,GACN,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC3E,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Naming Strategy — override the snake_case ↔ camelCase convention per-entity.
3
+ *
4
+ * Each entity class can declare `static namingStrategy = new MyStrategy()` to
5
+ * replace the default camelCase ↔ snake_case conversion with its own rules.
6
+ * Used to migrate legacy databases (e.g. PascalCase columns, prefixed tables,
7
+ * custom pivot table names).
8
+ *
9
+ * class LegacyUser extends BaseEntity {
10
+ * static namingStrategy = new SnakeCaseSingularStrategy()
11
+ * }
12
+ *
13
+ * @implements Story 32.7
14
+ */
15
+ /** Constructor-level hook for a naming override. Defaults to camelCase ↔ snake_case. */
16
+ export interface NamingStrategy {
17
+ /** Table name for an entity class, given its constructor name. */
18
+ tableName(className: string): string;
19
+ /** Database column name for a TS property (e.g. `userId` → `user_id`). */
20
+ columnName(propertyName: string): string;
21
+ /** Reverse mapping — DB column back to the TS property. Used by hydrate. */
22
+ propertyName(columnName: string): string;
23
+ /** Serialized field name in `toJSON()`. Defaults to the property name. */
24
+ serializedName(propertyName: string): string;
25
+ /** Local key for a belongsTo/hasMany relation (usually the parent PK). */
26
+ relationLocalKey(kind: "belongsTo" | "hasMany" | "hasOne" | "manyToMany", parentPk: string): string;
27
+ /** Foreign key column name on the owning side of a relation. */
28
+ relationForeignKey(kind: "belongsTo" | "hasMany" | "hasOne" | "manyToMany", parentClass: string, parentPk: string): string;
29
+ /** Default pivot table name for a manyToMany relation. */
30
+ relationPivotTable(aClass: string, bClass: string): string;
31
+ }
32
+ /**
33
+ * Default strategy — camelCase TS properties, snake_case DB columns, plural
34
+ * snake_case table names, `<parent_name>_<parent_pk>` foreign keys.
35
+ */
36
+ export declare class CamelCaseNamingStrategy implements NamingStrategy {
37
+ tableName(className: string): string;
38
+ columnName(propertyName: string): string;
39
+ propertyName(columnName: string): string;
40
+ serializedName(propertyName: string): string;
41
+ relationLocalKey(_kind: "belongsTo" | "hasMany" | "hasOne" | "manyToMany", parentPk: string): string;
42
+ relationForeignKey(_kind: "belongsTo" | "hasMany" | "hasOne" | "manyToMany", parentClass: string, parentPk: string): string;
43
+ relationPivotTable(aClass: string, bClass: string): string;
44
+ }
45
+ /** The default singleton — used when an entity doesn't override `static namingStrategy`. */
46
+ export declare const defaultNamingStrategy: NamingStrategy;
47
+ /**
48
+ * Resolve the naming strategy for an entity class. Walks the prototype chain
49
+ * so subclasses inherit their parent's strategy unless they override.
50
+ */
51
+ export declare function getNamingStrategy(entityClass: object): NamingStrategy;
52
+ //# sourceMappingURL=NamingStrategy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NamingStrategy.d.ts","sourceRoot":"","sources":["../../src/naming/NamingStrategy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,wFAAwF;AACxF,MAAM,WAAW,cAAc;IAC9B,kEAAkE;IAClE,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;IACrC,0EAA0E;IAC1E,UAAU,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAAC;IACzC,4EAA4E;IAC5E,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC;IACzC,0EAA0E;IAC1E,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7C,0EAA0E;IAC1E,gBAAgB,CACf,IAAI,EAAE,WAAW,GAAG,SAAS,GAAG,QAAQ,GAAG,YAAY,EACvD,QAAQ,EAAE,MAAM,GACd,MAAM,CAAC;IACV,gEAAgE;IAChE,kBAAkB,CACjB,IAAI,EAAE,WAAW,GAAG,SAAS,GAAG,QAAQ,GAAG,YAAY,EACvD,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACd,MAAM,CAAC;IACV,0DAA0D;IAC1D,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;CAC3D;AAED;;;GAGG;AACH,qBAAa,uBAAwB,YAAW,cAAc;IAC7D,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;IAOpC,UAAU,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM;IAIxC,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;IAIxC,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM;IAI5C,gBAAgB,CACf,KAAK,EAAE,WAAW,GAAG,SAAS,GAAG,QAAQ,GAAG,YAAY,EACxD,QAAQ,EAAE,MAAM,GACd,MAAM;IAIT,kBAAkB,CACjB,KAAK,EAAE,WAAW,GAAG,SAAS,GAAG,QAAQ,GAAG,YAAY,EACxD,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACd,MAAM;IAIT,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM;CAK1D;AAED,4FAA4F;AAC5F,eAAO,MAAM,qBAAqB,EAAE,cACN,CAAC;AAE/B;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,cAAc,CASrE"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Naming Strategy — override the snake_case ↔ camelCase convention per-entity.
3
+ *
4
+ * Each entity class can declare `static namingStrategy = new MyStrategy()` to
5
+ * replace the default camelCase ↔ snake_case conversion with its own rules.
6
+ * Used to migrate legacy databases (e.g. PascalCase columns, prefixed tables,
7
+ * custom pivot table names).
8
+ *
9
+ * class LegacyUser extends BaseEntity {
10
+ * static namingStrategy = new SnakeCaseSingularStrategy()
11
+ * }
12
+ *
13
+ * @implements Story 32.7
14
+ */
15
+ import { camelToSnake, snakeToCamel } from "../utils/casing.js";
16
+ /**
17
+ * Default strategy — camelCase TS properties, snake_case DB columns, plural
18
+ * snake_case table names, `<parent_name>_<parent_pk>` foreign keys.
19
+ */
20
+ export class CamelCaseNamingStrategy {
21
+ tableName(className) {
22
+ // Default: snake_case + plural-s. Entities wanting non-default (e.g. irregular
23
+ // plurals like "people") should override via static `namingStrategy`.
24
+ const snake = camelToSnake(className);
25
+ return snake.endsWith("s") ? snake : `${snake}s`;
26
+ }
27
+ columnName(propertyName) {
28
+ return camelToSnake(propertyName);
29
+ }
30
+ propertyName(columnName) {
31
+ return snakeToCamel(columnName);
32
+ }
33
+ serializedName(propertyName) {
34
+ return propertyName;
35
+ }
36
+ relationLocalKey(_kind, parentPk) {
37
+ return parentPk;
38
+ }
39
+ relationForeignKey(_kind, parentClass, parentPk) {
40
+ return `${camelToSnake(parentClass)}_${parentPk}`;
41
+ }
42
+ relationPivotTable(aClass, bClass) {
43
+ // Sort alphabetically so `UserSkill` and `SkillUser` collapse to the same name.
44
+ const [x, y] = [camelToSnake(aClass), camelToSnake(bClass)].sort();
45
+ return `${x}_${y}`;
46
+ }
47
+ }
48
+ /** The default singleton — used when an entity doesn't override `static namingStrategy`. */
49
+ export const defaultNamingStrategy = new CamelCaseNamingStrategy();
50
+ /**
51
+ * Resolve the naming strategy for an entity class. Walks the prototype chain
52
+ * so subclasses inherit their parent's strategy unless they override.
53
+ */
54
+ export function getNamingStrategy(entityClass) {
55
+ let current = entityClass;
56
+ while (current && current !== Function.prototype) {
57
+ const explicit = current
58
+ .namingStrategy;
59
+ if (explicit)
60
+ return explicit;
61
+ current = Object.getPrototypeOf(current);
62
+ }
63
+ return defaultNamingStrategy;
64
+ }
65
+ //# sourceMappingURL=NamingStrategy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NamingStrategy.js","sourceRoot":"","sources":["../../src/naming/NamingStrategy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AA2BhE;;;GAGG;AACH,MAAM,OAAO,uBAAuB;IACnC,SAAS,CAAC,SAAiB;QAC1B,+EAA+E;QAC/E,sEAAsE;QACtE,MAAM,KAAK,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;QACtC,OAAO,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC;IAClD,CAAC;IAED,UAAU,CAAC,YAAoB;QAC9B,OAAO,YAAY,CAAC,YAAY,CAAC,CAAC;IACnC,CAAC;IAED,YAAY,CAAC,UAAkB;QAC9B,OAAO,YAAY,CAAC,UAAU,CAAC,CAAC;IACjC,CAAC;IAED,cAAc,CAAC,YAAoB;QAClC,OAAO,YAAY,CAAC;IACrB,CAAC;IAED,gBAAgB,CACf,KAAwD,EACxD,QAAgB;QAEhB,OAAO,QAAQ,CAAC;IACjB,CAAC;IAED,kBAAkB,CACjB,KAAwD,EACxD,WAAmB,EACnB,QAAgB;QAEhB,OAAO,GAAG,YAAY,CAAC,WAAW,CAAC,IAAI,QAAQ,EAAE,CAAC;IACnD,CAAC;IAED,kBAAkB,CAAC,MAAc,EAAE,MAAc;QAChD,gFAAgF;QAChF,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACnE,OAAO,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;IACpB,CAAC;CACD;AAED,4FAA4F;AAC5F,MAAM,CAAC,MAAM,qBAAqB,GACjC,IAAI,uBAAuB,EAAE,CAAC;AAE/B;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,WAAmB;IACpD,IAAI,OAAO,GAAkB,WAAW,CAAC;IACzC,OAAO,OAAO,IAAI,OAAO,KAAK,QAAQ,CAAC,SAAS,EAAE,CAAC;QAClD,MAAM,QAAQ,GAAI,OAA+C;aAC/D,cAAc,CAAC;QACjB,IAAI,QAAQ;YAAE,OAAO,QAAQ,CAAC;QAC9B,OAAO,GAAG,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,qBAAqB,CAAC;AAC9B,CAAC"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Fluent Query Builder — with advanced features (CTE, subqueries, unions, window functions).
3
+ *
4
+ * @implements FR31, FR32, FR33, FR36, FR37
5
+ */
6
+ import { type AtlasDialect } from "./native.js";
7
+ export type WhereOperator = "=" | "!=" | ">" | ">=" | "<" | "<=" | "LIKE" | "IN" | "NOT IN" | "IS NULL" | "IS NOT NULL";
8
+ export interface WhereClause {
9
+ column: string;
10
+ operator: WhereOperator;
11
+ value: unknown;
12
+ type: "and" | "or";
13
+ }
14
+ export interface ExistsClause {
15
+ kind: "exists";
16
+ subquery: QueryBuilder;
17
+ type: "and" | "or";
18
+ }
19
+ export interface OrderByClause {
20
+ column: string;
21
+ direction: "asc" | "desc";
22
+ }
23
+ export interface CteDefinition {
24
+ name: string;
25
+ query: QueryBuilder | RawSql;
26
+ }
27
+ export interface QueryResult<T> {
28
+ data: T[];
29
+ total?: number;
30
+ page?: number;
31
+ perPage?: number;
32
+ }
33
+ /** Typed raw SQL with parameterized values. */
34
+ export declare class RawSql {
35
+ readonly sql: string;
36
+ readonly params: unknown[];
37
+ constructor(sql: string, params?: unknown[]);
38
+ /** Tagged template literal for raw SQL with automatic parameterization. */
39
+ static sql(strings: TemplateStringsArray, ...values: unknown[]): RawSql;
40
+ }
41
+ /**
42
+ * Fluent query builder — type-safe, composable, with advanced features.
43
+ */
44
+ export declare class QueryBuilder<_T = Record<string, unknown>> {
45
+ #private;
46
+ constructor(table: string, options?: {
47
+ dialect?: AtlasDialect;
48
+ });
49
+ /** SELECT DISTINCT. */
50
+ distinct(): this;
51
+ /** Select specific columns (supports expressions like 'COUNT(*) AS total'). */
52
+ select(...columns: string[]): this;
53
+ /** Add a WHERE condition. */
54
+ where(column: string, operatorOrValue: WhereOperator | unknown, value?: unknown): this;
55
+ /** Add an OR WHERE condition. */
56
+ orWhere(column: string, operatorOrValue: WhereOperator | unknown, value?: unknown): this;
57
+ /** WHERE column IN (values). */
58
+ whereIn(column: string, values: unknown[]): this;
59
+ /** WHERE column IS NULL. */
60
+ whereNull(column: string): this;
61
+ /** WHERE column IS NOT NULL. */
62
+ whereNotNull(column: string): this;
63
+ /** WHERE EXISTS (subquery). Subquery is deferred — toSQL() called at build time. */
64
+ whereExists(subquery: QueryBuilder): this;
65
+ /** GROUP BY columns. */
66
+ groupBy(...columns: string[]): this;
67
+ /** HAVING condition (used after GROUP BY). Supports aggregate expressions. */
68
+ having(column: string, operatorOrValue: WhereOperator | unknown, value?: unknown): this;
69
+ /** ORDER BY column. */
70
+ orderBy(column: string, direction?: "asc" | "desc"): this;
71
+ /** LIMIT results. */
72
+ limit(n: number): this;
73
+ /** OFFSET results. */
74
+ offset(n: number): this;
75
+ /** Paginate results. */
76
+ paginate(page: number, perPage?: number): this;
77
+ /** Eager-load a relation. */
78
+ preload(relation: string): this;
79
+ /** WITH (Common Table Expression). */
80
+ with(name: string, query: QueryBuilder | RawSql): this;
81
+ /** UNION with another query (wrapped in parentheses). */
82
+ union(query: QueryBuilder): this;
83
+ /** UNION ALL with another query (wrapped in parentheses). */
84
+ unionAll(query: QueryBuilder): this;
85
+ /** Build the SQL query string via the Rust compiler. */
86
+ toSQL(): {
87
+ sql: string;
88
+ params: unknown[];
89
+ };
90
+ /** Get the table name. */
91
+ getTable(): string;
92
+ /** Get preloaded relations. */
93
+ getPreloads(): string[];
94
+ }
95
+ //# sourceMappingURL=QueryBuilder.d.ts.map