@cogenta/core 0.1.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 (193) hide show
  1. package/dist/cache/entry.d.ts +32 -0
  2. package/dist/cache/entry.d.ts.map +1 -0
  3. package/dist/cache/entry.js +72 -0
  4. package/dist/cache/entry.js.map +1 -0
  5. package/dist/cache/file.d.ts +16 -0
  6. package/dist/cache/file.d.ts.map +1 -0
  7. package/dist/cache/file.js +191 -0
  8. package/dist/cache/file.js.map +1 -0
  9. package/dist/cache/index.d.ts +20 -0
  10. package/dist/cache/index.d.ts.map +1 -0
  11. package/dist/cache/index.js +25 -0
  12. package/dist/cache/index.js.map +1 -0
  13. package/dist/cache/memory.d.ts +11 -0
  14. package/dist/cache/memory.d.ts.map +1 -0
  15. package/dist/cache/memory.js +89 -0
  16. package/dist/cache/memory.js.map +1 -0
  17. package/dist/cache/redis.d.ts +54 -0
  18. package/dist/cache/redis.d.ts.map +1 -0
  19. package/dist/cache/redis.js +167 -0
  20. package/dist/cache/redis.js.map +1 -0
  21. package/dist/cache/types.d.ts +37 -0
  22. package/dist/cache/types.d.ts.map +1 -0
  23. package/dist/cache/types.js +2 -0
  24. package/dist/cache/types.js.map +1 -0
  25. package/dist/config/define-config.d.ts +19 -0
  26. package/dist/config/define-config.d.ts.map +1 -0
  27. package/dist/config/define-config.js +20 -0
  28. package/dist/config/define-config.js.map +1 -0
  29. package/dist/config/env.d.ts +30 -0
  30. package/dist/config/env.d.ts.map +1 -0
  31. package/dist/config/env.js +139 -0
  32. package/dist/config/env.js.map +1 -0
  33. package/dist/config/index.d.ts +7 -0
  34. package/dist/config/index.d.ts.map +1 -0
  35. package/dist/config/index.js +5 -0
  36. package/dist/config/index.js.map +1 -0
  37. package/dist/config/load-config.d.ts +30 -0
  38. package/dist/config/load-config.d.ts.map +1 -0
  39. package/dist/config/load-config.js +83 -0
  40. package/dist/config/load-config.js.map +1 -0
  41. package/dist/config/resolve-config.d.ts +14 -0
  42. package/dist/config/resolve-config.d.ts.map +1 -0
  43. package/dist/config/resolve-config.js +146 -0
  44. package/dist/config/resolve-config.js.map +1 -0
  45. package/dist/config/schema.d.ts +68 -0
  46. package/dist/config/schema.d.ts.map +1 -0
  47. package/dist/config/schema.js +75 -0
  48. package/dist/config/schema.js.map +1 -0
  49. package/dist/config/types.d.ts +126 -0
  50. package/dist/config/types.d.ts.map +1 -0
  51. package/dist/config/types.js +6 -0
  52. package/dist/config/types.js.map +1 -0
  53. package/dist/db/dialect.d.ts +64 -0
  54. package/dist/db/dialect.d.ts.map +1 -0
  55. package/dist/db/dialect.js +147 -0
  56. package/dist/db/dialect.js.map +1 -0
  57. package/dist/db/drizzle.d.ts +35 -0
  58. package/dist/db/drizzle.d.ts.map +1 -0
  59. package/dist/db/drizzle.js +128 -0
  60. package/dist/db/drizzle.js.map +1 -0
  61. package/dist/db/index.d.ts +28 -0
  62. package/dist/db/index.d.ts.map +1 -0
  63. package/dist/db/index.js +30 -0
  64. package/dist/db/index.js.map +1 -0
  65. package/dist/db/mysql.d.ts +39 -0
  66. package/dist/db/mysql.d.ts.map +1 -0
  67. package/dist/db/mysql.js +224 -0
  68. package/dist/db/mysql.js.map +1 -0
  69. package/dist/db/postgres.d.ts +47 -0
  70. package/dist/db/postgres.d.ts.map +1 -0
  71. package/dist/db/postgres.js +174 -0
  72. package/dist/db/postgres.js.map +1 -0
  73. package/dist/db/sqlite.d.ts +41 -0
  74. package/dist/db/sqlite.d.ts.map +1 -0
  75. package/dist/db/sqlite.js +213 -0
  76. package/dist/db/sqlite.js.map +1 -0
  77. package/dist/db/types.d.ts +71 -0
  78. package/dist/db/types.d.ts.map +1 -0
  79. package/dist/db/types.js +2 -0
  80. package/dist/db/types.js.map +1 -0
  81. package/dist/drivers/index.d.ts +5 -0
  82. package/dist/drivers/index.d.ts.map +1 -0
  83. package/dist/drivers/index.js +3 -0
  84. package/dist/drivers/index.js.map +1 -0
  85. package/dist/drivers/registry.d.ts +27 -0
  86. package/dist/drivers/registry.d.ts.map +1 -0
  87. package/dist/drivers/registry.js +162 -0
  88. package/dist/drivers/registry.js.map +1 -0
  89. package/dist/drivers/types.d.ts +59 -0
  90. package/dist/drivers/types.d.ts.map +1 -0
  91. package/dist/drivers/types.js +2 -0
  92. package/dist/drivers/types.js.map +1 -0
  93. package/dist/errors/codes.d.ts +8 -0
  94. package/dist/errors/codes.d.ts.map +1 -0
  95. package/dist/errors/codes.js +201 -0
  96. package/dist/errors/codes.js.map +1 -0
  97. package/dist/errors/cogenta-error.d.ts +38 -0
  98. package/dist/errors/cogenta-error.d.ts.map +1 -0
  99. package/dist/errors/cogenta-error.js +31 -0
  100. package/dist/errors/cogenta-error.js.map +1 -0
  101. package/dist/errors/index.d.ts +5 -0
  102. package/dist/errors/index.d.ts.map +1 -0
  103. package/dist/errors/index.js +3 -0
  104. package/dist/errors/index.js.map +1 -0
  105. package/dist/id.d.ts +5 -0
  106. package/dist/id.d.ts.map +1 -0
  107. package/dist/id.js +82 -0
  108. package/dist/id.js.map +1 -0
  109. package/dist/index.d.ts +12 -0
  110. package/dist/index.d.ts.map +1 -0
  111. package/dist/index.js +12 -0
  112. package/dist/index.js.map +1 -0
  113. package/dist/logger/index.d.ts +5 -0
  114. package/dist/logger/index.d.ts.map +1 -0
  115. package/dist/logger/index.js +4 -0
  116. package/dist/logger/index.js.map +1 -0
  117. package/dist/logger/logger.d.ts +10 -0
  118. package/dist/logger/logger.d.ts.map +1 -0
  119. package/dist/logger/logger.js +108 -0
  120. package/dist/logger/logger.js.map +1 -0
  121. package/dist/logger/redact.d.ts +12 -0
  122. package/dist/logger/redact.d.ts.map +1 -0
  123. package/dist/logger/redact.js +96 -0
  124. package/dist/logger/redact.js.map +1 -0
  125. package/dist/logger/types.d.ts +32 -0
  126. package/dist/logger/types.d.ts.map +1 -0
  127. package/dist/logger/types.js +3 -0
  128. package/dist/logger/types.js.map +1 -0
  129. package/dist/media/format-sniff.d.ts +22 -0
  130. package/dist/media/format-sniff.d.ts.map +1 -0
  131. package/dist/media/format-sniff.js +77 -0
  132. package/dist/media/format-sniff.js.map +1 -0
  133. package/dist/media/index.d.ts +5 -0
  134. package/dist/media/index.d.ts.map +1 -0
  135. package/dist/media/index.js +4 -0
  136. package/dist/media/index.js.map +1 -0
  137. package/dist/media/store.d.ts +13 -0
  138. package/dist/media/store.d.ts.map +1 -0
  139. package/dist/media/store.js +211 -0
  140. package/dist/media/store.js.map +1 -0
  141. package/dist/media/types.d.ts +70 -0
  142. package/dist/media/types.d.ts.map +1 -0
  143. package/dist/media/types.js +2 -0
  144. package/dist/media/types.js.map +1 -0
  145. package/dist/migrations/index.d.ts +4 -0
  146. package/dist/migrations/index.d.ts.map +1 -0
  147. package/dist/migrations/index.js +2 -0
  148. package/dist/migrations/index.js.map +1 -0
  149. package/dist/migrations/migrator.d.ts +18 -0
  150. package/dist/migrations/migrator.d.ts.map +1 -0
  151. package/dist/migrations/migrator.js +247 -0
  152. package/dist/migrations/migrator.js.map +1 -0
  153. package/dist/migrations/types.d.ts +63 -0
  154. package/dist/migrations/types.d.ts.map +1 -0
  155. package/dist/migrations/types.js +2 -0
  156. package/dist/migrations/types.js.map +1 -0
  157. package/dist/queue/bullmq.d.ts +119 -0
  158. package/dist/queue/bullmq.d.ts.map +1 -0
  159. package/dist/queue/bullmq.js +391 -0
  160. package/dist/queue/bullmq.js.map +1 -0
  161. package/dist/queue/database.d.ts +17 -0
  162. package/dist/queue/database.d.ts.map +1 -0
  163. package/dist/queue/database.js +242 -0
  164. package/dist/queue/database.js.map +1 -0
  165. package/dist/queue/index.d.ts +7 -0
  166. package/dist/queue/index.d.ts.map +1 -0
  167. package/dist/queue/index.js +4 -0
  168. package/dist/queue/index.js.map +1 -0
  169. package/dist/queue/types.d.ts +61 -0
  170. package/dist/queue/types.d.ts.map +1 -0
  171. package/dist/queue/types.js +2 -0
  172. package/dist/queue/types.js.map +1 -0
  173. package/dist/storage/index.d.ts +14 -0
  174. package/dist/storage/index.d.ts.map +1 -0
  175. package/dist/storage/index.js +17 -0
  176. package/dist/storage/index.js.map +1 -0
  177. package/dist/storage/key.d.ts +12 -0
  178. package/dist/storage/key.d.ts.map +1 -0
  179. package/dist/storage/key.js +43 -0
  180. package/dist/storage/key.js.map +1 -0
  181. package/dist/storage/local.d.ts +23 -0
  182. package/dist/storage/local.d.ts.map +1 -0
  183. package/dist/storage/local.js +204 -0
  184. package/dist/storage/local.js.map +1 -0
  185. package/dist/storage/s3.d.ts +54 -0
  186. package/dist/storage/s3.d.ts.map +1 -0
  187. package/dist/storage/s3.js +240 -0
  188. package/dist/storage/s3.js.map +1 -0
  189. package/dist/storage/types.d.ts +45 -0
  190. package/dist/storage/types.d.ts.map +1 -0
  191. package/dist/storage/types.js +2 -0
  192. package/dist/storage/types.js.map +1 -0
  193. package/package.json +82 -0
@@ -0,0 +1,18 @@
1
+ import { type DatabaseHandle } from '../db/index.js';
2
+ import { type Logger } from '../logger/index.js';
3
+ import type { Migration, MigrationOutcome, MigrationStatus, RollbackOptions, RunOptions } from './types.js';
4
+ export interface MigratorOptions {
5
+ readonly db: DatabaseHandle;
6
+ readonly migrations: readonly Migration[];
7
+ readonly logger?: Logger;
8
+ /** A lock older than this is assumed to belong to a process that died. */
9
+ readonly staleLockMs?: number;
10
+ readonly now?: () => number;
11
+ }
12
+ export interface Migrator {
13
+ status(): Promise<MigrationStatus[]>;
14
+ up(options?: RunOptions): Promise<MigrationOutcome[]>;
15
+ down(options?: RollbackOptions): Promise<MigrationOutcome[]>;
16
+ }
17
+ export declare function createMigrator(options: MigratorOptions): Migrator;
18
+ //# sourceMappingURL=migrator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrator.d.ts","sourceRoot":"","sources":["../../src/migrations/migrator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,cAAc,EAAqC,MAAM,gBAAgB,CAAA;AAEvF,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAC9D,OAAO,KAAK,EACV,SAAS,EACT,gBAAgB,EAEhB,eAAe,EACf,eAAe,EACf,UAAU,EACX,MAAM,YAAY,CAAA;AAOnB,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,EAAE,cAAc,CAAA;IAC3B,QAAQ,CAAC,UAAU,EAAE,SAAS,SAAS,EAAE,CAAA;IACzC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,0EAA0E;IAC1E,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CAC5B;AAED,MAAM,WAAW,QAAQ;IACvB,MAAM,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC,CAAA;IACpC,EAAE,CAAC,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAA;IACrD,IAAI,CAAC,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAA;CAC7D;AAqBD,wBAAgB,cAAc,CAAC,OAAO,EAAE,eAAe,GAAG,QAAQ,CAgQjE"}
@@ -0,0 +1,247 @@
1
+ import process from 'node:process';
2
+ import { identifier, sql } from '../db/index.js';
3
+ import { CogentaError } from '../errors/index.js';
4
+ import { createLogger } from '../logger/index.js';
5
+ const TABLE = 'cogenta_migrations';
6
+ const LOCK_TABLE = 'cogenta_migrations_lock';
7
+ const LOCK_ROW = 1;
8
+ const DEFAULT_STALE_LOCK_MS = 15 * 60 * 1000;
9
+ function sorted(migrations) {
10
+ return [...migrations].sort((a, b) => a.id.localeCompare(b.id));
11
+ }
12
+ function assertUniqueIds(migrations) {
13
+ const seen = new Set();
14
+ for (const migration of migrations) {
15
+ if (seen.has(migration.id)) {
16
+ throw new CogentaError({
17
+ code: 'MIGRATION_FAILED',
18
+ message: `Two migrations share the id "${migration.id}".`,
19
+ hint: 'Migration ids must be unique and are never renumbered once applied.',
20
+ details: { id: migration.id },
21
+ });
22
+ }
23
+ seen.add(migration.id);
24
+ }
25
+ }
26
+ export function createMigrator(options) {
27
+ const { db, migrations } = options;
28
+ const logger = (options.logger ?? createLogger()).child({ component: 'migrator' });
29
+ const now = options.now ?? Date.now;
30
+ const staleLockMs = options.staleLockMs ?? DEFAULT_STALE_LOCK_MS;
31
+ const owner = `${process.pid}@${new Date(now()).toISOString()}`;
32
+ assertUniqueIds(migrations);
33
+ const ordered = sorted(migrations);
34
+ const table = identifier(TABLE, db.dialect);
35
+ const lockTable = identifier(LOCK_TABLE, db.dialect);
36
+ async function ensureTables() {
37
+ // Portable on purpose: varchar keys stay under the MySQL index length limit
38
+ // in utf8mb4, and timestamps are ISO strings so the three dialects cannot
39
+ // disagree about time zones in the one table that records history.
40
+ await db.query(sql `
41
+ create table if not exists ${table} (
42
+ id varchar(255) not null primary key,
43
+ name varchar(255) not null,
44
+ checksum varchar(64),
45
+ applied_at varchar(32) not null,
46
+ duration_ms integer not null
47
+ )`);
48
+ await db.query(sql `
49
+ create table if not exists ${lockTable} (
50
+ id integer not null primary key,
51
+ acquired_at varchar(32) not null,
52
+ owner varchar(255) not null
53
+ )`);
54
+ }
55
+ async function appliedRecords() {
56
+ const result = await db.query(sql `select id, name, checksum, applied_at, duration_ms from ${table} order by id`);
57
+ return new Map(result.rows.map((row) => [
58
+ row.id,
59
+ {
60
+ id: row.id,
61
+ name: row.name,
62
+ checksum: row.checksum,
63
+ appliedAt: row.applied_at,
64
+ durationMs: Number(row.duration_ms),
65
+ },
66
+ ]));
67
+ }
68
+ /**
69
+ * Takes an exclusive lock so two deployments cannot migrate at once.
70
+ *
71
+ * The primary key does the work: whoever inserts the row first wins, and the
72
+ * loser gets a conflict rather than a half-applied schema. A lock older than
73
+ * `staleLockMs` belonged to a process that died, and is taken over.
74
+ */
75
+ async function acquireLock() {
76
+ const cutoff = new Date(now() - staleLockMs).toISOString();
77
+ await db.query(sql `delete from ${lockTable} where id = ${LOCK_ROW} and acquired_at < ${cutoff}`);
78
+ try {
79
+ await db.query(sql `insert into ${lockTable} (id, acquired_at, owner)
80
+ values (${LOCK_ROW}, ${new Date(now()).toISOString()}, ${owner})`);
81
+ }
82
+ catch (error) {
83
+ throw new CogentaError({
84
+ code: 'MIGRATION_LOCKED',
85
+ message: 'Another process is already running migrations on this database.',
86
+ hint: `Wait for it to finish. If a previous run crashed, the lock is released automatically after ${Math.round(staleLockMs / 60000)} minutes, or you can delete the row from ${LOCK_TABLE}.`,
87
+ cause: error,
88
+ });
89
+ }
90
+ }
91
+ async function releaseLock() {
92
+ await db.query(sql `delete from ${lockTable} where id = ${LOCK_ROW} and owner = ${owner}`);
93
+ }
94
+ function assertAllowed(pending, run) {
95
+ const destructive = pending.filter((migration) => migration.destructive === true);
96
+ if (destructive.length === 0)
97
+ return;
98
+ if (run.confirmDestructive !== true || run.backupVerified !== true) {
99
+ throw new CogentaError({
100
+ code: 'MIGRATION_DESTRUCTIVE',
101
+ message: `This run includes ${destructive.length} destructive migration(s): ${destructive
102
+ .map((migration) => migration.id)
103
+ .join(', ')}.`,
104
+ hint: 'A destructive migration removes or rewrites data that its down() cannot restore. Take a backup, verify it restores, then re-run confirming both.',
105
+ details: {
106
+ migrations: destructive.map((migration) => ({
107
+ id: migration.id,
108
+ impact: migration.impact ?? 'not documented',
109
+ })),
110
+ },
111
+ });
112
+ }
113
+ }
114
+ /**
115
+ * Runs one direction of one migration, in a transaction where the database
116
+ * has transactional DDL.
117
+ *
118
+ * **MySQL does not.** A `CREATE TABLE` commits implicitly, so a migration that
119
+ * fails halfway leaves the schema partly changed and no rollback happens. The
120
+ * engine cannot fix that; it records the failure loudly so the operator knows
121
+ * the schema is in between two states rather than believing it rolled back.
122
+ */
123
+ async function runOne(migration, direction) {
124
+ const startedAt = now();
125
+ const name = migration.name ?? migration.id;
126
+ const transactionalDdl = db.dialect !== 'mysql';
127
+ const body = async (tx) => {
128
+ if (direction === 'up') {
129
+ await migration.up(tx);
130
+ await tx.query(sql `insert into ${table} (id, name, checksum, applied_at, duration_ms)
131
+ values (${migration.id}, ${name}, ${migration.checksum ?? null},
132
+ ${new Date(now()).toISOString()}, ${now() - startedAt})`);
133
+ }
134
+ else {
135
+ await migration.down(tx);
136
+ await tx.query(sql `delete from ${table} where id = ${migration.id}`);
137
+ }
138
+ };
139
+ try {
140
+ if (transactionalDdl) {
141
+ await db.transaction(body, { immediate: true });
142
+ }
143
+ else {
144
+ await body(db);
145
+ }
146
+ }
147
+ catch (error) {
148
+ throw new CogentaError({
149
+ code: 'MIGRATION_FAILED',
150
+ message: `Migration "${migration.id}" failed going ${direction}: ${error instanceof Error ? error.message : String(error)}`,
151
+ hint: transactionalDdl
152
+ ? 'The transaction was rolled back, so the schema is unchanged. Fix the migration and run again.'
153
+ : 'MySQL commits DDL implicitly, so this migration may be half applied. Inspect the schema before running again — the engine cannot roll it back for you.',
154
+ cause: error,
155
+ details: { id: migration.id, direction, rolledBack: transactionalDdl },
156
+ });
157
+ }
158
+ const durationMs = now() - startedAt;
159
+ logger.info(`migration ${direction}`, { id: migration.id, name, durationMs });
160
+ return { id: migration.id, name, direction, durationMs };
161
+ }
162
+ return {
163
+ status: async () => {
164
+ await ensureTables();
165
+ const applied = await appliedRecords();
166
+ return ordered.map((migration) => {
167
+ const record = applied.get(migration.id);
168
+ return {
169
+ id: migration.id,
170
+ name: migration.name ?? migration.id,
171
+ applied: record !== undefined,
172
+ appliedAt: record?.appliedAt,
173
+ durationMs: record?.durationMs,
174
+ checksumMismatch: record !== undefined &&
175
+ record.checksum !== null &&
176
+ migration.checksum !== undefined &&
177
+ record.checksum !== migration.checksum,
178
+ destructive: migration.destructive === true,
179
+ impact: migration.impact,
180
+ };
181
+ });
182
+ },
183
+ up: async (run = {}) => {
184
+ await ensureTables();
185
+ await acquireLock();
186
+ try {
187
+ const applied = await appliedRecords();
188
+ for (const migration of ordered) {
189
+ const record = applied.get(migration.id);
190
+ if (record !== undefined &&
191
+ record.checksum !== null &&
192
+ migration.checksum !== undefined &&
193
+ record.checksum !== migration.checksum) {
194
+ throw new CogentaError({
195
+ code: 'MIGRATION_CHECKSUM_MISMATCH',
196
+ message: `Migration "${migration.id}" changed after it was applied here.`,
197
+ hint: 'Never edit an applied migration: environments that ran the two versions now differ in ways nothing records. Write a new migration instead.',
198
+ details: { id: migration.id },
199
+ });
200
+ }
201
+ }
202
+ let pending = ordered.filter((migration) => !applied.has(migration.id));
203
+ if (run.to !== undefined) {
204
+ const limit = pending.findIndex((migration) => migration.id === run.to);
205
+ if (limit === -1 && !applied.has(run.to)) {
206
+ throw new CogentaError({
207
+ code: 'MIGRATION_FAILED',
208
+ message: `No migration with id "${run.to}".`,
209
+ hint: 'Check the id against `cogenta migrate status`.',
210
+ });
211
+ }
212
+ pending = limit === -1 ? [] : pending.slice(0, limit + 1);
213
+ }
214
+ assertAllowed(pending, run);
215
+ const outcomes = [];
216
+ for (const migration of pending)
217
+ outcomes.push(await runOne(migration, 'up'));
218
+ return outcomes;
219
+ }
220
+ finally {
221
+ await releaseLock();
222
+ }
223
+ },
224
+ down: async (run = {}) => {
225
+ await ensureTables();
226
+ await acquireLock();
227
+ try {
228
+ const applied = await appliedRecords();
229
+ const reversible = ordered.filter((migration) => applied.has(migration.id)).reverse();
230
+ let target = reversible.slice(0, run.steps ?? 1);
231
+ if (run.to !== undefined) {
232
+ const limit = reversible.findIndex((migration) => migration.id === run.to);
233
+ target = limit === -1 ? [] : reversible.slice(0, limit + 1);
234
+ }
235
+ assertAllowed(target, run);
236
+ const outcomes = [];
237
+ for (const migration of target)
238
+ outcomes.push(await runOne(migration, 'down'));
239
+ return outcomes;
240
+ }
241
+ finally {
242
+ await releaseLock();
243
+ }
244
+ },
245
+ };
246
+ }
247
+ //# sourceMappingURL=migrator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrator.js","sourceRoot":"","sources":["../../src/migrations/migrator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ import type { SqlExecutor } from '../db/index.js';
2
+ export interface Migration {
3
+ /** Sortable and stable, e.g. `0001_create_content`. Never renumbered. */
4
+ readonly id: string;
5
+ readonly name?: string;
6
+ /**
7
+ * Hash of the source this migration came from. When it is present, changing
8
+ * an already-applied migration is detected and refused: two environments that
9
+ * ran different SQL under the same id is the worst state to debug.
10
+ */
11
+ readonly checksum?: string;
12
+ /**
13
+ * Removes or rewrites existing data in a way `down` cannot restore. Requires
14
+ * an explicit confirmation and a verified backup before it will run.
15
+ */
16
+ readonly destructive?: boolean;
17
+ /** What this does to existing data, in one sentence, for the operator. */
18
+ readonly impact?: string;
19
+ readonly estimatedDurationMs?: number;
20
+ up(tx: SqlExecutor): Promise<void>;
21
+ /**
22
+ * Required, not optional. AGENTS.md says migrations are always reversible, and
23
+ * a type that allows an irreversible one makes that rule a suggestion.
24
+ */
25
+ down(tx: SqlExecutor): Promise<void>;
26
+ }
27
+ export interface MigrationStatus {
28
+ readonly id: string;
29
+ readonly name: string;
30
+ readonly applied: boolean;
31
+ readonly appliedAt: string | undefined;
32
+ readonly durationMs: number | undefined;
33
+ /** The migration changed after it was applied here. */
34
+ readonly checksumMismatch: boolean;
35
+ readonly destructive: boolean;
36
+ readonly impact: string | undefined;
37
+ }
38
+ export interface MigrationRecord {
39
+ readonly id: string;
40
+ readonly name: string;
41
+ readonly checksum: string | null;
42
+ readonly appliedAt: string;
43
+ readonly durationMs: number;
44
+ }
45
+ export interface RunOptions {
46
+ /** Stop after this migration, inclusive. */
47
+ readonly to?: string;
48
+ /** The operator has read the impact of every destructive migration. */
49
+ readonly confirmDestructive?: boolean;
50
+ /** A backup was taken **and verified**. Required alongside the confirmation. */
51
+ readonly backupVerified?: boolean;
52
+ }
53
+ export interface RollbackOptions extends RunOptions {
54
+ /** How many applied migrations to revert. Defaults to one. */
55
+ readonly steps?: number;
56
+ }
57
+ export interface MigrationOutcome {
58
+ readonly id: string;
59
+ readonly name: string;
60
+ readonly direction: 'up' | 'down';
61
+ readonly durationMs: number;
62
+ }
63
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/migrations/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAEjD,MAAM,WAAW,SAAS;IACxB,yEAAyE;IACzE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAA;IAC9B,0EAA0E;IAC1E,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAErC,EAAE,CAAC,EAAE,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAClC;;;OAGG;IACH,IAAI,CAAC,EAAE,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACrC;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAA;IACtC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;IACvC,uDAAuD;IACvD,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAA;IAClC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAA;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;CACpC;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAC5B;AAED,MAAM,WAAW,UAAU;IACzB,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAA;IACpB,uEAAuE;IACvE,QAAQ,CAAC,kBAAkB,CAAC,EAAE,OAAO,CAAA;IACrC,gFAAgF;IAChF,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAA;CAClC;AAED,MAAM,WAAW,eAAgB,SAAQ,UAAU;IACjD,8DAA8D;IAC9D,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,SAAS,EAAE,IAAI,GAAG,MAAM,CAAA;IACjC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAC5B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/migrations/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,119 @@
1
+ import type { Driver } from '../drivers/index.js';
2
+ import { type Logger } from '../logger/index.js';
3
+ import type { QueueConfig, QueueDriver, QueueDriverOptions } from './types.js';
4
+ /**
5
+ * Only what this driver calls, described structurally.
6
+ *
7
+ * Importing bullmq's own types would put `bullmq` in the published type
8
+ * declarations, and it is an *optional* peer: a site running the database queue
9
+ * must not be asked to install it — nor to install `ioredis` behind it — just to
10
+ * typecheck (rule R1).
11
+ */
12
+ interface BullmqConnectionLike {
13
+ readonly url: string;
14
+ readonly retryStrategy?: () => null;
15
+ }
16
+ /**
17
+ * The raw client bullmq keeps for its own connection. It is a documented escape
18
+ * hatch on the Redis backend, and the only way to store the one thing bullmq has
19
+ * no state for: a cancelled job.
20
+ */
21
+ interface BullmqRedisLike {
22
+ ping(): Promise<string>;
23
+ hset(key: string, field: string, value: string): Promise<number>;
24
+ hget(key: string, field: string): Promise<string | null>;
25
+ }
26
+ interface BullmqBackendLike {
27
+ readonly client: Promise<BullmqRedisLike>;
28
+ }
29
+ interface BullmqAddOptionsLike {
30
+ readonly jobId?: string;
31
+ readonly delay?: number;
32
+ readonly priority?: number;
33
+ readonly attempts?: number;
34
+ readonly backoff?: {
35
+ readonly type: string;
36
+ readonly delay: number;
37
+ };
38
+ }
39
+ interface BullmqJobLike {
40
+ readonly id?: string | undefined;
41
+ readonly name: string;
42
+ readonly data: unknown;
43
+ readonly attemptsMade: number;
44
+ readonly failedReason?: string | undefined;
45
+ readonly timestamp: number;
46
+ readonly delay: number;
47
+ readonly opts: {
48
+ readonly attempts?: number | undefined;
49
+ };
50
+ getState(): Promise<string>;
51
+ moveToCompleted(returnValue: unknown, token: string, fetchNext?: boolean): Promise<unknown>;
52
+ moveToFailed(error: Error, token: string, fetchNext?: boolean): Promise<unknown>;
53
+ remove(): Promise<void>;
54
+ }
55
+ interface BullmqQueueLike {
56
+ add(name: string, data: unknown, options?: BullmqAddOptionsLike): Promise<BullmqJobLike>;
57
+ getJob(id: string): Promise<BullmqJobLike | undefined>;
58
+ getBackend(): BullmqBackendLike;
59
+ close(): Promise<void>;
60
+ }
61
+ interface BullmqWorkerLike {
62
+ getNextJob(token: string, options?: {
63
+ block?: boolean;
64
+ }): Promise<BullmqJobLike | undefined>;
65
+ startStalledCheckTimer(): Promise<void>;
66
+ close(force?: boolean): Promise<void>;
67
+ }
68
+ interface BullmqQueueOptionsLike {
69
+ readonly connection: BullmqConnectionLike;
70
+ readonly prefix?: string;
71
+ }
72
+ interface BullmqWorkerOptionsLike extends BullmqQueueOptionsLike {
73
+ readonly autorun: false;
74
+ readonly lockDuration: number;
75
+ readonly stalledInterval: number;
76
+ readonly skipLockRenewal: true;
77
+ }
78
+ export interface BullmqModule {
79
+ Queue: new (name: string, options: BullmqQueueOptionsLike) => BullmqQueueLike;
80
+ Worker: new (name: string, processor: null, options: BullmqWorkerOptionsLike) => BullmqWorkerLike;
81
+ }
82
+ /**
83
+ * Loads bullmq if the host application installed it. Absent is a normal
84
+ * outcome, not an error: it is what makes a site without Redis fall back to the
85
+ * database queue instead of failing to boot.
86
+ */
87
+ export declare function loadBullmqModule(): Promise<BullmqModule | null>;
88
+ export interface BullmqQueueOptions extends QueueDriverOptions {
89
+ readonly module: BullmqModule;
90
+ readonly url: string;
91
+ /**
92
+ * Namespace for every Redis key this driver writes. A Redis instance is often
93
+ * shared; two Cogenta sites on one server must not drain each other's jobs.
94
+ */
95
+ readonly prefix?: string;
96
+ /** Base delay of the exponential retry backoff. */
97
+ readonly backoffMs?: number;
98
+ /**
99
+ * How often a worker looks for jobs whose owner died. bullmq needs two passes
100
+ * separated by this interval before it returns such a job to the queue.
101
+ */
102
+ readonly stalledIntervalMs?: number;
103
+ readonly logger?: Logger;
104
+ }
105
+ /**
106
+ * The optimal job queue: Redis, driven through bullmq.
107
+ *
108
+ * Jobs are fetched by hand rather than by a bullmq `Worker` loop, because
109
+ * `QueueDriver.tick()` is the contract both drivers answer to — a site on shared
110
+ * hosting drives it from cron, and the same call has to mean the same thing
111
+ * here. bullmq documents this as the manual-fetching pattern, and it keeps the
112
+ * atomic claim (the L0 acceptance criterion) inside Redis where it belongs.
113
+ */
114
+ export declare function createBullmqQueue(options: BullmqQueueOptions): QueueDriver;
115
+ export interface BullmqQueueDriverOptions extends Omit<BullmqQueueOptions, 'module' | 'url'> {
116
+ }
117
+ export declare function bullmqQueueDriver(options?: BullmqQueueDriverOptions): Driver<QueueDriver, QueueConfig>;
118
+ export {};
119
+ //# sourceMappingURL=bullmq.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bullmq.d.ts","sourceRoot":"","sources":["../../src/queue/bullmq.ts"],"names":[],"mappings":"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"}