@stratal/framework 0.0.0-canary-e93db60 → 0.0.0-canary-ab95f52
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/access-control/index.d.mts +1 -1
- package/dist/database/index.d.mts +1 -1
- package/dist/database/index.mjs +24 -2
- package/dist/database/index.mjs.map +1 -1
- package/dist/factory/index.d.mts +1 -1
- package/dist/{index-DTXzJzpy.d.mts → index-Dt0YUA7r.d.mts} +3 -2
- package/dist/index-Dt0YUA7r.d.mts.map +1 -0
- package/package.json +2 -2
- package/dist/index-DTXzJzpy.d.mts.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as RolePermissions, t as AccessControlOptions } from "../types-DabF8LGz.mjs";
|
|
2
|
-
import { M as DatabaseService } from "../index-
|
|
2
|
+
import { M as DatabaseService } from "../index-Dt0YUA7r.mjs";
|
|
3
3
|
import { t as AuthContext } from "../auth-context-CGVbiSX3.mjs";
|
|
4
4
|
import { HttpException } from "stratal/errors";
|
|
5
5
|
import { AccessControl, Role, Statements } from "better-auth/plugins/access";
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { a as InferConnectionSchema, i as InferConnectionExtensions, n as DefaultConnectionName, o as InternalDatabaseEventContext, r as InferAnySchema, s as StratalDatabase, t as ConnectionName } from "../types-CWZ9q74G.mjs";
|
|
2
|
-
import { A as DATABASE_TOKENS, C as GetResult, D as UniqueConstraintError, E as fromZenStackError, F as DatabaseModuleConfig, M as DatabaseService, N as DatabaseConnectionConfig, O as RecordNotFoundError, P as DatabaseModule, S as GetEntity, T as ParseEvent, _ as EntityEventName, a as DbPushCommand, b as EventPhase, c as ZenStackCommand, d as EventEmitterPluginOptions, f as ErrorHandlerPlugin, g as DatabaseOperation, h as DatabaseEvents, i as MigrateDeployCommand, j as connectionSymbol, k as InjectDB, l as SchemaSwitcher, m as DatabaseEventName, n as MigrateResetCommand, o as DbPullCommand, p as databaseMessages, r as MigrateDevCommand, s as DbGenerateCommand, t as MigrateStatusCommand, u as EventEmitterPlugin, v as EntityEvents, w as ModelName, x as GetData, y as EntityMutationVerb } from "../index-
|
|
2
|
+
import { A as DATABASE_TOKENS, C as GetResult, D as UniqueConstraintError, E as fromZenStackError, F as DatabaseModuleConfig, M as DatabaseService, N as DatabaseConnectionConfig, O as RecordNotFoundError, P as DatabaseModule, S as GetEntity, T as ParseEvent, _ as EntityEventName, a as DbPushCommand, b as EventPhase, c as ZenStackCommand, d as EventEmitterPluginOptions, f as ErrorHandlerPlugin, g as DatabaseOperation, h as DatabaseEvents, i as MigrateDeployCommand, j as connectionSymbol, k as InjectDB, l as SchemaSwitcher, m as DatabaseEventName, n as MigrateResetCommand, o as DbPullCommand, p as databaseMessages, r as MigrateDevCommand, s as DbGenerateCommand, t as MigrateStatusCommand, u as EventEmitterPlugin, v as EntityEvents, w as ModelName, x as GetData, y as EntityMutationVerb } from "../index-Dt0YUA7r.mjs";
|
|
3
3
|
export { ConnectionName, DATABASE_TOKENS, DatabaseConnectionConfig, DatabaseEventName, DatabaseEvents, DatabaseModule, DatabaseModuleConfig, DatabaseOperation, DatabaseService, DbGenerateCommand, DbPullCommand, DbPushCommand, DefaultConnectionName, EntityEventName, EntityEvents, EntityMutationVerb, ErrorHandlerPlugin, EventEmitterPlugin, EventEmitterPluginOptions, EventPhase, GetData, GetEntity, GetResult, InferAnySchema, InferConnectionExtensions, InferConnectionSchema, InjectDB, InternalDatabaseEventContext, MigrateDeployCommand, MigrateDevCommand, MigrateResetCommand, MigrateStatusCommand, ModelName, ParseEvent, RecordNotFoundError, SchemaSwitcher, StratalDatabase, UniqueConstraintError, ZenStackCommand, connectionSymbol, databaseMessages, fromZenStackError };
|
package/dist/database/index.mjs
CHANGED
|
@@ -357,6 +357,7 @@ z.object({
|
|
|
357
357
|
*/
|
|
358
358
|
function makeReentrantTransaction(client, activeTransaction) {
|
|
359
359
|
return new Proxy(client, { get(target, prop, receiver) {
|
|
360
|
+
if (prop === Symbol.asyncDispose) return () => target.$disconnect();
|
|
360
361
|
if (prop !== "$transaction") return Reflect.get(target, prop, receiver);
|
|
361
362
|
const transaction = Reflect.get(target, prop);
|
|
362
363
|
return (input, options) => {
|
|
@@ -374,6 +375,7 @@ function createDatabaseService(conn, eventRegistry) {
|
|
|
374
375
|
...conn.plugins ?? []
|
|
375
376
|
];
|
|
376
377
|
const activeTransaction = new AsyncLocalStorage();
|
|
378
|
+
const instances = /* @__PURE__ */ new Set();
|
|
377
379
|
let DatabaseClient = class DatabaseClient extends ZenStackClient {
|
|
378
380
|
constructor() {
|
|
379
381
|
const dialect = conn.dialect();
|
|
@@ -382,7 +384,23 @@ function createDatabaseService(conn, eventRegistry) {
|
|
|
382
384
|
plugins,
|
|
383
385
|
computedFields: conn.computedFields
|
|
384
386
|
});
|
|
385
|
-
|
|
387
|
+
const client = makeReentrantTransaction(this, activeTransaction);
|
|
388
|
+
for (const ref of instances) if (ref.deref() === void 0) instances.delete(ref);
|
|
389
|
+
instances.add(new WeakRef(client));
|
|
390
|
+
return client;
|
|
391
|
+
}
|
|
392
|
+
static async disposeInstances() {
|
|
393
|
+
const live = [...instances];
|
|
394
|
+
instances.clear();
|
|
395
|
+
await Promise.all(live.map(async (ref) => {
|
|
396
|
+
const client = ref.deref();
|
|
397
|
+
if (!client) return;
|
|
398
|
+
try {
|
|
399
|
+
await client.$disconnect();
|
|
400
|
+
} catch (error) {
|
|
401
|
+
console.error(`[stratal] Failed to disconnect database client "${conn.name}":`, error);
|
|
402
|
+
}
|
|
403
|
+
}));
|
|
386
404
|
}
|
|
387
405
|
};
|
|
388
406
|
DatabaseClient = __decorate([Transient()], DatabaseClient);
|
|
@@ -410,6 +428,7 @@ const databaseMessages = { en: {
|
|
|
410
428
|
//#region src/database/database.module.ts
|
|
411
429
|
var _DatabaseModule;
|
|
412
430
|
let DatabaseModule = _DatabaseModule = class DatabaseModule {
|
|
431
|
+
services = [];
|
|
413
432
|
static forRoot(config) {
|
|
414
433
|
return {
|
|
415
434
|
module: _DatabaseModule,
|
|
@@ -434,12 +453,15 @@ let DatabaseModule = _DatabaseModule = class DatabaseModule {
|
|
|
434
453
|
const eventRegistry = (await context.container.resolve(DI_TOKENS.LazyModuleLoader).load(() => import("stratal/events").then((m) => m.EventsModule))).get(DI_TOKENS.EventRegistry);
|
|
435
454
|
for (const conn of config.connections) {
|
|
436
455
|
const Service = createDatabaseService(conn, eventRegistry);
|
|
456
|
+
this.services.push(Service);
|
|
437
457
|
context.container.register(connectionSymbol(conn.name), lazy(() => Service));
|
|
438
458
|
}
|
|
439
459
|
context.container.registerExisting(DI_TOKENS.Database, connectionSymbol(config.default));
|
|
440
460
|
context.logger.info("DatabaseModule initialized");
|
|
441
461
|
}
|
|
442
|
-
onShutdown(context) {
|
|
462
|
+
async onShutdown(context) {
|
|
463
|
+
await Promise.all(this.services.map((service) => service.disposeInstances()));
|
|
464
|
+
this.services.length = 0;
|
|
443
465
|
context.logger.info("DatabaseModule shutdown");
|
|
444
466
|
}
|
|
445
467
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/database/commands/zenstack.command.ts","../../src/database/commands/db-generate.command.ts","../../src/database/commands/db-pull.command.ts","../../src/database/commands/db-push.command.ts","../../src/database/commands/migrate-deploy.command.ts","../../src/database/commands/migrate-dev.command.ts","../../src/database/commands/migrate-reset.command.ts","../../src/database/commands/migrate-status.command.ts","../../src/database/errors/record-not-found.error.ts","../../src/database/errors/unique-constraint.error.ts","../../src/database/errors/from-zenstack-error.ts","../../src/database/plugins/error-handler.plugin.ts","../../src/database/plugins/event-emitter.plugin.ts","../../src/database/plugins/schema-switcher.ts","../../src/database/database.helpers.ts","../../src/database/database.tokens.ts","../../src/database/i18n/en.ts","../../src/database/database.module.ts","../../src/database/decorators/inject-db.decorator.ts"],"sourcesContent":["import { Command } from 'stratal/quarry'\n\n/**\n * Base command for ZenStack CLI wrappers.\n * Uses execFileSync with array arguments to prevent shell injection.\n */\nexport abstract class ZenStackCommand extends Command {\n protected async zenstack(args: string[]): Promise<number> {\n // Dynamic import — node:child_process is only available in the Quarry CLI (Node) context\n const { execFileSync } = await import('node:child_process')\n\n try {\n const output = execFileSync('npx', ['zenstack', ...args], {\n encoding: 'utf-8',\n stdio: 'pipe',\n })\n if (output) this.info(output.trim())\n return 0\n } catch (err) {\n const error = err as { stderr?: string; stdout?: string; status?: number }\n if (error.stderr) this.error(error.stderr.trim())\n if (error.stdout) this.info(error.stdout.trim())\n return error.status ?? 1\n }\n }\n}\n","import { ZenStackCommand } from './zenstack.command'\n\nexport class DbGenerateCommand extends ZenStackCommand {\n static command = 'db:generate {--schema= : Path to schema file} {--watch : Enable watch mode}'\n static description = 'Generate ZenStack ORM client'\n\n async handle(): Promise<number> {\n const args = ['generate']\n const schema = this.string('schema')\n\n if (schema) args.push('--schema', schema)\n if (this.boolean('watch')) args.push('--watch')\n\n return this.zenstack(args)\n }\n}\n","import { ZenStackCommand } from './zenstack.command'\n\nexport class DbPullCommand extends ZenStackCommand {\n static command = 'db:pull {--schema= : Path to schema file}'\n static description = 'Introspect database and generate schema'\n\n async handle(): Promise<number> {\n const args = ['db', 'pull']\n const schema = this.string('schema')\n\n if (schema) args.push('--schema', schema)\n\n return this.zenstack(args)\n }\n}\n","import { ZenStackCommand } from './zenstack.command'\n\nexport class DbPushCommand extends ZenStackCommand {\n static command = 'db:push {--schema= : Path to schema file} {--accept-data-loss : Accept data loss} {--force-reset : Force reset database}'\n static description = 'Push database schema changes'\n\n async handle(): Promise<number> {\n const args = ['db', 'push']\n const schema = this.string('schema')\n\n if (schema) args.push('--schema', schema)\n if (this.boolean('accept-data-loss')) args.push('--accept-data-loss')\n if (this.boolean('force-reset')) args.push('--force-reset')\n\n return this.zenstack(args)\n }\n}\n","import { ZenStackCommand } from './zenstack.command'\n\nexport class MigrateDeployCommand extends ZenStackCommand {\n static command = 'migrate:deploy {--schema= : Path to schema file}'\n static description = 'Deploy pending migrations'\n\n async handle(): Promise<number> {\n const args = ['migrate', 'deploy']\n const schema = this.string('schema')\n\n if (schema) args.push('--schema', schema)\n\n return this.zenstack(args)\n }\n}\n","import { ZenStackCommand } from './zenstack.command'\n\nexport class MigrateDevCommand extends ZenStackCommand {\n static command = 'migrate:dev {--schema= : Path to schema file} {--name= : Migration name} {--create-only : Create without applying}'\n static description = 'Create and apply migration'\n\n async handle(): Promise<number> {\n const args = ['migrate', 'dev']\n const schema = this.string('schema')\n const name = this.string('name')\n\n if (schema) args.push('--schema', schema)\n if (name) args.push('--name', name)\n if (this.boolean('create-only')) args.push('--create-only')\n\n return this.zenstack(args)\n }\n}\n","import { ZenStackCommand } from './zenstack.command'\n\nexport class MigrateResetCommand extends ZenStackCommand {\n static command = 'migrate:reset {--schema= : Path to schema file} {--force : Skip confirmation} {--skip-seed : Skip seeding}'\n static description = 'Reset database'\n\n async handle(): Promise<number> {\n const args = ['migrate', 'reset']\n const schema = this.string('schema')\n\n if (schema) args.push('--schema', schema)\n if (this.boolean('force')) args.push('--force')\n if (this.boolean('skip-seed')) args.push('--skip-seed')\n\n return this.zenstack(args)\n }\n}\n","import { ZenStackCommand } from './zenstack.command'\n\nexport class MigrateStatusCommand extends ZenStackCommand {\n static command = 'migrate:status {--schema= : Path to schema file}'\n static description = 'Check migration status'\n\n async handle(): Promise<number> {\n const args = ['migrate', 'status']\n const schema = this.string('schema')\n\n if (schema) args.push('--schema', schema)\n\n return this.zenstack(args)\n }\n}\n","import { HttpException } from 'stratal/errors'\n\nexport class RecordNotFoundError extends HttpException {\n constructor(public readonly details?: string, cause?: unknown) {\n super(404, 'Record not found', cause)\n }\n}\n","import { HttpException } from 'stratal/errors'\n\nexport class UniqueConstraintError extends HttpException {\n constructor(public readonly fields?: string[], cause?: unknown) {\n super(409, 'Record already exists', cause)\n }\n}\n","import { ORMError, ORMErrorReason } from '@zenstackhq/orm';\nimport { type ApplicationError, DatabaseError } from 'stratal/errors';\nimport { RecordNotFoundError } from './record-not-found.error';\nimport { UniqueConstraintError } from './unique-constraint.error';\n\nexport function fromZenStackError(error: unknown): ApplicationError {\n if (error instanceof ORMError) {\n switch (error.reason) {\n case ORMErrorReason.NOT_FOUND:\n return new RecordNotFoundError(error.model, error)\n case ORMErrorReason.DB_QUERY_ERROR:\n return parseDatabaseError(error)\n case ORMErrorReason.INVALID_INPUT:\n return new DatabaseError('Invalid database query', error)\n case ORMErrorReason.CONFIG_ERROR:\n return new DatabaseError('Database configuration error', error)\n case ORMErrorReason.NOT_SUPPORTED:\n return new DatabaseError('Operation not supported', error)\n case ORMErrorReason.INTERNAL_ERROR:\n return new DatabaseError('Database internal error', error)\n default:\n return new DatabaseError('Database error', error)\n }\n }\n return new DatabaseError('Database error', error)\n}\n\nfunction parseDatabaseError(error: ORMError): ApplicationError {\n const dbErrorCode = error.dbErrorCode as string | undefined\n if (dbErrorCode) {\n if (dbErrorCode === '23505') return new UniqueConstraintError([error.model ?? 'unknown'], error)\n if (dbErrorCode === '23503') return new DatabaseError('Foreign key constraint violation', error)\n if (dbErrorCode === '23502') return new DatabaseError('Required field is missing', error)\n if (dbErrorCode === '23514') return new DatabaseError('Database constraint violated', error)\n if (dbErrorCode === '42P01') return new DatabaseError('Table does not exist', error)\n if (dbErrorCode === '42703') return new DatabaseError('Column does not exist', error)\n if (dbErrorCode.startsWith('42')) return new DatabaseError('Database syntax or access error', error)\n if (dbErrorCode.startsWith('08')) return new DatabaseError('Database connection failed', error)\n if (dbErrorCode === '57014') return new DatabaseError('Database query timeout', error)\n if (dbErrorCode.startsWith('40')) return new DatabaseError('Transaction conflict or deadlock', error)\n if (dbErrorCode === '53300') return new DatabaseError('Too many database connections', error)\n }\n return new DatabaseError('Database error', error)\n}\n","import { type RuntimePlugin } from '@zenstackhq/orm'\nimport { type SchemaDef } from '@zenstackhq/orm/schema'\nimport { fromZenStackError } from '../errors'\n\n/**\n * ZenStack runtime plugin that transforms ORM errors into ApplicationError instances.\n *\n * @example\n * ```typescript\n * super(schema, {\n * dialect: new PostgresDialect({ pool }),\n * plugins: [new ErrorHandlerPlugin()]\n * })\n * ```\n */\nexport class ErrorHandlerPlugin implements RuntimePlugin<SchemaDef, Record<string, unknown>, Record<string, unknown>, {}> {\n readonly id = 'error-handler'\n\n onQuery = async ({ args, proceed }: {\n args: Record<string, unknown> | undefined\n proceed: (args: Record<string, unknown> | undefined) => Promise<unknown>\n }): Promise<unknown> => {\n try {\n return await proceed(args)\n } catch (error) {\n throw fromZenStackError(error)\n }\n }\n}\n","import { type EntityMutationHooksDef, type RuntimePlugin } from '@zenstackhq/orm';\nimport { type SchemaDef } from '@zenstackhq/orm/schema';\nimport type { EventContext, EventName, IEventRegistry } from 'stratal/events';\nimport type { ModelName } from '../event-types';\n\nexport interface EventEmitterPluginOptions {\n eventRegistry: IEventRegistry\n}\n\ntype EntityMutationAction = 'create' | 'update' | 'delete'\n\nconst ENTITY_ACTION_VERB = {\n create: 'created',\n update: 'updated',\n delete: 'deleted',\n} as const satisfies Record<EntityMutationAction, string>\n\ntype Entity = Record<string, unknown>\n\n/**\n * Pair before/after entity snapshots for a mutation. Rows are matched by\n * `id` when both sides carry one, falling back to positional pairing.\n */\nfunction pairEntities(\n before: Entity[] | undefined,\n after: Entity[] | undefined\n): { before: Entity | undefined; after: Entity | undefined }[] {\n const primary = after ?? before ?? []\n const counterpart = after ? before : undefined\n const counterpartById = counterpart\n ? new Map(counterpart.filter((c) => c.id !== undefined).map((c) => [c.id, c]))\n : undefined\n\n return primary.map((entity, index) => {\n const match = counterpart\n ? (entity.id !== undefined ? counterpartById?.get(entity.id) : undefined) ?? counterpart[index]\n : undefined\n\n return after\n ? { before: match, after: entity }\n : { before: entity, after: undefined }\n })\n}\n\n/**\n * ZenStack runtime plugin that emits before/after events for database operations.\n *\n * Emits events in the format:\n * - `before.{Model}.{operation}` - Before the database operation\n * - `after.{Model}.{operation}` - After the database operation\n *\n * Additionally emits entity-mutation events carrying full entity snapshots:\n * - `entity.{Model}.created` - `{ after }`\n * - `entity.{Model}.updated` - `{ before, after }`\n * - `entity.{Model}.deleted` - `{ before }`\n *\n * Entity events are listener-driven: the pre-mutation snapshot is only\n * loaded (inside the mutation's transaction) when `hasListeners()` reports\n * a matching subscription, so models nobody observes pay no cost. Note that\n * a wildcard subscription (`entity`) therefore makes every model pay the\n * pre-read — subscribe per model when cost matters.\n *\n * @example\n * ```typescript\n * super(schema, {\n * dialect: new PostgresDialect({ pool }),\n * plugins: [\n * new EventEmitterPlugin({\n * eventRegistry,\n * })\n * ]\n * })\n * ```\n */\nexport class EventEmitterPlugin implements RuntimePlugin<SchemaDef, Record<string, unknown>, Record<string, unknown>, {}> {\n readonly id = 'event-emitter'\n\n constructor(private options: EventEmitterPluginOptions) { }\n\n onEntityMutation: EntityMutationHooksDef<SchemaDef> = {\n // Run after-hooks inside the mutation's transaction boundary so they\n // execute within the caller's async context (AsyncLocalStorage intact):\n // listeners resolve from the live request scope and tenant schema\n // switching still applies. Post-commit hooks would run detached from the\n // request's ALS. Listeners registered `blocking: false` still do their\n // real work outside the transaction via waitUntil.\n runAfterMutationWithinTransaction: true,\n\n beforeEntityMutation: async (args) => {\n // Created rows have no prior state to snapshot\n if (args.action === 'create') return\n\n const event = `entity.${args.model}.${ENTITY_ACTION_VERB[args.action]}` as EventName\n if (!this.options.eventRegistry.hasListeners(event)) return\n\n // Runs inside the mutation's transaction; ZenStack hands the result\n // to afterEntityMutation as `beforeMutationEntities`\n await args.loadBeforeMutationEntities()\n },\n\n afterEntityMutation: async (args) => {\n const { model, action, beforeMutationEntities } = args\n const verb = ENTITY_ACTION_VERB[action]\n const event = `entity.${model}.${verb}` as EventName\n const { eventRegistry } = this.options\n\n if (!eventRegistry.hasListeners(event)) return\n\n const after = action === 'delete' ? undefined : await args.loadAfterMutationEntities()\n\n for (const pair of pairEntities(beforeMutationEntities, after)) {\n // Producer boundary: ZenStack types `model` as plain string, but at\n // runtime it is always a schema model name — assert that one fact.\n const context: EventContext<'entity'> = {\n model: model as ModelName,\n action: verb,\n before: pair.before,\n after: pair.after,\n }\n await eventRegistry.emit(event, context)\n }\n },\n }\n\n onQuery = async ({ model, operation, args, proceed }: {\n model: string\n operation: string\n args: Record<string, unknown> | undefined\n proceed: (args: Record<string, unknown> | undefined) => Promise<unknown>\n }): Promise<unknown> => {\n const { eventRegistry } = this.options\n const eventBase = `${model}.${operation}`\n\n // Emit BEFORE event\n await eventRegistry.emit(`before.${eventBase}` as EventName, {\n data: args,\n })\n\n // Execute the actual database operation\n const result = await proceed(args)\n\n // Emit AFTER event\n await eventRegistry.emit(`after.${eventBase}` as EventName, {\n data: args,\n result,\n })\n\n return result\n }\n}\n","interface SwitchableClient {\n $schema: { provider: { defaultSchema: string } } & Record<string, unknown>\n schema: unknown\n}\n\n/**\n * Switches the active schema on a ZenStack/Kysely database client by mutating\n * `$schema.provider.defaultSchema`. This causes ZenStack's QueryNameMapper to\n * generate fully-qualified table references (e.g. `\"tenant_123\".\"User\"`).\n *\n * Must be called BEFORE any queries are made on the client.\n *\n * Note: The ZenStack RuntimePlugin `onQuery` hook fires after table names are\n * already resolved, so a plugin-based approach cannot set the schema prefix.\n * Direct client mutation is the only supported method.\n */\nexport class SchemaSwitcher {\n static apply<T>(client: T, schemaName: string): T {\n const c = client as unknown as SwitchableClient\n const switched = {\n ...c.$schema,\n provider: { ...c.$schema.provider, defaultSchema: schemaName },\n }\n c.$schema = switched\n c.schema = switched\n return client\n }\n}\n","import { ZenStackClient, type AnyPlugin } from '@zenstackhq/orm';\nimport { AsyncLocalStorage } from 'node:async_hooks';\nimport { Transient } from 'stratal/di';\nimport type { IEventRegistry } from 'stratal/events';\nimport { withZodI18n, z } from 'stratal/validation';\nimport type { DatabaseConnectionConfig } from './database.module';\nimport { ErrorHandlerPlugin, EventEmitterPlugin } from './plugins';\n\nconst databaseConnectionSchema = z.object({\n name: z.string().min(1, withZodI18n('database.connectionNameRequired')),\n schema: z.object({}).loose(),\n dialect: z.function(),\n plugins: z.array(z.object({}).loose()).optional(),\n computedFields: z.object({}).loose().optional(),\n})\n\nexport const databaseModuleConfigSchema = z.object({\n default: z.string().min(1, withZodI18n('database.defaultConnectionRequired')),\n connections: z.array(databaseConnectionSchema).min(1, withZodI18n('database.connectionRequired')),\n}).refine(\n (config) => {\n const names = config.connections.map(c => c.name)\n return new Set(names).size === names.length\n },\n withZodI18n('database.duplicateConnections')\n).refine(\n (config) => config.connections.some(c => c.name === config.default),\n withZodI18n('database.defaultConnectionNotFound')\n)\n\ntype ZenStackClientInstance = InstanceType<typeof ZenStackClient>\n\n/**\n * Wrap a ZenStack client so `$transaction` is reentrant: when a transaction is\n * already open on this connection (tracked per-connection via\n * {@link AsyncLocalStorage}), nested calls run within the active transaction's\n * client instead of opening a new one. ZenStack only reuses a connection when\n * `$transaction` is called on a transaction client; callers holding the base\n * client (e.g. the better-auth adapter, which since better-auth 1.6.11 nests\n * transactions to atomically consume verification rows) would otherwise open a\n * fresh transaction. On a small pool (e.g. a Hyperdrive-fronted `max: 1` pg\n * pool) that inner transaction blocks forever waiting for the connection the\n * outer one holds — a deadlock surfacing as a backend stuck `idle in\n * transaction`. Reusing the active client is also the correct semantics: nested\n * transactions form a single atomic unit.\n *\n * ZenStackClient's constructor returns a Proxy (for dynamic model accessors), so\n * a subclass method override is shadowed — hence the proxy wrapper here.\n */\nfunction makeReentrantTransaction<T extends object>(\n client: T,\n activeTransaction: AsyncLocalStorage<ZenStackClientInstance>,\n): T {\n return new Proxy(client, {\n get(target, prop, receiver) {\n if (prop !== '$transaction') {\n // Forward the receiver so getters/methods resolve `this` against the\n // proxy (correct for layered proxies / accessor properties).\n return Reflect.get(target, prop, receiver)\n }\n // Read the original `$transaction` off the target WITHOUT the receiver — a\n // receiver of the proxy would re-enter this trap and recurse infinitely.\n const transaction = Reflect.get(target, prop) as (\n input: unknown,\n options?: unknown,\n ) => unknown\n return (input: unknown, options?: unknown) => {\n const active = activeTransaction.getStore()\n if (active) {\n return typeof input === 'function'\n ? (input as (tx: ZenStackClientInstance) => unknown)(active)\n : (active.$transaction as (i: unknown, o?: unknown) => unknown)(input, options)\n }\n if (typeof input !== 'function') {\n return transaction.call(target, input, options)\n }\n return transaction.call(\n target,\n (tx: ZenStackClientInstance) =>\n activeTransaction.run(tx, () => (input as (t: ZenStackClientInstance) => unknown)(tx)),\n options,\n )\n }\n },\n })\n}\n\nexport function createDatabaseService(\n conn: DatabaseConnectionConfig,\n eventRegistry: IEventRegistry,\n): new () => InstanceType<typeof ZenStackClient> {\n const plugins: AnyPlugin[] = [\n new ErrorHandlerPlugin(),\n new EventEmitterPlugin({\n eventRegistry,\n }),\n ...(conn.plugins ?? []),\n ]\n\n // Tracks the in-flight interactive transaction client for this connection so\n // nested `$transaction` calls reuse it instead of acquiring a second\n // connection. ZenStack's own reuse only triggers when `$transaction` is\n // invoked on a transaction client; callers that hold the base client (e.g.\n // the better-auth adapter, which since better-auth 1.6.11 nests transactions\n // to atomically consume verification rows) instead open a fresh transaction.\n // On a small pool (e.g. a Hyperdrive-fronted `max: 1` pg pool) the inner\n // transaction then blocks forever waiting for the connection the outer one\n // holds — a deadlock that surfaces as a Postgres backend stuck `idle in\n // transaction`. Reusing the active client makes nested transactions share the\n // single connection, which is also the correct semantics (one atomic unit).\n const activeTransaction = new AsyncLocalStorage<InstanceType<typeof ZenStackClient>>()\n\n @Transient()\n class DatabaseClient extends ZenStackClient<typeof conn.schema> {\n constructor() {\n const dialect = conn.dialect()\n // ZenStack 3+ requires `computedFields` whenever the schema declares any\n // `@computed` fields, so pass them through when the consumer provides them.\n super(conn.schema, {\n dialect,\n plugins,\n // @ts-expect-error - ZenStack 3+ requires `computedFields` whenever the schema declares any `@computed` fields, so pass them through when the consumer provides them.\n computedFields: conn.computedFields\n })\n // ZenStackClient's constructor returns a Proxy (for dynamic model\n // accessors), so subclass method overrides are shadowed. Wrap it in a\n // proxy that makes `$transaction` reentrant. Returning from the\n // constructor replaces the instance DI receives.\n return makeReentrantTransaction(this as InstanceType<typeof ZenStackClient>, activeTransaction)\n }\n }\n\n return DatabaseClient\n}\n","export const DATABASE_TOKENS = {\n Options: Symbol.for('stratal:database:options'),\n Services: Symbol.for('stratal:database:services'),\n} as const\n\nimport type { ConnectionName } from './types'\n\nexport function connectionSymbol(name: ConnectionName): symbol {\n return Symbol.for(`stratal:database:connection:${name}`)\n}\n","export const databaseMessages = {\n en: {\n connectionNameRequired: 'Connection name is required',\n defaultConnectionRequired: 'Default connection name is required',\n connectionRequired: 'At least one connection is required',\n duplicateConnections: 'Duplicate connection names found',\n defaultConnectionNotFound: 'Default connection not found in connections',\n },\n} as const\n\ndeclare module 'stratal/i18n' {\n interface AppMessageNamespaces {\n database: typeof databaseMessages['en']\n }\n}\n","import type { AnyPlugin, ClientOptions, ComputedFieldsOptions } from '@zenstackhq/orm';\nimport type { SchemaDef } from '@zenstackhq/schema';\nimport { DI_TOKENS, lazy } from 'stratal/di';\nimport type { IEventRegistry } from 'stratal/events';\nimport { I18nModule } from 'stratal/i18n';\nimport {\n Module,\n type AsyncModuleOptions,\n type DynamicModule,\n type LazyModuleLoader,\n type ModuleContext,\n type OnInitialize,\n type OnShutdown,\n} from 'stratal/module';\nimport { DbGenerateCommand } from './commands/db-generate.command';\nimport { DbPullCommand } from './commands/db-pull.command';\nimport { DbPushCommand } from './commands/db-push.command';\nimport { MigrateDeployCommand } from './commands/migrate-deploy.command';\nimport { MigrateDevCommand } from './commands/migrate-dev.command';\nimport { MigrateResetCommand } from './commands/migrate-reset.command';\nimport { MigrateStatusCommand } from './commands/migrate-status.command';\nimport { createDatabaseService } from './database.helpers';\nimport { connectionSymbol, DATABASE_TOKENS } from './database.tokens';\nimport { databaseMessages } from './i18n';\nimport type { ConnectionName, DefaultConnectionName } from './types';\n\nexport interface DatabaseConnectionConfig<\n Schema extends SchemaDef = SchemaDef,\n Name extends ConnectionName = ConnectionName,\n> {\n name: Name\n schema: Schema\n dialect: () => ClientOptions<SchemaDef>['dialect']\n plugins?: AnyPlugin[]\n /**\n * Schema-level @computed field implementations. Required when the schema\n * declares any `@computed` fields. Keyed by uncapitalized model name; values\n * map field name to a Kysely-expression compute callback.\n */\n computedFields?: ComputedFieldsOptions<Schema>\n}\n\nexport interface DatabaseModuleConfig {\n default: DefaultConnectionName\n connections: DatabaseConnectionConfig[]\n}\n\n@Module({\n imports: [\n I18nModule.registerMessages({ en: { database: databaseMessages.en } }),\n ],\n providers: [\n DbGenerateCommand,\n DbPushCommand,\n DbPullCommand,\n MigrateDevCommand,\n MigrateDeployCommand,\n MigrateStatusCommand,\n MigrateResetCommand,\n ],\n})\nexport class DatabaseModule implements OnInitialize, OnShutdown {\n static forRoot(config: DatabaseModuleConfig): DynamicModule {\n return {\n module: DatabaseModule,\n providers: [\n { provide: DATABASE_TOKENS.Options, useValue: config as unknown as object },\n ],\n }\n }\n\n static forRootAsync(options: AsyncModuleOptions<DatabaseModuleConfig>): DynamicModule {\n return {\n module: DatabaseModule,\n providers: [\n {\n provide: DATABASE_TOKENS.Options,\n useFactory: options.useFactory,\n inject: options.inject,\n },\n ],\n }\n }\n\n async onInitialize(context: ModuleContext): Promise<void> {\n const config = context.container.resolve<DatabaseModuleConfig>(DATABASE_TOKENS.Options)\n // EventRegistry is loaded on demand — pull in EventsModule via the loader.\n const loader = context.container.resolve<LazyModuleLoader>(DI_TOKENS.LazyModuleLoader)\n const eventsRef = await loader.load(() => import('stratal/events').then((m) => m.EventsModule))\n const eventRegistry = eventsRef.get<IEventRegistry>(DI_TOKENS.EventRegistry)\n for (const conn of config.connections) {\n const Service = createDatabaseService(conn, eventRegistry);\n\n context.container.register(connectionSymbol(conn.name), lazy(() => Service))\n }\n\n context.container.registerExisting(DI_TOKENS.Database, connectionSymbol(config.default))\n\n context.logger.info('DatabaseModule initialized')\n }\n\n onShutdown(context: ModuleContext): void {\n context.logger.info('DatabaseModule shutdown')\n }\n}\n","import { inject } from 'stratal/di'\nimport type { ConnectionName } from '../types'\nimport { connectionSymbol } from '../database.tokens'\n\nexport function InjectDB(name: ConnectionName): ParameterDecorator {\n return inject(connectionSymbol(name))\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/database/commands/zenstack.command.ts","../../src/database/commands/db-generate.command.ts","../../src/database/commands/db-pull.command.ts","../../src/database/commands/db-push.command.ts","../../src/database/commands/migrate-deploy.command.ts","../../src/database/commands/migrate-dev.command.ts","../../src/database/commands/migrate-reset.command.ts","../../src/database/commands/migrate-status.command.ts","../../src/database/errors/record-not-found.error.ts","../../src/database/errors/unique-constraint.error.ts","../../src/database/errors/from-zenstack-error.ts","../../src/database/plugins/error-handler.plugin.ts","../../src/database/plugins/event-emitter.plugin.ts","../../src/database/plugins/schema-switcher.ts","../../src/database/database.helpers.ts","../../src/database/database.tokens.ts","../../src/database/i18n/en.ts","../../src/database/database.module.ts","../../src/database/decorators/inject-db.decorator.ts"],"sourcesContent":["import { Command } from 'stratal/quarry'\n\n/**\n * Base command for ZenStack CLI wrappers.\n * Uses execFileSync with array arguments to prevent shell injection.\n */\nexport abstract class ZenStackCommand extends Command {\n protected async zenstack(args: string[]): Promise<number> {\n // Dynamic import — node:child_process is only available in the Quarry CLI (Node) context\n const { execFileSync } = await import('node:child_process')\n\n try {\n const output = execFileSync('npx', ['zenstack', ...args], {\n encoding: 'utf-8',\n stdio: 'pipe',\n })\n if (output) this.info(output.trim())\n return 0\n } catch (err) {\n const error = err as { stderr?: string; stdout?: string; status?: number }\n if (error.stderr) this.error(error.stderr.trim())\n if (error.stdout) this.info(error.stdout.trim())\n return error.status ?? 1\n }\n }\n}\n","import { ZenStackCommand } from './zenstack.command'\n\nexport class DbGenerateCommand extends ZenStackCommand {\n static command = 'db:generate {--schema= : Path to schema file} {--watch : Enable watch mode}'\n static description = 'Generate ZenStack ORM client'\n\n async handle(): Promise<number> {\n const args = ['generate']\n const schema = this.string('schema')\n\n if (schema) args.push('--schema', schema)\n if (this.boolean('watch')) args.push('--watch')\n\n return this.zenstack(args)\n }\n}\n","import { ZenStackCommand } from './zenstack.command'\n\nexport class DbPullCommand extends ZenStackCommand {\n static command = 'db:pull {--schema= : Path to schema file}'\n static description = 'Introspect database and generate schema'\n\n async handle(): Promise<number> {\n const args = ['db', 'pull']\n const schema = this.string('schema')\n\n if (schema) args.push('--schema', schema)\n\n return this.zenstack(args)\n }\n}\n","import { ZenStackCommand } from './zenstack.command'\n\nexport class DbPushCommand extends ZenStackCommand {\n static command = 'db:push {--schema= : Path to schema file} {--accept-data-loss : Accept data loss} {--force-reset : Force reset database}'\n static description = 'Push database schema changes'\n\n async handle(): Promise<number> {\n const args = ['db', 'push']\n const schema = this.string('schema')\n\n if (schema) args.push('--schema', schema)\n if (this.boolean('accept-data-loss')) args.push('--accept-data-loss')\n if (this.boolean('force-reset')) args.push('--force-reset')\n\n return this.zenstack(args)\n }\n}\n","import { ZenStackCommand } from './zenstack.command'\n\nexport class MigrateDeployCommand extends ZenStackCommand {\n static command = 'migrate:deploy {--schema= : Path to schema file}'\n static description = 'Deploy pending migrations'\n\n async handle(): Promise<number> {\n const args = ['migrate', 'deploy']\n const schema = this.string('schema')\n\n if (schema) args.push('--schema', schema)\n\n return this.zenstack(args)\n }\n}\n","import { ZenStackCommand } from './zenstack.command'\n\nexport class MigrateDevCommand extends ZenStackCommand {\n static command = 'migrate:dev {--schema= : Path to schema file} {--name= : Migration name} {--create-only : Create without applying}'\n static description = 'Create and apply migration'\n\n async handle(): Promise<number> {\n const args = ['migrate', 'dev']\n const schema = this.string('schema')\n const name = this.string('name')\n\n if (schema) args.push('--schema', schema)\n if (name) args.push('--name', name)\n if (this.boolean('create-only')) args.push('--create-only')\n\n return this.zenstack(args)\n }\n}\n","import { ZenStackCommand } from './zenstack.command'\n\nexport class MigrateResetCommand extends ZenStackCommand {\n static command = 'migrate:reset {--schema= : Path to schema file} {--force : Skip confirmation} {--skip-seed : Skip seeding}'\n static description = 'Reset database'\n\n async handle(): Promise<number> {\n const args = ['migrate', 'reset']\n const schema = this.string('schema')\n\n if (schema) args.push('--schema', schema)\n if (this.boolean('force')) args.push('--force')\n if (this.boolean('skip-seed')) args.push('--skip-seed')\n\n return this.zenstack(args)\n }\n}\n","import { ZenStackCommand } from './zenstack.command'\n\nexport class MigrateStatusCommand extends ZenStackCommand {\n static command = 'migrate:status {--schema= : Path to schema file}'\n static description = 'Check migration status'\n\n async handle(): Promise<number> {\n const args = ['migrate', 'status']\n const schema = this.string('schema')\n\n if (schema) args.push('--schema', schema)\n\n return this.zenstack(args)\n }\n}\n","import { HttpException } from 'stratal/errors'\n\nexport class RecordNotFoundError extends HttpException {\n constructor(public readonly details?: string, cause?: unknown) {\n super(404, 'Record not found', cause)\n }\n}\n","import { HttpException } from 'stratal/errors'\n\nexport class UniqueConstraintError extends HttpException {\n constructor(public readonly fields?: string[], cause?: unknown) {\n super(409, 'Record already exists', cause)\n }\n}\n","import { ORMError, ORMErrorReason } from '@zenstackhq/orm';\nimport { type ApplicationError, DatabaseError } from 'stratal/errors';\nimport { RecordNotFoundError } from './record-not-found.error';\nimport { UniqueConstraintError } from './unique-constraint.error';\n\nexport function fromZenStackError(error: unknown): ApplicationError {\n if (error instanceof ORMError) {\n switch (error.reason) {\n case ORMErrorReason.NOT_FOUND:\n return new RecordNotFoundError(error.model, error)\n case ORMErrorReason.DB_QUERY_ERROR:\n return parseDatabaseError(error)\n case ORMErrorReason.INVALID_INPUT:\n return new DatabaseError('Invalid database query', error)\n case ORMErrorReason.CONFIG_ERROR:\n return new DatabaseError('Database configuration error', error)\n case ORMErrorReason.NOT_SUPPORTED:\n return new DatabaseError('Operation not supported', error)\n case ORMErrorReason.INTERNAL_ERROR:\n return new DatabaseError('Database internal error', error)\n default:\n return new DatabaseError('Database error', error)\n }\n }\n return new DatabaseError('Database error', error)\n}\n\nfunction parseDatabaseError(error: ORMError): ApplicationError {\n const dbErrorCode = error.dbErrorCode as string | undefined\n if (dbErrorCode) {\n if (dbErrorCode === '23505') return new UniqueConstraintError([error.model ?? 'unknown'], error)\n if (dbErrorCode === '23503') return new DatabaseError('Foreign key constraint violation', error)\n if (dbErrorCode === '23502') return new DatabaseError('Required field is missing', error)\n if (dbErrorCode === '23514') return new DatabaseError('Database constraint violated', error)\n if (dbErrorCode === '42P01') return new DatabaseError('Table does not exist', error)\n if (dbErrorCode === '42703') return new DatabaseError('Column does not exist', error)\n if (dbErrorCode.startsWith('42')) return new DatabaseError('Database syntax or access error', error)\n if (dbErrorCode.startsWith('08')) return new DatabaseError('Database connection failed', error)\n if (dbErrorCode === '57014') return new DatabaseError('Database query timeout', error)\n if (dbErrorCode.startsWith('40')) return new DatabaseError('Transaction conflict or deadlock', error)\n if (dbErrorCode === '53300') return new DatabaseError('Too many database connections', error)\n }\n return new DatabaseError('Database error', error)\n}\n","import { type RuntimePlugin } from '@zenstackhq/orm'\nimport { type SchemaDef } from '@zenstackhq/orm/schema'\nimport { fromZenStackError } from '../errors'\n\n/**\n * ZenStack runtime plugin that transforms ORM errors into ApplicationError instances.\n *\n * @example\n * ```typescript\n * super(schema, {\n * dialect: new PostgresDialect({ pool }),\n * plugins: [new ErrorHandlerPlugin()]\n * })\n * ```\n */\nexport class ErrorHandlerPlugin implements RuntimePlugin<SchemaDef, Record<string, unknown>, Record<string, unknown>, {}> {\n readonly id = 'error-handler'\n\n onQuery = async ({ args, proceed }: {\n args: Record<string, unknown> | undefined\n proceed: (args: Record<string, unknown> | undefined) => Promise<unknown>\n }): Promise<unknown> => {\n try {\n return await proceed(args)\n } catch (error) {\n throw fromZenStackError(error)\n }\n }\n}\n","import { type EntityMutationHooksDef, type RuntimePlugin } from '@zenstackhq/orm';\nimport { type SchemaDef } from '@zenstackhq/orm/schema';\nimport type { EventContext, EventName, IEventRegistry } from 'stratal/events';\nimport type { ModelName } from '../event-types';\n\nexport interface EventEmitterPluginOptions {\n eventRegistry: IEventRegistry\n}\n\ntype EntityMutationAction = 'create' | 'update' | 'delete'\n\nconst ENTITY_ACTION_VERB = {\n create: 'created',\n update: 'updated',\n delete: 'deleted',\n} as const satisfies Record<EntityMutationAction, string>\n\ntype Entity = Record<string, unknown>\n\n/**\n * Pair before/after entity snapshots for a mutation. Rows are matched by\n * `id` when both sides carry one, falling back to positional pairing.\n */\nfunction pairEntities(\n before: Entity[] | undefined,\n after: Entity[] | undefined\n): { before: Entity | undefined; after: Entity | undefined }[] {\n const primary = after ?? before ?? []\n const counterpart = after ? before : undefined\n const counterpartById = counterpart\n ? new Map(counterpart.filter((c) => c.id !== undefined).map((c) => [c.id, c]))\n : undefined\n\n return primary.map((entity, index) => {\n const match = counterpart\n ? (entity.id !== undefined ? counterpartById?.get(entity.id) : undefined) ?? counterpart[index]\n : undefined\n\n return after\n ? { before: match, after: entity }\n : { before: entity, after: undefined }\n })\n}\n\n/**\n * ZenStack runtime plugin that emits before/after events for database operations.\n *\n * Emits events in the format:\n * - `before.{Model}.{operation}` - Before the database operation\n * - `after.{Model}.{operation}` - After the database operation\n *\n * Additionally emits entity-mutation events carrying full entity snapshots:\n * - `entity.{Model}.created` - `{ after }`\n * - `entity.{Model}.updated` - `{ before, after }`\n * - `entity.{Model}.deleted` - `{ before }`\n *\n * Entity events are listener-driven: the pre-mutation snapshot is only\n * loaded (inside the mutation's transaction) when `hasListeners()` reports\n * a matching subscription, so models nobody observes pay no cost. Note that\n * a wildcard subscription (`entity`) therefore makes every model pay the\n * pre-read — subscribe per model when cost matters.\n *\n * @example\n * ```typescript\n * super(schema, {\n * dialect: new PostgresDialect({ pool }),\n * plugins: [\n * new EventEmitterPlugin({\n * eventRegistry,\n * })\n * ]\n * })\n * ```\n */\nexport class EventEmitterPlugin implements RuntimePlugin<SchemaDef, Record<string, unknown>, Record<string, unknown>, {}> {\n readonly id = 'event-emitter'\n\n constructor(private options: EventEmitterPluginOptions) { }\n\n onEntityMutation: EntityMutationHooksDef<SchemaDef> = {\n // Run after-hooks inside the mutation's transaction boundary so they\n // execute within the caller's async context (AsyncLocalStorage intact):\n // listeners resolve from the live request scope and tenant schema\n // switching still applies. Post-commit hooks would run detached from the\n // request's ALS. Listeners registered `blocking: false` still do their\n // real work outside the transaction via waitUntil.\n runAfterMutationWithinTransaction: true,\n\n beforeEntityMutation: async (args) => {\n // Created rows have no prior state to snapshot\n if (args.action === 'create') return\n\n const event = `entity.${args.model}.${ENTITY_ACTION_VERB[args.action]}` as EventName\n if (!this.options.eventRegistry.hasListeners(event)) return\n\n // Runs inside the mutation's transaction; ZenStack hands the result\n // to afterEntityMutation as `beforeMutationEntities`\n await args.loadBeforeMutationEntities()\n },\n\n afterEntityMutation: async (args) => {\n const { model, action, beforeMutationEntities } = args\n const verb = ENTITY_ACTION_VERB[action]\n const event = `entity.${model}.${verb}` as EventName\n const { eventRegistry } = this.options\n\n if (!eventRegistry.hasListeners(event)) return\n\n const after = action === 'delete' ? undefined : await args.loadAfterMutationEntities()\n\n for (const pair of pairEntities(beforeMutationEntities, after)) {\n // Producer boundary: ZenStack types `model` as plain string, but at\n // runtime it is always a schema model name — assert that one fact.\n const context: EventContext<'entity'> = {\n model: model as ModelName,\n action: verb,\n before: pair.before,\n after: pair.after,\n }\n await eventRegistry.emit(event, context)\n }\n },\n }\n\n onQuery = async ({ model, operation, args, proceed }: {\n model: string\n operation: string\n args: Record<string, unknown> | undefined\n proceed: (args: Record<string, unknown> | undefined) => Promise<unknown>\n }): Promise<unknown> => {\n const { eventRegistry } = this.options\n const eventBase = `${model}.${operation}`\n\n // Emit BEFORE event\n await eventRegistry.emit(`before.${eventBase}` as EventName, {\n data: args,\n })\n\n // Execute the actual database operation\n const result = await proceed(args)\n\n // Emit AFTER event\n await eventRegistry.emit(`after.${eventBase}` as EventName, {\n data: args,\n result,\n })\n\n return result\n }\n}\n","interface SwitchableClient {\n $schema: { provider: { defaultSchema: string } } & Record<string, unknown>\n schema: unknown\n}\n\n/**\n * Switches the active schema on a ZenStack/Kysely database client by mutating\n * `$schema.provider.defaultSchema`. This causes ZenStack's QueryNameMapper to\n * generate fully-qualified table references (e.g. `\"tenant_123\".\"User\"`).\n *\n * Must be called BEFORE any queries are made on the client.\n *\n * Note: The ZenStack RuntimePlugin `onQuery` hook fires after table names are\n * already resolved, so a plugin-based approach cannot set the schema prefix.\n * Direct client mutation is the only supported method.\n */\nexport class SchemaSwitcher {\n static apply<T>(client: T, schemaName: string): T {\n const c = client as unknown as SwitchableClient\n const switched = {\n ...c.$schema,\n provider: { ...c.$schema.provider, defaultSchema: schemaName },\n }\n c.$schema = switched\n c.schema = switched\n return client\n }\n}\n","import { ZenStackClient, type AnyPlugin } from '@zenstackhq/orm';\nimport { AsyncLocalStorage } from 'node:async_hooks';\nimport { Transient } from 'stratal/di';\nimport type { IEventRegistry } from 'stratal/events';\nimport { withZodI18n, z } from 'stratal/validation';\nimport type { DatabaseConnectionConfig } from './database.module';\nimport { ErrorHandlerPlugin, EventEmitterPlugin } from './plugins';\n\nconst databaseConnectionSchema = z.object({\n name: z.string().min(1, withZodI18n('database.connectionNameRequired')),\n schema: z.object({}).loose(),\n dialect: z.function(),\n plugins: z.array(z.object({}).loose()).optional(),\n computedFields: z.object({}).loose().optional(),\n})\n\nexport const databaseModuleConfigSchema = z.object({\n default: z.string().min(1, withZodI18n('database.defaultConnectionRequired')),\n connections: z.array(databaseConnectionSchema).min(1, withZodI18n('database.connectionRequired')),\n}).refine(\n (config) => {\n const names = config.connections.map(c => c.name)\n return new Set(names).size === names.length\n },\n withZodI18n('database.duplicateConnections')\n).refine(\n (config) => config.connections.some(c => c.name === config.default),\n withZodI18n('database.defaultConnectionNotFound')\n)\n\ntype ZenStackClientInstance = InstanceType<typeof ZenStackClient>\n\n/**\n * Wrap a ZenStack client so `$transaction` is reentrant: when a transaction is\n * already open on this connection (tracked per-connection via\n * {@link AsyncLocalStorage}), nested calls run within the active transaction's\n * client instead of opening a new one. ZenStack only reuses a connection when\n * `$transaction` is called on a transaction client; callers holding the base\n * client (e.g. the better-auth adapter, which since better-auth 1.6.11 nests\n * transactions to atomically consume verification rows) would otherwise open a\n * fresh transaction. On a small pool (e.g. a Hyperdrive-fronted `max: 1` pg\n * pool) that inner transaction blocks forever waiting for the connection the\n * outer one holds — a deadlock surfacing as a backend stuck `idle in\n * transaction`. Reusing the active client is also the correct semantics: nested\n * transactions form a single atomic unit.\n *\n * ZenStackClient's constructor returns a Proxy (for dynamic model accessors), so\n * a subclass method override is shadowed — hence the proxy wrapper here.\n */\nexport function makeReentrantTransaction<T extends object>(\n client: T,\n activeTransaction: AsyncLocalStorage<ZenStackClientInstance>,\n): T {\n return new Proxy(client, {\n get(target, prop, receiver) {\n // DI disposal contract (stratal `Disposable`): release the underlying\n // pool/socket when the owning container shuts down (e.g. a Vite HMR\n // reload replacing the Application). Handled here because ZenStack's\n // own constructor proxy shadows subclass method definitions.\n if (prop === Symbol.asyncDispose) {\n return () => (target as ZenStackClientInstance).$disconnect()\n }\n if (prop !== '$transaction') {\n // Forward the receiver so getters/methods resolve `this` against the\n // proxy (correct for layered proxies / accessor properties).\n return Reflect.get(target, prop, receiver)\n }\n // Read the original `$transaction` off the target WITHOUT the receiver — a\n // receiver of the proxy would re-enter this trap and recurse infinitely.\n const transaction = Reflect.get(target, prop) as (\n input: unknown,\n options?: unknown,\n ) => unknown\n return (input: unknown, options?: unknown) => {\n const active = activeTransaction.getStore()\n if (active) {\n return typeof input === 'function'\n ? (input as (tx: ZenStackClientInstance) => unknown)(active)\n : (active.$transaction as (i: unknown, o?: unknown) => unknown)(input, options)\n }\n if (typeof input !== 'function') {\n return transaction.call(target, input, options)\n }\n return transaction.call(\n target,\n (tx: ZenStackClientInstance) =>\n activeTransaction.run(tx, () => (input as (t: ZenStackClientInstance) => unknown)(tx)),\n options,\n )\n }\n },\n })\n}\n\nexport interface DatabaseServiceClass {\n new (): InstanceType<typeof ZenStackClient>\n /**\n * Disconnects every still-live client created from this service class.\n * Called by `DatabaseModule.onShutdown` so pools/sockets are released when\n * the Application is torn down (e.g. a Vite HMR reload).\n */\n disposeInstances(): Promise<void>\n}\n\nexport function createDatabaseService(\n conn: DatabaseConnectionConfig,\n eventRegistry: IEventRegistry,\n): DatabaseServiceClass {\n const plugins: AnyPlugin[] = [\n new ErrorHandlerPlugin(),\n new EventEmitterPlugin({\n eventRegistry,\n }),\n ...(conn.plugins ?? []),\n ]\n\n // Tracks the in-flight interactive transaction client for this connection so\n // nested `$transaction` calls reuse it instead of acquiring a second\n // connection. ZenStack's own reuse only triggers when `$transaction` is\n // invoked on a transaction client; callers that hold the base client (e.g.\n // the better-auth adapter, which since better-auth 1.6.11 nests transactions\n // to atomically consume verification rows) instead open a fresh transaction.\n // On a small pool (e.g. a Hyperdrive-fronted `max: 1` pg pool) the inner\n // transaction then blocks forever waiting for the connection the outer one\n // holds — a deadlock that surfaces as a Postgres backend stuck `idle in\n // transaction`. Reusing the active client makes nested transactions share the\n // single connection, which is also the correct semantics (one atomic unit).\n const activeTransaction = new AsyncLocalStorage<InstanceType<typeof ZenStackClient>>()\n\n // Live clients created from this service class, tracked weakly: the client\n // is `@Transient`, so request-scoped resolutions must stay GC-able with\n // their request. Dead refs are pruned on each add; live ones are\n // disconnected by `disposeInstances()` on module shutdown.\n const instances = new Set<WeakRef<ZenStackClientInstance>>()\n\n @Transient()\n class DatabaseClient extends ZenStackClient<typeof conn.schema> {\n constructor() {\n const dialect = conn.dialect()\n // ZenStack 3+ requires `computedFields` whenever the schema declares any\n // `@computed` fields, so pass them through when the consumer provides them.\n super(conn.schema, {\n dialect,\n plugins,\n // @ts-expect-error - ZenStack 3+ requires `computedFields` whenever the schema declares any `@computed` fields, so pass them through when the consumer provides them.\n computedFields: conn.computedFields\n })\n // ZenStackClient's constructor returns a Proxy (for dynamic model\n // accessors), so subclass method overrides are shadowed. Wrap it in a\n // proxy that makes `$transaction` reentrant. Returning from the\n // constructor replaces the instance DI receives.\n const client = makeReentrantTransaction(this as InstanceType<typeof ZenStackClient>, activeTransaction)\n for (const ref of instances) {\n if (ref.deref() === undefined) instances.delete(ref)\n }\n instances.add(new WeakRef(client))\n return client\n }\n\n static async disposeInstances(): Promise<void> {\n const live = [...instances]\n instances.clear()\n await Promise.all(live.map(async (ref) => {\n const client = ref.deref()\n if (!client) return\n try {\n await client.$disconnect()\n } catch (error) {\n console.error(`[stratal] Failed to disconnect database client \"${conn.name}\":`, error)\n }\n }))\n }\n }\n\n return DatabaseClient\n}\n","export const DATABASE_TOKENS = {\n Options: Symbol.for('stratal:database:options'),\n Services: Symbol.for('stratal:database:services'),\n} as const\n\nimport type { ConnectionName } from './types'\n\nexport function connectionSymbol(name: ConnectionName): symbol {\n return Symbol.for(`stratal:database:connection:${name}`)\n}\n","export const databaseMessages = {\n en: {\n connectionNameRequired: 'Connection name is required',\n defaultConnectionRequired: 'Default connection name is required',\n connectionRequired: 'At least one connection is required',\n duplicateConnections: 'Duplicate connection names found',\n defaultConnectionNotFound: 'Default connection not found in connections',\n },\n} as const\n\ndeclare module 'stratal/i18n' {\n interface AppMessageNamespaces {\n database: typeof databaseMessages['en']\n }\n}\n","import type { AnyPlugin, ClientOptions, ComputedFieldsOptions } from '@zenstackhq/orm';\nimport type { SchemaDef } from '@zenstackhq/schema';\nimport { DI_TOKENS, lazy } from 'stratal/di';\nimport type { IEventRegistry } from 'stratal/events';\nimport { I18nModule } from 'stratal/i18n';\nimport {\n Module,\n type AsyncModuleOptions,\n type DynamicModule,\n type LazyModuleLoader,\n type ModuleContext,\n type OnInitialize,\n type OnShutdown,\n} from 'stratal/module';\nimport { DbGenerateCommand } from './commands/db-generate.command';\nimport { DbPullCommand } from './commands/db-pull.command';\nimport { DbPushCommand } from './commands/db-push.command';\nimport { MigrateDeployCommand } from './commands/migrate-deploy.command';\nimport { MigrateDevCommand } from './commands/migrate-dev.command';\nimport { MigrateResetCommand } from './commands/migrate-reset.command';\nimport { MigrateStatusCommand } from './commands/migrate-status.command';\nimport { createDatabaseService, type DatabaseServiceClass } from './database.helpers';\nimport { connectionSymbol, DATABASE_TOKENS } from './database.tokens';\nimport { databaseMessages } from './i18n';\nimport type { ConnectionName, DefaultConnectionName } from './types';\n\nexport interface DatabaseConnectionConfig<\n Schema extends SchemaDef = SchemaDef,\n Name extends ConnectionName = ConnectionName,\n> {\n name: Name\n schema: Schema\n dialect: () => ClientOptions<SchemaDef>['dialect']\n plugins?: AnyPlugin[]\n /**\n * Schema-level @computed field implementations. Required when the schema\n * declares any `@computed` fields. Keyed by uncapitalized model name; values\n * map field name to a Kysely-expression compute callback.\n */\n computedFields?: ComputedFieldsOptions<Schema>\n}\n\nexport interface DatabaseModuleConfig {\n default: DefaultConnectionName\n connections: DatabaseConnectionConfig[]\n}\n\n@Module({\n imports: [\n I18nModule.registerMessages({ en: { database: databaseMessages.en } }),\n ],\n providers: [\n DbGenerateCommand,\n DbPushCommand,\n DbPullCommand,\n MigrateDevCommand,\n MigrateDeployCommand,\n MigrateStatusCommand,\n MigrateResetCommand,\n ],\n})\nexport class DatabaseModule implements OnInitialize, OnShutdown {\n private readonly services: DatabaseServiceClass[] = []\n\n static forRoot(config: DatabaseModuleConfig): DynamicModule {\n return {\n module: DatabaseModule,\n providers: [\n { provide: DATABASE_TOKENS.Options, useValue: config as unknown as object },\n ],\n }\n }\n\n static forRootAsync(options: AsyncModuleOptions<DatabaseModuleConfig>): DynamicModule {\n return {\n module: DatabaseModule,\n providers: [\n {\n provide: DATABASE_TOKENS.Options,\n useFactory: options.useFactory,\n inject: options.inject,\n },\n ],\n }\n }\n\n async onInitialize(context: ModuleContext): Promise<void> {\n const config = context.container.resolve<DatabaseModuleConfig>(DATABASE_TOKENS.Options)\n // EventRegistry is loaded on demand — pull in EventsModule via the loader.\n const loader = context.container.resolve<LazyModuleLoader>(DI_TOKENS.LazyModuleLoader)\n const eventsRef = await loader.load(() => import('stratal/events').then((m) => m.EventsModule))\n const eventRegistry = eventsRef.get<IEventRegistry>(DI_TOKENS.EventRegistry)\n for (const conn of config.connections) {\n const Service = createDatabaseService(conn, eventRegistry);\n\n this.services.push(Service)\n context.container.register(connectionSymbol(conn.name), lazy(() => Service))\n }\n\n context.container.registerExisting(DI_TOKENS.Database, connectionSymbol(config.default))\n\n context.logger.info('DatabaseModule initialized')\n }\n\n async onShutdown(context: ModuleContext): Promise<void> {\n // Disconnect every live client so pools/sockets don't outlive the\n // Application across dev-server hot reloads.\n await Promise.all(this.services.map(service => service.disposeInstances()))\n this.services.length = 0\n context.logger.info('DatabaseModule shutdown')\n }\n}\n","import { inject } from 'stratal/di'\nimport type { ConnectionName } from '../types'\nimport { connectionSymbol } from '../database.tokens'\n\nexport function InjectDB(name: ConnectionName): ParameterDecorator {\n return inject(connectionSymbol(name))\n}\n"],"mappings":"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"}
|
package/dist/factory/index.d.mts
CHANGED
|
@@ -25,10 +25,11 @@ interface DatabaseModuleConfig {
|
|
|
25
25
|
connections: DatabaseConnectionConfig[];
|
|
26
26
|
}
|
|
27
27
|
declare class DatabaseModule implements OnInitialize, OnShutdown {
|
|
28
|
+
private readonly services;
|
|
28
29
|
static forRoot(config: DatabaseModuleConfig): DynamicModule;
|
|
29
30
|
static forRootAsync(options: AsyncModuleOptions<DatabaseModuleConfig>): DynamicModule;
|
|
30
31
|
onInitialize(context: ModuleContext): Promise<void>;
|
|
31
|
-
onShutdown(context: ModuleContext): void
|
|
32
|
+
onShutdown(context: ModuleContext): Promise<void>;
|
|
32
33
|
}
|
|
33
34
|
//#endregion
|
|
34
35
|
//#region src/database/database.service.d.ts
|
|
@@ -442,4 +443,4 @@ declare class MigrateStatusCommand extends ZenStackCommand {
|
|
|
442
443
|
}
|
|
443
444
|
//#endregion
|
|
444
445
|
export { DATABASE_TOKENS as A, GetResult as C, UniqueConstraintError as D, fromZenStackError as E, DatabaseModuleConfig as F, DatabaseService as M, DatabaseConnectionConfig as N, RecordNotFoundError as O, DatabaseModule as P, GetEntity as S, ParseEvent as T, EntityEventName as _, DbPushCommand as a, EventPhase as b, ZenStackCommand as c, EventEmitterPluginOptions as d, ErrorHandlerPlugin as f, DatabaseOperation as g, DatabaseEvents as h, MigrateDeployCommand as i, connectionSymbol as j, InjectDB as k, SchemaSwitcher as l, DatabaseEventName as m, MigrateResetCommand as n, DbPullCommand as o, databaseMessages as p, MigrateDevCommand as r, DbGenerateCommand as s, MigrateStatusCommand as t, EventEmitterPlugin as u, EntityEvents as v, ModelName as w, GetData as x, EntityMutationVerb as y };
|
|
445
|
-
//# sourceMappingURL=index-
|
|
446
|
+
//# sourceMappingURL=index-Dt0YUA7r.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-Dt0YUA7r.d.mts","names":[],"sources":["../src/database/database.module.ts","../src/database/database.service.ts","../src/database/database.tokens.ts","../src/database/decorators/inject-db.decorator.ts","../src/database/errors/record-not-found.error.ts","../src/database/errors/unique-constraint.error.ts","../src/database/errors/from-zenstack-error.ts","../src/database/event-types.ts","../src/database/i18n/en.ts","../src/database/plugins/error-handler.plugin.ts","../src/database/plugins/event-emitter.plugin.ts","../src/database/plugins/schema-switcher.ts","../src/database/commands/zenstack.command.ts","../src/database/commands/db-generate.command.ts","../src/database/commands/db-pull.command.ts","../src/database/commands/db-push.command.ts","../src/database/commands/migrate-deploy.command.ts","../src/database/commands/migrate-dev.command.ts","../src/database/commands/migrate-reset.command.ts","../src/database/commands/migrate-status.command.ts"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stratal/framework",
|
|
3
|
-
"version": "0.0.0-canary-
|
|
3
|
+
"version": "0.0.0-canary-ab95f52",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Temitayo Fadojutimi",
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
"@zenstackhq/schema": ">=3.6",
|
|
78
78
|
"better-auth": ">=1.6",
|
|
79
79
|
"pg": "^8.0.0",
|
|
80
|
-
"stratal": "0.0.0-canary-
|
|
80
|
+
"stratal": "0.0.0-canary-ab95f52"
|
|
81
81
|
},
|
|
82
82
|
"devDependencies": {
|
|
83
83
|
"@better-auth/core": "^1.6.14",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index-DTXzJzpy.d.mts","names":[],"sources":["../src/database/database.module.ts","../src/database/database.service.ts","../src/database/database.tokens.ts","../src/database/decorators/inject-db.decorator.ts","../src/database/errors/record-not-found.error.ts","../src/database/errors/unique-constraint.error.ts","../src/database/errors/from-zenstack-error.ts","../src/database/event-types.ts","../src/database/i18n/en.ts","../src/database/plugins/error-handler.plugin.ts","../src/database/plugins/event-emitter.plugin.ts","../src/database/plugins/schema-switcher.ts","../src/database/commands/zenstack.command.ts","../src/database/commands/db-generate.command.ts","../src/database/commands/db-pull.command.ts","../src/database/commands/db-push.command.ts","../src/database/commands/migrate-deploy.command.ts","../src/database/commands/migrate-dev.command.ts","../src/database/commands/migrate-reset.command.ts","../src/database/commands/migrate-status.command.ts"],"mappings":";;;;;;;;;;UA0BiB,wBAAA,gBACA,SAAA,GAAY,SAAA,eACd,cAAA,GAAiB,cAAA;EAE9B,IAAA,EAAM,IAAA;EACN,MAAA,EAAQ,MAAA;EACR,OAAA,QAAe,aAAA,CAAc,SAAA;EAC7B,OAAA,GAAU,SAAA;;AAPZ;;;;EAaE,cAAA,GAAiB,qBAAA,CAAsB,MAAA;AAAA;AAAA,UAGxB,oBAAA;EACf,OAAA,EAAS,qBAAA;EACT,WAAA,EAAa,wBAAwB;AAAA;AAAA,cAiB1B,cAAA,YAA0B,YAAA,EAAc,UAAA;EAAA,OAC5C,OAAA,CAAQ,MAAA,EAAQ,oBAAA,GAAuB,aAAA;EAAA,OASvC,YAAA,CAAa,OAAA,EAAS,kBAAA,CAAmB,oBAAA,IAAwB,aAAA;EAalE,YAAA,CAAa,OAAA,EAAS,aAAA,GAAgB,OAAA;EAiB5C,UAAA,CAAW,OAAA,EAAS,aAAA;AAAA;;;;;;;;;;;AA3EtB;;;;;;;KCRY,eAAA,WACA,cAAA,GAAiB,qBAAA,IACzB,cAAA,CACF,qBAAA,CAAsB,CAAA,GACtB,aAAA,CAAc,qBAAA,CAAsB,CAAA,IACpC,yBAAA,CAA0B,CAAA,mBAC1B,yBAAA,CAA0B,CAAA,uBAE1B,yBAAA,CAA0B,CAAA;;;cC1Bf,eAAA;EAAA,SAGH,OAAA;EAAA,SAAA,QAAA;AAAA;AAAA,iBAIM,gBAAA,CAAiB,IAAoB,EAAd,cAAc;;;iBCHrC,QAAA,CAAS,IAAA,EAAM,cAAA,GAAiB,kBAAkB;;;cCFrD,mBAAA,SAA4B,aAAa;EAAA,SACxB,OAAA;cAAA,OAAA,uBAAkB,KAAA;AAAA;;;cCDnC,qBAAA,SAA8B,aAAa;EAAA,SAC1B,MAAA;cAAA,MAAA,yBAAmB,KAAA;AAAA;;;iBCEjC,iBAAA,CAAkB,KAAA,YAAiB,gBAAgB;;;;;;KCkCvD,UAAA;;;;KAKA,iBAAA,GAAoB,iBAAiB;;;;;;KAO5C,kBAAA,MAAwB,CAAA;EAAY,MAAA;AAAA,IAAoB,OAAA,OAAc,CAAA;;;;;KAM/D,SAAA,GAAY,kBAAkB,CAAC,cAAA;;;;KAS/B,iBAAA,MACL,UAAA,IAAc,SAAA,IAAa,iBAAA,QAC3B,UAAA,IAAc,SAAA,QACd,UAAA,IAAc,iBAAA,KACjB,UAAA;;;;KASC,gBAAA,WACO,SAAA,YACA,OAAA,OAAc,CAAA,+BACd,iBAAA,IAEV,CAAA,oBAAqB,UAAA,CAAW,CAAA,EAAG,CAAA,IACnC,CAAA,wBAAyB,cAAA,CAAe,CAAA,EAAG,CAAA,IAC3C,CAAA,oBAAqB,UAAA,CAAW,CAAA,EAAG,CAAA,IACnC,CAAA,wBAAyB,cAAA,CAAe,CAAA,EAAG,CAAA,IAC3C,CAAA,oBAAqB,UAAA,CAAW,CAAA,EAAG,CAAA,IACnC,CAAA,wBAAyB,cAAA,CAAe,CAAA,EAAG,CAAA,IAC3C,CAAA,wBAAyB,cAAA,CAAe,CAAA,EAAG,CAAA,IAC3C,CAAA,uBAAwB,aAAA,CAAc,CAAA,EAAG,CAAA,IACzC,CAAA,sBAAuB,YAAA,CAAa,CAAA,EAAG,CAAA,IACvC,CAAA,oBAAqB,UAAA,CAAW,CAAA,EAAG,CAAA,IACnC,CAAA,mBAAoB,SAAA,CAAU,CAAA,EAAG,CAAA,IACjC,CAAA,uBAAwB,aAAA,CAAc,CAAA,EAAG,CAAA,IACzC,CAAA,qBAAsB,WAAA,CAAY,CAAA,EAAG,CAAA;;;APzDQ;KO+D1C,YAAA,gCAA4C,iBAAA,IAC/C,CAAA,SAAU,SAAA,GACR,CAAA,SAAU,OAAA,OAAc,CAAA,sBACxB,gBAAA,CAAiB,CAAA,EAAG,CAAA,EAAG,CAAA;EAAa,IAAA;AAAA,IACpC,CAAA,GACA,gBAAA,CAAiB,CAAA,EAAG,CAAA,EAAG,CAAA;EAAa,KAAA;AAAA,IACpC,CAAA,GACA,gBAAA,CAAiB,CAAA,EAAG,CAAA,EAAG,CAAA;;;;;KAQf,OAAA,WAAkB,SAAA,YAAqB,iBAAA,IACjD,YAAA,CAAa,cAAA,EAAgB,CAAA,EAAG,CAAA,4BAA6B,YAAA,CAAa,cAAA,EAAgB,CAAA,EAAG,CAAA;APvE/F;;;AAAA,KO4EK,cAAA,gCAA8C,iBAAA,IACjD,CAAA,SAAU,SAAA,GACR,CAAA,SAAU,OAAA,OAAc,CAAA,sBACxB,CAAA,mEACA,WAAA,CAAY,CAAA,EAAG,CAAA,MACf,CAAA,4BAEA,WAAA,CAAY,CAAA,EAAG,CAAA;;;;;KAQP,SAAA,WAAoB,SAAA,YAAqB,iBAAA,IACnD,cAAA,CAAe,cAAA,EAAgB,CAAA,EAAG,CAAA,4BAA6B,cAAA,CAAe,cAAA,EAAgB,CAAA,EAAG,CAAA;;;;KASvF,kBAAA;;;;;;;;;;;KAYA,eAAA,aACE,SAAA,IAAa,kBAAA,eACb,SAAA,eACA,kBAAA;;;;KAMT,cAAA,wBACH,CAAA,SAAU,SAAA,GACR,CAAA,SAAU,OAAA,OAAc,CAAA,sBACxB,WAAA,CAAY,CAAA,EAAG,CAAA;;;;KAOP,SAAA,WAAoB,SAAA,IAC9B,cAAA,CAAe,cAAA,EAAgB,CAAA,4BAA6B,cAAA,CAAe,cAAA,EAAgB,CAAA;AAAA,UAEnF,yBAAA,WAAoC,SAAA;EAC5C,KAAA,EAAO,CAAA;EACP,MAAA;EACA,MAAA;EACA,KAAA,EAAO,SAAA,CAAU,CAAA;AAAA;AAAA,UAGT,yBAAA,WAAoC,SAAA;EAC5C,KAAA,EAAO,CAAA;EACP,MAAA;EACA,MAAA,EAAQ,SAAA,CAAU,CAAA;EAClB,KAAA,EAAO,SAAA,CAAU,CAAA;AAAA;AAAA,UAGT,yBAAA,WAAoC,SAAA;EAC5C,KAAA,EAAO,CAAA;EACP,MAAA;EACA,MAAA,EAAQ,SAAA,CAAU,CAAA;EAClB,KAAA;AAAA;;UAIQ,0BAAA,WAAqC,SAAA;EAC7C,KAAA,EAAO,CAAA;EACP,MAAA,EAAQ,kBAAA;EACR,MAAA,EAAQ,SAAA,CAAU,CAAA;EAClB,KAAA,EAAO,SAAA,CAAU,CAAA;AAAA;;UAIT,yBAAA,WAAoC,kBAAA;EAC5C,KAAA,EAAO,SAAA;EACP,MAAA,EAAQ,CAAA;EACR,MAAA,EAAQ,CAAA;EACR,KAAA,EAAO,CAAA;AAAA;;UAIC,qBAAA;EACR,KAAA,EAAO,SAAA;EACP,MAAA,EAAQ,kBAAkB;EAC1B,MAAA;EACA,KAAA;AAAA;AAAA,KAGG,kBAAA,qBACH,CAAA,mCAAoC,SAAA,aAAsB,yBAAA,CAA0B,CAAA,IAClF,CAAA,mCAAoC,SAAA,aAAsB,yBAAA,CAA0B,CAAA,IACpF,CAAA,mCAAoC,SAAA,aAAsB,yBAAA,CAA0B,CAAA,IACpF,CAAA,mCAAoC,SAAA,KAAc,0BAAA,CAA2B,CAAA,IAC7E,CAAA,mCAAoC,kBAAA,KAAuB,yBAAA,CAA0B,CAAA,IACrF,qBAAA;;AN/MyB;;KMoNjB,YAAA,WACJ,eAAA,GAAkB,kBAAA,CAAmB,CAAA;;;;KAUjC,UAAA,qBACV,CAAA,gCAAiC,UAAA,wBAAkC,SAAA,qBAA8B,iBAAA;EAC7F,KAAA,EAAO,KAAA;EAAO,KAAA,EAAO,KAAA;EAAO,SAAA,EAAW,EAAA;EAAI,IAAA;AAAA,IAC7C,CAAA,gCAAiC,UAAA,qBACjC,MAAA,SAAe,SAAA;EACb,KAAA,EAAO,KAAA;EAAO,KAAA,EAAO,MAAA;EAAQ,IAAA;AAAA,IAC/B,MAAA,SAAe,iBAAA;EACb,KAAA,EAAO,KAAA;EAAO,SAAA,EAAW,MAAA;EAAQ,IAAA;AAAA,YAEnC,CAAA,SAAU,UAAA;EACR,KAAA,EAAO,CAAA;EAAG,IAAA;AAAA;AJ/PkD;AAAA,UIuQxD,gBAAA;;UAIA,yBAAA,WACE,SAAA,YACA,iBAAA,gBACI,UAAA,UACN,gBAAA;EACR,IAAA,EAAM,KAAA,oBAAyB,OAAA,CAAQ,CAAA,EAAG,CAAA,IAAK,QAAA,CAAS,OAAA,CAAQ,CAAA,EAAG,CAAA;EACnE,MAAA,EAAQ,KAAA,mBAAwB,SAAA,CAAU,CAAA,EAAG,CAAA;AAAA;;UAIrC,yBAAA,eACM,UAAA,UACN,gBAAA;EACR,SAAA,EAAW,iBAAA;EACX,IAAA,EAAM,KAAA,8BAAmC,QAAA;EACzC,MAAA,EAAQ,KAAA;AAAA;AH3RqD;AAAA,UG+RrD,6BAAA,eACM,UAAA,UACN,gBAAA;EACR,KAAA,EAAO,SAAA;EACP,IAAA,EAAM,KAAA,8BAAmC,QAAA;EACzC,MAAA,EAAQ,KAAA;AAAA;;UAIA,yBAAA,eACM,UAAA,UACN,gBAAA;EACR,KAAA,EAAO,SAAA;EACP,SAAA,EAAW,iBAAA;EACX,IAAA,EAAM,KAAA,8BAAmC,QAAA;EACzC,MAAA,EAAQ,KAAA;AAAA;;AF9SsD;;KEwT3D,oBAAA,qBACH,UAAA,CAAW,CAAA;EACT,KAAA,kBAAuB,UAAA;EACvB,KAAA,kBAAuB,SAAA;EACvB,SAAA,kBAA2B,iBAAA;EAC3B,IAAA;AAAA,IAEA,yBAAA,CAA0B,CAAA,EAAG,CAAA,EAAG,CAAA,IAChC,UAAA,CAAW,CAAA;EACX,KAAA,kBAAuB,UAAA;EACvB,KAAA,mBAAwB,SAAA;EACxB,IAAA;AAAA,IAEA,yBAAA,CAA0B,CAAA,IAC1B,UAAA,CAAW,CAAA;EACX,KAAA,kBAAuB,UAAA;EACvB,SAAA,mBAA4B,iBAAA;EAC5B,IAAA;AAAA,IAEA,6BAAA,CAA8B,CAAA,IAC9B,UAAA,CAAW,CAAA;EAAa,KAAA,kBAAuB,UAAA;EAAY,IAAA;AAAA,IAC3D,yBAAA,CAA0B,CAAA,IAC1B,gBAAA;;;AArS6C;AAAA;;;;;;;;;KAuTrC,cAAA,WACJ,iBAAA,GAAoB,oBAAA,CAAqB,CAAA;AAAA;EAAA,UAQrC,mBAAA,SAA4B,cAAA,EAAgB,YAAY;AAAA;;;cC5WvD,gBAAA;EAAA;;;;;;;;;YAWD,oBAAA;IACR,QAAA,SAAiB,gBAAgB;EAAA;AAAA;;;;;;;;;;;ARcrC;;;cSXa,kBAAA,YAA8B,aAAA,CAAc,WAAA,EAAW,MAAA,mBAAyB,MAAA;EAAA,SAClF,EAAA;EAET,OAAA;IAAiB,IAAA;IAAA;EAAA;IACf,IAAA,EAAM,MAAA;IACN,OAAA,GAAU,IAAA,EAAM,MAAA,kCAAwC,OAAA;EAAA,MACtD,OAAA;AAAA;;;UChBW,yBAAA;EACf,aAAA,EAAe,cAAc;AAAA;;;;;AVoB/B;;;;;;;;;;;;;;;;;;;;;;;;;;cUgDa,kBAAA,YAA8B,aAAA,CAAc,WAAA,EAAW,MAAA,mBAAyB,MAAA;EAAA,QAGvE,OAAA;EAAA,SAFX,EAAA;cAEW,OAAA,EAAS,yBAAA;EAE7B,gBAAA,EAAkB,sBAAA,CAAuB,WAAA;EA6CzC,OAAA;IAAiB,KAAA;IAAA,SAAA;IAAA,IAAA;IAAA;EAAA;IACf,KAAA;IACA,SAAA;IACA,IAAA,EAAM,MAAA;IACN,OAAA,GAAU,IAAA,EAAM,MAAA,kCAAwC,OAAA;EAAA,MACtD,OAAA;AAAA;;;;;;;;;;;;;AVvGN;cWVa,cAAA;EAAA,OACJ,KAAA,IAAS,MAAA,EAAQ,CAAA,EAAG,UAAA,WAAqB,CAAC;AAAA;;;;;;;uBCX7B,eAAA,SAAwB,OAAO;EAAA,UACnC,QAAA,CAAS,IAAA,aAAiB,OAAA;AAAA;;;cCL/B,iBAAA,SAA0B,eAAe;EAAA,OAC7C,OAAA;EAAA,OACA,WAAA;EAED,MAAA,IAAU,OAAA;AAAA;;;cCJL,aAAA,SAAsB,eAAe;EAAA,OACzC,OAAA;EAAA,OACA,WAAA;EAED,MAAA,IAAU,OAAA;AAAA;;;cCJL,aAAA,SAAsB,eAAe;EAAA,OACzC,OAAA;EAAA,OACA,WAAA;EAED,MAAA,IAAU,OAAA;AAAA;;;cCJL,oBAAA,SAA6B,eAAe;EAAA,OAChD,OAAA;EAAA,OACA,WAAA;EAED,MAAA,IAAU,OAAA;AAAA;;;cCJL,iBAAA,SAA0B,eAAe;EAAA,OAC7C,OAAA;EAAA,OACA,WAAA;EAED,MAAA,IAAU,OAAA;AAAA;;;cCJL,mBAAA,SAA4B,eAAe;EAAA,OAC/C,OAAA;EAAA,OACA,WAAA;EAED,MAAA,IAAU,OAAA;AAAA;;;cCJL,oBAAA,SAA6B,eAAe;EAAA,OAChD,OAAA;EAAA,OACA,WAAA;EAED,MAAA,IAAU,OAAA;AAAA"}
|