@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.
- package/README.md +63 -14
- package/db.darwin-arm64.node +0 -0
- package/db.darwin-x64.node +0 -0
- package/db.linux-arm64-gnu.node +0 -0
- package/db.linux-x64-gnu.node +0 -0
- package/db.win32-x64-msvc.node +0 -0
- package/dist/AtlasProvider.d.ts +66 -7
- package/dist/AtlasProvider.d.ts.map +1 -1
- package/dist/AtlasProvider.js +205 -39
- package/dist/AtlasProvider.js.map +1 -1
- package/dist/BaseEntity.d.ts +181 -5
- package/dist/BaseEntity.d.ts.map +1 -1
- package/dist/BaseEntity.js +339 -33
- package/dist/BaseEntity.js.map +1 -1
- package/dist/BaseModel.d.ts +127 -0
- package/dist/BaseModel.d.ts.map +1 -0
- package/dist/BaseModel.js +250 -0
- package/dist/BaseModel.js.map +1 -0
- package/dist/BaseRepository.d.ts +81 -15
- package/dist/BaseRepository.d.ts.map +1 -1
- package/dist/BaseRepository.js +1433 -387
- package/dist/BaseRepository.js.map +1 -1
- package/dist/ConnectionManager.d.ts +106 -0
- package/dist/ConnectionManager.d.ts.map +1 -0
- package/dist/ConnectionManager.js +228 -0
- package/dist/ConnectionManager.js.map +1 -0
- package/dist/ModelQuery.d.ts +577 -41
- package/dist/ModelQuery.d.ts.map +1 -1
- package/dist/ModelQuery.js +2188 -291
- package/dist/ModelQuery.js.map +1 -1
- package/dist/Transaction.d.ts +71 -1
- package/dist/Transaction.d.ts.map +1 -1
- package/dist/Transaction.js +138 -24
- package/dist/Transaction.js.map +1 -1
- package/dist/adapters/NapiDbAdapter.d.ts +44 -4
- package/dist/adapters/NapiDbAdapter.d.ts.map +1 -1
- package/dist/adapters/NapiDbAdapter.js +131 -13
- package/dist/adapters/NapiDbAdapter.js.map +1 -1
- package/dist/console/contract.d.ts +62 -0
- package/dist/console/contract.d.ts.map +1 -0
- package/dist/console/contract.js +38 -0
- package/dist/console/contract.js.map +1 -0
- package/dist/console/factoryCommands.d.ts +23 -0
- package/dist/console/factoryCommands.d.ts.map +1 -0
- package/dist/console/factoryCommands.js +62 -0
- package/dist/console/factoryCommands.js.map +1 -0
- package/dist/console/migrationCommands.d.ts +78 -0
- package/dist/console/migrationCommands.d.ts.map +1 -0
- package/dist/console/migrationCommands.js +327 -0
- package/dist/console/migrationCommands.js.map +1 -0
- package/dist/console/schemaCheckCommand.d.ts +11 -17
- package/dist/console/schemaCheckCommand.d.ts.map +1 -1
- package/dist/console/schemaCheckCommand.js +21 -15
- package/dist/console/schemaCheckCommand.js.map +1 -1
- package/dist/console/schemaDumpCommand.d.ts +30 -0
- package/dist/console/schemaDumpCommand.d.ts.map +1 -0
- package/dist/console/schemaDumpCommand.js +69 -0
- package/dist/console/schemaDumpCommand.js.map +1 -0
- package/dist/console/schemaGenerateCommand.d.ts +100 -0
- package/dist/console/schemaGenerateCommand.d.ts.map +1 -0
- package/dist/console/schemaGenerateCommand.js +246 -0
- package/dist/console/schemaGenerateCommand.js.map +1 -0
- package/dist/console/seederCommands.d.ts +46 -0
- package/dist/console/seederCommands.d.ts.map +1 -0
- package/dist/console/seederCommands.js +136 -0
- package/dist/console/seederCommands.js.map +1 -0
- package/dist/decorators/entity.d.ts +50 -8
- package/dist/decorators/entity.d.ts.map +1 -1
- package/dist/decorators/entity.js +42 -2
- package/dist/decorators/entity.js.map +1 -1
- package/dist/decorators/hooks.d.ts +3 -3
- package/dist/decorators/hooks.d.ts.map +1 -1
- package/dist/decorators/hooks.js.map +1 -1
- package/dist/events.d.ts +69 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +82 -0
- package/dist/events.js.map +1 -0
- package/dist/factories.d.ts +8 -0
- package/dist/factories.d.ts.map +1 -0
- package/dist/factories.js +8 -0
- package/dist/factories.js.map +1 -0
- package/dist/index.d.ts +15 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -3
- package/dist/index.js.map +1 -1
- package/dist/lucid-schema.d.ts +15 -0
- package/dist/lucid-schema.d.ts.map +1 -0
- package/dist/lucid-schema.js +16 -0
- package/dist/lucid-schema.js.map +1 -0
- package/dist/metadata-keys.d.ts +3 -2
- package/dist/metadata-keys.d.ts.map +1 -1
- package/dist/naming/NamingStrategy.d.ts +7 -0
- package/dist/naming/NamingStrategy.d.ts.map +1 -1
- package/dist/naming/NamingStrategy.js +16 -0
- package/dist/naming/NamingStrategy.js.map +1 -1
- package/dist/orm.d.ts +14 -0
- package/dist/orm.d.ts.map +1 -0
- package/dist/orm.js +14 -0
- package/dist/orm.js.map +1 -0
- package/dist/query/DatabaseQueryBuilder.d.ts +557 -0
- package/dist/query/DatabaseQueryBuilder.d.ts.map +1 -0
- package/dist/query/DatabaseQueryBuilder.js +1798 -0
- package/dist/query/DatabaseQueryBuilder.js.map +1 -0
- package/dist/query/DmlBuilder.d.ts +62 -0
- package/dist/query/DmlBuilder.d.ts.map +1 -0
- package/dist/query/DmlBuilder.js +84 -0
- package/dist/query/DmlBuilder.js.map +1 -0
- package/dist/query/QueryBuilder.d.ts +5 -0
- package/dist/query/QueryBuilder.d.ts.map +1 -1
- package/dist/query/QueryBuilder.js +7 -0
- package/dist/query/QueryBuilder.js.map +1 -1
- package/dist/query/RawQueryBuilder.d.ts +47 -0
- package/dist/query/RawQueryBuilder.d.ts.map +1 -0
- package/dist/query/RawQueryBuilder.js +138 -0
- package/dist/query/RawQueryBuilder.js.map +1 -0
- package/dist/query/interpolate.d.ts +45 -0
- package/dist/query/interpolate.d.ts.map +1 -0
- package/dist/query/interpolate.js +51 -0
- package/dist/query/interpolate.js.map +1 -0
- package/dist/query/native.d.ts +8 -0
- package/dist/query/native.d.ts.map +1 -1
- package/dist/query/native.js +14 -0
- package/dist/query/native.js.map +1 -1
- package/dist/query/operators.d.ts +4 -0
- package/dist/query/operators.d.ts.map +1 -0
- package/dist/query/operators.js +27 -0
- package/dist/query/operators.js.map +1 -0
- package/dist/schema/Migration.d.ts +50 -3
- package/dist/schema/Migration.d.ts.map +1 -1
- package/dist/schema/Migration.js +60 -24
- package/dist/schema/Migration.js.map +1 -1
- package/dist/schema/MigrationRunner.d.ts +95 -34
- package/dist/schema/MigrationRunner.d.ts.map +1 -1
- package/dist/schema/MigrationRunner.js +523 -68
- package/dist/schema/MigrationRunner.js.map +1 -1
- package/dist/schema/Schema.d.ts +114 -0
- package/dist/schema/Schema.d.ts.map +1 -1
- package/dist/schema/Schema.js +272 -3
- package/dist/schema/Schema.js.map +1 -1
- package/dist/schema/SchemaDumper.d.ts +121 -0
- package/dist/schema/SchemaDumper.d.ts.map +1 -0
- package/dist/schema/SchemaDumper.js +365 -0
- package/dist/schema/SchemaDumper.js.map +1 -0
- package/dist/schema/Seeder.d.ts +13 -0
- package/dist/schema/Seeder.d.ts.map +1 -1
- package/dist/schema/Seeder.js +28 -5
- package/dist/schema/Seeder.js.map +1 -1
- package/dist/schema/TableBuilder.d.ts +274 -16
- package/dist/schema/TableBuilder.d.ts.map +1 -1
- package/dist/schema/TableBuilder.js +656 -52
- package/dist/schema/TableBuilder.js.map +1 -1
- package/dist/schema/catalog.d.ts +71 -0
- package/dist/schema/catalog.d.ts.map +1 -0
- package/dist/schema/catalog.js +158 -0
- package/dist/schema/catalog.js.map +1 -0
- package/dist/schema/introspect.d.ts +1 -1
- package/dist/schema/introspect.d.ts.map +1 -1
- package/dist/schema/introspect.js +26 -11
- package/dist/schema/introspect.js.map +1 -1
- package/dist/schema/types.d.ts +150 -1
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/schema/types.js +11 -0
- package/dist/schema/types.js.map +1 -1
- package/dist/seeders.d.ts +7 -0
- package/dist/seeders.d.ts.map +1 -0
- package/dist/seeders.js +7 -0
- package/dist/seeders.js.map +1 -0
- package/dist/services/db.d.ts +122 -5
- package/dist/services/db.d.ts.map +1 -1
- package/dist/services/db.js +187 -14
- package/dist/services/db.js.map +1 -1
- package/dist/testing/DatabaseCleanup.d.ts +33 -7
- package/dist/testing/DatabaseCleanup.d.ts.map +1 -1
- package/dist/testing/DatabaseCleanup.js +54 -24
- package/dist/testing/DatabaseCleanup.js.map +1 -1
- package/dist/testing/DbAssertions.d.ts +48 -0
- package/dist/testing/DbAssertions.d.ts.map +1 -0
- package/dist/testing/DbAssertions.js +80 -0
- package/dist/testing/DbAssertions.js.map +1 -0
- package/dist/testing/Factory.d.ts +166 -15
- package/dist/testing/Factory.d.ts.map +1 -1
- package/dist/testing/Factory.js +497 -23
- package/dist/testing/Factory.js.map +1 -1
- package/dist/testing/TestUtils.d.ts +49 -0
- package/dist/testing/TestUtils.d.ts.map +1 -0
- package/dist/testing/TestUtils.js +79 -0
- package/dist/testing/TestUtils.js.map +1 -0
- package/dist/testing/index.d.ts +3 -1
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +3 -1
- package/dist/testing/index.js.map +1 -1
- package/dist/types/relations.d.ts +31 -0
- package/dist/types/relations.d.ts.map +1 -0
- package/dist/types/relations.js +20 -0
- package/dist/types/relations.js.map +1 -0
- package/index.darwin-arm64.node +0 -0
- package/index.darwin-x64.node +0 -0
- package/index.linux-arm64-gnu.node +0 -0
- package/index.linux-x64-gnu.node +0 -0
- package/index.win32-x64-msvc.node +0 -0
- package/package.json +32 -2
- package/scripts/guard-publish.mjs +15 -0
- package/src/AtlasProvider.ts +305 -52
- package/src/BaseEntity.ts +460 -41
- package/src/BaseModel.ts +461 -0
- package/src/BaseRepository.ts +1710 -421
- package/src/ConnectionManager.ts +298 -0
- package/src/ModelQuery.ts +2998 -335
- package/src/Transaction.ts +227 -30
- package/src/adapters/NapiDbAdapter.ts +224 -17
- package/src/console/contract.ts +96 -0
- package/src/console/factoryCommands.ts +73 -0
- package/src/console/migrationCommands.ts +448 -0
- package/src/console/schemaCheckCommand.ts +26 -22
- package/src/console/schemaDumpCommand.ts +96 -0
- package/src/console/schemaGenerateCommand.ts +380 -0
- package/src/console/seederCommands.ts +174 -0
- package/src/decorators/entity.ts +71 -8
- package/src/decorators/hooks.ts +5 -3
- package/src/events.ts +117 -0
- package/src/factories.ts +10 -0
- package/src/index.ts +69 -3
- package/src/lucid-schema.ts +22 -0
- package/src/metadata-keys.ts +3 -2
- package/src/naming/NamingStrategy.ts +23 -0
- package/src/orm.ts +13 -0
- package/src/query/DatabaseQueryBuilder.ts +2724 -0
- package/src/query/DmlBuilder.ts +131 -0
- package/src/query/QueryBuilder.ts +8 -0
- package/src/query/RawQueryBuilder.ts +173 -0
- package/src/query/interpolate.ts +73 -0
- package/src/query/native.ts +29 -0
- package/src/query/operators.ts +27 -0
- package/src/schema/Migration.ts +71 -3
- package/src/schema/MigrationRunner.ts +676 -69
- package/src/schema/Schema.ts +359 -3
- package/src/schema/SchemaDumper.ts +518 -0
- package/src/schema/Seeder.ts +47 -10
- package/src/schema/TableBuilder.ts +783 -52
- package/src/schema/catalog.ts +236 -0
- package/src/schema/introspect.ts +26 -9
- package/src/schema/types.ts +137 -2
- package/src/seeders.ts +16 -0
- package/src/services/db.ts +361 -21
- package/src/testing/DatabaseCleanup.ts +78 -25
- package/src/testing/DbAssertions.ts +127 -0
- package/src/testing/Factory.ts +837 -40
- package/src/testing/TestUtils.ts +123 -0
- package/src/testing/index.ts +12 -1
- package/src/types/relations.ts +43 -0
package/README.md
CHANGED
|
@@ -1,11 +1,60 @@
|
|
|
1
1
|
# @c9up/atlas
|
|
2
2
|
|
|
3
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
18
|
-
|
|
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
|
-
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
- `
|
|
30
|
-
-
|
|
31
|
-
-
|
|
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
|
|
package/db.darwin-arm64.node
CHANGED
|
Binary file
|
package/db.darwin-x64.node
CHANGED
|
Binary file
|
package/db.linux-arm64-gnu.node
CHANGED
|
Binary file
|
package/db.linux-x64-gnu.node
CHANGED
|
Binary file
|
package/db.win32-x64-msvc.node
CHANGED
|
Binary file
|
package/dist/AtlasProvider.d.ts
CHANGED
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
* }
|
|
18
18
|
*
|
|
19
19
|
* // Code
|
|
20
|
-
* const primary = app.container.resolve('db')
|
|
21
|
-
* const tenant1 = app.container.resolve('db:tenant1')
|
|
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
|
-
/**
|
|
64
|
-
|
|
65
|
-
|
|
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
|
-
/**
|
|
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;
|
|
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"}
|
package/dist/AtlasProvider.js
CHANGED
|
@@ -17,13 +17,20 @@
|
|
|
17
17
|
* }
|
|
18
18
|
*
|
|
19
19
|
* // Code
|
|
20
|
-
* const primary = app.container.resolve('db')
|
|
21
|
-
* const tenant1 = app.container.resolve('db:tenant1')
|
|
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
|
-
|
|
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
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
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
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
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
|
-
|
|
147
|
-
|
|
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
|
|
185
|
-
|
|
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
|
|
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":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAEN,oBAAoB,GACpB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAEN,eAAe,GACf,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAgC3D,0EAA0E;AAC1E,SAAS,OAAO,CACf,CAAU;IAEV,OAAO,CACN,OAAO,CAAC,KAAK,QAAQ;QACrB,CAAC,KAAK,IAAI;QACV,MAAM,IAAI,CAAC;QACX,OAAO,CAAC,CAAC,IAAI,KAAK,UAAU,CAC5B,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,CAAC;IAChD,YAAY,EAAE,KAAK;IACnB,WAAW,EAAE,QAAQ;CACZ,CAAC,CAAC;AAmHZ,MAAM,CAAC,OAAO,OAAO,aAAa;IAOX;IANtB,mEAAmE;IACnE,YAAY,GAAG,IAAI,GAAG,EAAmC,CAAC;IAC1D,YAAY,GAAG,SAAS,CAAC;IACzB,kFAAkF;IAClF,cAAc,CAAc;IAE5B,YAAsB,GAAoB;QAApB,QAAG,GAAH,GAAG,CAAiB;IAAG,CAAC;IAE9C;;gFAE4E;IAC5E,kBAAkB,CAAC,IAAY;QAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACzC,IAAI,CAAC,IAAI,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CACd,8BAA8B,IAAI,iEAAiE,CACnG,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC;IACb,CAAC;IAED,QAAQ,KAAI,CAAC;IAEb;;;;;OAKG;IACH,KAAK,CAAC,oBAAoB;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC;QAC3C,IAAI,OAAO,OAAO,KAAK,UAAU;YAAE,OAAO;QAC1C,IAAI,OAAgB,CAAC;QACrB,IAAI,CAAC;YACJ,OAAO,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QAC5D,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,CAAC,4DAA4D;QACrE,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;YAAE,OAAO;QAC9B,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;QAClD,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC;QACxB,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE;YACzC,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;IACJ,CAAC;IAED,kEAAkE;IAClE,iBAAiB,CAAc;IAE/B;;;;OAIG;IACH,KAAK,CAAC,uBAAuB;QAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC;QAC3C,IAAI,OAAO,OAAO,KAAK,UAAU;YAAE,OAAO;QAC1C,IAAI,OAAgB,CAAC;QACrB,IAAI,CAAC;YACJ,OAAO,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QAC5D,CAAC;QAAC,MAAM,CAAC;YACR,OAAO;QACR,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;YAAE,OAAO;QAC9B,MAAM,EAAE,iBAAiB,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;QAC/D,MAAM,GAAG,GAAG,iBAAiB,EAAE,CAAC;QAChC,IAAI,CAAC,iBAAiB,EAAE,EAAE,CAAC;QAC3B,MAAM,SAAS,GAAG,CAAC,IAAa,EAAE,EAAE,CACnC,OAAO,CAAC,IAAI,CAAC,uBAAuB,EAAE,IAAI,CAAC,CAAC;QAC7C,MAAM,YAAY,GAAG,CAAC,IAAa,EAAE,EAAE,CACtC,OAAO,CAAC,IAAI,CAAC,0BAA0B,EAAE,IAAI,CAAC,CAAC;QAChD,MAAM,OAAO,GAAG,CAAC,IAAa,EAAE,GAAa,EAAE,EAAE,CAChD,OAAO,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;QAClD,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QAC7B,GAAG,CAAC,EAAE,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;QACnC,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACzB,IAAI,CAAC,iBAAiB,GAAG,GAAG,EAAE;YAC7B,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;YAC9B,GAAG,CAAC,GAAG,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;YACpC,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC3B,CAAC,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI;QACT,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAsB,UAAU,CAAC,CAAC;QACpE,IAAI,CAAC,MAAM;YAAE,OAAO;QAEpB,0FAA0F;QAC1F,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC;QACtE,IAAI,CAAC,YAAY,GAAG,WAAW,CAAC;QAEhC,wEAAwE;QACxE,0EAA0E;QAC1E,MAAM,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAClC,2EAA2E;QAC3E,oEAAoE;QACpE,MAAM,IAAI,CAAC,uBAAuB,EAAE,CAAC;QAErC,4EAA4E;QAC5E,6EAA6E;QAC7E,kDAAkD;QAClD,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;QAEpD,wEAAwE;QACxE,yEAAyE;QACzE,yDAAyD;QACzD,EAAE;QACF,2EAA2E;QAC3E,wEAAwE;QACxE,uEAAuE;QACvE,uBAAuB;QACvB,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAC5C,4EAA4E;QAC5E,yEAAyE;QACzE,KAAK,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,OAAO,EAAE,CAAC;YACxC,UAAU,CAAC,iBAAiB,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACpD,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CACvC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,EAAE,CAChC,oBAAoB,CACnB,QAAQ,CAAC,GAAG,EACZ,QAAQ,CAAC,IAAI,EAAE,GAAG,IAAI,QAAQ,CAAC,OAAO,IAAI,CAAC,EAC3C,QAAQ,CAAC,IAAI,EAAE,GAAG,IAAI,QAAQ,CAAC,OAAO,IAAI,EAAE,EAC5C,QAAQ,CAAC,OAAO,EAChB;YACC,OAAO,EAAE,QAAQ,CAAC,cAAc;YAChC,SAAS,EAAE,QAAQ,CAAC,gBAAgB;YACpC,SAAS,EAAE,QAAQ,CAAC,gBAAgB;SACpC,EACD,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,IAAI,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,CACxD,CACD,CACD,CAAC;QACF,MAAM,QAAQ,GAA4C,EAAE,CAAC;QAC7D,MAAM,SAAS,GACd,EAAE,CAAC;QACJ,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACxB,MAAM,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;YAC1B,IAAI,CAAC,CAAC,MAAM,KAAK,WAAW;gBAAE,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;;gBACjE,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;QACH,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,4DAA4D;YAC5D,6DAA6D;YAC7D,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;gBAC1B,UAAU,CAAC,iBAAiB,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;YACpE,CAAC;YACD,qEAAqE;YACrE,oEAAoE;YACpE,+CAA+C;YAC/C,MAAM,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;YAC/D,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;YAC1B,MAAM,MAAM,GAAG,QAAQ;iBACrB,KAAK,CAAC,CAAC,CAAC;iBACR,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;iBAC3C,IAAI,CAAC,IAAI,CAAC,CAAC;YACb,MAAM,IAAI,KAAK,CACd,iCAAiC,QAAQ,CAAC,MAAM,mBAAmB;gBAClE,IAAI,KAAK,CAAC,IAAI,aAAa,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;gBAChD,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CACrC,CAAC;QACH,CAAC;QACD,wEAAwE;QACxE,0EAA0E;QAC1E,uEAAuE;QACvE,wDAAwD;QACxD,IAAI,CAAC;YACJ,wEAAwE;YACxE,yEAAyE;YACzE,uEAAuE;YACvE,MAAM,YAAY,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC;YACnE,IAAI,CAAC,YAAY,EAAE,CAAC;gBACnB,MAAM,IAAI,KAAK,CACd,sCAAsC,WAAW,iDAAiD,CAClG,CAAC;YACH,CAAC;YACD,MAAM,WAAW,GAAG,YAAY,CAAC,IAAI,CAAC;YAEtC,wEAAwE;YACxE,wEAAwE;YACxE,uEAAuE;YACvE,qEAAqE;YACrE,2EAA2E;YAC3E,sEAAsE;YACtE,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,SAAS,EAAE,CAAC;gBACxC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;gBAClC,UAAU,CAAC,kBAAkB,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;gBAC7D,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,IAAI,EAAE,EAAE,GAAG,EAAE,CAC/C,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAC7B,CAAC;YACH,CAAC;YAED,uEAAuE;YACvE,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,EAAE,GAAG,EAAE,CACvC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,YAAY,CAAC,CAC1C,CAAC;YACF,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,eAAe,EAAE,GAAG,EAAE,CAClD,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,YAAY,CAAC,CAC1C,CAAC;YAEF,2DAA2D;YAC3D,4DAA4D;YAC5D,UAAU,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YAE9B,mEAAmE;YACnE,uEAAuE;YACvE,iEAAiE;YACjE,eAAe,CAAC,cAAc,CAAC,WAAW,CAAC,WAAW,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;YAE/D,wEAAwE;YACxE,sEAAsE;YACtE,qEAAqE;YACrE,uEAAuE;YACvE,sCAAsC;YACtC,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,CAAC;YAC3D,MAAM,kBAAkB,GACvB,CAAC,YAAY,IAAI,MAAM,CAAC,UAAU,EAAE,mBAAmB,KAAK,IAAI,CAAC;YAClE,IACC,CAAC,MAAM,CAAC,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC;gBAC1D,OAAO,CAAC,GAAG,CAAC,sBAAsB,KAAK,GAAG;gBAC1C,kBAAkB,EACjB,CAAC;gBACF,MAAM,IAAI,CAAC,cAAc,CACxB,MAAM,CAAC,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,UAAU,EAAE,IAAI,IAAI,EAAE,EAC9D,WAAW,CAAC,WAAW,CAAC,EAAE,GAAG,EAC7B,WAAW,EACX,MAAM,CAAC,UAAU,CAAC,KAAK,EACvB;oBACC,WAAW,EAAE,MAAM,CAAC,UAAU,CAAC,WAAW;oBAC1C,mBAAmB,EAAE,MAAM,CAAC,UAAU,CAAC,mBAAmB;iBAC1D,CACD,CAAC;YACH,CAAC;QACF,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,MAAM,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;YAC/D,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,SAAS,EAAE,CAAC;gBACxC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;gBACzB,UAAU,CAAC,oBAAoB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YAC7C,CAAC;YACD,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;YAC1B,MAAM,GAAG,CAAC;QACX,CAAC;IACF,CAAC;IAED,KAAK,CAAC,QAAQ;QACb,sEAAsE;QACtE,uEAAuE;QACvE,mEAAmE;QACnE,EAAE;QACF,uEAAuE;QACvE,oDAAoD;QACpD,wEAAwE;QACxE,oEAAoE;QACpE,+DAA+D;QAC/D,yEAAyE;QACzE,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC;QACxB,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC;QAChC,IAAI,CAAC,iBAAiB,EAAE,EAAE,CAAC;QAC3B,IAAI,CAAC,iBAAiB,GAAG,SAAS,CAAC;QAEnC,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC,CAAC;QAC/C,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAC1E,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;QAE1B,2EAA2E;QAC3E,yEAAyE;QACzE,4EAA4E;QAC5E,qEAAqE;QACrE,sEAAsE;QACtE,0EAA0E;QAC1E,yBAAyB;QACzB,MAAM,EAAE,OAAO,EAAE,oBAAoB,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;QAC3E,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,KAAK,EAAE,CAAC;YAClC,OAAO,CAAC,IAAI,CAAC,CAAC;YACd,oBAAoB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAClC,CAAC;QACD,iBAAiB,EAAE,CAAC;QACpB,MAAM,MAAM,GAAG,OAAO;aACpB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACb,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CACvE;aACA,MAAM,CAAC,CAAC,CAAC,EAAyC,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;QACnE,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,OAAO,GAAG,MAAM;iBACpB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,MAAM,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;iBAC7C,IAAI,CAAC,IAAI,CAAC,CAAC;YACb,MAAM,IAAI,cAAc,CACvB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,EAC1B,kBAAkB,MAAM,CAAC,MAAM,oCAAoC,OAAO,EAAE,CAC5E,CAAC;QACH,CAAC;IACF,CAAC;IAED,KAAK,CAAC,KAAK;QACV,sEAAsE;QACtE,uEAAuE;QACvE,uEAAuE;QACvE,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAsB,UAAU,CAAC,CAAC;QACpE,MAAM,MAAM,GAAG,MAAM,EAAE,YAAY,CAAC;QACpC,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QACpD,MAAM,EAAE,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACpD,IAAI,CAAC,EAAE;YAAE,OAAO;QAChB,MAAM,CAAC,EAAE,YAAY,EAAE,EAAE,EAAE,eAAe,EAAE,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YACjE,MAAM,CAAC,yBAAyB,CAAC;YACjC,MAAM,CAAC,mBAAmB,CAAC;SAC3B,CAAC,CAAC;QACH,MAAM,YAAY,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,EAAE,eAAe,EAAE,EAAE;YAC1D,IAAI,EAAE,MAAM,CAAC,IAAI;SACjB,CAAC,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,KAAK,KAAI,CAAC;IAEhB,oFAAoF;IACpF,mBAAmB,CAAC,MAA2B;QAI9C,IAAI,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtE,6EAA6E;YAC7E,MAAM,WAAW,GAChB,EAAE,CAAC;YACJ,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC;gBAChE,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,UAAU,CAAC;gBAC1C,IAAI,CAAC,GAAG,EAAE,CAAC;oBACV,MAAM,IAAI,KAAK,CACd,uBAAuB,IAAI,qFAAqF,IAAI,GAAG,CACvH,CAAC;gBACH,CAAC;gBACD,WAAW,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,GAAG,EAAE,CAAC;YACvC,CAAC;YACD,OAAO;gBACN,WAAW;gBACX,mEAAmE;gBACnE,WAAW,EAAE,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,OAAO,IAAI,SAAS;aAC7D,CAAC;QACH,CAAC;QACD,qEAAqE;QACrE,oEAAoE;QACpE,qEAAqE;QACrE,0EAA0E;QAC1E,0EAA0E;QAC1E,8EAA8E;QAC9E,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CACd,6HAA6H,CAC7H,CAAC;QACH,CAAC;QACD,OAAO;YACN,WAAW,EAAE;gBACZ,OAAO,EAAE;oBACR,GAAG,EAAE,MAAM,CAAC,GAAG;oBACf,OAAO,EAAE,MAAM,CAAC,OAAO;oBACvB,OAAO,EAAE,MAAM,CAAC,OAAO;oBACvB,IAAI,EAAE,MAAM,CAAC,IAAI;oBACjB,OAAO,EAAE,MAAM,CAAC,OAAO;oBACvB,KAAK,EAAE,MAAM,CAAC,KAAK;oBACnB,cAAc,EAAE,MAAM,CAAC,cAAc;oBACrC,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;oBACzC,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;iBACzC;aACD;YACD,WAAW,EAAE,SAAS;SACtB,CAAC;IACH,CAAC;IAED,KAAK,CAAC,cAAc,CACnB,cAAsB,EACtB,GAAW,EACX,EAA2B,EAC3B,SAA6B,EAC7B,OAAkE;QAElE,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;QAC/C,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC;YAAE,OAAO;QAExC,MAAM,OAAO,GAAoB;YAChC,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE;gBAC9B,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAC/B,CAAC;YACD,KAAK,EAAE,CAAI,GAAW,EAAE,MAAkB,EAAE,EAAE,CAC7C,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,CAAiB;YACtC,KAAK,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE;YACvB,qEAAqE;YACrE,yEAAyE;YACzE,wEAAwE;YACxE,sDAAsD;YACtD,gBAAgB,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,KAAK,CAAC;YAC7D,kEAAkE;YAClE,gEAAgE;YAChE,WAAW,EAAE,EAAE,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC;SACrC,CAAC;QACF,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,OAAO,EAAE;YAC3C,aAAa,EAAE,cAAc;YAC7B,OAAO,EAAE,cAAc,CAAC,GAAG,CAAC;YAC5B,SAAS;YACT,WAAW,EAAE,OAAO,EAAE,WAAW;YACjC,mBAAmB,EAAE,OAAO,EAAE,mBAAmB;SACjD,CAAC,CAAC;QACH,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;IACxB,CAAC;CACD"}
|