@strapi/database 5.57.0 → 5.59.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/dist/connection.d.ts.map +1 -1
  2. package/dist/connection.js +15 -2
  3. package/dist/connection.js.map +1 -1
  4. package/dist/connection.mjs +15 -2
  5. package/dist/connection.mjs.map +1 -1
  6. package/dist/dialects/sqlite/index.js +3 -3
  7. package/dist/dialects/sqlite/index.js.map +1 -1
  8. package/dist/dialects/sqlite/index.mjs +3 -3
  9. package/dist/dialects/sqlite/index.mjs.map +1 -1
  10. package/dist/entity-manager/regular-relations.js +1 -1
  11. package/dist/entity-manager/regular-relations.js.map +1 -1
  12. package/dist/entity-manager/regular-relations.mjs +1 -1
  13. package/dist/entity-manager/regular-relations.mjs.map +1 -1
  14. package/dist/index.d.ts +25 -0
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +55 -13
  17. package/dist/index.js.map +1 -1
  18. package/dist/index.mjs +44 -3
  19. package/dist/index.mjs.map +1 -1
  20. package/dist/migrations/internal.d.ts.map +1 -1
  21. package/dist/migrations/internal.js +1 -0
  22. package/dist/migrations/internal.js.map +1 -1
  23. package/dist/migrations/internal.mjs +1 -0
  24. package/dist/migrations/internal.mjs.map +1 -1
  25. package/dist/migrations/runner.d.ts +2 -0
  26. package/dist/migrations/runner.d.ts.map +1 -1
  27. package/dist/migrations/runner.js +7 -2
  28. package/dist/migrations/runner.js.map +1 -1
  29. package/dist/migrations/runner.mjs +7 -2
  30. package/dist/migrations/runner.mjs.map +1 -1
  31. package/dist/migrations/users.d.ts.map +1 -1
  32. package/dist/migrations/users.js +1 -0
  33. package/dist/migrations/users.js.map +1 -1
  34. package/dist/migrations/users.mjs +1 -0
  35. package/dist/migrations/users.mjs.map +1 -1
  36. package/dist/pool-diagnostics/details.d.ts +58 -0
  37. package/dist/pool-diagnostics/details.d.ts.map +1 -0
  38. package/dist/pool-diagnostics/details.js +42 -0
  39. package/dist/pool-diagnostics/details.js.map +1 -0
  40. package/dist/pool-diagnostics/details.mjs +38 -0
  41. package/dist/pool-diagnostics/details.mjs.map +1 -0
  42. package/dist/pool-diagnostics/event-loop.d.ts +31 -0
  43. package/dist/pool-diagnostics/event-loop.d.ts.map +1 -0
  44. package/dist/pool-diagnostics/event-loop.js +59 -0
  45. package/dist/pool-diagnostics/event-loop.js.map +1 -0
  46. package/dist/pool-diagnostics/event-loop.mjs +54 -0
  47. package/dist/pool-diagnostics/event-loop.mjs.map +1 -0
  48. package/dist/pool-diagnostics/format.d.ts +9 -0
  49. package/dist/pool-diagnostics/format.d.ts.map +1 -0
  50. package/dist/pool-diagnostics/format.js +46 -0
  51. package/dist/pool-diagnostics/format.js.map +1 -0
  52. package/dist/pool-diagnostics/format.mjs +42 -0
  53. package/dist/pool-diagnostics/format.mjs.map +1 -0
  54. package/dist/pool-diagnostics/index.d.ts +33 -0
  55. package/dist/pool-diagnostics/index.d.ts.map +1 -0
  56. package/dist/pool-diagnostics/index.js +117 -0
  57. package/dist/pool-diagnostics/index.js.map +1 -0
  58. package/dist/pool-diagnostics/index.mjs +109 -0
  59. package/dist/pool-diagnostics/index.mjs.map +1 -0
  60. package/dist/pool-diagnostics/stack.d.ts +12 -0
  61. package/dist/pool-diagnostics/stack.d.ts.map +1 -0
  62. package/dist/pool-diagnostics/stack.js +46 -0
  63. package/dist/pool-diagnostics/stack.js.map +1 -0
  64. package/dist/pool-diagnostics/stack.mjs +44 -0
  65. package/dist/pool-diagnostics/stack.mjs.map +1 -0
  66. package/dist/query/helpers/populate/apply.d.ts.map +1 -1
  67. package/dist/query/helpers/populate/apply.js +21 -3
  68. package/dist/query/helpers/populate/apply.js.map +1 -1
  69. package/dist/query/helpers/populate/apply.mjs +21 -3
  70. package/dist/query/helpers/populate/apply.mjs.map +1 -1
  71. package/dist/query/helpers/streams/readable.d.ts +1 -1
  72. package/dist/query/helpers/streams/readable.d.ts.map +1 -1
  73. package/dist/query/helpers/streams/readable.js +2 -2
  74. package/dist/query/helpers/streams/readable.js.map +1 -1
  75. package/dist/query/helpers/streams/readable.mjs +1 -1
  76. package/dist/query/helpers/streams/readable.mjs.map +1 -1
  77. package/dist/schema/diff.d.ts.map +1 -1
  78. package/dist/schema/diff.js +3 -3
  79. package/dist/schema/diff.js.map +1 -1
  80. package/dist/schema/diff.mjs +3 -3
  81. package/dist/schema/diff.mjs.map +1 -1
  82. package/dist/schema/index.d.ts.map +1 -1
  83. package/dist/schema/index.js +20 -18
  84. package/dist/schema/index.js.map +1 -1
  85. package/dist/schema/index.mjs +20 -18
  86. package/dist/schema/index.mjs.map +1 -1
  87. package/dist/utils/knex-log.d.ts +19 -0
  88. package/dist/utils/knex-log.d.ts.map +1 -0
  89. package/dist/utils/knex-log.js +51 -0
  90. package/dist/utils/knex-log.js.map +1 -0
  91. package/dist/utils/knex-log.mjs +47 -0
  92. package/dist/utils/knex-log.mjs.map +1 -0
  93. package/dist/utils/throttle.d.ts +26 -0
  94. package/dist/utils/throttle.d.ts.map +1 -0
  95. package/dist/utils/throttle.js +34 -0
  96. package/dist/utils/throttle.js.map +1 -0
  97. package/dist/utils/throttle.mjs +32 -0
  98. package/dist/utils/throttle.mjs.map +1 -0
  99. package/dist/utils/types.d.ts.map +1 -1
  100. package/dist/utils/types.js +9 -9
  101. package/dist/utils/types.js.map +1 -1
  102. package/dist/utils/types.mjs +9 -9
  103. package/dist/utils/types.mjs.map +1 -1
  104. package/package.json +7 -7
package/dist/index.js CHANGED
@@ -2,17 +2,20 @@
2
2
 
3
3
  var path = require('node:path');
4
4
  var index$2 = require('./dialects/index.js');
5
- var index$4 = require('./schema/index.js');
5
+ var index$5 = require('./schema/index.js');
6
6
  var index$3 = require('./metadata/index.js');
7
- var index$7 = require('./entity-manager/index.js');
8
- var index$5 = require('./migrations/index.js');
9
- var index$6 = require('./lifecycles/index.js');
7
+ var index$8 = require('./entity-manager/index.js');
8
+ var index$6 = require('./migrations/index.js');
9
+ var index$7 = require('./lifecycles/index.js');
10
10
  var connection = require('./connection.js');
11
11
  var index = require('./errors/index.js');
12
12
  var transactionContext = require('./transaction-context.js');
13
13
  var index$1 = require('./validations/index.js');
14
- var index$8 = require('./repairs/index.js');
14
+ var index$9 = require('./repairs/index.js');
15
+ var index$4 = require('./pool-diagnostics/index.js');
16
+ var knexLog = require('./utils/knex-log.js');
15
17
  var knex = require('./utils/knex.js');
18
+ var details = require('./pool-diagnostics/details.js');
16
19
  var attributeNaming = require('./metadata/attribute-naming.js');
17
20
 
18
21
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
@@ -42,7 +45,9 @@ class Database {
42
45
  if (this.config.connection.client === 'sqlite') {
43
46
  await this.connection.raw('SELECT 1');
44
47
  } else {
45
- await this.connection.client.acquireConnection();
48
+ // release it straight away, otherwise it holds a pool slot for the life of the process
49
+ const conn = await this.connection.client.acquireConnection();
50
+ await this.connection.client.releaseConnection(conn);
46
51
  }
47
52
  }
48
53
  this.metadata.loadModels(models);
@@ -58,6 +63,24 @@ class Database {
58
63
  inTransaction() {
59
64
  return !!transactionContext.transactionCtx.get();
60
65
  }
66
+ /**
67
+ * Labels pool timeout reports raised while `fn` runs, for example "schema sync". Nested calls
68
+ * restore the outer label. Calls that overlap without nesting can restore the wrong label; core
69
+ * only nests them (schema sync, then a migration).
70
+ *
71
+ * The label is process-wide, not per call: a call made at runtime relabels every concurrent
72
+ * timeout report until it returns. It is meant for boot-time work (schema sync, migrations).
73
+ *
74
+ * @internal
75
+ */ async runInPhase(phase, fn) {
76
+ const previous = this.phase;
77
+ this.phase = phase;
78
+ try {
79
+ return await fn();
80
+ } finally{
81
+ this.phase = previous;
82
+ }
83
+ }
61
84
  async transaction(cb) {
62
85
  const notNestedTransaction = !transactionContext.transactionCtx.get();
63
86
  const trx = notNestedTransaction ? await this.connection.transaction() : transactionContext.transactionCtx.get();
@@ -134,7 +157,11 @@ class Database {
134
157
  return this.entityManager.createQueryBuilder(uid);
135
158
  }
136
159
  async destroy() {
137
- await this.lifecycles.clear();
160
+ try {
161
+ await this.lifecycles.clear();
162
+ } finally{
163
+ this.poolDiagnostics?.dispose();
164
+ }
138
165
  await this.connection.destroy();
139
166
  }
140
167
  constructor(config){
@@ -165,22 +192,37 @@ class Database {
165
192
  };
166
193
  }
167
194
  this.metadata = index$3.createMetadata([]);
168
- this.connection = connection.createConnection(knexConfig, {
195
+ this.connection = connection.createConnection(knexLog.withStrapiKnexLog(knexConfig, this.logger), {
169
196
  pool: {
170
197
  afterCreate: afterCreate(this)
171
198
  }
172
199
  });
173
- this.schema = index$4.createSchemaProvider(this);
174
- this.migrations = index$5.createMigrationsProvider(this);
175
- this.lifecycles = index$6.createLifecyclesProvider(this);
176
- this.entityManager = index$7.createEntityManager(this);
177
- this.repair = index$8.createRepairManager(this);
200
+ if (this.config.settings.poolTimeoutDiagnostics !== false) {
201
+ try {
202
+ this.poolDiagnostics = index$4.installPoolDiagnostics(this.connection, {
203
+ logger: {
204
+ warn: (message)=>this.logger.warn(message)
205
+ },
206
+ getPhase: ()=>this.phase ?? this.config.getPhase?.()
207
+ });
208
+ } catch (error) {
209
+ // Diagnostics are optional: failing to install them must not stop the application booting
210
+ const reason = error instanceof Error ? error.message : String(error);
211
+ this.logger.debug(`[database] pool timeout diagnostics not installed: ${reason}`);
212
+ }
213
+ }
214
+ this.schema = index$5.createSchemaProvider(this);
215
+ this.migrations = index$6.createMigrationsProvider(this);
216
+ this.lifecycles = index$7.createLifecyclesProvider(this);
217
+ this.entityManager = index$8.createEntityManager(this);
218
+ this.repair = index$9.createRepairManager(this);
178
219
  }
179
220
  }
180
221
 
181
222
  exports.isDatabaseClientKind = connection.isDatabaseClientKind;
182
223
  exports.errors = index;
183
224
  exports.isKnexQuery = knex.isKnexQuery;
225
+ exports.POOL_TIMEOUT_CODE = details.POOL_TIMEOUT_CODE;
184
226
  exports.attributeNaming = attributeNaming.attributeNaming;
185
227
  exports.Database = Database;
186
228
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import type { Knex } from 'knex';\n\nimport path from 'node:path';\n\nimport { Dialect, getDialect } from './dialects';\nimport { createSchemaProvider, SchemaProvider } from './schema';\nimport { createMetadata, Metadata } from './metadata';\nimport { createEntityManager, EntityManager } from './entity-manager';\nimport { createMigrationsProvider, MigrationProvider } from './migrations';\nimport { createLifecyclesProvider, LifecycleProvider } from './lifecycles';\nimport { createConnection } from './connection';\nimport * as errors from './errors';\nimport { Callback, transactionCtx, TransactionObject } from './transaction-context';\nimport { validateDatabase } from './validations';\nimport type { Model } from './types';\nimport { createRepairManager, type RepairManager } from './repairs';\n\nexport { isKnexQuery } from './utils/knex';\nexport { isDatabaseClientKind } from './connection';\nexport { attributeNaming } from './metadata';\nexport type { AttributeNaming, Meta } from './metadata';\nexport type {\n AttributeRenamesOperation,\n Migration,\n BuiltMigrationFile,\n MigrationFileBuilder,\n MigrationFileFormat,\n MigrationFileOperation,\n} from './migrations';\nexport type { Event } from './lifecycles';\nexport type { Attribute, Model, JoinTable } from './types';\nexport type { AttributeRenameHandler, AttributeRenames } from './schema';\nexport type { Identifiers } from './utils/identifiers';\n\ninterface Settings {\n forceMigration?: boolean;\n runMigrations?: boolean;\n migrations: {\n dir: string;\n };\n [key: string]: unknown;\n}\n\nexport type Logger = Record<\n 'info' | 'warn' | 'error' | 'debug',\n (message: string | Record<string, unknown>) => void\n>;\n\nexport interface DatabaseConfig {\n connection: Knex.Config;\n settings: Settings;\n logger?: Logger;\n}\n\nconst afterCreate =\n (db: Database) =>\n (\n nativeConnection: unknown,\n done: (error: Error | null, nativeConnection: unknown) => Promise<void>\n ) => {\n // run initialize for it since commands such as postgres SET and sqlite PRAGMA are per-connection\n db.dialect.initialize(nativeConnection).then(() => {\n return done(null, nativeConnection);\n });\n };\n\nclass Database {\n connection: Knex;\n\n dialect: Dialect;\n\n config: DatabaseConfig;\n\n metadata: Metadata;\n\n schema: SchemaProvider;\n\n migrations: MigrationProvider;\n\n lifecycles: LifecycleProvider;\n\n entityManager: EntityManager;\n\n repair: RepairManager;\n\n logger: Logger;\n\n constructor(config: DatabaseConfig) {\n this.config = {\n ...config,\n settings: {\n forceMigration: true,\n runMigrations: true,\n ...config.settings,\n },\n };\n\n this.logger = config.logger ?? console;\n\n this.dialect = getDialect(this);\n\n let knexConfig: Knex.Config = this.config.connection;\n\n // for object connections, we can configure the dialect synchronously\n if (typeof this.config.connection.connection !== 'function') {\n this.dialect.configure();\n }\n // for connection functions, we wrap it so that we can modify it with dialect configure before it reaches knex\n else {\n this.logger.warn(\n 'Knex connection functions are currently experimental. Attempting to access the connection object before database initialization will result in errors.'\n );\n\n knexConfig = {\n ...this.config.connection,\n connection: async () => {\n // @ts-expect-error confirmed it was a function above\n const conn = await this.config.connection.connection();\n this.dialect.configure(conn);\n return conn;\n },\n };\n }\n\n this.metadata = createMetadata([]);\n\n this.connection = createConnection(knexConfig, {\n pool: { afterCreate: afterCreate(this) },\n });\n\n this.schema = createSchemaProvider(this);\n\n this.migrations = createMigrationsProvider(this);\n this.lifecycles = createLifecyclesProvider(this);\n\n this.entityManager = createEntityManager(this);\n\n this.repair = createRepairManager(this);\n }\n\n async init({ models }: { models: Model[] }) {\n if (typeof this.config.connection.connection === 'function') {\n /*\n * User code needs to be able to access `connection.connection` directly as if\n * it were always an object. For a connection function, that doesn't happen\n * until the pool is created, so we need to do that here\n *\n * TODO: In the next major version, we need to replace all internal code that\n * directly references `connection.connection` prior to init, and make a breaking\n * change that it cannot be relied on to exist before init so that we can call\n * this feature stable.\n */\n this.logger.debug('Forcing Knex to make real connection to db');\n\n // sqlite does not support connection pooling so acquireConnection doesn't work\n if (this.config.connection.client === 'sqlite') {\n await this.connection.raw('SELECT 1');\n } else {\n await this.connection.client.acquireConnection();\n }\n }\n\n this.metadata.loadModels(models);\n await validateDatabase(this);\n return this;\n }\n\n query(uid: string) {\n if (!this.metadata.has(uid)) {\n throw new Error(`Model ${uid} not found`);\n }\n\n return this.entityManager.getRepository(uid);\n }\n\n inTransaction() {\n return !!transactionCtx.get();\n }\n\n /**\n * Run work inside a DB transaction. On a fulfilled callback, the transaction\n * is committed; on rejection, it is rolled back. The callback receives Knex\n * `commit` and `rollback` helpers: if you call `rollback` and return without\n * throwing, the implementation avoids attempting a second `commit` on an\n * already-finalised transactor.\n */\n transaction(): Promise<TransactionObject>;\n transaction<TCallback extends Callback>(c: TCallback): Promise<ReturnType<TCallback>>;\n async transaction<TCallback extends Callback>(\n cb?: TCallback\n ): Promise<ReturnType<TCallback> | TransactionObject> {\n const notNestedTransaction = !transactionCtx.get();\n const trx = notNestedTransaction\n ? await this.connection.transaction()\n : (transactionCtx.get() as Knex.Transaction);\n\n async function commit() {\n if (notNestedTransaction) {\n await transactionCtx.commit(trx);\n }\n }\n\n async function rollback() {\n if (notNestedTransaction) {\n await transactionCtx.rollback(trx);\n }\n }\n\n if (!cb) {\n return { commit, rollback, get: () => trx };\n }\n\n return transactionCtx.run(trx, async () => {\n try {\n const callbackParams = {\n trx,\n commit,\n rollback,\n onCommit: transactionCtx.onCommit,\n onRollback: transactionCtx.onRollback,\n };\n const res = await cb(callbackParams);\n await commit();\n return res;\n } catch (error) {\n await rollback();\n throw error;\n }\n });\n }\n\n getSchemaName(): string | undefined {\n return this.connection.client.connectionSettings.schema;\n }\n\n getConnection(): Knex;\n getConnection(tableName?: string): Knex.QueryBuilder;\n getConnection(tableName?: string): Knex | Knex.QueryBuilder {\n const schema = this.getSchemaName();\n const connection = tableName ? this.connection(tableName) : this.connection;\n return schema ? connection.withSchema(schema) : connection;\n }\n\n // Returns basic info about the database connection\n getInfo() {\n const connectionSettings = this.connection?.client?.connectionSettings || {};\n const client = this.dialect?.client || '';\n\n let displayName = '';\n let schema;\n\n // For SQLite, get the relative filename\n if (client === 'sqlite') {\n const absolutePath = connectionSettings?.filename;\n if (absolutePath) {\n displayName = path.relative(process.cwd(), absolutePath);\n }\n }\n // For other dialects, get the database name\n else {\n displayName = connectionSettings?.database;\n schema = connectionSettings?.schema;\n }\n\n return {\n displayName,\n schema,\n client,\n };\n }\n\n getSchemaConnection(trx = this.connection) {\n const schema = this.getSchemaName();\n return schema ? trx.schema.withSchema(schema) : trx.schema;\n }\n\n queryBuilder(uid: string) {\n return this.entityManager.createQueryBuilder(uid);\n }\n\n async destroy() {\n await this.lifecycles.clear();\n await this.connection.destroy();\n }\n}\n\nexport { Database, errors };\n"],"names":["afterCreate","db","nativeConnection","done","dialect","initialize","then","Database","init","models","config","connection","logger","debug","client","raw","acquireConnection","metadata","loadModels","validateDatabase","query","uid","has","Error","entityManager","getRepository","inTransaction","transactionCtx","get","transaction","cb","notNestedTransaction","trx","commit","rollback","run","callbackParams","onCommit","onRollback","res","error","getSchemaName","connectionSettings","schema","getConnection","tableName","withSchema","getInfo","displayName","absolutePath","filename","path","relative","process","cwd","database","getSchemaConnection","queryBuilder","createQueryBuilder","destroy","lifecycles","clear","settings","forceMigration","runMigrations","console","getDialect","knexConfig","configure","warn","conn","createMetadata","createConnection","pool","createSchemaProvider","migrations","createMigrationsProvider","createLifecyclesProvider","createEntityManager","repair","createRepairManager"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import type { Knex } from 'knex';\n\nimport path from 'node:path';\n\nimport { Dialect, getDialect } from './dialects';\nimport { createSchemaProvider, SchemaProvider } from './schema';\nimport { createMetadata, Metadata } from './metadata';\nimport { createEntityManager, EntityManager } from './entity-manager';\nimport { createMigrationsProvider, MigrationProvider } from './migrations';\nimport { createLifecyclesProvider, LifecycleProvider } from './lifecycles';\nimport { createConnection } from './connection';\nimport * as errors from './errors';\nimport { Callback, transactionCtx, TransactionObject } from './transaction-context';\nimport { validateDatabase } from './validations';\nimport type { Model } from './types';\nimport { createRepairManager, type RepairManager } from './repairs';\nimport { installPoolDiagnostics, type PoolDiagnostics } from './pool-diagnostics';\nimport { withStrapiKnexLog } from './utils/knex-log';\n\nexport { isKnexQuery } from './utils/knex';\nexport { isDatabaseClientKind } from './connection';\nexport { attributeNaming } from './metadata';\nexport type { AttributeNaming, Meta } from './metadata';\nexport type {\n AttributeRenamesOperation,\n Migration,\n BuiltMigrationFile,\n MigrationFileBuilder,\n MigrationFileFormat,\n MigrationFileOperation,\n} from './migrations';\nexport type { Event } from './lifecycles';\nexport type { Attribute, Model, JoinTable } from './types';\nexport type { AttributeRenameHandler, AttributeRenames } from './schema';\nexport type { Identifiers } from './utils/identifiers';\nexport { POOL_TIMEOUT_CODE } from './pool-diagnostics';\nexport type {\n EventLoopDelay,\n PoolDiagnostics,\n PoolState,\n PoolTimeoutDetails,\n} from './pool-diagnostics';\n\ninterface Settings {\n forceMigration?: boolean;\n runMigrations?: boolean;\n /**\n * Describe the pool on knex connection pool timeouts (details on the error, a docs link, one\n * warning block per 30 s). Defaults to true; false leaves knex's error untouched. Must be a\n * boolean (for example `env.bool('DATABASE_POOL_TIMEOUT_DIAGNOSTICS', true)`): a string is not\n * read as false.\n */\n poolTimeoutDiagnostics?: boolean;\n migrations: {\n dir: string;\n };\n [key: string]: unknown;\n}\n\nexport type Logger = Record<\n 'info' | 'warn' | 'error' | 'debug',\n (message: string | Record<string, unknown>) => void\n>;\n\nexport interface DatabaseConfig {\n connection: Knex.Config;\n settings: Settings;\n logger?: Logger;\n /** Lifecycle phase of the host application, e.g. \"boot\" or \"runtime\", for pool timeout reports. */\n getPhase?: () => string | undefined;\n}\n\nconst afterCreate =\n (db: Database) =>\n (\n nativeConnection: unknown,\n done: (error: Error | null, nativeConnection: unknown) => Promise<void>\n ) => {\n // run initialize for it since commands such as postgres SET and sqlite PRAGMA are per-connection\n db.dialect.initialize(nativeConnection).then(() => {\n return done(null, nativeConnection);\n });\n };\n\nclass Database {\n connection: Knex;\n\n dialect: Dialect;\n\n config: DatabaseConfig;\n\n metadata: Metadata;\n\n schema: SchemaProvider;\n\n migrations: MigrationProvider;\n\n lifecycles: LifecycleProvider;\n\n entityManager: EntityManager;\n\n repair: RepairManager;\n\n logger: Logger;\n\n /** Set unless `settings.poolTimeoutDiagnostics` is false or the install failed. */\n private poolDiagnostics?: PoolDiagnostics;\n\n private phase?: string;\n\n constructor(config: DatabaseConfig) {\n this.config = {\n ...config,\n settings: {\n forceMigration: true,\n runMigrations: true,\n ...config.settings,\n },\n };\n\n this.logger = config.logger ?? console;\n\n this.dialect = getDialect(this);\n\n let knexConfig: Knex.Config = this.config.connection;\n\n // for object connections, we can configure the dialect synchronously\n if (typeof this.config.connection.connection !== 'function') {\n this.dialect.configure();\n }\n // for connection functions, we wrap it so that we can modify it with dialect configure before it reaches knex\n else {\n this.logger.warn(\n 'Knex connection functions are currently experimental. Attempting to access the connection object before database initialization will result in errors.'\n );\n\n knexConfig = {\n ...this.config.connection,\n connection: async () => {\n // @ts-expect-error confirmed it was a function above\n const conn = await this.config.connection.connection();\n this.dialect.configure(conn);\n return conn;\n },\n };\n }\n\n this.metadata = createMetadata([]);\n\n this.connection = createConnection(withStrapiKnexLog(knexConfig, this.logger), {\n pool: { afterCreate: afterCreate(this) },\n });\n\n if (this.config.settings.poolTimeoutDiagnostics !== false) {\n try {\n this.poolDiagnostics = installPoolDiagnostics(this.connection, {\n logger: { warn: (message) => this.logger.warn(message) },\n getPhase: () => this.phase ?? this.config.getPhase?.(),\n });\n } catch (error) {\n // Diagnostics are optional: failing to install them must not stop the application booting\n const reason = error instanceof Error ? error.message : String(error);\n this.logger.debug(`[database] pool timeout diagnostics not installed: ${reason}`);\n }\n }\n\n this.schema = createSchemaProvider(this);\n\n this.migrations = createMigrationsProvider(this);\n this.lifecycles = createLifecyclesProvider(this);\n\n this.entityManager = createEntityManager(this);\n\n this.repair = createRepairManager(this);\n }\n\n async init({ models }: { models: Model[] }) {\n if (typeof this.config.connection.connection === 'function') {\n /*\n * User code needs to be able to access `connection.connection` directly as if\n * it were always an object. For a connection function, that doesn't happen\n * until the pool is created, so we need to do that here\n *\n * TODO: In the next major version, we need to replace all internal code that\n * directly references `connection.connection` prior to init, and make a breaking\n * change that it cannot be relied on to exist before init so that we can call\n * this feature stable.\n */\n this.logger.debug('Forcing Knex to make real connection to db');\n\n // sqlite does not support connection pooling so acquireConnection doesn't work\n if (this.config.connection.client === 'sqlite') {\n await this.connection.raw('SELECT 1');\n } else {\n // release it straight away, otherwise it holds a pool slot for the life of the process\n const conn = await this.connection.client.acquireConnection();\n await this.connection.client.releaseConnection(conn);\n }\n }\n\n this.metadata.loadModels(models);\n await validateDatabase(this);\n return this;\n }\n\n query(uid: string) {\n if (!this.metadata.has(uid)) {\n throw new Error(`Model ${uid} not found`);\n }\n\n return this.entityManager.getRepository(uid);\n }\n\n inTransaction() {\n return !!transactionCtx.get();\n }\n\n /**\n * Labels pool timeout reports raised while `fn` runs, for example \"schema sync\". Nested calls\n * restore the outer label. Calls that overlap without nesting can restore the wrong label; core\n * only nests them (schema sync, then a migration).\n *\n * The label is process-wide, not per call: a call made at runtime relabels every concurrent\n * timeout report until it returns. It is meant for boot-time work (schema sync, migrations).\n *\n * @internal\n */\n async runInPhase<T>(phase: string, fn: () => Promise<T>): Promise<T> {\n const previous = this.phase;\n this.phase = phase;\n\n try {\n return await fn();\n } finally {\n this.phase = previous;\n }\n }\n\n /**\n * Run work inside a DB transaction. On a fulfilled callback, the transaction\n * is committed; on rejection, it is rolled back. The callback receives Knex\n * `commit` and `rollback` helpers: if you call `rollback` and return without\n * throwing, the implementation avoids attempting a second `commit` on an\n * already-finalised transactor.\n */\n transaction(): Promise<TransactionObject>;\n transaction<TCallback extends Callback>(c: TCallback): Promise<ReturnType<TCallback>>;\n async transaction<TCallback extends Callback>(\n cb?: TCallback\n ): Promise<ReturnType<TCallback> | TransactionObject> {\n const notNestedTransaction = !transactionCtx.get();\n const trx = notNestedTransaction\n ? await this.connection.transaction()\n : (transactionCtx.get() as Knex.Transaction);\n\n async function commit() {\n if (notNestedTransaction) {\n await transactionCtx.commit(trx);\n }\n }\n\n async function rollback() {\n if (notNestedTransaction) {\n await transactionCtx.rollback(trx);\n }\n }\n\n if (!cb) {\n return { commit, rollback, get: () => trx };\n }\n\n return transactionCtx.run(trx, async () => {\n try {\n const callbackParams = {\n trx,\n commit,\n rollback,\n onCommit: transactionCtx.onCommit,\n onRollback: transactionCtx.onRollback,\n };\n const res = await cb(callbackParams);\n await commit();\n return res;\n } catch (error) {\n await rollback();\n throw error;\n }\n });\n }\n\n getSchemaName(): string | undefined {\n return this.connection.client.connectionSettings.schema;\n }\n\n getConnection(): Knex;\n getConnection(tableName?: string): Knex.QueryBuilder;\n getConnection(tableName?: string): Knex | Knex.QueryBuilder {\n const schema = this.getSchemaName();\n const connection = tableName ? this.connection(tableName) : this.connection;\n return schema ? connection.withSchema(schema) : connection;\n }\n\n // Returns basic info about the database connection\n getInfo() {\n const connectionSettings = this.connection?.client?.connectionSettings || {};\n const client = this.dialect?.client || '';\n\n let displayName = '';\n let schema;\n\n // For SQLite, get the relative filename\n if (client === 'sqlite') {\n const absolutePath = connectionSettings?.filename;\n if (absolutePath) {\n displayName = path.relative(process.cwd(), absolutePath);\n }\n }\n // For other dialects, get the database name\n else {\n displayName = connectionSettings?.database;\n schema = connectionSettings?.schema;\n }\n\n return {\n displayName,\n schema,\n client,\n };\n }\n\n getSchemaConnection(trx = this.connection) {\n const schema = this.getSchemaName();\n return schema ? trx.schema.withSchema(schema) : trx.schema;\n }\n\n queryBuilder(uid: string) {\n return this.entityManager.createQueryBuilder(uid);\n }\n\n async destroy() {\n try {\n await this.lifecycles.clear();\n } finally {\n this.poolDiagnostics?.dispose();\n }\n\n await this.connection.destroy();\n }\n}\n\nexport { Database, errors };\n"],"names":["afterCreate","db","nativeConnection","done","dialect","initialize","then","Database","init","models","config","connection","logger","debug","client","raw","conn","acquireConnection","releaseConnection","metadata","loadModels","validateDatabase","query","uid","has","Error","entityManager","getRepository","inTransaction","transactionCtx","get","runInPhase","phase","fn","previous","transaction","cb","notNestedTransaction","trx","commit","rollback","run","callbackParams","onCommit","onRollback","res","error","getSchemaName","connectionSettings","schema","getConnection","tableName","withSchema","getInfo","displayName","absolutePath","filename","path","relative","process","cwd","database","getSchemaConnection","queryBuilder","createQueryBuilder","destroy","lifecycles","clear","poolDiagnostics","dispose","settings","forceMigration","runMigrations","console","getDialect","knexConfig","configure","warn","createMetadata","createConnection","withStrapiKnexLog","pool","poolTimeoutDiagnostics","installPoolDiagnostics","message","getPhase","reason","String","createSchemaProvider","migrations","createMigrationsProvider","createLifecyclesProvider","createEntityManager","repair","createRepairManager"],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -12,7 +12,10 @@ export { index as errors };
12
12
  import { transactionCtx } from './transaction-context.mjs';
13
13
  import { validateDatabase } from './validations/index.mjs';
14
14
  import { createRepairManager } from './repairs/index.mjs';
15
+ import { installPoolDiagnostics } from './pool-diagnostics/index.mjs';
16
+ import { withStrapiKnexLog } from './utils/knex-log.mjs';
15
17
  export { isKnexQuery } from './utils/knex.mjs';
18
+ export { POOL_TIMEOUT_CODE } from './pool-diagnostics/details.mjs';
16
19
  export { attributeNaming } from './metadata/attribute-naming.mjs';
17
20
 
18
21
  const afterCreate = (db)=>(nativeConnection, done)=>{
@@ -38,7 +41,9 @@ class Database {
38
41
  if (this.config.connection.client === 'sqlite') {
39
42
  await this.connection.raw('SELECT 1');
40
43
  } else {
41
- await this.connection.client.acquireConnection();
44
+ // release it straight away, otherwise it holds a pool slot for the life of the process
45
+ const conn = await this.connection.client.acquireConnection();
46
+ await this.connection.client.releaseConnection(conn);
42
47
  }
43
48
  }
44
49
  this.metadata.loadModels(models);
@@ -54,6 +59,24 @@ class Database {
54
59
  inTransaction() {
55
60
  return !!transactionCtx.get();
56
61
  }
62
+ /**
63
+ * Labels pool timeout reports raised while `fn` runs, for example "schema sync". Nested calls
64
+ * restore the outer label. Calls that overlap without nesting can restore the wrong label; core
65
+ * only nests them (schema sync, then a migration).
66
+ *
67
+ * The label is process-wide, not per call: a call made at runtime relabels every concurrent
68
+ * timeout report until it returns. It is meant for boot-time work (schema sync, migrations).
69
+ *
70
+ * @internal
71
+ */ async runInPhase(phase, fn) {
72
+ const previous = this.phase;
73
+ this.phase = phase;
74
+ try {
75
+ return await fn();
76
+ } finally{
77
+ this.phase = previous;
78
+ }
79
+ }
57
80
  async transaction(cb) {
58
81
  const notNestedTransaction = !transactionCtx.get();
59
82
  const trx = notNestedTransaction ? await this.connection.transaction() : transactionCtx.get();
@@ -130,7 +153,11 @@ class Database {
130
153
  return this.entityManager.createQueryBuilder(uid);
131
154
  }
132
155
  async destroy() {
133
- await this.lifecycles.clear();
156
+ try {
157
+ await this.lifecycles.clear();
158
+ } finally{
159
+ this.poolDiagnostics?.dispose();
160
+ }
134
161
  await this.connection.destroy();
135
162
  }
136
163
  constructor(config){
@@ -161,11 +188,25 @@ class Database {
161
188
  };
162
189
  }
163
190
  this.metadata = createMetadata([]);
164
- this.connection = createConnection(knexConfig, {
191
+ this.connection = createConnection(withStrapiKnexLog(knexConfig, this.logger), {
165
192
  pool: {
166
193
  afterCreate: afterCreate(this)
167
194
  }
168
195
  });
196
+ if (this.config.settings.poolTimeoutDiagnostics !== false) {
197
+ try {
198
+ this.poolDiagnostics = installPoolDiagnostics(this.connection, {
199
+ logger: {
200
+ warn: (message)=>this.logger.warn(message)
201
+ },
202
+ getPhase: ()=>this.phase ?? this.config.getPhase?.()
203
+ });
204
+ } catch (error) {
205
+ // Diagnostics are optional: failing to install them must not stop the application booting
206
+ const reason = error instanceof Error ? error.message : String(error);
207
+ this.logger.debug(`[database] pool timeout diagnostics not installed: ${reason}`);
208
+ }
209
+ }
169
210
  this.schema = createSchemaProvider(this);
170
211
  this.migrations = createMigrationsProvider(this);
171
212
  this.lifecycles = createLifecyclesProvider(this);
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../src/index.ts"],"sourcesContent":["import type { Knex } from 'knex';\n\nimport path from 'node:path';\n\nimport { Dialect, getDialect } from './dialects';\nimport { createSchemaProvider, SchemaProvider } from './schema';\nimport { createMetadata, Metadata } from './metadata';\nimport { createEntityManager, EntityManager } from './entity-manager';\nimport { createMigrationsProvider, MigrationProvider } from './migrations';\nimport { createLifecyclesProvider, LifecycleProvider } from './lifecycles';\nimport { createConnection } from './connection';\nimport * as errors from './errors';\nimport { Callback, transactionCtx, TransactionObject } from './transaction-context';\nimport { validateDatabase } from './validations';\nimport type { Model } from './types';\nimport { createRepairManager, type RepairManager } from './repairs';\n\nexport { isKnexQuery } from './utils/knex';\nexport { isDatabaseClientKind } from './connection';\nexport { attributeNaming } from './metadata';\nexport type { AttributeNaming, Meta } from './metadata';\nexport type {\n AttributeRenamesOperation,\n Migration,\n BuiltMigrationFile,\n MigrationFileBuilder,\n MigrationFileFormat,\n MigrationFileOperation,\n} from './migrations';\nexport type { Event } from './lifecycles';\nexport type { Attribute, Model, JoinTable } from './types';\nexport type { AttributeRenameHandler, AttributeRenames } from './schema';\nexport type { Identifiers } from './utils/identifiers';\n\ninterface Settings {\n forceMigration?: boolean;\n runMigrations?: boolean;\n migrations: {\n dir: string;\n };\n [key: string]: unknown;\n}\n\nexport type Logger = Record<\n 'info' | 'warn' | 'error' | 'debug',\n (message: string | Record<string, unknown>) => void\n>;\n\nexport interface DatabaseConfig {\n connection: Knex.Config;\n settings: Settings;\n logger?: Logger;\n}\n\nconst afterCreate =\n (db: Database) =>\n (\n nativeConnection: unknown,\n done: (error: Error | null, nativeConnection: unknown) => Promise<void>\n ) => {\n // run initialize for it since commands such as postgres SET and sqlite PRAGMA are per-connection\n db.dialect.initialize(nativeConnection).then(() => {\n return done(null, nativeConnection);\n });\n };\n\nclass Database {\n connection: Knex;\n\n dialect: Dialect;\n\n config: DatabaseConfig;\n\n metadata: Metadata;\n\n schema: SchemaProvider;\n\n migrations: MigrationProvider;\n\n lifecycles: LifecycleProvider;\n\n entityManager: EntityManager;\n\n repair: RepairManager;\n\n logger: Logger;\n\n constructor(config: DatabaseConfig) {\n this.config = {\n ...config,\n settings: {\n forceMigration: true,\n runMigrations: true,\n ...config.settings,\n },\n };\n\n this.logger = config.logger ?? console;\n\n this.dialect = getDialect(this);\n\n let knexConfig: Knex.Config = this.config.connection;\n\n // for object connections, we can configure the dialect synchronously\n if (typeof this.config.connection.connection !== 'function') {\n this.dialect.configure();\n }\n // for connection functions, we wrap it so that we can modify it with dialect configure before it reaches knex\n else {\n this.logger.warn(\n 'Knex connection functions are currently experimental. Attempting to access the connection object before database initialization will result in errors.'\n );\n\n knexConfig = {\n ...this.config.connection,\n connection: async () => {\n // @ts-expect-error confirmed it was a function above\n const conn = await this.config.connection.connection();\n this.dialect.configure(conn);\n return conn;\n },\n };\n }\n\n this.metadata = createMetadata([]);\n\n this.connection = createConnection(knexConfig, {\n pool: { afterCreate: afterCreate(this) },\n });\n\n this.schema = createSchemaProvider(this);\n\n this.migrations = createMigrationsProvider(this);\n this.lifecycles = createLifecyclesProvider(this);\n\n this.entityManager = createEntityManager(this);\n\n this.repair = createRepairManager(this);\n }\n\n async init({ models }: { models: Model[] }) {\n if (typeof this.config.connection.connection === 'function') {\n /*\n * User code needs to be able to access `connection.connection` directly as if\n * it were always an object. For a connection function, that doesn't happen\n * until the pool is created, so we need to do that here\n *\n * TODO: In the next major version, we need to replace all internal code that\n * directly references `connection.connection` prior to init, and make a breaking\n * change that it cannot be relied on to exist before init so that we can call\n * this feature stable.\n */\n this.logger.debug('Forcing Knex to make real connection to db');\n\n // sqlite does not support connection pooling so acquireConnection doesn't work\n if (this.config.connection.client === 'sqlite') {\n await this.connection.raw('SELECT 1');\n } else {\n await this.connection.client.acquireConnection();\n }\n }\n\n this.metadata.loadModels(models);\n await validateDatabase(this);\n return this;\n }\n\n query(uid: string) {\n if (!this.metadata.has(uid)) {\n throw new Error(`Model ${uid} not found`);\n }\n\n return this.entityManager.getRepository(uid);\n }\n\n inTransaction() {\n return !!transactionCtx.get();\n }\n\n /**\n * Run work inside a DB transaction. On a fulfilled callback, the transaction\n * is committed; on rejection, it is rolled back. The callback receives Knex\n * `commit` and `rollback` helpers: if you call `rollback` and return without\n * throwing, the implementation avoids attempting a second `commit` on an\n * already-finalised transactor.\n */\n transaction(): Promise<TransactionObject>;\n transaction<TCallback extends Callback>(c: TCallback): Promise<ReturnType<TCallback>>;\n async transaction<TCallback extends Callback>(\n cb?: TCallback\n ): Promise<ReturnType<TCallback> | TransactionObject> {\n const notNestedTransaction = !transactionCtx.get();\n const trx = notNestedTransaction\n ? await this.connection.transaction()\n : (transactionCtx.get() as Knex.Transaction);\n\n async function commit() {\n if (notNestedTransaction) {\n await transactionCtx.commit(trx);\n }\n }\n\n async function rollback() {\n if (notNestedTransaction) {\n await transactionCtx.rollback(trx);\n }\n }\n\n if (!cb) {\n return { commit, rollback, get: () => trx };\n }\n\n return transactionCtx.run(trx, async () => {\n try {\n const callbackParams = {\n trx,\n commit,\n rollback,\n onCommit: transactionCtx.onCommit,\n onRollback: transactionCtx.onRollback,\n };\n const res = await cb(callbackParams);\n await commit();\n return res;\n } catch (error) {\n await rollback();\n throw error;\n }\n });\n }\n\n getSchemaName(): string | undefined {\n return this.connection.client.connectionSettings.schema;\n }\n\n getConnection(): Knex;\n getConnection(tableName?: string): Knex.QueryBuilder;\n getConnection(tableName?: string): Knex | Knex.QueryBuilder {\n const schema = this.getSchemaName();\n const connection = tableName ? this.connection(tableName) : this.connection;\n return schema ? connection.withSchema(schema) : connection;\n }\n\n // Returns basic info about the database connection\n getInfo() {\n const connectionSettings = this.connection?.client?.connectionSettings || {};\n const client = this.dialect?.client || '';\n\n let displayName = '';\n let schema;\n\n // For SQLite, get the relative filename\n if (client === 'sqlite') {\n const absolutePath = connectionSettings?.filename;\n if (absolutePath) {\n displayName = path.relative(process.cwd(), absolutePath);\n }\n }\n // For other dialects, get the database name\n else {\n displayName = connectionSettings?.database;\n schema = connectionSettings?.schema;\n }\n\n return {\n displayName,\n schema,\n client,\n };\n }\n\n getSchemaConnection(trx = this.connection) {\n const schema = this.getSchemaName();\n return schema ? trx.schema.withSchema(schema) : trx.schema;\n }\n\n queryBuilder(uid: string) {\n return this.entityManager.createQueryBuilder(uid);\n }\n\n async destroy() {\n await this.lifecycles.clear();\n await this.connection.destroy();\n }\n}\n\nexport { Database, errors };\n"],"names":["afterCreate","db","nativeConnection","done","dialect","initialize","then","Database","init","models","config","connection","logger","debug","client","raw","acquireConnection","metadata","loadModels","validateDatabase","query","uid","has","Error","entityManager","getRepository","inTransaction","transactionCtx","get","transaction","cb","notNestedTransaction","trx","commit","rollback","run","callbackParams","onCommit","onRollback","res","error","getSchemaName","connectionSettings","schema","getConnection","tableName","withSchema","getInfo","displayName","absolutePath","filename","path","relative","process","cwd","database","getSchemaConnection","queryBuilder","createQueryBuilder","destroy","lifecycles","clear","settings","forceMigration","runMigrations","console","getDialect","knexConfig","configure","warn","conn","createMetadata","createConnection","pool","createSchemaProvider","migrations","createMigrationsProvider","createLifecyclesProvider","createEntityManager","repair","createRepairManager"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","sources":["../src/index.ts"],"sourcesContent":["import type { Knex } from 'knex';\n\nimport path from 'node:path';\n\nimport { Dialect, getDialect } from './dialects';\nimport { createSchemaProvider, SchemaProvider } from './schema';\nimport { createMetadata, Metadata } from './metadata';\nimport { createEntityManager, EntityManager } from './entity-manager';\nimport { createMigrationsProvider, MigrationProvider } from './migrations';\nimport { createLifecyclesProvider, LifecycleProvider } from './lifecycles';\nimport { createConnection } from './connection';\nimport * as errors from './errors';\nimport { Callback, transactionCtx, TransactionObject } from './transaction-context';\nimport { validateDatabase } from './validations';\nimport type { Model } from './types';\nimport { createRepairManager, type RepairManager } from './repairs';\nimport { installPoolDiagnostics, type PoolDiagnostics } from './pool-diagnostics';\nimport { withStrapiKnexLog } from './utils/knex-log';\n\nexport { isKnexQuery } from './utils/knex';\nexport { isDatabaseClientKind } from './connection';\nexport { attributeNaming } from './metadata';\nexport type { AttributeNaming, Meta } from './metadata';\nexport type {\n AttributeRenamesOperation,\n Migration,\n BuiltMigrationFile,\n MigrationFileBuilder,\n MigrationFileFormat,\n MigrationFileOperation,\n} from './migrations';\nexport type { Event } from './lifecycles';\nexport type { Attribute, Model, JoinTable } from './types';\nexport type { AttributeRenameHandler, AttributeRenames } from './schema';\nexport type { Identifiers } from './utils/identifiers';\nexport { POOL_TIMEOUT_CODE } from './pool-diagnostics';\nexport type {\n EventLoopDelay,\n PoolDiagnostics,\n PoolState,\n PoolTimeoutDetails,\n} from './pool-diagnostics';\n\ninterface Settings {\n forceMigration?: boolean;\n runMigrations?: boolean;\n /**\n * Describe the pool on knex connection pool timeouts (details on the error, a docs link, one\n * warning block per 30 s). Defaults to true; false leaves knex's error untouched. Must be a\n * boolean (for example `env.bool('DATABASE_POOL_TIMEOUT_DIAGNOSTICS', true)`): a string is not\n * read as false.\n */\n poolTimeoutDiagnostics?: boolean;\n migrations: {\n dir: string;\n };\n [key: string]: unknown;\n}\n\nexport type Logger = Record<\n 'info' | 'warn' | 'error' | 'debug',\n (message: string | Record<string, unknown>) => void\n>;\n\nexport interface DatabaseConfig {\n connection: Knex.Config;\n settings: Settings;\n logger?: Logger;\n /** Lifecycle phase of the host application, e.g. \"boot\" or \"runtime\", for pool timeout reports. */\n getPhase?: () => string | undefined;\n}\n\nconst afterCreate =\n (db: Database) =>\n (\n nativeConnection: unknown,\n done: (error: Error | null, nativeConnection: unknown) => Promise<void>\n ) => {\n // run initialize for it since commands such as postgres SET and sqlite PRAGMA are per-connection\n db.dialect.initialize(nativeConnection).then(() => {\n return done(null, nativeConnection);\n });\n };\n\nclass Database {\n connection: Knex;\n\n dialect: Dialect;\n\n config: DatabaseConfig;\n\n metadata: Metadata;\n\n schema: SchemaProvider;\n\n migrations: MigrationProvider;\n\n lifecycles: LifecycleProvider;\n\n entityManager: EntityManager;\n\n repair: RepairManager;\n\n logger: Logger;\n\n /** Set unless `settings.poolTimeoutDiagnostics` is false or the install failed. */\n private poolDiagnostics?: PoolDiagnostics;\n\n private phase?: string;\n\n constructor(config: DatabaseConfig) {\n this.config = {\n ...config,\n settings: {\n forceMigration: true,\n runMigrations: true,\n ...config.settings,\n },\n };\n\n this.logger = config.logger ?? console;\n\n this.dialect = getDialect(this);\n\n let knexConfig: Knex.Config = this.config.connection;\n\n // for object connections, we can configure the dialect synchronously\n if (typeof this.config.connection.connection !== 'function') {\n this.dialect.configure();\n }\n // for connection functions, we wrap it so that we can modify it with dialect configure before it reaches knex\n else {\n this.logger.warn(\n 'Knex connection functions are currently experimental. Attempting to access the connection object before database initialization will result in errors.'\n );\n\n knexConfig = {\n ...this.config.connection,\n connection: async () => {\n // @ts-expect-error confirmed it was a function above\n const conn = await this.config.connection.connection();\n this.dialect.configure(conn);\n return conn;\n },\n };\n }\n\n this.metadata = createMetadata([]);\n\n this.connection = createConnection(withStrapiKnexLog(knexConfig, this.logger), {\n pool: { afterCreate: afterCreate(this) },\n });\n\n if (this.config.settings.poolTimeoutDiagnostics !== false) {\n try {\n this.poolDiagnostics = installPoolDiagnostics(this.connection, {\n logger: { warn: (message) => this.logger.warn(message) },\n getPhase: () => this.phase ?? this.config.getPhase?.(),\n });\n } catch (error) {\n // Diagnostics are optional: failing to install them must not stop the application booting\n const reason = error instanceof Error ? error.message : String(error);\n this.logger.debug(`[database] pool timeout diagnostics not installed: ${reason}`);\n }\n }\n\n this.schema = createSchemaProvider(this);\n\n this.migrations = createMigrationsProvider(this);\n this.lifecycles = createLifecyclesProvider(this);\n\n this.entityManager = createEntityManager(this);\n\n this.repair = createRepairManager(this);\n }\n\n async init({ models }: { models: Model[] }) {\n if (typeof this.config.connection.connection === 'function') {\n /*\n * User code needs to be able to access `connection.connection` directly as if\n * it were always an object. For a connection function, that doesn't happen\n * until the pool is created, so we need to do that here\n *\n * TODO: In the next major version, we need to replace all internal code that\n * directly references `connection.connection` prior to init, and make a breaking\n * change that it cannot be relied on to exist before init so that we can call\n * this feature stable.\n */\n this.logger.debug('Forcing Knex to make real connection to db');\n\n // sqlite does not support connection pooling so acquireConnection doesn't work\n if (this.config.connection.client === 'sqlite') {\n await this.connection.raw('SELECT 1');\n } else {\n // release it straight away, otherwise it holds a pool slot for the life of the process\n const conn = await this.connection.client.acquireConnection();\n await this.connection.client.releaseConnection(conn);\n }\n }\n\n this.metadata.loadModels(models);\n await validateDatabase(this);\n return this;\n }\n\n query(uid: string) {\n if (!this.metadata.has(uid)) {\n throw new Error(`Model ${uid} not found`);\n }\n\n return this.entityManager.getRepository(uid);\n }\n\n inTransaction() {\n return !!transactionCtx.get();\n }\n\n /**\n * Labels pool timeout reports raised while `fn` runs, for example \"schema sync\". Nested calls\n * restore the outer label. Calls that overlap without nesting can restore the wrong label; core\n * only nests them (schema sync, then a migration).\n *\n * The label is process-wide, not per call: a call made at runtime relabels every concurrent\n * timeout report until it returns. It is meant for boot-time work (schema sync, migrations).\n *\n * @internal\n */\n async runInPhase<T>(phase: string, fn: () => Promise<T>): Promise<T> {\n const previous = this.phase;\n this.phase = phase;\n\n try {\n return await fn();\n } finally {\n this.phase = previous;\n }\n }\n\n /**\n * Run work inside a DB transaction. On a fulfilled callback, the transaction\n * is committed; on rejection, it is rolled back. The callback receives Knex\n * `commit` and `rollback` helpers: if you call `rollback` and return without\n * throwing, the implementation avoids attempting a second `commit` on an\n * already-finalised transactor.\n */\n transaction(): Promise<TransactionObject>;\n transaction<TCallback extends Callback>(c: TCallback): Promise<ReturnType<TCallback>>;\n async transaction<TCallback extends Callback>(\n cb?: TCallback\n ): Promise<ReturnType<TCallback> | TransactionObject> {\n const notNestedTransaction = !transactionCtx.get();\n const trx = notNestedTransaction\n ? await this.connection.transaction()\n : (transactionCtx.get() as Knex.Transaction);\n\n async function commit() {\n if (notNestedTransaction) {\n await transactionCtx.commit(trx);\n }\n }\n\n async function rollback() {\n if (notNestedTransaction) {\n await transactionCtx.rollback(trx);\n }\n }\n\n if (!cb) {\n return { commit, rollback, get: () => trx };\n }\n\n return transactionCtx.run(trx, async () => {\n try {\n const callbackParams = {\n trx,\n commit,\n rollback,\n onCommit: transactionCtx.onCommit,\n onRollback: transactionCtx.onRollback,\n };\n const res = await cb(callbackParams);\n await commit();\n return res;\n } catch (error) {\n await rollback();\n throw error;\n }\n });\n }\n\n getSchemaName(): string | undefined {\n return this.connection.client.connectionSettings.schema;\n }\n\n getConnection(): Knex;\n getConnection(tableName?: string): Knex.QueryBuilder;\n getConnection(tableName?: string): Knex | Knex.QueryBuilder {\n const schema = this.getSchemaName();\n const connection = tableName ? this.connection(tableName) : this.connection;\n return schema ? connection.withSchema(schema) : connection;\n }\n\n // Returns basic info about the database connection\n getInfo() {\n const connectionSettings = this.connection?.client?.connectionSettings || {};\n const client = this.dialect?.client || '';\n\n let displayName = '';\n let schema;\n\n // For SQLite, get the relative filename\n if (client === 'sqlite') {\n const absolutePath = connectionSettings?.filename;\n if (absolutePath) {\n displayName = path.relative(process.cwd(), absolutePath);\n }\n }\n // For other dialects, get the database name\n else {\n displayName = connectionSettings?.database;\n schema = connectionSettings?.schema;\n }\n\n return {\n displayName,\n schema,\n client,\n };\n }\n\n getSchemaConnection(trx = this.connection) {\n const schema = this.getSchemaName();\n return schema ? trx.schema.withSchema(schema) : trx.schema;\n }\n\n queryBuilder(uid: string) {\n return this.entityManager.createQueryBuilder(uid);\n }\n\n async destroy() {\n try {\n await this.lifecycles.clear();\n } finally {\n this.poolDiagnostics?.dispose();\n }\n\n await this.connection.destroy();\n }\n}\n\nexport { Database, errors };\n"],"names":["afterCreate","db","nativeConnection","done","dialect","initialize","then","Database","init","models","config","connection","logger","debug","client","raw","conn","acquireConnection","releaseConnection","metadata","loadModels","validateDatabase","query","uid","has","Error","entityManager","getRepository","inTransaction","transactionCtx","get","runInPhase","phase","fn","previous","transaction","cb","notNestedTransaction","trx","commit","rollback","run","callbackParams","onCommit","onRollback","res","error","getSchemaName","connectionSettings","schema","getConnection","tableName","withSchema","getInfo","displayName","absolutePath","filename","path","relative","process","cwd","database","getSchemaConnection","queryBuilder","createQueryBuilder","destroy","lifecycles","clear","poolDiagnostics","dispose","settings","forceMigration","runMigrations","console","getDialect","knexConfig","configure","warn","createMetadata","createConnection","withStrapiKnexLog","pool","poolTimeoutDiagnostics","installPoolDiagnostics","message","getPhase","reason","String","createSchemaProvider","migrations","createMigrationsProvider","createLifecyclesProvider","createEntityManager","repair","createRepairManager"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../../src/migrations/internal.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,yBAAyB,EAAa,MAAM,UAAU,CAAC;AACrE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AAEnC,eAAO,MAAM,+BAA+B,GAAI,IAAI,QAAQ,KAAG,yBAkC9D,CAAC"}
1
+ {"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../../src/migrations/internal.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,yBAAyB,EAAa,MAAM,UAAU,CAAC;AACrE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AAEnC,eAAO,MAAM,+BAA+B,GAAI,IAAI,QAAQ,KAAG,yBAmC9D,CAAC"}
@@ -18,6 +18,7 @@ const createInternalMigrationProvider = (db)=>{
18
18
  db,
19
19
  tableName: 'strapi_migrations_internal'
20
20
  }),
21
+ withPhase: (phase, fn)=>db.runInPhase(phase, fn),
21
22
  logger: {
22
23
  info (message) {
23
24
  db.logger.info(logger.transformLogMessage('info', message));
@@ -1 +1 @@
1
- {"version":3,"file":"internal.js","sources":["../../src/migrations/internal.ts"],"sourcesContent":["import { wrapTransaction } from './common';\nimport { createMigrationRunner } from './runner';\nimport { internalMigrations } from './internal-migrations';\nimport { createStorage } from './storage';\nimport { transformLogMessage } from './logger';\n\nimport type { InternalMigrationProvider, Migration } from './common';\nimport type { Database } from '..';\n\nexport const createInternalMigrationProvider = (db: Database): InternalMigrationProvider => {\n const context = { db };\n const migrations: Migration[] = [...internalMigrations];\n\n const runner = createMigrationRunner({\n storage: createStorage({ db, tableName: 'strapi_migrations_internal' }),\n logger: {\n info(message) {\n db.logger.info(transformLogMessage('info', message));\n },\n },\n getMigrations: async () =>\n migrations.map((migration) => ({\n name: migration.name,\n up: wrapTransaction(context.db)(migration.up),\n down: wrapTransaction(context.db)(migration.down),\n })),\n });\n\n return {\n async register(migration: Migration) {\n migrations.push(migration);\n },\n async shouldRun() {\n const pendingMigrations = await runner.pending();\n return pendingMigrations.length > 0;\n },\n async up() {\n await runner.up();\n },\n async down() {\n await runner.down();\n },\n };\n};\n"],"names":["createInternalMigrationProvider","db","context","migrations","internalMigrations","runner","createMigrationRunner","storage","createStorage","tableName","logger","info","message","transformLogMessage","getMigrations","map","migration","name","up","wrapTransaction","down","register","push","shouldRun","pendingMigrations","pending","length"],"mappings":";;;;;;;;AASO,MAAMA,kCAAkC,CAACC,EAAAA,GAAAA;AAC9C,IAAA,MAAMC,OAAAA,GAAU;AAAED,QAAAA;AAAG,KAAA;AACrB,IAAA,MAAME,UAAAA,GAA0B;AAAIC,QAAAA,GAAAA;AAAmB,KAAA;AAEvD,IAAA,MAAMC,WAASC,4BAAAA,CAAsB;AACnCC,QAAAA,OAAAA,EAASC,qBAAAA,CAAc;AAAEP,YAAAA,EAAAA;YAAIQ,SAAAA,EAAW;AAA6B,SAAA,CAAA;QACrEC,MAAAA,EAAQ;AACNC,YAAAA,IAAAA,CAAAA,CAAKC,OAAO,EAAA;AACVX,gBAAAA,EAAAA,CAAGS,MAAM,CAACC,IAAI,CAACE,2BAAoB,MAAA,EAAQD,OAAAA,CAAAA,CAAAA;AAC7C,YAAA;AACF,SAAA;AACAE,QAAAA,aAAAA,EAAe,UACbX,UAAAA,CAAWY,GAAG,CAAC,CAACC,aAAe;AAC7BC,oBAAAA,IAAAA,EAAMD,UAAUC,IAAI;AACpBC,oBAAAA,EAAAA,EAAIC,sBAAAA,CAAgBjB,OAAAA,CAAQD,EAAE,CAAA,CAAEe,UAAUE,EAAE,CAAA;AAC5CE,oBAAAA,IAAAA,EAAMD,sBAAAA,CAAgBjB,OAAAA,CAAQD,EAAE,CAAA,CAAEe,UAAUI,IAAI;iBAClD,CAAA;AACJ,KAAA,CAAA;IAEA,OAAO;AACL,QAAA,MAAMC,UAASL,SAAoB,EAAA;AACjCb,YAAAA,UAAAA,CAAWmB,IAAI,CAACN,SAAAA,CAAAA;AAClB,QAAA,CAAA;QACA,MAAMO,SAAAA,CAAAA,GAAAA;YACJ,MAAMC,iBAAAA,GAAoB,MAAMnB,QAAAA,CAAOoB,OAAO,EAAA;YAC9C,OAAOD,iBAAAA,CAAkBE,MAAM,GAAG,CAAA;AACpC,QAAA,CAAA;QACA,MAAMR,EAAAA,CAAAA,GAAAA;AACJ,YAAA,MAAMb,SAAOa,EAAE,EAAA;AACjB,QAAA,CAAA;QACA,MAAME,IAAAA,CAAAA,GAAAA;AACJ,YAAA,MAAMf,SAAOe,IAAI,EAAA;AACnB,QAAA;AACF,KAAA;AACF;;;;"}
1
+ {"version":3,"file":"internal.js","sources":["../../src/migrations/internal.ts"],"sourcesContent":["import { wrapTransaction } from './common';\nimport { createMigrationRunner } from './runner';\nimport { internalMigrations } from './internal-migrations';\nimport { createStorage } from './storage';\nimport { transformLogMessage } from './logger';\n\nimport type { InternalMigrationProvider, Migration } from './common';\nimport type { Database } from '..';\n\nexport const createInternalMigrationProvider = (db: Database): InternalMigrationProvider => {\n const context = { db };\n const migrations: Migration[] = [...internalMigrations];\n\n const runner = createMigrationRunner({\n storage: createStorage({ db, tableName: 'strapi_migrations_internal' }),\n withPhase: (phase, fn) => db.runInPhase(phase, fn),\n logger: {\n info(message) {\n db.logger.info(transformLogMessage('info', message));\n },\n },\n getMigrations: async () =>\n migrations.map((migration) => ({\n name: migration.name,\n up: wrapTransaction(context.db)(migration.up),\n down: wrapTransaction(context.db)(migration.down),\n })),\n });\n\n return {\n async register(migration: Migration) {\n migrations.push(migration);\n },\n async shouldRun() {\n const pendingMigrations = await runner.pending();\n return pendingMigrations.length > 0;\n },\n async up() {\n await runner.up();\n },\n async down() {\n await runner.down();\n },\n };\n};\n"],"names":["createInternalMigrationProvider","db","context","migrations","internalMigrations","runner","createMigrationRunner","storage","createStorage","tableName","withPhase","phase","fn","runInPhase","logger","info","message","transformLogMessage","getMigrations","map","migration","name","up","wrapTransaction","down","register","push","shouldRun","pendingMigrations","pending","length"],"mappings":";;;;;;;;AASO,MAAMA,kCAAkC,CAACC,EAAAA,GAAAA;AAC9C,IAAA,MAAMC,OAAAA,GAAU;AAAED,QAAAA;AAAG,KAAA;AACrB,IAAA,MAAME,UAAAA,GAA0B;AAAIC,QAAAA,GAAAA;AAAmB,KAAA;AAEvD,IAAA,MAAMC,WAASC,4BAAAA,CAAsB;AACnCC,QAAAA,OAAAA,EAASC,qBAAAA,CAAc;AAAEP,YAAAA,EAAAA;YAAIQ,SAAAA,EAAW;AAA6B,SAAA,CAAA;AACrEC,QAAAA,SAAAA,EAAW,CAACC,KAAAA,EAAOC,EAAAA,GAAOX,EAAAA,CAAGY,UAAU,CAACF,KAAAA,EAAOC,EAAAA,CAAAA;QAC/CE,MAAAA,EAAQ;AACNC,YAAAA,IAAAA,CAAAA,CAAKC,OAAO,EAAA;AACVf,gBAAAA,EAAAA,CAAGa,MAAM,CAACC,IAAI,CAACE,2BAAoB,MAAA,EAAQD,OAAAA,CAAAA,CAAAA;AAC7C,YAAA;AACF,SAAA;AACAE,QAAAA,aAAAA,EAAe,UACbf,UAAAA,CAAWgB,GAAG,CAAC,CAACC,aAAe;AAC7BC,oBAAAA,IAAAA,EAAMD,UAAUC,IAAI;AACpBC,oBAAAA,EAAAA,EAAIC,sBAAAA,CAAgBrB,OAAAA,CAAQD,EAAE,CAAA,CAAEmB,UAAUE,EAAE,CAAA;AAC5CE,oBAAAA,IAAAA,EAAMD,sBAAAA,CAAgBrB,OAAAA,CAAQD,EAAE,CAAA,CAAEmB,UAAUI,IAAI;iBAClD,CAAA;AACJ,KAAA,CAAA;IAEA,OAAO;AACL,QAAA,MAAMC,UAASL,SAAoB,EAAA;AACjCjB,YAAAA,UAAAA,CAAWuB,IAAI,CAACN,SAAAA,CAAAA;AAClB,QAAA,CAAA;QACA,MAAMO,SAAAA,CAAAA,GAAAA;YACJ,MAAMC,iBAAAA,GAAoB,MAAMvB,QAAAA,CAAOwB,OAAO,EAAA;YAC9C,OAAOD,iBAAAA,CAAkBE,MAAM,GAAG,CAAA;AACpC,QAAA,CAAA;QACA,MAAMR,EAAAA,CAAAA,GAAAA;AACJ,YAAA,MAAMjB,SAAOiB,EAAE,EAAA;AACjB,QAAA,CAAA;QACA,MAAME,IAAAA,CAAAA,GAAAA;AACJ,YAAA,MAAMnB,SAAOmB,IAAI,EAAA;AACnB,QAAA;AACF,KAAA;AACF;;;;"}
@@ -16,6 +16,7 @@ const createInternalMigrationProvider = (db)=>{
16
16
  db,
17
17
  tableName: 'strapi_migrations_internal'
18
18
  }),
19
+ withPhase: (phase, fn)=>db.runInPhase(phase, fn),
19
20
  logger: {
20
21
  info (message) {
21
22
  db.logger.info(transformLogMessage('info', message));
@@ -1 +1 @@
1
- {"version":3,"file":"internal.mjs","sources":["../../src/migrations/internal.ts"],"sourcesContent":["import { wrapTransaction } from './common';\nimport { createMigrationRunner } from './runner';\nimport { internalMigrations } from './internal-migrations';\nimport { createStorage } from './storage';\nimport { transformLogMessage } from './logger';\n\nimport type { InternalMigrationProvider, Migration } from './common';\nimport type { Database } from '..';\n\nexport const createInternalMigrationProvider = (db: Database): InternalMigrationProvider => {\n const context = { db };\n const migrations: Migration[] = [...internalMigrations];\n\n const runner = createMigrationRunner({\n storage: createStorage({ db, tableName: 'strapi_migrations_internal' }),\n logger: {\n info(message) {\n db.logger.info(transformLogMessage('info', message));\n },\n },\n getMigrations: async () =>\n migrations.map((migration) => ({\n name: migration.name,\n up: wrapTransaction(context.db)(migration.up),\n down: wrapTransaction(context.db)(migration.down),\n })),\n });\n\n return {\n async register(migration: Migration) {\n migrations.push(migration);\n },\n async shouldRun() {\n const pendingMigrations = await runner.pending();\n return pendingMigrations.length > 0;\n },\n async up() {\n await runner.up();\n },\n async down() {\n await runner.down();\n },\n };\n};\n"],"names":["createInternalMigrationProvider","db","context","migrations","internalMigrations","runner","createMigrationRunner","storage","createStorage","tableName","logger","info","message","transformLogMessage","getMigrations","map","migration","name","up","wrapTransaction","down","register","push","shouldRun","pendingMigrations","pending","length"],"mappings":";;;;;;AASO,MAAMA,kCAAkC,CAACC,EAAAA,GAAAA;AAC9C,IAAA,MAAMC,OAAAA,GAAU;AAAED,QAAAA;AAAG,KAAA;AACrB,IAAA,MAAME,UAAAA,GAA0B;AAAIC,QAAAA,GAAAA;AAAmB,KAAA;AAEvD,IAAA,MAAMC,SAASC,qBAAAA,CAAsB;AACnCC,QAAAA,OAAAA,EAASC,aAAAA,CAAc;AAAEP,YAAAA,EAAAA;YAAIQ,SAAAA,EAAW;AAA6B,SAAA,CAAA;QACrEC,MAAAA,EAAQ;AACNC,YAAAA,IAAAA,CAAAA,CAAKC,OAAO,EAAA;AACVX,gBAAAA,EAAAA,CAAGS,MAAM,CAACC,IAAI,CAACE,oBAAoB,MAAA,EAAQD,OAAAA,CAAAA,CAAAA;AAC7C,YAAA;AACF,SAAA;AACAE,QAAAA,aAAAA,EAAe,UACbX,UAAAA,CAAWY,GAAG,CAAC,CAACC,aAAe;AAC7BC,oBAAAA,IAAAA,EAAMD,UAAUC,IAAI;AACpBC,oBAAAA,EAAAA,EAAIC,eAAAA,CAAgBjB,OAAAA,CAAQD,EAAE,CAAA,CAAEe,UAAUE,EAAE,CAAA;AAC5CE,oBAAAA,IAAAA,EAAMD,eAAAA,CAAgBjB,OAAAA,CAAQD,EAAE,CAAA,CAAEe,UAAUI,IAAI;iBAClD,CAAA;AACJ,KAAA,CAAA;IAEA,OAAO;AACL,QAAA,MAAMC,UAASL,SAAoB,EAAA;AACjCb,YAAAA,UAAAA,CAAWmB,IAAI,CAACN,SAAAA,CAAAA;AAClB,QAAA,CAAA;QACA,MAAMO,SAAAA,CAAAA,GAAAA;YACJ,MAAMC,iBAAAA,GAAoB,MAAMnB,MAAAA,CAAOoB,OAAO,EAAA;YAC9C,OAAOD,iBAAAA,CAAkBE,MAAM,GAAG,CAAA;AACpC,QAAA,CAAA;QACA,MAAMR,EAAAA,CAAAA,GAAAA;AACJ,YAAA,MAAMb,OAAOa,EAAE,EAAA;AACjB,QAAA,CAAA;QACA,MAAME,IAAAA,CAAAA,GAAAA;AACJ,YAAA,MAAMf,OAAOe,IAAI,EAAA;AACnB,QAAA;AACF,KAAA;AACF;;;;"}
1
+ {"version":3,"file":"internal.mjs","sources":["../../src/migrations/internal.ts"],"sourcesContent":["import { wrapTransaction } from './common';\nimport { createMigrationRunner } from './runner';\nimport { internalMigrations } from './internal-migrations';\nimport { createStorage } from './storage';\nimport { transformLogMessage } from './logger';\n\nimport type { InternalMigrationProvider, Migration } from './common';\nimport type { Database } from '..';\n\nexport const createInternalMigrationProvider = (db: Database): InternalMigrationProvider => {\n const context = { db };\n const migrations: Migration[] = [...internalMigrations];\n\n const runner = createMigrationRunner({\n storage: createStorage({ db, tableName: 'strapi_migrations_internal' }),\n withPhase: (phase, fn) => db.runInPhase(phase, fn),\n logger: {\n info(message) {\n db.logger.info(transformLogMessage('info', message));\n },\n },\n getMigrations: async () =>\n migrations.map((migration) => ({\n name: migration.name,\n up: wrapTransaction(context.db)(migration.up),\n down: wrapTransaction(context.db)(migration.down),\n })),\n });\n\n return {\n async register(migration: Migration) {\n migrations.push(migration);\n },\n async shouldRun() {\n const pendingMigrations = await runner.pending();\n return pendingMigrations.length > 0;\n },\n async up() {\n await runner.up();\n },\n async down() {\n await runner.down();\n },\n };\n};\n"],"names":["createInternalMigrationProvider","db","context","migrations","internalMigrations","runner","createMigrationRunner","storage","createStorage","tableName","withPhase","phase","fn","runInPhase","logger","info","message","transformLogMessage","getMigrations","map","migration","name","up","wrapTransaction","down","register","push","shouldRun","pendingMigrations","pending","length"],"mappings":";;;;;;AASO,MAAMA,kCAAkC,CAACC,EAAAA,GAAAA;AAC9C,IAAA,MAAMC,OAAAA,GAAU;AAAED,QAAAA;AAAG,KAAA;AACrB,IAAA,MAAME,UAAAA,GAA0B;AAAIC,QAAAA,GAAAA;AAAmB,KAAA;AAEvD,IAAA,MAAMC,SAASC,qBAAAA,CAAsB;AACnCC,QAAAA,OAAAA,EAASC,aAAAA,CAAc;AAAEP,YAAAA,EAAAA;YAAIQ,SAAAA,EAAW;AAA6B,SAAA,CAAA;AACrEC,QAAAA,SAAAA,EAAW,CAACC,KAAAA,EAAOC,EAAAA,GAAOX,EAAAA,CAAGY,UAAU,CAACF,KAAAA,EAAOC,EAAAA,CAAAA;QAC/CE,MAAAA,EAAQ;AACNC,YAAAA,IAAAA,CAAAA,CAAKC,OAAO,EAAA;AACVf,gBAAAA,EAAAA,CAAGa,MAAM,CAACC,IAAI,CAACE,oBAAoB,MAAA,EAAQD,OAAAA,CAAAA,CAAAA;AAC7C,YAAA;AACF,SAAA;AACAE,QAAAA,aAAAA,EAAe,UACbf,UAAAA,CAAWgB,GAAG,CAAC,CAACC,aAAe;AAC7BC,oBAAAA,IAAAA,EAAMD,UAAUC,IAAI;AACpBC,oBAAAA,EAAAA,EAAIC,eAAAA,CAAgBrB,OAAAA,CAAQD,EAAE,CAAA,CAAEmB,UAAUE,EAAE,CAAA;AAC5CE,oBAAAA,IAAAA,EAAMD,eAAAA,CAAgBrB,OAAAA,CAAQD,EAAE,CAAA,CAAEmB,UAAUI,IAAI;iBAClD,CAAA;AACJ,KAAA,CAAA;IAEA,OAAO;AACL,QAAA,MAAMC,UAASL,SAAoB,EAAA;AACjCjB,YAAAA,UAAAA,CAAWuB,IAAI,CAACN,SAAAA,CAAAA;AAClB,QAAA,CAAA;QACA,MAAMO,SAAAA,CAAAA,GAAAA;YACJ,MAAMC,iBAAAA,GAAoB,MAAMvB,MAAAA,CAAOwB,OAAO,EAAA;YAC9C,OAAOD,iBAAAA,CAAkBE,MAAM,GAAG,CAAA;AACpC,QAAA,CAAA;QACA,MAAMR,EAAAA,CAAAA,GAAAA;AACJ,YAAA,MAAMjB,OAAOiB,EAAE,EAAA;AACjB,QAAA,CAAA;QACA,MAAME,IAAAA,CAAAA,GAAAA;AACJ,YAAA,MAAMnB,OAAOmB,IAAI,EAAA;AACnB,QAAA;AACF,KAAA;AACF;;;;"}
@@ -15,6 +15,8 @@ export interface MigrationRunnerOptions {
15
15
  storage: ReturnType<typeof createStorage>;
16
16
  logger: MigrationRunnerLogger;
17
17
  getMigrations: () => Promise<RunnableMigration[]>;
18
+ /** Labels pool timeout reports with the running migration's name. */
19
+ withPhase?: <T>(phase: string, fn: () => Promise<T>) => Promise<T>;
18
20
  }
19
21
  export declare const createMigrationRunner: (opts: MigrationRunnerOptions) => {
20
22
  pending(): Promise<MigrationMeta[]>;
@@ -1 +1 @@
1
- {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/migrations/runner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE/C,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,iBAAkB,SAAQ,aAAa;IACtD,EAAE,EAAE,iBAAiB,CAAC;IACtB,IAAI,EAAE,iBAAiB,CAAC;CACzB;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;IAC1C,MAAM,EAAE,qBAAqB,CAAC;IAC9B,aAAa,EAAE,MAAM,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;CACnD;AAoBD,eAAO,MAAM,qBAAqB,GAAI,MAAM,sBAAsB;eAsB7C,OAAO,CAAC,aAAa,EAAE,CAAC;UAK7B,OAAO,CAAC,aAAa,EAAE,CAAC;YAuBtB,OAAO,CAAC,aAAa,EAAE,CAAC;CAwBzC,CAAC"}
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/migrations/runner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE/C,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,iBAAkB,SAAQ,aAAa;IACtD,EAAE,EAAE,iBAAiB,CAAC;IACtB,IAAI,EAAE,iBAAiB,CAAC;CACzB;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;IAC1C,MAAM,EAAE,qBAAqB,CAAC;IAC9B,aAAa,EAAE,MAAM,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;IAClD,qEAAqE;IACrE,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;CACpE;AAoBD,eAAO,MAAM,qBAAqB,GAAI,MAAM,sBAAsB;eAyB7C,OAAO,CAAC,aAAa,EAAE,CAAC;UAK7B,OAAO,CAAC,aAAa,EAAE,CAAC;YAyBtB,OAAO,CAAC,aAAa,EAAE,CAAC;CA0BzC,CAAC"}
@@ -14,6 +14,7 @@ const wrapMigrationError = (name, direction, cause)=>{
14
14
  });
15
15
  };
16
16
  const createMigrationRunner = (opts)=>{
17
+ const withPhase = opts.withPhase ?? ((_phase, fn)=>fn());
17
18
  const getPendingMigrations = async ()=>{
18
19
  const [migrations, executedNames] = await Promise.all([
19
20
  opts.getMigrations(),
@@ -44,7 +45,9 @@ const createMigrationRunner = (opts)=>{
44
45
  const start = Date.now();
45
46
  logEvent(opts.logger, 'migrating', migration.name);
46
47
  try {
47
- await migration.up();
48
+ await withPhase(`migration ${migration.name}`, async ()=>{
49
+ await migration.up();
50
+ });
48
51
  } catch (error) {
49
52
  throw wrapMigrationError(migration.name, 'up', error);
50
53
  }
@@ -68,7 +71,9 @@ const createMigrationRunner = (opts)=>{
68
71
  const start = Date.now();
69
72
  logEvent(opts.logger, 'reverting', migration.name);
70
73
  try {
71
- await migration.down();
74
+ await withPhase(`migration ${migration.name}`, async ()=>{
75
+ await migration.down();
76
+ });
72
77
  } catch (error) {
73
78
  throw wrapMigrationError(migration.name, 'down', error);
74
79
  }
@@ -1 +1 @@
1
- {"version":3,"file":"runner.js","sources":["../../src/migrations/runner.ts"],"sourcesContent":["import type { MigrationRunnerFn } from './common';\nimport type { createStorage } from './storage';\n\nexport interface MigrationMeta {\n name: string;\n path?: string;\n}\n\nexport interface RunnableMigration extends MigrationMeta {\n up: MigrationRunnerFn;\n down: MigrationRunnerFn;\n}\n\nexport interface MigrationRunnerLogger {\n info(message: unknown): void;\n}\n\nexport interface MigrationRunnerOptions {\n storage: ReturnType<typeof createStorage>;\n logger: MigrationRunnerLogger;\n getMigrations: () => Promise<RunnableMigration[]>;\n}\n\nconst logEvent = (\n logger: MigrationRunnerLogger,\n event: string,\n name: string,\n extra?: Record<string, unknown>\n) => {\n logger.info({ event, name, ...extra });\n};\n\nconst wrapMigrationError = (name: string, direction: 'up' | 'down', cause: unknown): Error => {\n const causeMessage =\n cause instanceof Error\n ? `Original error: ${cause.message}`\n : `Non-error value thrown. See cause for full value: ${String(cause)}`;\n\n return new Error(`Migration ${name} (${direction}) failed: ${causeMessage}`, { cause });\n};\n\nexport const createMigrationRunner = (opts: MigrationRunnerOptions) => {\n const getPendingMigrations = async (): Promise<RunnableMigration[]> => {\n const [migrations, executedNames] = await Promise.all([\n opts.getMigrations(),\n opts.storage.executed(),\n ]);\n\n const executedSet = new Set(executedNames);\n return migrations.filter((migration) => !executedSet.has(migration.name));\n };\n\n const getExecutedMigrations = async (): Promise<RunnableMigration[]> => {\n const [migrations, executedNames] = await Promise.all([\n opts.getMigrations(),\n opts.storage.executed(),\n ]);\n\n const executedSet = new Set(executedNames);\n return migrations.filter((migration) => executedSet.has(migration.name));\n };\n\n return {\n async pending(): Promise<MigrationMeta[]> {\n const pending = await getPendingMigrations();\n return pending.map(({ name, path }) => ({ name, path }));\n },\n\n async up(): Promise<MigrationMeta[]> {\n const toBeApplied = await getPendingMigrations();\n\n for (const migration of toBeApplied) {\n const start = Date.now();\n\n logEvent(opts.logger, 'migrating', migration.name);\n\n try {\n await migration.up();\n } catch (error) {\n throw wrapMigrationError(migration.name, 'up', error);\n }\n\n await opts.storage.logMigration({ name: migration.name });\n\n const durationSeconds = (Date.now() - start) / 1000;\n logEvent(opts.logger, 'migrated', migration.name, { durationSeconds });\n }\n\n return toBeApplied.map(({ name, path }) => ({ name, path }));\n },\n\n async down(): Promise<MigrationMeta[]> {\n const executedReversed = (await getExecutedMigrations()).slice().reverse();\n const toBeReverted = executedReversed.slice(0, 1);\n\n for (const migration of toBeReverted) {\n const start = Date.now();\n\n logEvent(opts.logger, 'reverting', migration.name);\n\n try {\n await migration.down();\n } catch (error) {\n throw wrapMigrationError(migration.name, 'down', error);\n }\n\n await opts.storage.unlogMigration({ name: migration.name });\n\n const durationSeconds = Number.parseFloat(((Date.now() - start) / 1000).toFixed(3));\n logEvent(opts.logger, 'reverted', migration.name, { durationSeconds });\n }\n\n return toBeReverted.map(({ name, path }) => ({ name, path }));\n },\n };\n};\n"],"names":["logEvent","logger","event","name","extra","info","wrapMigrationError","direction","cause","causeMessage","Error","message","String","createMigrationRunner","opts","getPendingMigrations","migrations","executedNames","Promise","all","getMigrations","storage","executed","executedSet","Set","filter","migration","has","getExecutedMigrations","pending","map","path","up","toBeApplied","start","Date","now","error","logMigration","durationSeconds","down","executedReversed","slice","reverse","toBeReverted","unlogMigration","Number","parseFloat","toFixed"],"mappings":"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"}
1
+ {"version":3,"file":"runner.js","sources":["../../src/migrations/runner.ts"],"sourcesContent":["import type { MigrationRunnerFn } from './common';\nimport type { createStorage } from './storage';\n\nexport interface MigrationMeta {\n name: string;\n path?: string;\n}\n\nexport interface RunnableMigration extends MigrationMeta {\n up: MigrationRunnerFn;\n down: MigrationRunnerFn;\n}\n\nexport interface MigrationRunnerLogger {\n info(message: unknown): void;\n}\n\nexport interface MigrationRunnerOptions {\n storage: ReturnType<typeof createStorage>;\n logger: MigrationRunnerLogger;\n getMigrations: () => Promise<RunnableMigration[]>;\n /** Labels pool timeout reports with the running migration's name. */\n withPhase?: <T>(phase: string, fn: () => Promise<T>) => Promise<T>;\n}\n\nconst logEvent = (\n logger: MigrationRunnerLogger,\n event: string,\n name: string,\n extra?: Record<string, unknown>\n) => {\n logger.info({ event, name, ...extra });\n};\n\nconst wrapMigrationError = (name: string, direction: 'up' | 'down', cause: unknown): Error => {\n const causeMessage =\n cause instanceof Error\n ? `Original error: ${cause.message}`\n : `Non-error value thrown. See cause for full value: ${String(cause)}`;\n\n return new Error(`Migration ${name} (${direction}) failed: ${causeMessage}`, { cause });\n};\n\nexport const createMigrationRunner = (opts: MigrationRunnerOptions) => {\n const withPhase =\n opts.withPhase ?? (<T>(_phase: string, fn: () => Promise<T>): Promise<T> => fn());\n\n const getPendingMigrations = async (): Promise<RunnableMigration[]> => {\n const [migrations, executedNames] = await Promise.all([\n opts.getMigrations(),\n opts.storage.executed(),\n ]);\n\n const executedSet = new Set(executedNames);\n return migrations.filter((migration) => !executedSet.has(migration.name));\n };\n\n const getExecutedMigrations = async (): Promise<RunnableMigration[]> => {\n const [migrations, executedNames] = await Promise.all([\n opts.getMigrations(),\n opts.storage.executed(),\n ]);\n\n const executedSet = new Set(executedNames);\n return migrations.filter((migration) => executedSet.has(migration.name));\n };\n\n return {\n async pending(): Promise<MigrationMeta[]> {\n const pending = await getPendingMigrations();\n return pending.map(({ name, path }) => ({ name, path }));\n },\n\n async up(): Promise<MigrationMeta[]> {\n const toBeApplied = await getPendingMigrations();\n\n for (const migration of toBeApplied) {\n const start = Date.now();\n\n logEvent(opts.logger, 'migrating', migration.name);\n\n try {\n await withPhase(`migration ${migration.name}`, async () => {\n await migration.up();\n });\n } catch (error) {\n throw wrapMigrationError(migration.name, 'up', error);\n }\n\n await opts.storage.logMigration({ name: migration.name });\n\n const durationSeconds = (Date.now() - start) / 1000;\n logEvent(opts.logger, 'migrated', migration.name, { durationSeconds });\n }\n\n return toBeApplied.map(({ name, path }) => ({ name, path }));\n },\n\n async down(): Promise<MigrationMeta[]> {\n const executedReversed = (await getExecutedMigrations()).slice().reverse();\n const toBeReverted = executedReversed.slice(0, 1);\n\n for (const migration of toBeReverted) {\n const start = Date.now();\n\n logEvent(opts.logger, 'reverting', migration.name);\n\n try {\n await withPhase(`migration ${migration.name}`, async () => {\n await migration.down();\n });\n } catch (error) {\n throw wrapMigrationError(migration.name, 'down', error);\n }\n\n await opts.storage.unlogMigration({ name: migration.name });\n\n const durationSeconds = Number.parseFloat(((Date.now() - start) / 1000).toFixed(3));\n logEvent(opts.logger, 'reverted', migration.name, { durationSeconds });\n }\n\n return toBeReverted.map(({ name, path }) => ({ name, path }));\n },\n };\n};\n"],"names":["logEvent","logger","event","name","extra","info","wrapMigrationError","direction","cause","causeMessage","Error","message","String","createMigrationRunner","opts","withPhase","_phase","fn","getPendingMigrations","migrations","executedNames","Promise","all","getMigrations","storage","executed","executedSet","Set","filter","migration","has","getExecutedMigrations","pending","map","path","up","toBeApplied","start","Date","now","error","logMigration","durationSeconds","down","executedReversed","slice","reverse","toBeReverted","unlogMigration","Number","parseFloat","toFixed"],"mappings":";;AAyBA,MAAMA,QAAAA,GAAW,CACfC,MAAAA,EACAC,KAAAA,EACAC,IAAAA,EACAC,KAAAA,GAAAA;AAEAH,IAAAA,MAAAA,CAAOI,IAAI,CAAC;AAAEH,QAAAA,KAAAA;AAAOC,QAAAA,IAAAA;AAAM,QAAA,GAAGC;AAAM,KAAA,CAAA;AACtC,CAAA;AAEA,MAAME,kBAAAA,GAAqB,CAACH,IAAAA,EAAcI,SAAAA,EAA0BC,KAAAA,GAAAA;AAClE,IAAA,MAAMC,YAAAA,GACJD,KAAAA,YAAiBE,KAAAA,GACb,CAAC,gBAAgB,EAAEF,KAAAA,CAAMG,OAAO,CAAA,CAAE,GAClC,CAAC,kDAAkD,EAAEC,OAAOJ,KAAAA,CAAAA,CAAAA,CAAQ;AAE1E,IAAA,OAAO,IAAIE,KAAAA,CAAM,CAAC,UAAU,EAAEP,IAAAA,CAAK,EAAE,EAAEI,SAAAA,CAAU,UAAU,EAAEE,YAAAA,CAAAA,CAAc,EAAE;AAAED,QAAAA;AAAM,KAAA,CAAA;AACvF,CAAA;AAEO,MAAMK,wBAAwB,CAACC,IAAAA,GAAAA;IACpC,MAAMC,SAAAA,GACJD,KAAKC,SAAS,KAAK,CAAIC,MAAAA,EAAgBC,KAAqCA,EAAAA,EAAG,CAAA;AAEjF,IAAA,MAAMC,oBAAAA,GAAuB,UAAA;AAC3B,QAAA,MAAM,CAACC,UAAAA,EAAYC,aAAAA,CAAc,GAAG,MAAMC,OAAAA,CAAQC,GAAG,CAAC;AACpDR,YAAAA,IAAAA,CAAKS,aAAa,EAAA;YAClBT,IAAAA,CAAKU,OAAO,CAACC,QAAQ;AACtB,SAAA,CAAA;QAED,MAAMC,WAAAA,GAAc,IAAIC,GAAAA,CAAIP,aAAAA,CAAAA;QAC5B,OAAOD,UAAAA,CAAWS,MAAM,CAAC,CAACC,SAAAA,GAAc,CAACH,WAAAA,CAAYI,GAAG,CAACD,SAAAA,CAAU1B,IAAI,CAAA,CAAA;AACzE,IAAA,CAAA;AAEA,IAAA,MAAM4B,qBAAAA,GAAwB,UAAA;AAC5B,QAAA,MAAM,CAACZ,UAAAA,EAAYC,aAAAA,CAAc,GAAG,MAAMC,OAAAA,CAAQC,GAAG,CAAC;AACpDR,YAAAA,IAAAA,CAAKS,aAAa,EAAA;YAClBT,IAAAA,CAAKU,OAAO,CAACC,QAAQ;AACtB,SAAA,CAAA;QAED,MAAMC,WAAAA,GAAc,IAAIC,GAAAA,CAAIP,aAAAA,CAAAA;QAC5B,OAAOD,UAAAA,CAAWS,MAAM,CAAC,CAACC,YAAcH,WAAAA,CAAYI,GAAG,CAACD,SAAAA,CAAU1B,IAAI,CAAA,CAAA;AACxE,IAAA,CAAA;IAEA,OAAO;QACL,MAAM6B,OAAAA,CAAAA,GAAAA;AACJ,YAAA,MAAMA,UAAU,MAAMd,oBAAAA,EAAAA;YACtB,OAAOc,OAAAA,CAAQC,GAAG,CAAC,CAAC,EAAE9B,IAAI,EAAE+B,IAAI,EAAE,IAAM;AAAE/B,oBAAAA,IAAAA;AAAM+B,oBAAAA;iBAAK,CAAA,CAAA;AACvD,QAAA,CAAA;QAEA,MAAMC,EAAAA,CAAAA,GAAAA;AACJ,YAAA,MAAMC,cAAc,MAAMlB,oBAAAA,EAAAA;YAE1B,KAAK,MAAMW,aAAaO,WAAAA,CAAa;gBACnC,MAAMC,KAAAA,GAAQC,KAAKC,GAAG,EAAA;AAEtBvC,gBAAAA,QAAAA,CAASc,IAAAA,CAAKb,MAAM,EAAE,WAAA,EAAa4B,UAAU1B,IAAI,CAAA;gBAEjD,IAAI;AACF,oBAAA,MAAMY,UAAU,CAAC,UAAU,EAAEc,SAAAA,CAAU1B,IAAI,EAAE,EAAE,UAAA;AAC7C,wBAAA,MAAM0B,UAAUM,EAAE,EAAA;AACpB,oBAAA,CAAA,CAAA;AACF,gBAAA,CAAA,CAAE,OAAOK,KAAAA,EAAO;AACd,oBAAA,MAAMlC,kBAAAA,CAAmBuB,SAAAA,CAAU1B,IAAI,EAAE,IAAA,EAAMqC,KAAAA,CAAAA;AACjD,gBAAA;AAEA,gBAAA,MAAM1B,IAAAA,CAAKU,OAAO,CAACiB,YAAY,CAAC;AAAEtC,oBAAAA,IAAAA,EAAM0B,UAAU1B;AAAK,iBAAA,CAAA;AAEvD,gBAAA,MAAMuC,kBAAkB,CAACJ,KAAKC,GAAG,EAAA,GAAKF,KAAI,IAAK,IAAA;AAC/CrC,gBAAAA,QAAAA,CAASc,KAAKb,MAAM,EAAE,UAAA,EAAY4B,SAAAA,CAAU1B,IAAI,EAAE;AAAEuC,oBAAAA;AAAgB,iBAAA,CAAA;AACtE,YAAA;YAEA,OAAON,WAAAA,CAAYH,GAAG,CAAC,CAAC,EAAE9B,IAAI,EAAE+B,IAAI,EAAE,IAAM;AAAE/B,oBAAAA,IAAAA;AAAM+B,oBAAAA;iBAAK,CAAA,CAAA;AAC3D,QAAA,CAAA;QAEA,MAAMS,IAAAA,CAAAA,GAAAA;YACJ,MAAMC,gBAAAA,GAAmB,CAAC,MAAMb,uBAAsB,EAAGc,KAAK,GAAGC,OAAO,EAAA;AACxE,YAAA,MAAMC,YAAAA,GAAeH,gBAAAA,CAAiBC,KAAK,CAAC,CAAA,EAAG,CAAA,CAAA;YAE/C,KAAK,MAAMhB,aAAakB,YAAAA,CAAc;gBACpC,MAAMV,KAAAA,GAAQC,KAAKC,GAAG,EAAA;AAEtBvC,gBAAAA,QAAAA,CAASc,IAAAA,CAAKb,MAAM,EAAE,WAAA,EAAa4B,UAAU1B,IAAI,CAAA;gBAEjD,IAAI;AACF,oBAAA,MAAMY,UAAU,CAAC,UAAU,EAAEc,SAAAA,CAAU1B,IAAI,EAAE,EAAE,UAAA;AAC7C,wBAAA,MAAM0B,UAAUc,IAAI,EAAA;AACtB,oBAAA,CAAA,CAAA;AACF,gBAAA,CAAA,CAAE,OAAOH,KAAAA,EAAO;AACd,oBAAA,MAAMlC,kBAAAA,CAAmBuB,SAAAA,CAAU1B,IAAI,EAAE,MAAA,EAAQqC,KAAAA,CAAAA;AACnD,gBAAA;AAEA,gBAAA,MAAM1B,IAAAA,CAAKU,OAAO,CAACwB,cAAc,CAAC;AAAE7C,oBAAAA,IAAAA,EAAM0B,UAAU1B;AAAK,iBAAA,CAAA;AAEzD,gBAAA,MAAMuC,kBAAkBO,MAAAA,CAAOC,UAAU,CAAE,CAAA,CAACZ,IAAAA,CAAKC,GAAG,KAAKF,KAAI,IAAK,IAAG,EAAGc,OAAO,CAAC,CAAA,CAAA,CAAA;AAChFnD,gBAAAA,QAAAA,CAASc,KAAKb,MAAM,EAAE,UAAA,EAAY4B,SAAAA,CAAU1B,IAAI,EAAE;AAAEuC,oBAAAA;AAAgB,iBAAA,CAAA;AACtE,YAAA;YAEA,OAAOK,YAAAA,CAAad,GAAG,CAAC,CAAC,EAAE9B,IAAI,EAAE+B,IAAI,EAAE,IAAM;AAAE/B,oBAAAA,IAAAA;AAAM+B,oBAAAA;iBAAK,CAAA,CAAA;AAC5D,QAAA;AACF,KAAA;AACF;;;;"}
@@ -12,6 +12,7 @@ const wrapMigrationError = (name, direction, cause)=>{
12
12
  });
13
13
  };
14
14
  const createMigrationRunner = (opts)=>{
15
+ const withPhase = opts.withPhase ?? ((_phase, fn)=>fn());
15
16
  const getPendingMigrations = async ()=>{
16
17
  const [migrations, executedNames] = await Promise.all([
17
18
  opts.getMigrations(),
@@ -42,7 +43,9 @@ const createMigrationRunner = (opts)=>{
42
43
  const start = Date.now();
43
44
  logEvent(opts.logger, 'migrating', migration.name);
44
45
  try {
45
- await migration.up();
46
+ await withPhase(`migration ${migration.name}`, async ()=>{
47
+ await migration.up();
48
+ });
46
49
  } catch (error) {
47
50
  throw wrapMigrationError(migration.name, 'up', error);
48
51
  }
@@ -66,7 +69,9 @@ const createMigrationRunner = (opts)=>{
66
69
  const start = Date.now();
67
70
  logEvent(opts.logger, 'reverting', migration.name);
68
71
  try {
69
- await migration.down();
72
+ await withPhase(`migration ${migration.name}`, async ()=>{
73
+ await migration.down();
74
+ });
70
75
  } catch (error) {
71
76
  throw wrapMigrationError(migration.name, 'down', error);
72
77
  }
@@ -1 +1 @@
1
- {"version":3,"file":"runner.mjs","sources":["../../src/migrations/runner.ts"],"sourcesContent":["import type { MigrationRunnerFn } from './common';\nimport type { createStorage } from './storage';\n\nexport interface MigrationMeta {\n name: string;\n path?: string;\n}\n\nexport interface RunnableMigration extends MigrationMeta {\n up: MigrationRunnerFn;\n down: MigrationRunnerFn;\n}\n\nexport interface MigrationRunnerLogger {\n info(message: unknown): void;\n}\n\nexport interface MigrationRunnerOptions {\n storage: ReturnType<typeof createStorage>;\n logger: MigrationRunnerLogger;\n getMigrations: () => Promise<RunnableMigration[]>;\n}\n\nconst logEvent = (\n logger: MigrationRunnerLogger,\n event: string,\n name: string,\n extra?: Record<string, unknown>\n) => {\n logger.info({ event, name, ...extra });\n};\n\nconst wrapMigrationError = (name: string, direction: 'up' | 'down', cause: unknown): Error => {\n const causeMessage =\n cause instanceof Error\n ? `Original error: ${cause.message}`\n : `Non-error value thrown. See cause for full value: ${String(cause)}`;\n\n return new Error(`Migration ${name} (${direction}) failed: ${causeMessage}`, { cause });\n};\n\nexport const createMigrationRunner = (opts: MigrationRunnerOptions) => {\n const getPendingMigrations = async (): Promise<RunnableMigration[]> => {\n const [migrations, executedNames] = await Promise.all([\n opts.getMigrations(),\n opts.storage.executed(),\n ]);\n\n const executedSet = new Set(executedNames);\n return migrations.filter((migration) => !executedSet.has(migration.name));\n };\n\n const getExecutedMigrations = async (): Promise<RunnableMigration[]> => {\n const [migrations, executedNames] = await Promise.all([\n opts.getMigrations(),\n opts.storage.executed(),\n ]);\n\n const executedSet = new Set(executedNames);\n return migrations.filter((migration) => executedSet.has(migration.name));\n };\n\n return {\n async pending(): Promise<MigrationMeta[]> {\n const pending = await getPendingMigrations();\n return pending.map(({ name, path }) => ({ name, path }));\n },\n\n async up(): Promise<MigrationMeta[]> {\n const toBeApplied = await getPendingMigrations();\n\n for (const migration of toBeApplied) {\n const start = Date.now();\n\n logEvent(opts.logger, 'migrating', migration.name);\n\n try {\n await migration.up();\n } catch (error) {\n throw wrapMigrationError(migration.name, 'up', error);\n }\n\n await opts.storage.logMigration({ name: migration.name });\n\n const durationSeconds = (Date.now() - start) / 1000;\n logEvent(opts.logger, 'migrated', migration.name, { durationSeconds });\n }\n\n return toBeApplied.map(({ name, path }) => ({ name, path }));\n },\n\n async down(): Promise<MigrationMeta[]> {\n const executedReversed = (await getExecutedMigrations()).slice().reverse();\n const toBeReverted = executedReversed.slice(0, 1);\n\n for (const migration of toBeReverted) {\n const start = Date.now();\n\n logEvent(opts.logger, 'reverting', migration.name);\n\n try {\n await migration.down();\n } catch (error) {\n throw wrapMigrationError(migration.name, 'down', error);\n }\n\n await opts.storage.unlogMigration({ name: migration.name });\n\n const durationSeconds = Number.parseFloat(((Date.now() - start) / 1000).toFixed(3));\n logEvent(opts.logger, 'reverted', migration.name, { durationSeconds });\n }\n\n return toBeReverted.map(({ name, path }) => ({ name, path }));\n },\n };\n};\n"],"names":["logEvent","logger","event","name","extra","info","wrapMigrationError","direction","cause","causeMessage","Error","message","String","createMigrationRunner","opts","getPendingMigrations","migrations","executedNames","Promise","all","getMigrations","storage","executed","executedSet","Set","filter","migration","has","getExecutedMigrations","pending","map","path","up","toBeApplied","start","Date","now","error","logMigration","durationSeconds","down","executedReversed","slice","reverse","toBeReverted","unlogMigration","Number","parseFloat","toFixed"],"mappings":"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"}
1
+ {"version":3,"file":"runner.mjs","sources":["../../src/migrations/runner.ts"],"sourcesContent":["import type { MigrationRunnerFn } from './common';\nimport type { createStorage } from './storage';\n\nexport interface MigrationMeta {\n name: string;\n path?: string;\n}\n\nexport interface RunnableMigration extends MigrationMeta {\n up: MigrationRunnerFn;\n down: MigrationRunnerFn;\n}\n\nexport interface MigrationRunnerLogger {\n info(message: unknown): void;\n}\n\nexport interface MigrationRunnerOptions {\n storage: ReturnType<typeof createStorage>;\n logger: MigrationRunnerLogger;\n getMigrations: () => Promise<RunnableMigration[]>;\n /** Labels pool timeout reports with the running migration's name. */\n withPhase?: <T>(phase: string, fn: () => Promise<T>) => Promise<T>;\n}\n\nconst logEvent = (\n logger: MigrationRunnerLogger,\n event: string,\n name: string,\n extra?: Record<string, unknown>\n) => {\n logger.info({ event, name, ...extra });\n};\n\nconst wrapMigrationError = (name: string, direction: 'up' | 'down', cause: unknown): Error => {\n const causeMessage =\n cause instanceof Error\n ? `Original error: ${cause.message}`\n : `Non-error value thrown. See cause for full value: ${String(cause)}`;\n\n return new Error(`Migration ${name} (${direction}) failed: ${causeMessage}`, { cause });\n};\n\nexport const createMigrationRunner = (opts: MigrationRunnerOptions) => {\n const withPhase =\n opts.withPhase ?? (<T>(_phase: string, fn: () => Promise<T>): Promise<T> => fn());\n\n const getPendingMigrations = async (): Promise<RunnableMigration[]> => {\n const [migrations, executedNames] = await Promise.all([\n opts.getMigrations(),\n opts.storage.executed(),\n ]);\n\n const executedSet = new Set(executedNames);\n return migrations.filter((migration) => !executedSet.has(migration.name));\n };\n\n const getExecutedMigrations = async (): Promise<RunnableMigration[]> => {\n const [migrations, executedNames] = await Promise.all([\n opts.getMigrations(),\n opts.storage.executed(),\n ]);\n\n const executedSet = new Set(executedNames);\n return migrations.filter((migration) => executedSet.has(migration.name));\n };\n\n return {\n async pending(): Promise<MigrationMeta[]> {\n const pending = await getPendingMigrations();\n return pending.map(({ name, path }) => ({ name, path }));\n },\n\n async up(): Promise<MigrationMeta[]> {\n const toBeApplied = await getPendingMigrations();\n\n for (const migration of toBeApplied) {\n const start = Date.now();\n\n logEvent(opts.logger, 'migrating', migration.name);\n\n try {\n await withPhase(`migration ${migration.name}`, async () => {\n await migration.up();\n });\n } catch (error) {\n throw wrapMigrationError(migration.name, 'up', error);\n }\n\n await opts.storage.logMigration({ name: migration.name });\n\n const durationSeconds = (Date.now() - start) / 1000;\n logEvent(opts.logger, 'migrated', migration.name, { durationSeconds });\n }\n\n return toBeApplied.map(({ name, path }) => ({ name, path }));\n },\n\n async down(): Promise<MigrationMeta[]> {\n const executedReversed = (await getExecutedMigrations()).slice().reverse();\n const toBeReverted = executedReversed.slice(0, 1);\n\n for (const migration of toBeReverted) {\n const start = Date.now();\n\n logEvent(opts.logger, 'reverting', migration.name);\n\n try {\n await withPhase(`migration ${migration.name}`, async () => {\n await migration.down();\n });\n } catch (error) {\n throw wrapMigrationError(migration.name, 'down', error);\n }\n\n await opts.storage.unlogMigration({ name: migration.name });\n\n const durationSeconds = Number.parseFloat(((Date.now() - start) / 1000).toFixed(3));\n logEvent(opts.logger, 'reverted', migration.name, { durationSeconds });\n }\n\n return toBeReverted.map(({ name, path }) => ({ name, path }));\n },\n };\n};\n"],"names":["logEvent","logger","event","name","extra","info","wrapMigrationError","direction","cause","causeMessage","Error","message","String","createMigrationRunner","opts","withPhase","_phase","fn","getPendingMigrations","migrations","executedNames","Promise","all","getMigrations","storage","executed","executedSet","Set","filter","migration","has","getExecutedMigrations","pending","map","path","up","toBeApplied","start","Date","now","error","logMigration","durationSeconds","down","executedReversed","slice","reverse","toBeReverted","unlogMigration","Number","parseFloat","toFixed"],"mappings":"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"}