@c9up/atlas 0.1.19 → 0.2.1

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 (250) hide show
  1. package/README.md +63 -14
  2. package/db.darwin-arm64.node +0 -0
  3. package/db.darwin-x64.node +0 -0
  4. package/db.linux-arm64-gnu.node +0 -0
  5. package/db.linux-x64-gnu.node +0 -0
  6. package/db.win32-x64-msvc.node +0 -0
  7. package/dist/AtlasProvider.d.ts +66 -7
  8. package/dist/AtlasProvider.d.ts.map +1 -1
  9. package/dist/AtlasProvider.js +205 -39
  10. package/dist/AtlasProvider.js.map +1 -1
  11. package/dist/BaseEntity.d.ts +181 -5
  12. package/dist/BaseEntity.d.ts.map +1 -1
  13. package/dist/BaseEntity.js +339 -33
  14. package/dist/BaseEntity.js.map +1 -1
  15. package/dist/BaseModel.d.ts +127 -0
  16. package/dist/BaseModel.d.ts.map +1 -0
  17. package/dist/BaseModel.js +250 -0
  18. package/dist/BaseModel.js.map +1 -0
  19. package/dist/BaseRepository.d.ts +81 -15
  20. package/dist/BaseRepository.d.ts.map +1 -1
  21. package/dist/BaseRepository.js +1433 -387
  22. package/dist/BaseRepository.js.map +1 -1
  23. package/dist/ConnectionManager.d.ts +106 -0
  24. package/dist/ConnectionManager.d.ts.map +1 -0
  25. package/dist/ConnectionManager.js +228 -0
  26. package/dist/ConnectionManager.js.map +1 -0
  27. package/dist/ModelQuery.d.ts +577 -41
  28. package/dist/ModelQuery.d.ts.map +1 -1
  29. package/dist/ModelQuery.js +2188 -291
  30. package/dist/ModelQuery.js.map +1 -1
  31. package/dist/Transaction.d.ts +71 -1
  32. package/dist/Transaction.d.ts.map +1 -1
  33. package/dist/Transaction.js +138 -24
  34. package/dist/Transaction.js.map +1 -1
  35. package/dist/adapters/NapiDbAdapter.d.ts +44 -4
  36. package/dist/adapters/NapiDbAdapter.d.ts.map +1 -1
  37. package/dist/adapters/NapiDbAdapter.js +131 -13
  38. package/dist/adapters/NapiDbAdapter.js.map +1 -1
  39. package/dist/console/contract.d.ts +62 -0
  40. package/dist/console/contract.d.ts.map +1 -0
  41. package/dist/console/contract.js +38 -0
  42. package/dist/console/contract.js.map +1 -0
  43. package/dist/console/factoryCommands.d.ts +23 -0
  44. package/dist/console/factoryCommands.d.ts.map +1 -0
  45. package/dist/console/factoryCommands.js +62 -0
  46. package/dist/console/factoryCommands.js.map +1 -0
  47. package/dist/console/migrationCommands.d.ts +78 -0
  48. package/dist/console/migrationCommands.d.ts.map +1 -0
  49. package/dist/console/migrationCommands.js +327 -0
  50. package/dist/console/migrationCommands.js.map +1 -0
  51. package/dist/console/schemaCheckCommand.d.ts +11 -17
  52. package/dist/console/schemaCheckCommand.d.ts.map +1 -1
  53. package/dist/console/schemaCheckCommand.js +21 -15
  54. package/dist/console/schemaCheckCommand.js.map +1 -1
  55. package/dist/console/schemaDumpCommand.d.ts +30 -0
  56. package/dist/console/schemaDumpCommand.d.ts.map +1 -0
  57. package/dist/console/schemaDumpCommand.js +69 -0
  58. package/dist/console/schemaDumpCommand.js.map +1 -0
  59. package/dist/console/schemaGenerateCommand.d.ts +100 -0
  60. package/dist/console/schemaGenerateCommand.d.ts.map +1 -0
  61. package/dist/console/schemaGenerateCommand.js +246 -0
  62. package/dist/console/schemaGenerateCommand.js.map +1 -0
  63. package/dist/console/seederCommands.d.ts +46 -0
  64. package/dist/console/seederCommands.d.ts.map +1 -0
  65. package/dist/console/seederCommands.js +136 -0
  66. package/dist/console/seederCommands.js.map +1 -0
  67. package/dist/decorators/entity.d.ts +50 -8
  68. package/dist/decorators/entity.d.ts.map +1 -1
  69. package/dist/decorators/entity.js +42 -2
  70. package/dist/decorators/entity.js.map +1 -1
  71. package/dist/decorators/hooks.d.ts +3 -3
  72. package/dist/decorators/hooks.d.ts.map +1 -1
  73. package/dist/decorators/hooks.js.map +1 -1
  74. package/dist/events.d.ts +69 -0
  75. package/dist/events.d.ts.map +1 -0
  76. package/dist/events.js +82 -0
  77. package/dist/events.js.map +1 -0
  78. package/dist/factories.d.ts +8 -0
  79. package/dist/factories.d.ts.map +1 -0
  80. package/dist/factories.js +8 -0
  81. package/dist/factories.js.map +1 -0
  82. package/dist/index.d.ts +15 -5
  83. package/dist/index.d.ts.map +1 -1
  84. package/dist/index.js +14 -3
  85. package/dist/index.js.map +1 -1
  86. package/dist/lucid-schema.d.ts +15 -0
  87. package/dist/lucid-schema.d.ts.map +1 -0
  88. package/dist/lucid-schema.js +16 -0
  89. package/dist/lucid-schema.js.map +1 -0
  90. package/dist/metadata-keys.d.ts +3 -2
  91. package/dist/metadata-keys.d.ts.map +1 -1
  92. package/dist/naming/NamingStrategy.d.ts +7 -0
  93. package/dist/naming/NamingStrategy.d.ts.map +1 -1
  94. package/dist/naming/NamingStrategy.js +16 -0
  95. package/dist/naming/NamingStrategy.js.map +1 -1
  96. package/dist/orm.d.ts +14 -0
  97. package/dist/orm.d.ts.map +1 -0
  98. package/dist/orm.js +14 -0
  99. package/dist/orm.js.map +1 -0
  100. package/dist/query/DatabaseQueryBuilder.d.ts +557 -0
  101. package/dist/query/DatabaseQueryBuilder.d.ts.map +1 -0
  102. package/dist/query/DatabaseQueryBuilder.js +1798 -0
  103. package/dist/query/DatabaseQueryBuilder.js.map +1 -0
  104. package/dist/query/DmlBuilder.d.ts +62 -0
  105. package/dist/query/DmlBuilder.d.ts.map +1 -0
  106. package/dist/query/DmlBuilder.js +84 -0
  107. package/dist/query/DmlBuilder.js.map +1 -0
  108. package/dist/query/QueryBuilder.d.ts +5 -0
  109. package/dist/query/QueryBuilder.d.ts.map +1 -1
  110. package/dist/query/QueryBuilder.js +7 -0
  111. package/dist/query/QueryBuilder.js.map +1 -1
  112. package/dist/query/RawQueryBuilder.d.ts +47 -0
  113. package/dist/query/RawQueryBuilder.d.ts.map +1 -0
  114. package/dist/query/RawQueryBuilder.js +138 -0
  115. package/dist/query/RawQueryBuilder.js.map +1 -0
  116. package/dist/query/interpolate.d.ts +45 -0
  117. package/dist/query/interpolate.d.ts.map +1 -0
  118. package/dist/query/interpolate.js +51 -0
  119. package/dist/query/interpolate.js.map +1 -0
  120. package/dist/query/native.d.ts +8 -0
  121. package/dist/query/native.d.ts.map +1 -1
  122. package/dist/query/native.js +14 -0
  123. package/dist/query/native.js.map +1 -1
  124. package/dist/query/operators.d.ts +4 -0
  125. package/dist/query/operators.d.ts.map +1 -0
  126. package/dist/query/operators.js +27 -0
  127. package/dist/query/operators.js.map +1 -0
  128. package/dist/schema/Migration.d.ts +50 -3
  129. package/dist/schema/Migration.d.ts.map +1 -1
  130. package/dist/schema/Migration.js +60 -24
  131. package/dist/schema/Migration.js.map +1 -1
  132. package/dist/schema/MigrationRunner.d.ts +95 -34
  133. package/dist/schema/MigrationRunner.d.ts.map +1 -1
  134. package/dist/schema/MigrationRunner.js +523 -68
  135. package/dist/schema/MigrationRunner.js.map +1 -1
  136. package/dist/schema/Schema.d.ts +114 -0
  137. package/dist/schema/Schema.d.ts.map +1 -1
  138. package/dist/schema/Schema.js +272 -3
  139. package/dist/schema/Schema.js.map +1 -1
  140. package/dist/schema/SchemaDumper.d.ts +121 -0
  141. package/dist/schema/SchemaDumper.d.ts.map +1 -0
  142. package/dist/schema/SchemaDumper.js +365 -0
  143. package/dist/schema/SchemaDumper.js.map +1 -0
  144. package/dist/schema/Seeder.d.ts +13 -0
  145. package/dist/schema/Seeder.d.ts.map +1 -1
  146. package/dist/schema/Seeder.js +28 -5
  147. package/dist/schema/Seeder.js.map +1 -1
  148. package/dist/schema/TableBuilder.d.ts +274 -16
  149. package/dist/schema/TableBuilder.d.ts.map +1 -1
  150. package/dist/schema/TableBuilder.js +656 -52
  151. package/dist/schema/TableBuilder.js.map +1 -1
  152. package/dist/schema/catalog.d.ts +71 -0
  153. package/dist/schema/catalog.d.ts.map +1 -0
  154. package/dist/schema/catalog.js +158 -0
  155. package/dist/schema/catalog.js.map +1 -0
  156. package/dist/schema/introspect.d.ts +1 -1
  157. package/dist/schema/introspect.d.ts.map +1 -1
  158. package/dist/schema/introspect.js +26 -11
  159. package/dist/schema/introspect.js.map +1 -1
  160. package/dist/schema/types.d.ts +150 -1
  161. package/dist/schema/types.d.ts.map +1 -1
  162. package/dist/schema/types.js +11 -0
  163. package/dist/schema/types.js.map +1 -1
  164. package/dist/seeders.d.ts +7 -0
  165. package/dist/seeders.d.ts.map +1 -0
  166. package/dist/seeders.js +7 -0
  167. package/dist/seeders.js.map +1 -0
  168. package/dist/services/db.d.ts +122 -5
  169. package/dist/services/db.d.ts.map +1 -1
  170. package/dist/services/db.js +187 -14
  171. package/dist/services/db.js.map +1 -1
  172. package/dist/testing/DatabaseCleanup.d.ts +33 -7
  173. package/dist/testing/DatabaseCleanup.d.ts.map +1 -1
  174. package/dist/testing/DatabaseCleanup.js +54 -24
  175. package/dist/testing/DatabaseCleanup.js.map +1 -1
  176. package/dist/testing/DbAssertions.d.ts +48 -0
  177. package/dist/testing/DbAssertions.d.ts.map +1 -0
  178. package/dist/testing/DbAssertions.js +80 -0
  179. package/dist/testing/DbAssertions.js.map +1 -0
  180. package/dist/testing/Factory.d.ts +166 -15
  181. package/dist/testing/Factory.d.ts.map +1 -1
  182. package/dist/testing/Factory.js +497 -23
  183. package/dist/testing/Factory.js.map +1 -1
  184. package/dist/testing/TestUtils.d.ts +49 -0
  185. package/dist/testing/TestUtils.d.ts.map +1 -0
  186. package/dist/testing/TestUtils.js +79 -0
  187. package/dist/testing/TestUtils.js.map +1 -0
  188. package/dist/testing/index.d.ts +3 -1
  189. package/dist/testing/index.d.ts.map +1 -1
  190. package/dist/testing/index.js +3 -1
  191. package/dist/testing/index.js.map +1 -1
  192. package/dist/types/relations.d.ts +31 -0
  193. package/dist/types/relations.d.ts.map +1 -0
  194. package/dist/types/relations.js +20 -0
  195. package/dist/types/relations.js.map +1 -0
  196. package/index.darwin-arm64.node +0 -0
  197. package/index.darwin-x64.node +0 -0
  198. package/index.linux-arm64-gnu.node +0 -0
  199. package/index.linux-x64-gnu.node +0 -0
  200. package/index.win32-x64-msvc.node +0 -0
  201. package/package.json +32 -2
  202. package/scripts/guard-publish.mjs +15 -0
  203. package/src/AtlasProvider.ts +305 -52
  204. package/src/BaseEntity.ts +460 -41
  205. package/src/BaseModel.ts +461 -0
  206. package/src/BaseRepository.ts +1710 -421
  207. package/src/ConnectionManager.ts +298 -0
  208. package/src/ModelQuery.ts +2998 -335
  209. package/src/Transaction.ts +227 -30
  210. package/src/adapters/NapiDbAdapter.ts +224 -17
  211. package/src/console/contract.ts +96 -0
  212. package/src/console/factoryCommands.ts +73 -0
  213. package/src/console/migrationCommands.ts +448 -0
  214. package/src/console/schemaCheckCommand.ts +26 -22
  215. package/src/console/schemaDumpCommand.ts +96 -0
  216. package/src/console/schemaGenerateCommand.ts +380 -0
  217. package/src/console/seederCommands.ts +174 -0
  218. package/src/decorators/entity.ts +71 -8
  219. package/src/decorators/hooks.ts +5 -3
  220. package/src/events.ts +117 -0
  221. package/src/factories.ts +10 -0
  222. package/src/index.ts +69 -3
  223. package/src/lucid-schema.ts +22 -0
  224. package/src/metadata-keys.ts +3 -2
  225. package/src/naming/NamingStrategy.ts +23 -0
  226. package/src/orm.ts +13 -0
  227. package/src/query/DatabaseQueryBuilder.ts +2724 -0
  228. package/src/query/DmlBuilder.ts +131 -0
  229. package/src/query/QueryBuilder.ts +8 -0
  230. package/src/query/RawQueryBuilder.ts +173 -0
  231. package/src/query/interpolate.ts +73 -0
  232. package/src/query/native.ts +29 -0
  233. package/src/query/operators.ts +27 -0
  234. package/src/schema/Migration.ts +71 -3
  235. package/src/schema/MigrationRunner.ts +676 -69
  236. package/src/schema/Schema.ts +359 -3
  237. package/src/schema/SchemaDumper.ts +518 -0
  238. package/src/schema/Seeder.ts +47 -10
  239. package/src/schema/TableBuilder.ts +783 -52
  240. package/src/schema/catalog.ts +236 -0
  241. package/src/schema/introspect.ts +26 -9
  242. package/src/schema/types.ts +137 -2
  243. package/src/seeders.ts +16 -0
  244. package/src/services/db.ts +361 -21
  245. package/src/testing/DatabaseCleanup.ts +78 -25
  246. package/src/testing/DbAssertions.ts +127 -0
  247. package/src/testing/Factory.ts +837 -40
  248. package/src/testing/TestUtils.ts +123 -0
  249. package/src/testing/index.ts +12 -1
  250. package/src/types/relations.ts +43 -0
package/README.md CHANGED
@@ -1,11 +1,60 @@
1
1
  # @c9up/atlas
2
2
 
3
- Data Mapper ORM for Node.js. Entity decorators, fluent QueryBuilder, domain events.
3
+ AdonisJS Lucid–style ORM for Node.js Active Record **models** *and* a Data Mapper **repository**, entity decorators, a fluent QueryBuilder, and domain events.
4
4
 
5
- ## Usage
5
+ > **Lucid parity scope:** Atlas is the **agnostic core ORM/database** layer,
6
+ > tracked closely against Lucid. The capabilities Lucid bundles via Adonis libs
7
+ > are covered by **Ream's own equivalent packages** — validation `@c9up/rune`,
8
+ > testing `@c9up/atlas/testing` + `@c9up/ream/testing`, health `@c9up/ream`
9
+ > `HealthCheck` — not VineJS/Japa/Adonis bindings. See
10
+ > [`LUCID-PARITY.md`](./LUCID-PARITY.md) for the authoritative contract, named
11
+ > deviations, and known limitations.
12
+
13
+ ## Active Record (AdonisJS Lucid parity)
14
+
15
+ Extend `BaseModel` for the Lucid-style Active Record API: static finders/creators
16
+ plus `instance.save()` / `instance.delete()`. `@Entity('table')` is **optional** —
17
+ the table name is inferred from the class name (`User` → `users`).
18
+
19
+ ```typescript
20
+ import { BaseModel, Column, PrimaryKey } from '@c9up/atlas'
21
+
22
+ class User extends BaseModel {
23
+ @PrimaryKey() declare id: number
24
+ @Column() declare email: string
25
+ @Column() declare role: string
26
+ }
27
+
28
+ const user = await User.find(1)
29
+ const admin = await User.findBy({ role: 'admin' }) // object clause
30
+ const fresh = await User.create({ email: 'a@b.co', role: 'user' })
31
+
32
+ if (user) {
33
+ user.email = 'new@b.co'
34
+ await user.save() // UPDATE only the dirty columns
35
+ console.log(user.$isPersisted, user.$isDirty)
36
+ }
37
+
38
+ // bulk, keyed by a unique column, in one transaction
39
+ await User.updateOrCreateMany('email', rows)
40
+
41
+ // per-instance serialization visibility
42
+ user?.makeHidden('role').toJSON()
43
+ ```
44
+
45
+ Static surface: `find`, `findOrFail`, `findBy`, `findByOrFail`, `findMany`,
46
+ `findManyBy`, `all`, `first`, `firstOrFail`, `query`, `create`, `createMany`,
47
+ `firstOrCreate`, `firstOrNew`, `updateOrCreate`, `updateOrCreateMany`,
48
+ `fetchOrCreateMany`, `fetchOrNewUpMany`, `truncate`. Config: `static table`,
49
+ `static connection`.
50
+
51
+ ## Data Mapper
52
+
53
+ Prefer separation of persistence from the model? Use `BaseRepository` directly —
54
+ same surface, with the connection injected.
6
55
 
7
56
  ```typescript
8
- import { Entity, Column, PrimaryKey, BaseEntity, QueryBuilder } from '@c9up/atlas'
57
+ import { BaseRepository, Entity, Column, PrimaryKey, BaseEntity } from '@c9up/atlas'
9
58
 
10
59
  @Entity('orders')
11
60
  class Order extends BaseEntity {
@@ -14,21 +63,21 @@ class Order extends BaseEntity {
14
63
  @Column({ type: 'decimal' }) declare total: number
15
64
  }
16
65
 
17
- const { sql, params } = new QueryBuilder('orders')
18
- .where('status', 'active')
19
- .orderBy('createdAt', 'desc')
20
- .paginate(1, 20)
21
- .toSQL()
66
+ const repo = new BaseRepository(Order, db)
67
+ const active = await repo.query().where('status', 'active').exec()
22
68
  ```
23
69
 
24
70
  ## Features
25
71
 
26
- - `@Entity`, `@Column`, `@PrimaryKey`, `@BelongsTo`, `@HasMany`, `@ManyToMany`
27
- - Fluent QueryBuilder with parameterized SQL (injection-safe)
28
- - CTE (`.with()`), UNION, WHERE EXISTS, GROUP BY, HAVING, DISTINCT
29
- - `RawSql` tagged template for edge cases
30
- - Domain events accumulated on entities, dispatched after save
31
- - BaseRepository with query builder access
72
+ - **Two styles** Active Record (`BaseModel`) and Data Mapper (`BaseRepository`), same repository underneath
73
+ - Zero-config conventions: table + primary key inferred, overridable via `static table` / `@Entity` / `@PrimaryKey`
74
+ - Model state: `$isPersisted`, `$isNew`, `$isLocal`, `$isDeleted`, `$dirty` / `isDirty()`, `$primaryKeyValue`
75
+ - Mass-assignment protection (`static fillable` / `guarded`) enforced on `create` / `createMany` / `updateOrCreate`
76
+ - Serialization: `static hidden`/`visible`, per-instance `makeHidden`/`makeVisible`, `@Column({ serializeAs, serialize })`, `@computed`
77
+ - `@Entity`, `@Column`, `@PrimaryKey`, `@BelongsTo`, `@HasMany`, `@ManyToMany` + relation preloading
78
+ - Fluent QueryBuilder with parameterized SQL (injection-safe): CTE (`.with()`), UNION, WHERE EXISTS, GROUP BY, HAVING, DISTINCT
79
+ - `RawSql` tagged template; domain events accumulated on entities, dispatched after save
80
+ - Interactive transactions, soft deletes, multi-dialect (sqlite / postgres / mysql)
32
81
 
33
82
  ## License
34
83
 
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -17,8 +17,8 @@
17
17
  * }
18
18
  *
19
19
  * // Code
20
- * const primary = app.container.resolve('db') // default
21
- * const tenant1 = app.container.resolve('db:tenant1') // named
20
+ * const primary = await app.container.resolve('db') // default
21
+ * const tenant1 = await app.container.resolve('db:tenant1') // named
22
22
  */
23
23
  /**
24
24
  * Structural slice of the host framework's app context — only the surface
@@ -35,6 +35,12 @@
35
35
  export interface AtlasAppContext {
36
36
  container: {
37
37
  singleton(token: string | symbol | (new (...args: never[]) => unknown), factory: () => unknown): void;
38
+ /**
39
+ * Optional reader — present on ream's real container. Used to look up the
40
+ * app emitter (`events`) so query events are bridged onto it as `db:query`
41
+ * (AdonisJS parity: `emitter.on('db:query', …)`). Structural, async-capable.
42
+ */
43
+ resolve?(token: string | symbol | (new (...args: never[]) => unknown)): unknown | Promise<unknown>;
38
44
  };
39
45
  config: {
40
46
  get<T = unknown>(key: string): T | undefined;
@@ -60,12 +66,35 @@ export declare const SQLITE_PROD_PRAGMAS: Readonly<{
60
66
  }>;
61
67
  /** One connection's settings. */
62
68
  export interface ConnectionConfig {
63
- /** Connection URL: "sqlite:data/app.db", "postgres://...", "mysql://..." */
64
- url: string;
65
- /** Minimum pool connections (default: 1) */
69
+ /**
70
+ * Connection URL: "sqlite:data/app.db", "postgres://...", "mysql://...".
71
+ * Lucid names this per-connection key `connection` — {@link connection} is
72
+ * accepted as an alias, so at least one of the two must be set.
73
+ */
74
+ url?: string;
75
+ /**
76
+ * Lucid's per-connection URL key (`connections: { primary: { connection: '…' } }`).
77
+ * Alias of {@link url}; `url` wins when both are present.
78
+ */
79
+ connection?: string;
80
+ /** Minimum pool connections (default: 1). Prefer the Lucid-shaped {@link pool}. */
66
81
  poolMin?: number;
67
- /** Maximum pool connections (default: 10) */
82
+ /** Maximum pool connections (default: 10). Prefer the Lucid-shaped {@link pool}. */
68
83
  poolMax?: number;
84
+ /**
85
+ * Connection-pool sizing, Lucid-shaped — `pool: { min: 2, max: 10 }`. Takes
86
+ * precedence over the flat `poolMin`/`poolMax` when both are set.
87
+ */
88
+ pool?: {
89
+ min?: number;
90
+ max?: number;
91
+ };
92
+ /**
93
+ * Emit a `db:query` event for every statement on this connection (Lucid's
94
+ * `debug` connection option). Off by default — subscribe with `onDbQuery`
95
+ * to receive them; with no subscriber nothing is emitted either way.
96
+ */
97
+ debug?: boolean;
69
98
  /**
70
99
  * Connection-level pragmas (sqlite only). Each entry becomes a
71
100
  * `PRAGMA <key> = <value>;` issued before the first query.
@@ -93,18 +122,48 @@ export interface ConnectionConfig {
93
122
  }
94
123
  /** Full database config — single-connection (legacy) OR multi-connection. */
95
124
  export interface AtlasDatabaseConfig extends ConnectionConfig {
96
- /** Name of the default connection when `connections` is set. Defaults to `"primary"`. */
125
+ /**
126
+ * Name of the default connection when `connections` is set (Lucid's top-level
127
+ * `connection`). `default` is a deprecated alias — `connection` wins when both
128
+ * are set. Defaults to `"primary"`.
129
+ */
130
+ connection?: string;
131
+ /** @deprecated Use {@link connection} (the Lucid key). */
97
132
  default?: string;
98
133
  /** Named connections. When present, top-level `url` is treated as `connections[default].url`. */
99
134
  connections?: Record<string, ConnectionConfig>;
100
135
  migrations?: {
136
+ /** @deprecated Use the Lucid-shaped {@link paths}. */
101
137
  path?: string;
138
+ /** Migration directories, Lucid-shaped — `paths: ['database/migrations']`. */
139
+ paths?: string[];
102
140
  /**
103
141
  * Custom name for the migrations tracking table. Defaults to `"ream_migrations"`.
104
142
  * Must match `/^[A-Za-z_][A-Za-z0-9_]*$/` — the `MigrationRunner` constructor
105
143
  * throws `AtlasError("MIGRATION_INVALID_TABLE_NAME")` otherwise.
106
144
  */
107
145
  table?: string;
146
+ /**
147
+ * Allow the boot-time auto-migrate in production. OFF by default:
148
+ * starting the app should NOT silently mutate the schema in prod (Adonis
149
+ * Lucid runs migrations only via the explicit `migration:run` command).
150
+ * In non-production, boot auto-migrate stays on for dev convenience. The
151
+ * CLI's `REAM_SKIP_BOOT_MIGRATE=1` always wins.
152
+ */
153
+ autoRunInProduction?: boolean;
154
+ /**
155
+ * Sort migration files with a numeric-aware comparator (`2_x` before
156
+ * `10_x`). Adonis Lucid `migrations.naturalSort`. Defaults to `false`
157
+ * (plain lexicographic, correct for `make:migration`'s fixed-width prefix).
158
+ */
159
+ naturalSort?: boolean;
160
+ /**
161
+ * Run every migration OUTSIDE a transaction. Adonis Lucid
162
+ * `migrations.disableTransactions`. A single migration can also opt out with
163
+ * `static disableTransactions = true`; the effective value is their OR.
164
+ * Defaults to `false`.
165
+ */
166
+ disableTransactions?: boolean;
108
167
  };
109
168
  /**
110
169
  * Boot-time schema verification. When set, atlas reconciles each listed
@@ -1 +1 @@
1
- {"version":3,"file":"AtlasProvider.d.ts","sourceRoot":"","sources":["../src/AtlasProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAaH;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,eAAe;IAC/B,SAAS,EAAE;QACV,SAAS,CACR,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,CAAC,KAAK,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC,EAC5D,OAAO,EAAE,MAAM,OAAO,GACpB,IAAI,CAAC;KACR,CAAC;IACF,MAAM,EAAE;QAAE,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS,CAAA;KAAE,CAAC;CACzD;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,mBAAmB;;;EAGrB,CAAC;AAEZ,iCAAiC;AACjC,MAAM,WAAW,gBAAgB;IAChC,4EAA4E;IAC5E,GAAG,EAAE,MAAM,CAAC;IACZ,4CAA4C;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;IAC1C;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,0FAA0F;IAC1F,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,6EAA6E;AAC7E,MAAM,WAAW,mBAAoB,SAAQ,gBAAgB;IAC5D,yFAAyF;IACzF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iGAAiG;IACjG,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC/C,UAAU,CAAC,EAAE;QACZ,IAAI,CAAC,EAAE,MAAM,CAAC;QACd;;;;WAIG;QACH,KAAK,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE;QACd,QAAQ,EAAE,aAAa,CAAC,KAAK,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,CAAC;QAC7D,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;KACxB,CAAC;CACF;AAED,MAAM,CAAC,OAAO,OAAO,aAAa;;IAKrB,SAAS,CAAC,GAAG,EAAE,eAAe;gBAApB,GAAG,EAAE,eAAe;IAE1C,QAAQ;IAEF,IAAI;IAmGJ,QAAQ;IAqCR,KAAK;IAiBL,KAAK;CAwDX"}
1
+ {"version":3,"file":"AtlasProvider.d.ts","sourceRoot":"","sources":["../src/AtlasProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAaH;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,eAAe;IAC/B,SAAS,EAAE;QACV,SAAS,CACR,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,CAAC,KAAK,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC,EAC5D,OAAO,EAAE,MAAM,OAAO,GACpB,IAAI,CAAC;QACR;;;;WAIG;QACH,OAAO,CAAC,CACP,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,CAAC,KAAK,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC,GAC1D,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;KAC9B,CAAC;IACF,MAAM,EAAE;QAAE,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS,CAAA;KAAE,CAAC;CACzD;AAcD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,mBAAmB;;;EAGrB,CAAC;AAEZ,iCAAiC;AACjC,MAAM,WAAW,gBAAgB;IAChC;;;;OAIG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mFAAmF;IACnF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oFAAoF;IACpF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,IAAI,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACtC;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;IAC1C;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,0FAA0F;IAC1F,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,6EAA6E;AAC7E,MAAM,WAAW,mBAAoB,SAAQ,gBAAgB;IAC5D;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iGAAiG;IACjG,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC/C,UAAU,CAAC,EAAE;QACZ,sDAAsD;QACtD,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,8EAA8E;QAC9E,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;QACjB;;;;WAIG;QACH,KAAK,CAAC,EAAE,MAAM,CAAC;QACf;;;;;;WAMG;QACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;QAC9B;;;;WAIG;QACH,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB;;;;;WAKG;QACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;KAC9B,CAAC;IACF;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE;QACd,QAAQ,EAAE,aAAa,CAAC,KAAK,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,CAAC;QAC7D,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;KACxB,CAAC;CACF;AAED,MAAM,CAAC,OAAO,OAAO,aAAa;;IAOrB,SAAS,CAAC,GAAG,EAAE,eAAe;gBAApB,GAAG,EAAE,eAAe;IAe1C,QAAQ;IA8DF,IAAI;IAiKJ,QAAQ;IAiDR,KAAK;IAiBL,KAAK;CA0FX"}
@@ -17,13 +17,20 @@
17
17
  * }
18
18
  *
19
19
  * // Code
20
- * const primary = app.container.resolve('db') // default
21
- * const tenant1 = app.container.resolve('db:tenant1') // named
20
+ * const primary = await app.container.resolve('db') // default
21
+ * const tenant1 = await app.container.resolve('db:tenant1') // named
22
22
  */
23
23
  import { createNapiConnection, } from "./adapters/NapiDbAdapter.js";
24
24
  import { clearCastRegistry, setAtlasDialect } from "./query/native.js";
25
25
  import { MigrationRunner, } from "./schema/MigrationRunner.js";
26
26
  import { dialectFromUrl } from "./utils/dialectFromUrl.js";
27
+ /** True when `x` looks like an event emitter with `emit(event, data)`. */
28
+ function hasEmit(x) {
29
+ return (typeof x === "object" &&
30
+ x !== null &&
31
+ "emit" in x &&
32
+ typeof x.emit === "function");
33
+ }
27
34
  /**
28
35
  * Canonical sqlite production pragma recipe.
29
36
  *
@@ -47,10 +54,82 @@ export default class AtlasProvider {
47
54
  /** Map of connection name → open connection. Populated at boot. */
48
55
  #connections = new Map();
49
56
  #defaultName = "primary";
57
+ /** Unsubscribe for the `db:query` → app-emitter bridge, torn down on shutdown. */
58
+ #dbQueryBridge;
50
59
  constructor(app) {
51
60
  this.app = app;
52
61
  }
62
+ /** Resolve a live connection by name, or throw — never hand out a closed one
63
+ * (used by the `db`/`db:<name>` container factories so a failed-boot or
64
+ * post-shutdown lookup fails loudly instead of returning a dead handle). */
65
+ #requireConnection(name) {
66
+ const conn = this.#connections.get(name);
67
+ if (!conn) {
68
+ throw new Error(`AtlasProvider: connection '${name}' is not available (boot failed or the provider was shut down).`);
69
+ }
70
+ return conn;
71
+ }
53
72
  register() { }
73
+ /**
74
+ * Bridge atlas's `db:query` observability onto the app emitter so consumers
75
+ * use the AdonisJS API — `emitter.on('db:query', (query) => …)`. The agnostic
76
+ * `onDbQuery(listener)` primitive stays available for hosts without an emitter.
77
+ * No-op when the container exposes no `events` emitter.
78
+ */
79
+ async #bridgeDbQueryEvents() {
80
+ const resolve = this.app.container.resolve;
81
+ if (typeof resolve !== "function")
82
+ return;
83
+ let emitter;
84
+ try {
85
+ emitter = await resolve.call(this.app.container, "events");
86
+ }
87
+ catch {
88
+ return; // no emitter bound — `onDbQuery` remains the way to observe
89
+ }
90
+ if (!hasEmit(emitter))
91
+ return;
92
+ const { onDbQuery } = await import("./events.js");
93
+ this.#dbQueryBridge?.();
94
+ this.#dbQueryBridge = onDbQuery((event) => {
95
+ emitter.emit("db:query", event);
96
+ });
97
+ }
98
+ /** Teardown for the connection-lifecycle → app-emitter bridge. */
99
+ #connectionBridge;
100
+ /**
101
+ * Bridge the connection manager's lifecycle events onto the app emitter as
102
+ * AdonisJS's `db:connection:connect` / `db:connection:disconnect` /
103
+ * `db:connection:error` (`[error, node]`). No-op without an `events` emitter.
104
+ */
105
+ async #bridgeConnectionEvents() {
106
+ const resolve = this.app.container.resolve;
107
+ if (typeof resolve !== "function")
108
+ return;
109
+ let emitter;
110
+ try {
111
+ emitter = await resolve.call(this.app.container, "events");
112
+ }
113
+ catch {
114
+ return;
115
+ }
116
+ if (!hasEmit(emitter))
117
+ return;
118
+ const { connectionManager } = await import("./services/db.js");
119
+ const mgr = connectionManager();
120
+ this.#connectionBridge?.();
121
+ const onConnect = (node) => emitter.emit("db:connection:connect", node);
122
+ const onDisconnect = (node) => emitter.emit("db:connection:disconnect", node);
123
+ const onError = (node, err) => emitter.emit("db:connection:error", [err, node]);
124
+ mgr.on("connect", onConnect);
125
+ mgr.on("disconnect", onDisconnect);
126
+ mgr.on("error", onError);
127
+ this.#connectionBridge = () => {
128
+ mgr.off("connect", onConnect);
129
+ mgr.off("disconnect", onDisconnect);
130
+ mgr.off("error", onError);
131
+ };
132
+ }
54
133
  async boot() {
55
134
  const config = this.app.config.get("database");
56
135
  if (!config)
@@ -58,6 +137,16 @@ export default class AtlasProvider {
58
137
  // Normalize: if `connections` is not set, build a single-entry map from top-level config.
59
138
  const { connections, defaultName } = this.#resolveConnections(config);
60
139
  this.#defaultName = defaultName;
140
+ // Bridge query observability onto the app emitter — AdonisJS parity, so
141
+ // consumers write `emitter.on('db:query', …)` (see #bridgeDbQueryEvents).
142
+ await this.#bridgeDbQueryEvents();
143
+ // Bridge connection lifecycle events too, BEFORE opening pools so the boot
144
+ // `connect` events reach the app emitter (`db:connection:connect`).
145
+ await this.#bridgeConnectionEvents();
146
+ // Import the services/db proxy BEFORE opening any pool: if this import ever
147
+ // failed (packaging/bundle issue), we must not have leaked open connections,
148
+ // and the cleanup catch below needs it available.
149
+ const dbServices = await import("./services/db.js");
61
150
  // Open every connection in parallel — multi-database apps with slow-to-
62
151
  // handshake drivers (Postgres over TLS, RDS proxies) previously paid the
63
152
  // sum of the round-trip times on boot; now it's the max.
@@ -67,11 +156,16 @@ export default class AtlasProvider {
67
156
  // close every successful one before rethrowing so a partial boot never
68
157
  // leaks pools/sockets.
69
158
  const entries = Object.entries(connections);
70
- const results = await Promise.allSettled(entries.map(([, settings]) => createNapiConnection(settings.url, settings.poolMin ?? 1, settings.poolMax ?? 10, settings.pragmas, {
159
+ // Register every connection's config up front (Lucid `manager.add`), so the
160
+ // manager knows all connections — including any that fail to open below.
161
+ for (const [name, settings] of entries) {
162
+ dbServices.connectionManager().add(name, settings);
163
+ }
164
+ const results = await Promise.allSettled(entries.map(([name, settings]) => createNapiConnection(settings.url, settings.pool?.min ?? settings.poolMin ?? 1, settings.pool?.max ?? settings.poolMax ?? 10, settings.pragmas, {
71
165
  retries: settings.connectRetries,
72
166
  backoffMs: settings.connectBackoffMs,
73
167
  timeoutMs: settings.connectTimeoutMs,
74
- })));
168
+ }, { debug: settings.debug ?? false, connectionName: name })));
75
169
  const failures = [];
76
170
  const successes = [];
77
171
  results.forEach((r, i) => {
@@ -82,6 +176,11 @@ export default class AtlasProvider {
82
176
  failures.push({ name, error: r.reason });
83
177
  });
84
178
  if (failures.length > 0) {
179
+ // Surface each failure through the manager → app emitter as
180
+ // `db:connection:error` ([error, node]) before rolling back.
181
+ for (const f of failures) {
182
+ dbServices.connectionManager().reportConnectError(f.name, f.error);
183
+ }
85
184
  // Tear down the successes so we don't leak any pool that the runtime
86
185
  // has already opened. Closures run in parallel with allSettled so a
87
186
  // stuck close doesn't block the rollback path.
@@ -95,35 +194,64 @@ export default class AtlasProvider {
95
194
  `'${first.name}' failed: ${String(first.error)}` +
96
195
  (others ? ` (also: ${others})` : ""));
97
196
  }
98
- for (const { name, conn } of successes) {
99
- this.#connections.set(name, conn);
100
- this.app.container.singleton(`db:${name}`, () => conn);
101
- }
102
- // Expose the default under the short aliases `db` and `db.connection`.
103
- const defaultConn = this.#connections.get(defaultName);
104
- if (!defaultConn) {
105
- throw new Error(`AtlasProvider: default connection '${defaultName}' is not defined in config.database.connections`);
197
+ // Everything past this point runs AFTER the pools are open — an invalid
198
+ // default connection, a boot-time migration crash, etc. must not leak the
199
+ // sockets/pools we just opened. On any failure, tear them all down and
200
+ // undo the registry/service bindings before rethrowing.
201
+ try {
202
+ // Validate the default connection opened BEFORE binding anything: a bad
203
+ // default must fail while the container/registry are still untouched, so
204
+ // we never leave handles pointing at connections we're about to close.
205
+ const defaultEntry = successes.find((s) => s.name === defaultName);
206
+ if (!defaultEntry) {
207
+ throw new Error(`AtlasProvider: default connection '${defaultName}' is not defined in config.database.connections`);
208
+ }
209
+ const defaultConn = defaultEntry.conn;
210
+ // Bind connections into the container AND the named-connection registry
211
+ // (the latter is what `BaseModel.connection` / `Factory.connection()` /
212
+ // `getConnection(name)` read). The container factories resolve through
213
+ // `#connections` (not a captured handle) so that if boot fails after
214
+ // binding — the catch clears `#connections` — or after shutdown, resolving
215
+ // `db`/`db:<name>` throws instead of handing out a CLOSED connection.
216
+ for (const { name, conn } of successes) {
217
+ this.#connections.set(name, conn);
218
+ dbServices.registerConnection(name, conn, connections[name]);
219
+ this.app.container.singleton(`db:${name}`, () => this.#requireConnection(name));
220
+ }
221
+ // Expose the default under the short aliases `db` and `db.connection`.
222
+ this.app.container.singleton("db", () => this.#requireConnection(this.#defaultName));
223
+ this.app.container.singleton("db.connection", () => this.#requireConnection(this.#defaultName));
224
+ // Populate the `@c9up/atlas/services/db` proxy so apps can
225
+ // `import db from '@c9up/atlas/services/db'` from anywhere.
226
+ dbServices.setDb(defaultConn);
227
+ // The dialect set module-wide is the DEFAULT connection's dialect.
228
+ // Per-connection dialect (when a user hits a non-default) is read from
229
+ // the connection URL at query time by each call site that cares.
230
+ setAtlasDialect(dialectFromUrl(connections[defaultName]?.url));
231
+ // Auto-run migrations on boot — but NOT in production unless explicitly
232
+ // opted in: starting the app should not silently mutate the schema in
233
+ // prod (Adonis Lucid only migrates via `migration:run`). Skipped too
234
+ // when a CLI migration command booted us (`REAM_SKIP_BOOT_MIGRATE=1`),
235
+ // which drives migrations explicitly.
236
+ const inProduction = process.env.NODE_ENV === "production";
237
+ const autoMigrateAllowed = !inProduction || config.migrations?.autoRunInProduction === true;
238
+ if ((config.migrations?.paths?.[0] ?? config.migrations?.path) &&
239
+ process.env.REAM_SKIP_BOOT_MIGRATE !== "1" &&
240
+ autoMigrateAllowed) {
241
+ await this.#runMigrations(config.migrations?.paths?.[0] ?? config.migrations?.path ?? "", connections[defaultName]?.url, defaultConn, config.migrations.table, {
242
+ naturalSort: config.migrations.naturalSort,
243
+ disableTransactions: config.migrations.disableTransactions,
244
+ });
245
+ }
106
246
  }
107
- this.app.container.singleton("db", () => defaultConn);
108
- this.app.container.singleton("db.connection", () => defaultConn);
109
- // Populate the `@c9up/atlas/services/db` proxy so apps can
110
- // `import db from '@c9up/atlas/services/db'` from anywhere.
111
- // Done inside the lazy-import to avoid pulling the services
112
- // module at construction time when the provider is type-imported
113
- // by `@c9up/ream`'s discovery scan.
114
- const { setDb } = await import("./services/db.js");
115
- setDb(defaultConn);
116
- // The dialect set module-wide is the DEFAULT connection's dialect.
117
- // Per-connection dialect (when a user hits a non-default) is read from
118
- // the connection URL at query time by each call site that cares.
119
- setAtlasDialect(dialectFromUrl(connections[defaultName]?.url));
120
- // Auto-run migrations on boot — EXCEPT when a CLI migration command
121
- // (`ream migrate` / `migrate:rollback` / `migrate:status`) booted us: it
122
- // drives migrations explicitly, so a boot-time pass would double-apply
123
- // (and silently re-apply right before a rollback/status). The CLI sets
124
- // `REAM_SKIP_BOOT_MIGRATE=1`; default (unset) preserves boot-migrate.
125
- if (config.migrations?.path && process.env.REAM_SKIP_BOOT_MIGRATE !== "1") {
126
- await this.#runMigrations(config.migrations.path, connections[defaultName]?.url, defaultConn, config.migrations.table);
247
+ catch (err) {
248
+ await Promise.allSettled(successes.map((s) => s.conn.close()));
249
+ for (const { name, conn } of successes) {
250
+ dbServices.clearDb(conn);
251
+ dbServices.unregisterConnection(name, conn);
252
+ }
253
+ this.#connections.clear();
254
+ throw err;
127
255
  }
128
256
  }
129
257
  async shutdown() {
@@ -136,16 +264,26 @@ export default class AtlasProvider {
136
264
  // - any rejection is aggregated into a single `AggregateError` thrown
137
265
  // at the end so supervisors / health-checks see a non-zero exit
138
266
  // signal instead of a silent "everything is fine" shutdown
267
+ // Detach the db:query → emitter bridge so a re-boot doesn't double-emit.
268
+ this.#dbQueryBridge?.();
269
+ this.#dbQueryBridge = undefined;
270
+ this.#connectionBridge?.();
271
+ this.#connectionBridge = undefined;
139
272
  const named = [...this.#connections.entries()];
140
273
  const results = await Promise.allSettled(named.map(([, c]) => c.close()));
141
274
  this.#connections.clear();
142
275
  // Release the module-level singletons this provider populated at boot so a
143
276
  // re-boot starts clean and `db.*` can't dereference a now-closed handle.
144
277
  // `clearDb` is ownership-guarded, so clearing every connection only unbinds
145
- // the one still owning the singleton.
146
- const { clearDb } = await import("./services/db.js");
147
- for (const [, conn] of named)
278
+ // the one still owning the singleton. Also drop the named-connection
279
+ // registry entries (boot registered them), so `getConnection(name)` /
280
+ // `BaseModel.connection` / `Factory.connection()` can't hand out a CLOSED
281
+ // handle after shutdown.
282
+ const { clearDb, unregisterConnection } = await import("./services/db.js");
283
+ for (const [name, conn] of named) {
148
284
  clearDb(conn);
285
+ unregisterConnection(name, conn);
286
+ }
149
287
  clearCastRegistry();
150
288
  const errors = results
151
289
  .map((r, i) => r.status === "rejected" ? { name: named[i][0], error: r.reason } : null)
@@ -180,25 +318,48 @@ export default class AtlasProvider {
180
318
  /** Normalize the config into a `{ name → ConnectionConfig }` map + default name. */
181
319
  #resolveConnections(config) {
182
320
  if (config.connections && Object.keys(config.connections).length > 0) {
321
+ // Normalize each block's URL from Lucid's `connection` key (alias of `url`).
322
+ const connections = {};
323
+ for (const [name, block] of Object.entries(config.connections)) {
324
+ const url = block.url ?? block.connection;
325
+ if (!url) {
326
+ throw new Error(`[atlas] connection '${name}' has no URL — set 'url' (or Lucid's 'connection') in config.database.connections.${name}.`);
327
+ }
328
+ connections[name] = { ...block, url };
329
+ }
183
330
  return {
184
- connections: config.connections,
185
- defaultName: config.default ?? "primary",
331
+ connections,
332
+ // Lucid's `connection` (default selector); `default` is the alias.
333
+ defaultName: config.connection ?? config.default ?? "primary",
186
334
  };
187
335
  }
188
- // Legacy single-connection shape — promote to multi-connection under "primary".
336
+ // Legacy single-connection shape — promote to multi-connection under
337
+ // "primary". Carry EVERY top-level option through: dropping debug /
338
+ // connectRetries / connectBackoffMs / connectTimeoutMs here silently
339
+ // disabled retry/timeout/query-debug for anyone still on the flat config.
340
+ // (Top-level `connection` is the default-selector, so the flat form's URL
341
+ // comes from `url` only — Lucid's `connection`-as-URL is a nested-block key.)
342
+ if (!config.url) {
343
+ throw new Error("[atlas] no database URL — set 'url' at the top level, or use 'connections: { … }' with a per-connection 'url'/'connection'.");
344
+ }
189
345
  return {
190
346
  connections: {
191
347
  primary: {
192
348
  url: config.url,
193
349
  poolMin: config.poolMin,
194
350
  poolMax: config.poolMax,
351
+ pool: config.pool,
195
352
  pragmas: config.pragmas,
353
+ debug: config.debug,
354
+ connectRetries: config.connectRetries,
355
+ connectBackoffMs: config.connectBackoffMs,
356
+ connectTimeoutMs: config.connectTimeoutMs,
196
357
  },
197
358
  },
198
359
  defaultName: "primary",
199
360
  };
200
361
  }
201
- async #runMigrations(migrationsPath, url, db, tableName) {
362
+ async #runMigrations(migrationsPath, url, db, tableName, options) {
202
363
  const { existsSync } = await import("node:fs");
203
364
  if (!existsSync(migrationsPath))
204
365
  return;
@@ -213,11 +374,16 @@ export default class AtlasProvider {
213
374
  // `ream_migrations` bookkeeping row together). Without this, the runner
214
375
  // silently falls back to non-transactional execution.
215
376
  runInTransaction: async (batch) => db.runInTransaction(batch),
377
+ // Managed interactive transaction, so this.defer() migrations run
378
+ // atomically (schema + deferred + tracking committed together).
379
+ transaction: db.transaction?.bind(db),
216
380
  };
217
381
  const runner = new MigrationRunner(adapter, {
218
382
  migrationsDir: migrationsPath,
219
383
  dialect: dialectFromUrl(url),
220
384
  tableName,
385
+ naturalSort: options?.naturalSort,
386
+ disableTransactions: options?.disableTransactions,
221
387
  });
222
388
  await runner.migrate();
223
389
  }
@@ -1 +1 @@
1
- {"version":3,"file":"AtlasProvider.js","sourceRoot":"","sources":["../src/AtlasProvider.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AtlasProvider.js","sourceRoot":"","sources":["../src/AtlasProvider.ts"],"names":[],"mappings":"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"}