@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,224 @@
1
+ import { CogentaError } from '../errors/index.js';
2
+ import { compile, isWrite, returnsRows } from './dialect.js';
3
+ /** `mysql2` is an optional peer: a site on SQLite or Postgres never installs it. */
4
+ export async function loadMysqlModule() {
5
+ try {
6
+ return (await import('mysql2/promise'));
7
+ }
8
+ catch {
9
+ return null;
10
+ }
11
+ }
12
+ function isHeader(value) {
13
+ return !Array.isArray(value);
14
+ }
15
+ /**
16
+ * A deadlock victim is not a bug to surface — InnoDB expects the losing
17
+ * transaction to simply restart from scratch. Two concurrent writers hitting
18
+ * the same rows (two agents publishing at once, real production traffic, not
19
+ * just this test's ten concurrent inserts) is exactly the case this covers.
20
+ */
21
+ const DEADLOCK_ERROR_CODE = 'ER_LOCK_DEADLOCK';
22
+ function isDeadlock(error) {
23
+ if (!(error instanceof CogentaError))
24
+ return false;
25
+ const cause = error.cause;
26
+ return (typeof cause === 'object' &&
27
+ cause !== null &&
28
+ 'code' in cause &&
29
+ cause.code === DEADLOCK_ERROR_CODE);
30
+ }
31
+ function executorFor(connection) {
32
+ const executor = {
33
+ dialect: 'mysql',
34
+ query: async (fragment) => executor.execute(compile(fragment, 'mysql')),
35
+ execute: async ({ text, params }, options) => {
36
+ try {
37
+ const statement = {
38
+ sql: text,
39
+ ...(options?.asArrays === true ? { rowsAsArray: true } : {}),
40
+ };
41
+ // Prepared statements for anything with parameters — they are faster on
42
+ // repeat and cannot be confused by the value. MySQL cannot prepare every
43
+ // DDL statement, and DDL never carries parameters, so it goes through
44
+ // the plain path.
45
+ const [result] = params.length === 0
46
+ ? await connection.query(statement)
47
+ : await connection.execute({ ...statement, values: params });
48
+ if (isHeader(result)) {
49
+ return { rows: [], rowsAffected: result.affectedRows, insertId: result.insertId };
50
+ }
51
+ return {
52
+ rows: returnsRows(text) ? result : [],
53
+ rowsAffected: isWrite(text) ? result.length : 0,
54
+ };
55
+ }
56
+ catch (error) {
57
+ throw new CogentaError({
58
+ code: 'DB_UNREACHABLE',
59
+ message: `MySQL rejected a statement: ${error instanceof Error ? error.message : String(error)}`,
60
+ hint: 'Check the statement and the schema. The failing SQL is in the details.',
61
+ cause: error,
62
+ details: { sql: text },
63
+ });
64
+ }
65
+ },
66
+ };
67
+ return executor;
68
+ }
69
+ export async function createMysqlHandle(options) {
70
+ const module = await loadMysqlModule();
71
+ if (module === null) {
72
+ throw new CogentaError({
73
+ code: 'DRIVER_INIT_FAILED',
74
+ message: 'The MySQL driver needs the "mysql2" package.',
75
+ hint: 'Run `pnpm add mysql2`, or point database.url at a SQLite file instead.',
76
+ });
77
+ }
78
+ const pool = module.createPool({
79
+ uri: options.url,
80
+ connectionLimit: options.poolSize ?? 5,
81
+ waitForConnections: true,
82
+ // Everything is stored in UTC; letting the server's zone decide would make
83
+ // the same row read back differently depending on where it is deployed.
84
+ timezone: 'Z',
85
+ // Dates and decimals come back as strings, so a value never silently loses
86
+ // precision or picks up the process time zone on the way out.
87
+ dateStrings: true,
88
+ decimalNumbers: false,
89
+ });
90
+ const executor = executorFor(pool);
91
+ return {
92
+ dialect: 'mysql',
93
+ query: executor.query,
94
+ execute: executor.execute,
95
+ transaction: async (run, _options) => {
96
+ // Pinned to one connection: BEGIN on a pool would start the transaction on
97
+ // whichever connection was free and run the rest outside it.
98
+ const connection = await pool.getConnection();
99
+ const txExecutor = executorFor(connection);
100
+ let depth = 0;
101
+ const enter = async (nested) => {
102
+ const savepoint = `cogenta_sp_${depth}`;
103
+ await connection.query(depth === 0 ? 'start transaction' : `savepoint ${savepoint}`);
104
+ depth += 1;
105
+ try {
106
+ const result = await nested(txExecutor);
107
+ await connection.query(depth === 1 ? 'commit' : `release savepoint ${savepoint}`);
108
+ return result;
109
+ }
110
+ catch (error) {
111
+ await connection.query(depth === 1 ? 'rollback' : `rollback to savepoint ${savepoint}`);
112
+ throw error;
113
+ }
114
+ finally {
115
+ depth -= 1;
116
+ }
117
+ };
118
+ // Retries only apply to the outer transaction: a deadlock aborts the
119
+ // whole thing regardless of how many savepoints were nested inside it,
120
+ // so a partially-applied nested savepoint is never left dangling —
121
+ // `enter` always resets `depth` back to 0 on its way out.
122
+ //
123
+ // Jittered backoff, not an immediate retry: several transactions that
124
+ // deadlocked against each other tend to be released by InnoDB at
125
+ // close to the same instant, so retrying instantly just re-collides
126
+ // them in lockstep. A few tens of milliseconds of random spread is
127
+ // enough to break that up in practice.
128
+ const MAX_DEADLOCK_RETRIES = 5;
129
+ try {
130
+ for (let attempt = 0;; attempt += 1) {
131
+ try {
132
+ return await enter(run);
133
+ }
134
+ catch (error) {
135
+ if (!isDeadlock(error) || attempt >= MAX_DEADLOCK_RETRIES)
136
+ throw error;
137
+ const backoffMs = Math.min(20 * 2 ** attempt, 200) + Math.random() * 20;
138
+ await new Promise((resolve) => setTimeout(resolve, backoffMs));
139
+ }
140
+ }
141
+ }
142
+ finally {
143
+ connection.release();
144
+ }
145
+ },
146
+ close: async () => {
147
+ await pool.end();
148
+ },
149
+ };
150
+ }
151
+ export function mysqlDatabaseDriver() {
152
+ let handle;
153
+ // A type predicate, not a boolean: it narrows `config.url` at every call site.
154
+ const isMysqlUrl = (url) => url !== undefined && /^(mysql|mariadb):\/\//i.test(url);
155
+ return {
156
+ name: 'mysql',
157
+ tier: 'optimal',
158
+ available: async (config) => {
159
+ if (!isMysqlUrl(config.url) || (await loadMysqlModule()) === null)
160
+ return false;
161
+ let probe;
162
+ try {
163
+ probe = await createMysqlHandle({ url: config.url, poolSize: 1 });
164
+ await probe.query({ parts: ['select 1'], values: [] });
165
+ return true;
166
+ }
167
+ catch {
168
+ return false;
169
+ }
170
+ finally {
171
+ await probe?.close();
172
+ }
173
+ },
174
+ init: async (config) => {
175
+ if (!isMysqlUrl(config.url)) {
176
+ throw new CogentaError({
177
+ code: 'CONFIG_INVALID',
178
+ message: 'The MySQL driver needs a mysql:// or mariadb:// URL.',
179
+ hint: 'Set database.url, or the DATABASE_URL environment variable.',
180
+ });
181
+ }
182
+ handle ??= await createMysqlHandle({
183
+ url: config.url,
184
+ ...(config.poolSize === undefined ? {} : { poolSize: config.poolSize }),
185
+ });
186
+ return handle;
187
+ },
188
+ dispose: async () => {
189
+ await handle?.close();
190
+ handle = undefined;
191
+ },
192
+ health: async () => {
193
+ if (handle === undefined) {
194
+ return { status: 'down', driver: 'mysql', tier: 'optimal', message: 'Not connected.' };
195
+ }
196
+ const startedAt = Date.now();
197
+ try {
198
+ const result = await handle.query({
199
+ parts: ['select version() as version'],
200
+ values: [],
201
+ });
202
+ const version = result.rows[0]?.version ?? 'unknown';
203
+ return {
204
+ status: 'ok',
205
+ driver: 'mysql',
206
+ tier: 'optimal',
207
+ latencyMs: Date.now() - startedAt,
208
+ // Worth surfacing: MariaDB 11.8+ has a native VECTOR type and MySQL
209
+ // Community does not, so the two are not interchangeable for search.
210
+ message: `Connected to ${version}.`,
211
+ };
212
+ }
213
+ catch (error) {
214
+ return {
215
+ status: 'down',
216
+ driver: 'mysql',
217
+ tier: 'optimal',
218
+ message: error instanceof Error ? error.message : 'MySQL did not answer.',
219
+ };
220
+ }
221
+ },
222
+ };
223
+ }
224
+ //# sourceMappingURL=mysql.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mysql.js","sourceRoot":"","sources":["../../src/db/mysql.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ import type { Driver } from '../drivers/index.js';
2
+ import type { DatabaseConfig, DatabaseHandle } from './types.js';
3
+ /**
4
+ * Only the slice of `postgres` this driver uses, described structurally so the
5
+ * published types do not depend on an optional peer.
6
+ */
7
+ interface PostgresResult extends Array<Record<string, unknown>> {
8
+ readonly count: number;
9
+ }
10
+ interface PostgresValuesResult extends Array<unknown[]> {
11
+ readonly count: number;
12
+ }
13
+ /**
14
+ * The pending query postgres.js hands back. It is a thenable, so awaiting it
15
+ * yields rows as objects; `values()` asks the same query for its rows as ordered
16
+ * value lists instead.
17
+ */
18
+ interface PostgresQuery extends Promise<PostgresResult> {
19
+ values(): Promise<PostgresValuesResult>;
20
+ }
21
+ interface PostgresSql {
22
+ unsafe(query: string, parameters?: readonly unknown[]): PostgresQuery;
23
+ reserve(): Promise<PostgresReserved>;
24
+ end(options?: {
25
+ timeout?: number;
26
+ }): Promise<void>;
27
+ }
28
+ interface PostgresReserved extends PostgresSql {
29
+ release(): void;
30
+ }
31
+ interface PostgresModuleLike {
32
+ default: (url: string, options?: Record<string, unknown>) => PostgresSql;
33
+ }
34
+ /**
35
+ * `postgres` (postgres.js) is an optional peer: a site on SQLite never installs
36
+ * it. It was chosen over `pg` because it has **no transitive dependencies at
37
+ * all**, which matters for a package that ships in the core of a CMS.
38
+ */
39
+ export declare function loadPostgresModule(): Promise<PostgresModuleLike['default'] | null>;
40
+ export interface PostgresHandleOptions {
41
+ readonly url: string;
42
+ readonly poolSize?: number;
43
+ }
44
+ export declare function createPostgresHandle(options: PostgresHandleOptions): Promise<DatabaseHandle>;
45
+ export declare function postgresDatabaseDriver(): Driver<DatabaseHandle, DatabaseConfig>;
46
+ export {};
47
+ //# sourceMappingURL=postgres.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../../src/db/postgres.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAgB,MAAM,qBAAqB,CAAA;AAG/D,OAAO,KAAK,EACV,cAAc,EACd,cAAc,EAKf,MAAM,YAAY,CAAA;AAEnB;;;GAGG;AACH,UAAU,cAAe,SAAQ,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACvB;AAED,UAAU,oBAAqB,SAAQ,KAAK,CAAC,OAAO,EAAE,CAAC;IACrD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACvB;AAED;;;;GAIG;AACH,UAAU,aAAc,SAAQ,OAAO,CAAC,cAAc,CAAC;IACrD,MAAM,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAAA;CACxC;AAED,UAAU,WAAW;IACnB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,SAAS,OAAO,EAAE,GAAG,aAAa,CAAA;IACrE,OAAO,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAAA;IACpC,GAAG,CAAC,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACnD;AAED,UAAU,gBAAiB,SAAQ,WAAW;IAC5C,OAAO,IAAI,IAAI,CAAA;CAChB;AAED,UAAU,kBAAkB;IAC1B,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,WAAW,CAAA;CACzE;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,kBAAkB,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,CAOxF;AAyCD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAC3B;AAED,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,cAAc,CAAC,CA+DzB;AAED,wBAAgB,sBAAsB,IAAI,MAAM,CAAC,cAAc,EAAE,cAAc,CAAC,CA4E/E"}
@@ -0,0 +1,174 @@
1
+ import { CogentaError } from '../errors/index.js';
2
+ import { compile, isWrite, returnsRows } from './dialect.js';
3
+ /**
4
+ * `postgres` (postgres.js) is an optional peer: a site on SQLite never installs
5
+ * it. It was chosen over `pg` because it has **no transitive dependencies at
6
+ * all**, which matters for a package that ships in the core of a CMS.
7
+ */
8
+ export async function loadPostgresModule() {
9
+ try {
10
+ const module = (await import('postgres'));
11
+ return module.default;
12
+ }
13
+ catch {
14
+ return null;
15
+ }
16
+ }
17
+ function fail(error, text) {
18
+ return new CogentaError({
19
+ code: 'DB_UNREACHABLE',
20
+ message: `Postgres rejected a statement: ${error instanceof Error ? error.message : String(error)}`,
21
+ hint: 'Check the statement and the schema. The failing SQL is in the details.',
22
+ cause: error,
23
+ // Parameters are deliberately absent: they routinely carry personal data.
24
+ details: { sql: text },
25
+ });
26
+ }
27
+ function executorFor(connection) {
28
+ const executor = {
29
+ dialect: 'postgres',
30
+ query: async (fragment) => executor.execute(compile(fragment, 'postgres')),
31
+ execute: async ({ text, params }, options) => {
32
+ try {
33
+ const pending = connection.unsafe(text, params);
34
+ const result = options?.asArrays === true ? await pending.values() : await pending;
35
+ return {
36
+ rows: returnsRows(text) ? [...result] : [],
37
+ rowsAffected: isWrite(text) ? result.count : 0,
38
+ };
39
+ }
40
+ catch (error) {
41
+ throw fail(error, text);
42
+ }
43
+ },
44
+ };
45
+ return executor;
46
+ }
47
+ export async function createPostgresHandle(options) {
48
+ const createClient = await loadPostgresModule();
49
+ if (createClient === null) {
50
+ throw new CogentaError({
51
+ code: 'DRIVER_INIT_FAILED',
52
+ message: 'The Postgres driver needs the "postgres" package.',
53
+ hint: 'Run `pnpm add postgres`, or point database.url at a SQLite file instead.',
54
+ });
55
+ }
56
+ const pool = createClient(options.url, {
57
+ // Modest on purpose: shared hosting allows very few connections, and
58
+ // exhausting them takes the whole site down rather than slowing it.
59
+ max: options.poolSize ?? 5,
60
+ onnotice: () => undefined,
61
+ });
62
+ const executor = executorFor(pool);
63
+ return {
64
+ dialect: 'postgres',
65
+ query: executor.query,
66
+ execute: executor.execute,
67
+ transaction: async (run, _options) => {
68
+ // A transaction must be pinned to one connection. Issuing BEGIN on the
69
+ // pool would start it on whichever connection was free and run the rest of
70
+ // the statements on others, silently outside the transaction.
71
+ const connection = await pool.reserve();
72
+ const txExecutor = executorFor(connection);
73
+ let depth = 0;
74
+ const enter = async (nested) => {
75
+ const savepoint = `cogenta_sp_${depth}`;
76
+ await connection.unsafe(depth === 0 ? 'begin' : `savepoint ${savepoint}`);
77
+ depth += 1;
78
+ try {
79
+ const result = await nested(txExecutor);
80
+ await connection.unsafe(depth === 1 ? 'commit' : `release savepoint ${savepoint}`);
81
+ return result;
82
+ }
83
+ catch (error) {
84
+ await connection.unsafe(depth === 1 ? 'rollback' : `rollback to savepoint ${savepoint}`);
85
+ throw error;
86
+ }
87
+ finally {
88
+ depth -= 1;
89
+ }
90
+ };
91
+ try {
92
+ return await enter(run);
93
+ }
94
+ finally {
95
+ connection.release();
96
+ }
97
+ },
98
+ close: async () => {
99
+ await pool.end({ timeout: 5 });
100
+ },
101
+ };
102
+ }
103
+ export function postgresDatabaseDriver() {
104
+ let handle;
105
+ // A type predicate, not a boolean: it narrows `config.url` at every call site,
106
+ // which is what removes the casts this driver would otherwise need.
107
+ const isPostgresUrl = (url) => url !== undefined && /^postgres(ql)?:\/\//i.test(url);
108
+ return {
109
+ name: 'postgres',
110
+ tier: 'optimal',
111
+ // Answering, not merely configured. A URL that points at nothing must make
112
+ // the registry fall through, not crash the site at startup.
113
+ available: async (config) => {
114
+ if (!isPostgresUrl(config.url) || (await loadPostgresModule()) === null)
115
+ return false;
116
+ let probe;
117
+ try {
118
+ probe = await createPostgresHandle({ url: config.url, poolSize: 1 });
119
+ await probe.query({ parts: ['select 1'], values: [] });
120
+ return true;
121
+ }
122
+ catch {
123
+ return false;
124
+ }
125
+ finally {
126
+ await probe?.close();
127
+ }
128
+ },
129
+ init: async (config) => {
130
+ if (!isPostgresUrl(config.url)) {
131
+ throw new CogentaError({
132
+ code: 'CONFIG_INVALID',
133
+ message: 'The Postgres driver needs a postgres:// or postgresql:// URL.',
134
+ hint: 'Set database.url, or the DATABASE_URL environment variable.',
135
+ });
136
+ }
137
+ handle ??= await createPostgresHandle({
138
+ url: config.url,
139
+ ...(config.poolSize === undefined ? {} : { poolSize: config.poolSize }),
140
+ });
141
+ return handle;
142
+ },
143
+ dispose: async () => {
144
+ await handle?.close();
145
+ handle = undefined;
146
+ },
147
+ health: async () => {
148
+ if (handle === undefined) {
149
+ return { status: 'down', driver: 'postgres', tier: 'optimal', message: 'Not connected.' };
150
+ }
151
+ const startedAt = Date.now();
152
+ try {
153
+ await handle.query({ parts: ['select 1'], values: [] });
154
+ return {
155
+ status: 'ok',
156
+ driver: 'postgres',
157
+ tier: 'optimal',
158
+ latencyMs: Date.now() - startedAt,
159
+ // The URL is never reported: it carries the password.
160
+ message: 'Connected.',
161
+ };
162
+ }
163
+ catch (error) {
164
+ return {
165
+ status: 'down',
166
+ driver: 'postgres',
167
+ tier: 'optimal',
168
+ message: error instanceof Error ? error.message : 'Postgres did not answer.',
169
+ };
170
+ }
171
+ },
172
+ };
173
+ }
174
+ //# sourceMappingURL=postgres.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres.js","sourceRoot":"","sources":["../../src/db/postgres.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import type { Driver } from '../drivers/index.js';
2
+ import type { DatabaseConfig, DatabaseHandle } from './types.js';
3
+ /** Only the slice of `node:sqlite` this driver uses. */
4
+ interface StatementSyncLike {
5
+ all(...params: readonly unknown[]): unknown[];
6
+ run(...params: readonly unknown[]): {
7
+ changes: number | bigint;
8
+ lastInsertRowid: number | bigint;
9
+ };
10
+ /**
11
+ * Optional because it landed after the first release of `node:sqlite`. When it
12
+ * is missing, `execute` falls back to reading the values out of the row
13
+ * objects, which is exact except when two selected columns share a name.
14
+ */
15
+ setReturnArrays?(enabled: boolean): void;
16
+ }
17
+ interface DatabaseSyncLike {
18
+ prepare(sql: string): StatementSyncLike;
19
+ exec(sql: string): void;
20
+ close(): void;
21
+ }
22
+ interface SqliteModuleLike {
23
+ DatabaseSync: new (path: string) => DatabaseSyncLike;
24
+ }
25
+ /**
26
+ * `node:sqlite` ships with Node, so the default install compiles nothing and
27
+ * depends on nothing. `better-sqlite3` is deliberately not used: it is native
28
+ * code, and rule R10 forbids that without a fallback because it breaks on ARM,
29
+ * musl and shared hosting — exactly the deployments SQLite is meant to serve.
30
+ *
31
+ * It is unflagged from Node 22.13. On an older runtime this returns null and the
32
+ * registry reports the driver as unavailable rather than crashing.
33
+ */
34
+ export declare function loadSqliteModule(): Promise<SqliteModuleLike | null>;
35
+ export interface SqliteHandleOptions {
36
+ readonly url: string;
37
+ }
38
+ export declare function createSqliteHandle(options: SqliteHandleOptions): Promise<DatabaseHandle>;
39
+ export declare function sqliteDatabaseDriver(): Driver<DatabaseHandle, DatabaseConfig>;
40
+ export {};
41
+ //# sourceMappingURL=sqlite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/db/sqlite.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAgB,MAAM,qBAAqB,CAAA;AAG/D,OAAO,KAAK,EACV,cAAc,EACd,cAAc,EAKf,MAAM,YAAY,CAAA;AAEnB,wDAAwD;AACxD,UAAU,iBAAiB;IACzB,GAAG,CAAC,GAAG,MAAM,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,EAAE,CAAA;IAC7C,GAAG,CAAC,GAAG,MAAM,EAAE,SAAS,OAAO,EAAE,GAAG;QAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAA;IAClG;;;;OAIG;IACH,eAAe,CAAC,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAA;CACzC;AAED,UAAU,gBAAgB;IACxB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,iBAAiB,CAAA;IACvC,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,KAAK,IAAI,IAAI,CAAA;CACd;AAED,UAAU,gBAAgB;IACxB,YAAY,EAAE,KAAK,IAAI,EAAE,MAAM,KAAK,gBAAgB,CAAA;CACrD;AAED;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAMzE;AAgGD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CACrB;AAED,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,cAAc,CAAC,CA+F9F;AAED,wBAAgB,oBAAoB,IAAI,MAAM,CAAC,cAAc,EAAE,cAAc,CAAC,CAkC7E"}