@nextlyhq/adapter-drizzle 0.0.2-alpha.6 → 0.0.2-alpha.62

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.
@@ -1,4 +1,5 @@
1
1
  import { a as SqlParam, S as SupportedDialect } from './core-CVO7WYDj.js';
2
+ import { SQL } from 'drizzle-orm';
2
3
 
3
4
  /**
4
5
  * Query building type definitions for database-agnostic queries.
@@ -7,19 +8,42 @@ import { a as SqlParam, S as SupportedDialect } from './core-CVO7WYDj.js';
7
8
  */
8
9
 
9
10
  /**
10
- * Supported WHERE clause operators.
11
+ * Every WHERE clause operator this package DECLARES, as a value.
11
12
  *
12
13
  * @remarks
14
+ * Declared, not guaranteed executable. Membership here means a `WhereCondition`
15
+ * carrying the operator type-checks — it does NOT mean the adapter can run it.
16
+ * `OVERLAPS` is declared and unimplemented, and throws at build time, so a
17
+ * validator written against this list will admit input the query layer then
18
+ * rejects. Validate against it to catch a misspelled operator; do not read
19
+ * acceptance here as a capability.
20
+ *
13
21
  * - Standard comparison: =, !=, <, >, <=, >=
14
22
  * - Set operations: IN, NOT IN
15
23
  * - Pattern matching: LIKE, ILIKE (case-insensitive, PostgreSQL/emulated)
16
24
  * - NULL checks: IS NULL, IS NOT NULL
17
25
  * - Range: BETWEEN, NOT BETWEEN
18
- * - JSON/Array: CONTAINS, OVERLAPS
26
+ * - Substring: CONTAINS — a LITERAL match on a TEXT column; see below
27
+ * - Declared but NOT implemented: OVERLAPS, which throws
28
+ *
29
+ * This list is the source of truth and {@link WhereOperator} is derived from it,
30
+ * rather than the two being written out separately. A guard that has to enumerate
31
+ * the operators — a validator over caller input, or a test asserting the builder
32
+ * handles or refuses each one — can only do that from a runtime value, and a
33
+ * hand-kept copy of the union would agree with it on the day it was written and
34
+ * silently stop agreeing the next time a member is added.
35
+ *
36
+ * @public
37
+ */
38
+ declare const WHERE_OPERATORS: readonly ["=", "!=", "<", ">", "<=", ">=", "IN", "NOT IN", "LIKE", "ILIKE", "IS NULL", "IS NOT NULL", "BETWEEN", "NOT BETWEEN", "CONTAINS", "OVERLAPS"];
39
+ /**
40
+ * Every WHERE clause operator this package declares. Derived from
41
+ * {@link WHERE_OPERATORS}, and carrying the same caveat: a value of this type
42
+ * type-checks, which is not the same as the adapter being able to execute it.
19
43
  *
20
44
  * @public
21
45
  */
22
- type WhereOperator = "=" | "!=" | "<" | ">" | "<=" | ">=" | "IN" | "NOT IN" | "LIKE" | "ILIKE" | "IS NULL" | "IS NOT NULL" | "BETWEEN" | "NOT BETWEEN" | "CONTAINS" | "OVERLAPS";
46
+ type WhereOperator = (typeof WHERE_OPERATORS)[number];
23
47
  /**
24
48
  * Individual WHERE condition.
25
49
  *
@@ -147,6 +171,17 @@ interface SelectOptions {
147
171
  having?: WhereClause;
148
172
  /** Return distinct rows only */
149
173
  distinct?: boolean;
174
+ /**
175
+ * Take a `FOR UPDATE` row lock on the selected rows for the rest of the
176
+ * transaction, and read the latest committed values rather than the
177
+ * transaction's snapshot. Use for read-modify-write sequences that must not
178
+ * interleave (e.g. re-reading a status under the lock the write will take).
179
+ *
180
+ * Requires a transaction executor. No-ops on SQLite, which has no `FOR UPDATE`
181
+ * and needs none — its transactions open with `BEGIN IMMEDIATE`, already
182
+ * serializing writers.
183
+ */
184
+ forUpdate?: boolean;
150
185
  }
151
186
  /**
152
187
  * Options for INSERT operations.
@@ -275,6 +310,58 @@ interface TransactionContext {
275
310
  * @returns Array of result rows
276
311
  */
277
312
  execute<T = unknown>(sql: string, params?: SqlParam[]): Promise<T[]>;
313
+ /**
314
+ * Run a Drizzle-built statement within the transaction, for its effect.
315
+ *
316
+ * @remarks
317
+ * The typed CRUD methods below resolve their table through the schema
318
+ * registry and reject any name it does not declare. That leaves no way to
319
+ * write to a table addressed under a name the ORM does not know — a table
320
+ * mid-rename, most of all — other than assembling SQL by hand, which also
321
+ * means hand-picking each driver's placeholder syntax.
322
+ *
323
+ * This accepts Drizzle's `sql` template instead, so identifier quoting and
324
+ * parameter binding are generated for the dialect in use. Implemented per
325
+ * adapter because the underlying call is not uniform: node-postgres and
326
+ * mysql2 expose `execute`, while better-sqlite3 needs `run` and throws on a
327
+ * statement that returns no rows.
328
+ *
329
+ * Returns nothing: this is for statements run to change data, not to read it.
330
+ *
331
+ * @param statement - Drizzle `sql` template to run
332
+ */
333
+ runStatement(statement: SQL): Promise<void>;
334
+ /**
335
+ * Run a Drizzle-built statement within the transaction and return its rows.
336
+ *
337
+ * @remarks
338
+ * The reading half of `runStatement`, for the same reason: a table the schema
339
+ * registry does not declare cannot be reached through the typed CRUD methods,
340
+ * which reject the name outright. Implemented per adapter because the drivers
341
+ * disagree about both the call and the result — node-postgres answers
342
+ * `{ rows }`, mysql2 a `[rows, fields]` tuple, and better-sqlite3 needs `all`.
343
+ *
344
+ * @param statement - Drizzle `sql` template to run
345
+ * @returns Rows the statement produced
346
+ */
347
+ queryStatement<T = Record<string, unknown>>(statement: SQL): Promise<T[]>;
348
+ /**
349
+ * Take an exclusive lock on a single row for the rest of this transaction.
350
+ *
351
+ * @remarks
352
+ * For read-modify-write sequences that must not interleave: without a lock
353
+ * another transaction can commit between the read and the write, leaving the
354
+ * caller's view of the prior state inconsistent with what its own write
355
+ * applied on top of.
356
+ *
357
+ * No-ops on dialects without row-level locking. SQLite is the case that
358
+ * matters and needs nothing — its transactions open with `BEGIN IMMEDIATE`,
359
+ * which already serializes writers.
360
+ *
361
+ * @param table - Table name
362
+ * @param id - Primary-key value of the row to lock
363
+ */
364
+ lockRow(table: string, id: SqlParam): Promise<void>;
278
365
  /**
279
366
  * Insert a single record.
280
367
  *
@@ -319,6 +406,31 @@ interface TransactionContext {
319
406
  * @returns Updated records (with RETURNING columns if specified)
320
407
  */
321
408
  update<T = unknown>(table: string, data: Record<string, unknown>, where: WhereClause, options?: UpdateOptions): Promise<T[]>;
409
+ /**
410
+ * Update records and report how many rows the statement affected.
411
+ *
412
+ * @remarks
413
+ * The transactional half of the adapter's `updateCount`, and the only way to
414
+ * perform a fenced compare-and-set inside a transaction. `update` cannot
415
+ * answer this: without `returning` it discards the driver's count, and WITH
416
+ * `returning` on a dialect that lacks RETURNING it re-SELECTs using the same
417
+ * WHERE — so a conditional update whose own write falsifies its predicate
418
+ * reads back zero rows, and a write that landed reports as unmatched.
419
+ *
420
+ * 🔴 Inherits the adapter's MySQL caveat: MySQL counts CHANGED rows rather
421
+ * than matched ones, so a caller using this as a compare-and-set must write
422
+ * at least one column the update always moves — a state transition, a version
423
+ * bump, a timestamp of sufficient resolution. Postgres (`rowCount`) and
424
+ * SQLite (`changes`) count matched rows and do not need the precaution, which
425
+ * is exactly why it cannot be dropped: the dialect where the distinction
426
+ * exists is the one with no RETURNING to fall back on.
427
+ *
428
+ * @param table - Table name
429
+ * @param data - Column values to write
430
+ * @param where - Conditions the update must match
431
+ * @returns Number of rows the statement affected
432
+ */
433
+ updateCount(table: string, data: Record<string, unknown>, where: WhereClause): Promise<number>;
322
434
  /**
323
435
  * Delete records.
324
436
  *
@@ -365,6 +477,20 @@ interface TransactionContext {
365
477
  * @param name - Savepoint name
366
478
  */
367
479
  releaseSavepoint?(name: string): Promise<void>;
480
+ /**
481
+ * Return the Drizzle ORM instance bound to THIS transaction's connection.
482
+ *
483
+ * @remarks
484
+ * Runs Drizzle `sql` templates / fluent queries inside the caller's
485
+ * transaction (same client the delegated CRUD methods use), so services
486
+ * that drop to Drizzle raw SQL (e.g. junction-table writes) can participate
487
+ * in the transaction instead of running on the pooled connection. Required
488
+ * so callers never silently fall back to the pooled connection (which would
489
+ * run a write outside the transaction); every adapter must implement it.
490
+ * Generic return so callers narrow to the dialect Drizzle type they need
491
+ * without an `any` cast.
492
+ */
493
+ getDrizzle<T = unknown>(): T;
368
494
  }
369
495
 
370
496
  /**
@@ -619,4 +745,4 @@ interface MigrationStatus {
619
745
  pending: Migration[];
620
746
  }
621
747
 
622
- export type { DatabaseCapabilities as D, InsertOptions as I, JoinSpec as J, MigrationRecord as M, OrderBySpec as O, PoolStats as P, SelectOptions as S, TransactionContext as T, UpdateOptions as U, WhereClause as W, Migration as a, MigrationStatus as b, MigrationOptions as c, MigrationResult as d, TransactionOptions as e, DeleteOptions as f, UpsertOptions as g, TransactionIsolationLevel as h, WhereCondition as i, WhereOperator as j };
748
+ export { type DeleteOptions as D, type InsertOptions as I, type JoinSpec as J, type MigrationRecord as M, type OrderBySpec as O, type PoolStats as P, type SelectOptions as S, type TransactionContext as T, type UpdateOptions as U, type WhereClause as W, type Migration as a, type MigrationStatus as b, type MigrationOptions as c, type MigrationResult as d, type UpsertOptions as e, type TransactionOptions as f, type DatabaseCapabilities as g, type TransactionIsolationLevel as h, WHERE_OPERATORS as i, type WhereCondition as j, type WhereOperator as k };
@@ -1,4 +1,5 @@
1
1
  import { a as SqlParam, S as SupportedDialect } from './core-CVO7WYDj.cjs';
2
+ import { SQL } from 'drizzle-orm';
2
3
 
3
4
  /**
4
5
  * Query building type definitions for database-agnostic queries.
@@ -7,19 +8,42 @@ import { a as SqlParam, S as SupportedDialect } from './core-CVO7WYDj.cjs';
7
8
  */
8
9
 
9
10
  /**
10
- * Supported WHERE clause operators.
11
+ * Every WHERE clause operator this package DECLARES, as a value.
11
12
  *
12
13
  * @remarks
14
+ * Declared, not guaranteed executable. Membership here means a `WhereCondition`
15
+ * carrying the operator type-checks — it does NOT mean the adapter can run it.
16
+ * `OVERLAPS` is declared and unimplemented, and throws at build time, so a
17
+ * validator written against this list will admit input the query layer then
18
+ * rejects. Validate against it to catch a misspelled operator; do not read
19
+ * acceptance here as a capability.
20
+ *
13
21
  * - Standard comparison: =, !=, <, >, <=, >=
14
22
  * - Set operations: IN, NOT IN
15
23
  * - Pattern matching: LIKE, ILIKE (case-insensitive, PostgreSQL/emulated)
16
24
  * - NULL checks: IS NULL, IS NOT NULL
17
25
  * - Range: BETWEEN, NOT BETWEEN
18
- * - JSON/Array: CONTAINS, OVERLAPS
26
+ * - Substring: CONTAINS — a LITERAL match on a TEXT column; see below
27
+ * - Declared but NOT implemented: OVERLAPS, which throws
28
+ *
29
+ * This list is the source of truth and {@link WhereOperator} is derived from it,
30
+ * rather than the two being written out separately. A guard that has to enumerate
31
+ * the operators — a validator over caller input, or a test asserting the builder
32
+ * handles or refuses each one — can only do that from a runtime value, and a
33
+ * hand-kept copy of the union would agree with it on the day it was written and
34
+ * silently stop agreeing the next time a member is added.
35
+ *
36
+ * @public
37
+ */
38
+ declare const WHERE_OPERATORS: readonly ["=", "!=", "<", ">", "<=", ">=", "IN", "NOT IN", "LIKE", "ILIKE", "IS NULL", "IS NOT NULL", "BETWEEN", "NOT BETWEEN", "CONTAINS", "OVERLAPS"];
39
+ /**
40
+ * Every WHERE clause operator this package declares. Derived from
41
+ * {@link WHERE_OPERATORS}, and carrying the same caveat: a value of this type
42
+ * type-checks, which is not the same as the adapter being able to execute it.
19
43
  *
20
44
  * @public
21
45
  */
22
- type WhereOperator = "=" | "!=" | "<" | ">" | "<=" | ">=" | "IN" | "NOT IN" | "LIKE" | "ILIKE" | "IS NULL" | "IS NOT NULL" | "BETWEEN" | "NOT BETWEEN" | "CONTAINS" | "OVERLAPS";
46
+ type WhereOperator = (typeof WHERE_OPERATORS)[number];
23
47
  /**
24
48
  * Individual WHERE condition.
25
49
  *
@@ -147,6 +171,17 @@ interface SelectOptions {
147
171
  having?: WhereClause;
148
172
  /** Return distinct rows only */
149
173
  distinct?: boolean;
174
+ /**
175
+ * Take a `FOR UPDATE` row lock on the selected rows for the rest of the
176
+ * transaction, and read the latest committed values rather than the
177
+ * transaction's snapshot. Use for read-modify-write sequences that must not
178
+ * interleave (e.g. re-reading a status under the lock the write will take).
179
+ *
180
+ * Requires a transaction executor. No-ops on SQLite, which has no `FOR UPDATE`
181
+ * and needs none — its transactions open with `BEGIN IMMEDIATE`, already
182
+ * serializing writers.
183
+ */
184
+ forUpdate?: boolean;
150
185
  }
151
186
  /**
152
187
  * Options for INSERT operations.
@@ -275,6 +310,58 @@ interface TransactionContext {
275
310
  * @returns Array of result rows
276
311
  */
277
312
  execute<T = unknown>(sql: string, params?: SqlParam[]): Promise<T[]>;
313
+ /**
314
+ * Run a Drizzle-built statement within the transaction, for its effect.
315
+ *
316
+ * @remarks
317
+ * The typed CRUD methods below resolve their table through the schema
318
+ * registry and reject any name it does not declare. That leaves no way to
319
+ * write to a table addressed under a name the ORM does not know — a table
320
+ * mid-rename, most of all — other than assembling SQL by hand, which also
321
+ * means hand-picking each driver's placeholder syntax.
322
+ *
323
+ * This accepts Drizzle's `sql` template instead, so identifier quoting and
324
+ * parameter binding are generated for the dialect in use. Implemented per
325
+ * adapter because the underlying call is not uniform: node-postgres and
326
+ * mysql2 expose `execute`, while better-sqlite3 needs `run` and throws on a
327
+ * statement that returns no rows.
328
+ *
329
+ * Returns nothing: this is for statements run to change data, not to read it.
330
+ *
331
+ * @param statement - Drizzle `sql` template to run
332
+ */
333
+ runStatement(statement: SQL): Promise<void>;
334
+ /**
335
+ * Run a Drizzle-built statement within the transaction and return its rows.
336
+ *
337
+ * @remarks
338
+ * The reading half of `runStatement`, for the same reason: a table the schema
339
+ * registry does not declare cannot be reached through the typed CRUD methods,
340
+ * which reject the name outright. Implemented per adapter because the drivers
341
+ * disagree about both the call and the result — node-postgres answers
342
+ * `{ rows }`, mysql2 a `[rows, fields]` tuple, and better-sqlite3 needs `all`.
343
+ *
344
+ * @param statement - Drizzle `sql` template to run
345
+ * @returns Rows the statement produced
346
+ */
347
+ queryStatement<T = Record<string, unknown>>(statement: SQL): Promise<T[]>;
348
+ /**
349
+ * Take an exclusive lock on a single row for the rest of this transaction.
350
+ *
351
+ * @remarks
352
+ * For read-modify-write sequences that must not interleave: without a lock
353
+ * another transaction can commit between the read and the write, leaving the
354
+ * caller's view of the prior state inconsistent with what its own write
355
+ * applied on top of.
356
+ *
357
+ * No-ops on dialects without row-level locking. SQLite is the case that
358
+ * matters and needs nothing — its transactions open with `BEGIN IMMEDIATE`,
359
+ * which already serializes writers.
360
+ *
361
+ * @param table - Table name
362
+ * @param id - Primary-key value of the row to lock
363
+ */
364
+ lockRow(table: string, id: SqlParam): Promise<void>;
278
365
  /**
279
366
  * Insert a single record.
280
367
  *
@@ -319,6 +406,31 @@ interface TransactionContext {
319
406
  * @returns Updated records (with RETURNING columns if specified)
320
407
  */
321
408
  update<T = unknown>(table: string, data: Record<string, unknown>, where: WhereClause, options?: UpdateOptions): Promise<T[]>;
409
+ /**
410
+ * Update records and report how many rows the statement affected.
411
+ *
412
+ * @remarks
413
+ * The transactional half of the adapter's `updateCount`, and the only way to
414
+ * perform a fenced compare-and-set inside a transaction. `update` cannot
415
+ * answer this: without `returning` it discards the driver's count, and WITH
416
+ * `returning` on a dialect that lacks RETURNING it re-SELECTs using the same
417
+ * WHERE — so a conditional update whose own write falsifies its predicate
418
+ * reads back zero rows, and a write that landed reports as unmatched.
419
+ *
420
+ * 🔴 Inherits the adapter's MySQL caveat: MySQL counts CHANGED rows rather
421
+ * than matched ones, so a caller using this as a compare-and-set must write
422
+ * at least one column the update always moves — a state transition, a version
423
+ * bump, a timestamp of sufficient resolution. Postgres (`rowCount`) and
424
+ * SQLite (`changes`) count matched rows and do not need the precaution, which
425
+ * is exactly why it cannot be dropped: the dialect where the distinction
426
+ * exists is the one with no RETURNING to fall back on.
427
+ *
428
+ * @param table - Table name
429
+ * @param data - Column values to write
430
+ * @param where - Conditions the update must match
431
+ * @returns Number of rows the statement affected
432
+ */
433
+ updateCount(table: string, data: Record<string, unknown>, where: WhereClause): Promise<number>;
322
434
  /**
323
435
  * Delete records.
324
436
  *
@@ -365,6 +477,20 @@ interface TransactionContext {
365
477
  * @param name - Savepoint name
366
478
  */
367
479
  releaseSavepoint?(name: string): Promise<void>;
480
+ /**
481
+ * Return the Drizzle ORM instance bound to THIS transaction's connection.
482
+ *
483
+ * @remarks
484
+ * Runs Drizzle `sql` templates / fluent queries inside the caller's
485
+ * transaction (same client the delegated CRUD methods use), so services
486
+ * that drop to Drizzle raw SQL (e.g. junction-table writes) can participate
487
+ * in the transaction instead of running on the pooled connection. Required
488
+ * so callers never silently fall back to the pooled connection (which would
489
+ * run a write outside the transaction); every adapter must implement it.
490
+ * Generic return so callers narrow to the dialect Drizzle type they need
491
+ * without an `any` cast.
492
+ */
493
+ getDrizzle<T = unknown>(): T;
368
494
  }
369
495
 
370
496
  /**
@@ -619,4 +745,4 @@ interface MigrationStatus {
619
745
  pending: Migration[];
620
746
  }
621
747
 
622
- export type { DatabaseCapabilities as D, InsertOptions as I, JoinSpec as J, MigrationRecord as M, OrderBySpec as O, PoolStats as P, SelectOptions as S, TransactionContext as T, UpdateOptions as U, WhereClause as W, Migration as a, MigrationStatus as b, MigrationOptions as c, MigrationResult as d, TransactionOptions as e, DeleteOptions as f, UpsertOptions as g, TransactionIsolationLevel as h, WhereCondition as i, WhereOperator as j };
748
+ export { type DeleteOptions as D, type InsertOptions as I, type JoinSpec as J, type MigrationRecord as M, type OrderBySpec as O, type PoolStats as P, type SelectOptions as S, type TransactionContext as T, type UpdateOptions as U, type WhereClause as W, type Migration as a, type MigrationStatus as b, type MigrationOptions as c, type MigrationResult as d, type UpsertOptions as e, type TransactionOptions as f, type DatabaseCapabilities as g, type TransactionIsolationLevel as h, WHERE_OPERATORS as i, type WhereCondition as j, type WhereOperator as k };
@@ -1,9 +1,10 @@
1
- import { D as DrizzleAdapter } from './adapter-nvlxFkF-.cjs';
2
- import { M as MigrationRecord, a as Migration, b as MigrationStatus, c as MigrationOptions } from './migration-BbO5meEV.cjs';
3
- export { d as MigrationResult } from './migration-BbO5meEV.cjs';
1
+ import { D as DrizzleAdapter } from './adapter-BeMxQXZs.cjs';
2
+ import { M as MigrationRecord, a as Migration, b as MigrationStatus, c as MigrationOptions } from './migration-DhMuYiIm.cjs';
3
+ export { d as MigrationResult } from './migration-DhMuYiIm.cjs';
4
+ import 'drizzle-orm';
4
5
  import './core-CVO7WYDj.cjs';
5
6
  import './schema-BDn8WfSL.cjs';
6
- import './error-um1d_3Uo.cjs';
7
+ import './error-BrdknH2s.cjs';
7
8
 
8
9
  /**
9
10
  * Database migration utilities.
@@ -1,9 +1,10 @@
1
- import { D as DrizzleAdapter } from './adapter-BxJVtttb.js';
2
- import { M as MigrationRecord, a as Migration, b as MigrationStatus, c as MigrationOptions } from './migration-Qe70wDOC.js';
3
- export { d as MigrationResult } from './migration-Qe70wDOC.js';
1
+ import { D as DrizzleAdapter } from './adapter-BRvxUZrS.js';
2
+ import { M as MigrationRecord, a as Migration, b as MigrationStatus, c as MigrationOptions } from './migration-BnT96HFp.js';
3
+ export { d as MigrationResult } from './migration-BnT96HFp.js';
4
+ import 'drizzle-orm';
4
5
  import './core-CVO7WYDj.js';
5
6
  import './schema-BIQ0YQZ_.js';
6
- import './error-um1d_3Uo.js';
7
+ import './error-BrdknH2s.js';
7
8
 
8
9
  /**
9
10
  * Database migration utilities.
@@ -1,9 +1,45 @@
1
1
  'use strict';
2
2
 
3
+ // src/types/query.ts
4
+ var WHERE_OPERATORS = [
5
+ "=",
6
+ "!=",
7
+ "<",
8
+ ">",
9
+ "<=",
10
+ ">=",
11
+ "IN",
12
+ "NOT IN",
13
+ "LIKE",
14
+ "ILIKE",
15
+ "IS NULL",
16
+ "IS NOT NULL",
17
+ "BETWEEN",
18
+ "NOT BETWEEN",
19
+ // Substring match on a TEXT column, with the value taken literally. Despite the name it is
20
+ // not JSON containment, and it is not safe to point at a JSON column: the builder emits a
21
+ // bare `LIKE` with no cast, so on PostgreSQL a `json`/`jsonb` column has no matching operator
22
+ // and the statement ERRORS (`operator does not exist: jsonb ~~ text`). MySQL and SQLite
23
+ // coerce, and there it searches the serialized text — which hits a key name as readily as a
24
+ // value. Text columns only, and a search rather than a containment check.
25
+ "CONTAINS",
26
+ // Declared, never implemented — the builder throws `Unsupported operator: OVERLAPS`. Kept in
27
+ // the union because removing it would be a breaking change to a published type; the refusal
28
+ // is pinned by a test so implementing it has to come through here.
29
+ "OVERLAPS"
30
+ ];
31
+
3
32
  // src/types/error.ts
4
33
  function isDatabaseError(error) {
5
34
  return typeof error === "object" && error !== null && "kind" in error && typeof error.kind === "string";
6
35
  }
36
+ var APPLICATION_ERROR_BRAND = Symbol.for("nextly/NextlyError");
37
+ function isApplicationError(error) {
38
+ if (error === null || typeof error !== "object" && typeof error !== "function") {
39
+ return false;
40
+ }
41
+ return error[APPLICATION_ERROR_BRAND] === true;
42
+ }
7
43
  function createDatabaseError(options) {
8
44
  const error = new Error(options.message);
9
45
  error.name = "DatabaseError";
@@ -18,7 +54,9 @@ function createDatabaseError(options) {
18
54
  return error;
19
55
  }
20
56
 
57
+ exports.WHERE_OPERATORS = WHERE_OPERATORS;
21
58
  exports.createDatabaseError = createDatabaseError;
59
+ exports.isApplicationError = isApplicationError;
22
60
  exports.isDatabaseError = isDatabaseError;
23
61
  //# sourceMappingURL=index.cjs.map
24
62
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/types/error.ts"],"names":[],"mappings":";;;AAuFO,SAAS,gBAAgB,KAAA,EAAwC;AACtE,EAAA,OACE,OAAO,UAAU,QAAA,IACjB,KAAA,KAAU,QACV,MAAA,IAAU,KAAA,IACV,OAAQ,KAAA,CAAwB,IAAA,KAAS,QAAA;AAE7C;AA+CO,SAAS,oBACd,OAAA,EACe;AACf,EAAA,MAAM,KAAA,GAAQ,IAAI,KAAA,CAAM,OAAA,CAAQ,OAAO,CAAA;AACvC,EAAA,KAAA,CAAM,IAAA,GAAO,eAAA;AACb,EAAA,KAAA,CAAM,OAAO,OAAA,CAAQ,IAAA;AAErB,EAAA,IAAI,OAAA,CAAQ,IAAA,KAAS,MAAA,EAAW,KAAA,CAAM,OAAO,OAAA,CAAQ,IAAA;AACrD,EAAA,IAAI,OAAA,CAAQ,UAAA,KAAe,MAAA,EAAW,KAAA,CAAM,aAAa,OAAA,CAAQ,UAAA;AACjE,EAAA,IAAI,OAAA,CAAQ,KAAA,KAAU,MAAA,EAAW,KAAA,CAAM,QAAQ,OAAA,CAAQ,KAAA;AACvD,EAAA,IAAI,OAAA,CAAQ,MAAA,KAAW,MAAA,EAAW,KAAA,CAAM,SAAS,OAAA,CAAQ,MAAA;AACzD,EAAA,IAAI,OAAA,CAAQ,MAAA,KAAW,MAAA,EAAW,KAAA,CAAM,SAAS,OAAA,CAAQ,MAAA;AACzD,EAAA,IAAI,OAAA,CAAQ,IAAA,KAAS,MAAA,EAAW,KAAA,CAAM,OAAO,OAAA,CAAQ,IAAA;AACrD,EAAA,IAAI,OAAA,CAAQ,KAAA,KAAU,MAAA,EAAW,KAAA,CAAM,QAAQ,OAAA,CAAQ,KAAA;AAEvD,EAAA,OAAO,KAAA;AACT","file":"index.cjs","sourcesContent":["/**\n * Database error type definitions.\n *\n * @packageDocumentation\n */\n\n/**\n * Database error classification.\n *\n * @remarks\n * Categorizes database errors for consistent error handling across adapters.\n * Each adapter translates database-specific error codes to these kinds.\n *\n * @public\n */\nexport type DatabaseErrorKind =\n | \"connection\" // Connection/network errors\n | \"query\" // Syntax or execution errors\n | \"constraint\" // Generic constraint violation\n | \"unique_violation\" // Unique constraint violation\n | \"foreign_key_violation\" // Foreign key constraint violation\n | \"check_violation\" // Check constraint violation\n | \"not_null_violation\" // NOT NULL constraint violation\n | \"deadlock\" // Transaction deadlock\n | \"timeout\" // Query or connection timeout\n | \"serialization_failure\" // Serializable transaction conflict\n | \"unsupported_version\" // F17: DB version below minimum or unparseable at connect\n | \"unknown\"; // Unclassified error\n\n/**\n * Enhanced database error interface.\n *\n * @remarks\n * Extends the standard Error interface with database-specific context.\n * Adapters should throw errors implementing this interface for consistent\n * error handling.\n *\n * @example\n * ```typescript\n * try {\n * await adapter.insert('users', { email: 'duplicate@example.com' });\n * } catch (error) {\n * if (isDatabaseError(error) && error.kind === 'unique_violation') {\n * console.log(`Duplicate ${error.column} in ${error.table}`);\n * }\n * }\n * ```\n *\n * @public\n */\nexport interface DatabaseError extends Error {\n /** Error classification */\n kind: DatabaseErrorKind;\n\n /** Database-specific error code (e.g., \"23505\" for PostgreSQL unique violation) */\n code?: string;\n\n /** Constraint name that was violated (if applicable) */\n constraint?: string;\n\n /** Table name involved in the error */\n table?: string;\n\n /** Column name involved in the error */\n column?: string;\n\n /** Detailed error description from the database */\n detail?: string;\n\n /** Hint for resolving the error */\n hint?: string;\n\n /** Original error from the database driver */\n cause?: Error;\n}\n\n/**\n * Type guard for DatabaseError.\n *\n * @remarks\n * Checks if an error is a DatabaseError with proper typing.\n *\n * @param error - Error to check\n * @returns True if error is a DatabaseError\n *\n * @public\n */\nexport function isDatabaseError(error: unknown): error is DatabaseError {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"kind\" in error &&\n typeof (error as DatabaseError).kind === \"string\"\n );\n}\n\n/**\n * Database error constructor options.\n *\n * @public\n */\nexport interface DatabaseErrorOptions {\n /** Error classification */\n kind: DatabaseErrorKind;\n\n /** Error message */\n message: string;\n\n /** Database-specific error code */\n code?: string;\n\n /** Constraint name */\n constraint?: string;\n\n /** Table name */\n table?: string;\n\n /** Column name */\n column?: string;\n\n /** Detailed description */\n detail?: string;\n\n /** Resolution hint */\n hint?: string;\n\n /** Original error */\n cause?: Error;\n}\n\n/**\n * Create a DatabaseError instance.\n *\n * @remarks\n * Helper function to create properly structured DatabaseError objects.\n *\n * @param options - Error options\n * @returns DatabaseError instance\n *\n * @public\n */\nexport function createDatabaseError(\n options: DatabaseErrorOptions\n): DatabaseError {\n const error = new Error(options.message) as DatabaseError;\n error.name = \"DatabaseError\";\n error.kind = options.kind;\n\n if (options.code !== undefined) error.code = options.code;\n if (options.constraint !== undefined) error.constraint = options.constraint;\n if (options.table !== undefined) error.table = options.table;\n if (options.column !== undefined) error.column = options.column;\n if (options.detail !== undefined) error.detail = options.detail;\n if (options.hint !== undefined) error.hint = options.hint;\n if (options.cause !== undefined) error.cause = options.cause;\n\n return error;\n}\n"]}
1
+ {"version":3,"sources":["../../src/types/query.ts","../../src/types/error.ts"],"names":[],"mappings":";;;AAoCO,IAAM,eAAA,GAAkB;AAAA,EAC7B,GAAA;AAAA,EACA,IAAA;AAAA,EACA,GAAA;AAAA,EACA,GAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,QAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA;AAAA,EACA,SAAA;AAAA,EACA,aAAA;AAAA,EACA,SAAA;AAAA,EACA,aAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,UAAA;AAAA;AAAA;AAAA;AAAA,EAIA;AACF;;;ACyBO,SAAS,gBAAgB,KAAA,EAAwC;AACtE,EAAA,OACE,OAAO,UAAU,QAAA,IACjB,KAAA,KAAU,QACV,MAAA,IAAU,KAAA,IACV,OAAQ,KAAA,CAAwB,IAAA,KAAS,QAAA;AAE7C;AAYA,IAAM,uBAAA,GAAyC,MAAA,CAAO,GAAA,CAAI,oBAAoB,CAAA;AAkBvE,SAAS,mBAAmB,KAAA,EAAyB;AAC1D,EAAA,IACE,UAAU,IAAA,IACT,OAAO,UAAU,QAAA,IAAY,OAAO,UAAU,UAAA,EAC/C;AACA,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,OAAQ,KAAA,CAAkC,uBAAuB,CAAA,KAAM,IAAA;AACzE;AA+CO,SAAS,oBACd,OAAA,EACe;AACf,EAAA,MAAM,KAAA,GAAQ,IAAI,KAAA,CAAM,OAAA,CAAQ,OAAO,CAAA;AACvC,EAAA,KAAA,CAAM,IAAA,GAAO,eAAA;AACb,EAAA,KAAA,CAAM,OAAO,OAAA,CAAQ,IAAA;AAErB,EAAA,IAAI,OAAA,CAAQ,IAAA,KAAS,MAAA,EAAW,KAAA,CAAM,OAAO,OAAA,CAAQ,IAAA;AACrD,EAAA,IAAI,OAAA,CAAQ,UAAA,KAAe,MAAA,EAAW,KAAA,CAAM,aAAa,OAAA,CAAQ,UAAA;AACjE,EAAA,IAAI,OAAA,CAAQ,KAAA,KAAU,MAAA,EAAW,KAAA,CAAM,QAAQ,OAAA,CAAQ,KAAA;AACvD,EAAA,IAAI,OAAA,CAAQ,MAAA,KAAW,MAAA,EAAW,KAAA,CAAM,SAAS,OAAA,CAAQ,MAAA;AACzD,EAAA,IAAI,OAAA,CAAQ,MAAA,KAAW,MAAA,EAAW,KAAA,CAAM,SAAS,OAAA,CAAQ,MAAA;AACzD,EAAA,IAAI,OAAA,CAAQ,IAAA,KAAS,MAAA,EAAW,KAAA,CAAM,OAAO,OAAA,CAAQ,IAAA;AACrD,EAAA,IAAI,OAAA,CAAQ,KAAA,KAAU,MAAA,EAAW,KAAA,CAAM,QAAQ,OAAA,CAAQ,KAAA;AAEvD,EAAA,OAAO,KAAA;AACT","file":"index.cjs","sourcesContent":["/**\n * Query building type definitions for database-agnostic queries.\n *\n * @packageDocumentation\n */\n\nimport type { SqlParam } from \"./core\";\n\n/**\n * Every WHERE clause operator this package DECLARES, as a value.\n *\n * @remarks\n * Declared, not guaranteed executable. Membership here means a `WhereCondition`\n * carrying the operator type-checks — it does NOT mean the adapter can run it.\n * `OVERLAPS` is declared and unimplemented, and throws at build time, so a\n * validator written against this list will admit input the query layer then\n * rejects. Validate against it to catch a misspelled operator; do not read\n * acceptance here as a capability.\n *\n * - Standard comparison: =, !=, <, >, <=, >=\n * - Set operations: IN, NOT IN\n * - Pattern matching: LIKE, ILIKE (case-insensitive, PostgreSQL/emulated)\n * - NULL checks: IS NULL, IS NOT NULL\n * - Range: BETWEEN, NOT BETWEEN\n * - Substring: CONTAINS — a LITERAL match on a TEXT column; see below\n * - Declared but NOT implemented: OVERLAPS, which throws\n *\n * This list is the source of truth and {@link WhereOperator} is derived from it,\n * rather than the two being written out separately. A guard that has to enumerate\n * the operators — a validator over caller input, or a test asserting the builder\n * handles or refuses each one — can only do that from a runtime value, and a\n * hand-kept copy of the union would agree with it on the day it was written and\n * silently stop agreeing the next time a member is added.\n *\n * @public\n */\nexport const WHERE_OPERATORS = [\n \"=\",\n \"!=\",\n \"<\",\n \">\",\n \"<=\",\n \">=\",\n \"IN\",\n \"NOT IN\",\n \"LIKE\",\n \"ILIKE\",\n \"IS NULL\",\n \"IS NOT NULL\",\n \"BETWEEN\",\n \"NOT BETWEEN\",\n // Substring match on a TEXT column, with the value taken literally. Despite the name it is\n // not JSON containment, and it is not safe to point at a JSON column: the builder emits a\n // bare `LIKE` with no cast, so on PostgreSQL a `json`/`jsonb` column has no matching operator\n // and the statement ERRORS (`operator does not exist: jsonb ~~ text`). MySQL and SQLite\n // coerce, and there it searches the serialized text — which hits a key name as readily as a\n // value. Text columns only, and a search rather than a containment check.\n \"CONTAINS\",\n // Declared, never implemented — the builder throws `Unsupported operator: OVERLAPS`. Kept in\n // the union because removing it would be a breaking change to a published type; the refusal\n // is pinned by a test so implementing it has to come through here.\n \"OVERLAPS\",\n] as const;\n\n/**\n * Every WHERE clause operator this package declares. Derived from\n * {@link WHERE_OPERATORS}, and carrying the same caveat: a value of this type\n * type-checks, which is not the same as the adapter being able to execute it.\n *\n * @public\n */\nexport type WhereOperator = (typeof WHERE_OPERATORS)[number];\n\n/**\n * Individual WHERE condition.\n *\n * @remarks\n * Represents a single condition in a WHERE clause. For IS NULL and IS NOT NULL\n * operators, the value field is optional.\n *\n * @public\n */\nexport interface WhereCondition {\n /** Column name to filter on */\n column: string;\n\n /** Comparison operator */\n op: WhereOperator;\n\n /** Value(s) to compare against (optional for IS NULL/IS NOT NULL) */\n value?: SqlParam | SqlParam[];\n\n /** Second value for BETWEEN operator */\n valueTo?: SqlParam;\n}\n\n/**\n * Complex WHERE clause with logical operators.\n *\n * @remarks\n * Supports nested conditions with AND, OR, and NOT logical operators.\n * Can be recursively nested for complex queries.\n *\n * @example\n * ```typescript\n * const where: WhereClause = {\n * and: [\n * { column: \"status\", op: \"=\", value: \"published\" },\n * {\n * or: [\n * { column: \"author\", op: \"=\", value: \"john\" },\n * { column: \"author\", op: \"=\", value: \"jane\" }\n * ]\n * }\n * ]\n * };\n * ```\n *\n * @public\n */\nexport interface WhereClause {\n /** All conditions must be true (AND) */\n and?: (WhereCondition | WhereClause)[];\n\n /** At least one condition must be true (OR) */\n or?: (WhereCondition | WhereClause)[];\n\n /** Negate a condition (NOT) */\n not?: WhereCondition | WhereClause;\n}\n\n/**\n * ORDER BY specification for query results.\n *\n * @remarks\n * Controls the sorting of query results. NULL handling varies by database\n * but can be explicitly controlled with the nulls field.\n *\n * @public\n */\nexport interface OrderBySpec {\n /** Column name to sort by */\n column: string;\n\n /** Sort direction (default: asc) */\n direction?: \"asc\" | \"desc\";\n\n /** NULL value ordering (database-specific defaults vary) */\n nulls?: \"first\" | \"last\";\n}\n\n/**\n * JOIN specification for table joins.\n *\n * @remarks\n * Supports different types of JOINs. Note that complex joins may require\n * dialect-specific handling.\n *\n * @public\n */\nexport interface JoinSpec {\n /** Type of join */\n type: \"inner\" | \"left\" | \"right\" | \"full\";\n\n /** Table name to join */\n table: string;\n\n /** Join condition */\n on: {\n /** Column from the left table */\n leftColumn: string;\n /** Column from the right table */\n rightColumn: string;\n };\n\n /** Optional alias for the joined table */\n alias?: string;\n}\n","/**\n * Database error type definitions.\n *\n * @packageDocumentation\n */\n\n/**\n * Database error classification.\n *\n * @remarks\n * Categorizes database errors for consistent error handling across adapters.\n * Each adapter translates database-specific error codes to these kinds.\n *\n * @public\n */\nexport type DatabaseErrorKind =\n | \"connection\" // Connection/network errors\n | \"query\" // Syntax or execution errors\n | \"constraint\" // Generic constraint violation\n | \"unique_violation\" // Unique constraint violation\n | \"foreign_key_violation\" // Foreign key constraint violation\n | \"check_violation\" // Check constraint violation\n | \"not_null_violation\" // NOT NULL constraint violation\n | \"deadlock\" // Transaction deadlock\n | \"timeout\" // Query or connection timeout\n | \"serialization_failure\" // Serializable transaction conflict\n | \"unsupported_version\" // F17: DB version below minimum or unparseable at connect\n | \"unknown\"; // Unclassified error\n\n/**\n * Enhanced database error interface.\n *\n * @remarks\n * Extends the standard Error interface with database-specific context.\n * Adapters should throw errors implementing this interface for consistent\n * error handling.\n *\n * @example\n * ```typescript\n * try {\n * await adapter.insert('users', { email: 'duplicate@example.com' });\n * } catch (error) {\n * if (isDatabaseError(error) && error.kind === 'unique_violation') {\n * console.log(`Duplicate ${error.column} in ${error.table}`);\n * }\n * }\n * ```\n *\n * @public\n */\nexport interface DatabaseError extends Error {\n /** Error classification */\n kind: DatabaseErrorKind;\n\n /** Database-specific error code (e.g., \"23505\" for PostgreSQL unique violation) */\n code?: string;\n\n /** Constraint name that was violated (if applicable) */\n constraint?: string;\n\n /** Table name involved in the error */\n table?: string;\n\n /** Column name involved in the error */\n column?: string;\n\n /** Detailed error description from the database */\n detail?: string;\n\n /** Hint for resolving the error */\n hint?: string;\n\n /** Original error from the database driver */\n cause?: Error;\n}\n\n/**\n * Type guard for DatabaseError.\n *\n * @remarks\n * Checks if an error is a DatabaseError with proper typing.\n *\n * @param error - Error to check\n * @returns True if error is a DatabaseError\n *\n * @public\n */\nexport function isDatabaseError(error: unknown): error is DatabaseError {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"kind\" in error &&\n typeof (error as DatabaseError).kind === \"string\"\n );\n}\n\n/**\n * The brand every Nextly application error carries.\n *\n * Read through the global symbol registry rather than imported, because the\n * adapters must not depend on the package that defines the error: `Symbol.for`\n * resolves to the same symbol in every module instance, which is why the brand\n * exists in that form to begin with.\n *\n * @internal\n */\nconst APPLICATION_ERROR_BRAND: unique symbol = Symbol.for(\"nextly/NextlyError\");\n\n/**\n * Whether an error is the application's verdict rather than the database's\n * failure.\n *\n * Work running inside a transaction may throw to roll the write back — a\n * refused value, a permission denial — and such an error is not something the\n * driver produced. Classifying it as a database error replaces its code and its\n * payload with a generic one, so a caller that asked for a refusal is handed an\n * unexplained failure instead, and per-field validation detail is lost on the\n * way out.\n *\n * @param error - Error to check\n * @returns True if the error was raised by application code\n *\n * @public\n */\nexport function isApplicationError(error: unknown): boolean {\n if (\n error === null ||\n (typeof error !== \"object\" && typeof error !== \"function\")\n ) {\n return false;\n }\n return (error as Record<symbol, unknown>)[APPLICATION_ERROR_BRAND] === true;\n}\n\n/**\n * Database error constructor options.\n *\n * @public\n */\nexport interface DatabaseErrorOptions {\n /** Error classification */\n kind: DatabaseErrorKind;\n\n /** Error message */\n message: string;\n\n /** Database-specific error code */\n code?: string;\n\n /** Constraint name */\n constraint?: string;\n\n /** Table name */\n table?: string;\n\n /** Column name */\n column?: string;\n\n /** Detailed description */\n detail?: string;\n\n /** Resolution hint */\n hint?: string;\n\n /** Original error */\n cause?: Error;\n}\n\n/**\n * Create a DatabaseError instance.\n *\n * @remarks\n * Helper function to create properly structured DatabaseError objects.\n *\n * @param options - Error options\n * @returns DatabaseError instance\n *\n * @public\n */\nexport function createDatabaseError(\n options: DatabaseErrorOptions\n): DatabaseError {\n const error = new Error(options.message) as DatabaseError;\n error.name = \"DatabaseError\";\n error.kind = options.kind;\n\n if (options.code !== undefined) error.code = options.code;\n if (options.constraint !== undefined) error.constraint = options.constraint;\n if (options.table !== undefined) error.table = options.table;\n if (options.column !== undefined) error.column = options.column;\n if (options.detail !== undefined) error.detail = options.detail;\n if (options.hint !== undefined) error.hint = options.hint;\n if (options.cause !== undefined) error.cause = options.cause;\n\n return error;\n}\n"]}
@@ -1,8 +1,9 @@
1
1
  import { a as SqlParam } from '../core-CVO7WYDj.cjs';
2
2
  export { J as JsonArray, b as JsonObject, c as JsonValue, S as SupportedDialect, T as TableResolver } from '../core-CVO7WYDj.cjs';
3
- export { D as DatabaseCapabilities, f as DeleteOptions, I as InsertOptions, J as JoinSpec, a as Migration, c as MigrationOptions, M as MigrationRecord, d as MigrationResult, b as MigrationStatus, O as OrderBySpec, P as PoolStats, S as SelectOptions, T as TransactionContext, h as TransactionIsolationLevel, e as TransactionOptions, U as UpdateOptions, g as UpsertOptions, W as WhereClause, i as WhereCondition, j as WhereOperator } from '../migration-BbO5meEV.cjs';
3
+ export { g as DatabaseCapabilities, D as DeleteOptions, I as InsertOptions, J as JoinSpec, a as Migration, c as MigrationOptions, M as MigrationRecord, d as MigrationResult, b as MigrationStatus, O as OrderBySpec, P as PoolStats, S as SelectOptions, T as TransactionContext, h as TransactionIsolationLevel, f as TransactionOptions, U as UpdateOptions, e as UpsertOptions, i as WHERE_OPERATORS, W as WhereClause, j as WhereCondition, k as WhereOperator } from '../migration-DhMuYiIm.cjs';
4
4
  export { A as AlterTableOperation, a as AlterTableOptions, b as ColumnDefinition, C as CreateTableOptions, D as DropTableOptions, I as IndexDefinition, c as TableConstraint, T as TableDefinition } from '../schema-BDn8WfSL.cjs';
5
- export { a as DatabaseError, D as DatabaseErrorKind, b as DatabaseErrorOptions, c as createDatabaseError, i as isDatabaseError } from '../error-um1d_3Uo.cjs';
5
+ export { a as DatabaseError, D as DatabaseErrorKind, b as DatabaseErrorOptions, c as createDatabaseError, i as isApplicationError, d as isDatabaseError } from '../error-BrdknH2s.cjs';
6
+ import 'drizzle-orm';
6
7
 
7
8
  /**
8
9
  * Database adapter configuration type definitions.
@@ -1,8 +1,9 @@
1
1
  import { a as SqlParam } from '../core-CVO7WYDj.js';
2
2
  export { J as JsonArray, b as JsonObject, c as JsonValue, S as SupportedDialect, T as TableResolver } from '../core-CVO7WYDj.js';
3
- export { D as DatabaseCapabilities, f as DeleteOptions, I as InsertOptions, J as JoinSpec, a as Migration, c as MigrationOptions, M as MigrationRecord, d as MigrationResult, b as MigrationStatus, O as OrderBySpec, P as PoolStats, S as SelectOptions, T as TransactionContext, h as TransactionIsolationLevel, e as TransactionOptions, U as UpdateOptions, g as UpsertOptions, W as WhereClause, i as WhereCondition, j as WhereOperator } from '../migration-Qe70wDOC.js';
3
+ export { g as DatabaseCapabilities, D as DeleteOptions, I as InsertOptions, J as JoinSpec, a as Migration, c as MigrationOptions, M as MigrationRecord, d as MigrationResult, b as MigrationStatus, O as OrderBySpec, P as PoolStats, S as SelectOptions, T as TransactionContext, h as TransactionIsolationLevel, f as TransactionOptions, U as UpdateOptions, e as UpsertOptions, i as WHERE_OPERATORS, W as WhereClause, j as WhereCondition, k as WhereOperator } from '../migration-BnT96HFp.js';
4
4
  export { A as AlterTableOperation, a as AlterTableOptions, b as ColumnDefinition, C as CreateTableOptions, D as DropTableOptions, I as IndexDefinition, c as TableConstraint, T as TableDefinition } from '../schema-BIQ0YQZ_.js';
5
- export { a as DatabaseError, D as DatabaseErrorKind, b as DatabaseErrorOptions, c as createDatabaseError, i as isDatabaseError } from '../error-um1d_3Uo.js';
5
+ export { a as DatabaseError, D as DatabaseErrorKind, b as DatabaseErrorOptions, c as createDatabaseError, i as isApplicationError, d as isDatabaseError } from '../error-BrdknH2s.js';
6
+ import 'drizzle-orm';
6
7
 
7
8
  /**
8
9
  * Database adapter configuration type definitions.
@@ -1,7 +1,43 @@
1
+ // src/types/query.ts
2
+ var WHERE_OPERATORS = [
3
+ "=",
4
+ "!=",
5
+ "<",
6
+ ">",
7
+ "<=",
8
+ ">=",
9
+ "IN",
10
+ "NOT IN",
11
+ "LIKE",
12
+ "ILIKE",
13
+ "IS NULL",
14
+ "IS NOT NULL",
15
+ "BETWEEN",
16
+ "NOT BETWEEN",
17
+ // Substring match on a TEXT column, with the value taken literally. Despite the name it is
18
+ // not JSON containment, and it is not safe to point at a JSON column: the builder emits a
19
+ // bare `LIKE` with no cast, so on PostgreSQL a `json`/`jsonb` column has no matching operator
20
+ // and the statement ERRORS (`operator does not exist: jsonb ~~ text`). MySQL and SQLite
21
+ // coerce, and there it searches the serialized text — which hits a key name as readily as a
22
+ // value. Text columns only, and a search rather than a containment check.
23
+ "CONTAINS",
24
+ // Declared, never implemented — the builder throws `Unsupported operator: OVERLAPS`. Kept in
25
+ // the union because removing it would be a breaking change to a published type; the refusal
26
+ // is pinned by a test so implementing it has to come through here.
27
+ "OVERLAPS"
28
+ ];
29
+
1
30
  // src/types/error.ts
2
31
  function isDatabaseError(error) {
3
32
  return typeof error === "object" && error !== null && "kind" in error && typeof error.kind === "string";
4
33
  }
34
+ var APPLICATION_ERROR_BRAND = Symbol.for("nextly/NextlyError");
35
+ function isApplicationError(error) {
36
+ if (error === null || typeof error !== "object" && typeof error !== "function") {
37
+ return false;
38
+ }
39
+ return error[APPLICATION_ERROR_BRAND] === true;
40
+ }
5
41
  function createDatabaseError(options) {
6
42
  const error = new Error(options.message);
7
43
  error.name = "DatabaseError";
@@ -16,6 +52,6 @@ function createDatabaseError(options) {
16
52
  return error;
17
53
  }
18
54
 
19
- export { createDatabaseError, isDatabaseError };
55
+ export { WHERE_OPERATORS, createDatabaseError, isApplicationError, isDatabaseError };
20
56
  //# sourceMappingURL=index.mjs.map
21
57
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/types/error.ts"],"names":[],"mappings":";AAuFO,SAAS,gBAAgB,KAAA,EAAwC;AACtE,EAAA,OACE,OAAO,UAAU,QAAA,IACjB,KAAA,KAAU,QACV,MAAA,IAAU,KAAA,IACV,OAAQ,KAAA,CAAwB,IAAA,KAAS,QAAA;AAE7C;AA+CO,SAAS,oBACd,OAAA,EACe;AACf,EAAA,MAAM,KAAA,GAAQ,IAAI,KAAA,CAAM,OAAA,CAAQ,OAAO,CAAA;AACvC,EAAA,KAAA,CAAM,IAAA,GAAO,eAAA;AACb,EAAA,KAAA,CAAM,OAAO,OAAA,CAAQ,IAAA;AAErB,EAAA,IAAI,OAAA,CAAQ,IAAA,KAAS,MAAA,EAAW,KAAA,CAAM,OAAO,OAAA,CAAQ,IAAA;AACrD,EAAA,IAAI,OAAA,CAAQ,UAAA,KAAe,MAAA,EAAW,KAAA,CAAM,aAAa,OAAA,CAAQ,UAAA;AACjE,EAAA,IAAI,OAAA,CAAQ,KAAA,KAAU,MAAA,EAAW,KAAA,CAAM,QAAQ,OAAA,CAAQ,KAAA;AACvD,EAAA,IAAI,OAAA,CAAQ,MAAA,KAAW,MAAA,EAAW,KAAA,CAAM,SAAS,OAAA,CAAQ,MAAA;AACzD,EAAA,IAAI,OAAA,CAAQ,MAAA,KAAW,MAAA,EAAW,KAAA,CAAM,SAAS,OAAA,CAAQ,MAAA;AACzD,EAAA,IAAI,OAAA,CAAQ,IAAA,KAAS,MAAA,EAAW,KAAA,CAAM,OAAO,OAAA,CAAQ,IAAA;AACrD,EAAA,IAAI,OAAA,CAAQ,KAAA,KAAU,MAAA,EAAW,KAAA,CAAM,QAAQ,OAAA,CAAQ,KAAA;AAEvD,EAAA,OAAO,KAAA;AACT","file":"index.mjs","sourcesContent":["/**\n * Database error type definitions.\n *\n * @packageDocumentation\n */\n\n/**\n * Database error classification.\n *\n * @remarks\n * Categorizes database errors for consistent error handling across adapters.\n * Each adapter translates database-specific error codes to these kinds.\n *\n * @public\n */\nexport type DatabaseErrorKind =\n | \"connection\" // Connection/network errors\n | \"query\" // Syntax or execution errors\n | \"constraint\" // Generic constraint violation\n | \"unique_violation\" // Unique constraint violation\n | \"foreign_key_violation\" // Foreign key constraint violation\n | \"check_violation\" // Check constraint violation\n | \"not_null_violation\" // NOT NULL constraint violation\n | \"deadlock\" // Transaction deadlock\n | \"timeout\" // Query or connection timeout\n | \"serialization_failure\" // Serializable transaction conflict\n | \"unsupported_version\" // F17: DB version below minimum or unparseable at connect\n | \"unknown\"; // Unclassified error\n\n/**\n * Enhanced database error interface.\n *\n * @remarks\n * Extends the standard Error interface with database-specific context.\n * Adapters should throw errors implementing this interface for consistent\n * error handling.\n *\n * @example\n * ```typescript\n * try {\n * await adapter.insert('users', { email: 'duplicate@example.com' });\n * } catch (error) {\n * if (isDatabaseError(error) && error.kind === 'unique_violation') {\n * console.log(`Duplicate ${error.column} in ${error.table}`);\n * }\n * }\n * ```\n *\n * @public\n */\nexport interface DatabaseError extends Error {\n /** Error classification */\n kind: DatabaseErrorKind;\n\n /** Database-specific error code (e.g., \"23505\" for PostgreSQL unique violation) */\n code?: string;\n\n /** Constraint name that was violated (if applicable) */\n constraint?: string;\n\n /** Table name involved in the error */\n table?: string;\n\n /** Column name involved in the error */\n column?: string;\n\n /** Detailed error description from the database */\n detail?: string;\n\n /** Hint for resolving the error */\n hint?: string;\n\n /** Original error from the database driver */\n cause?: Error;\n}\n\n/**\n * Type guard for DatabaseError.\n *\n * @remarks\n * Checks if an error is a DatabaseError with proper typing.\n *\n * @param error - Error to check\n * @returns True if error is a DatabaseError\n *\n * @public\n */\nexport function isDatabaseError(error: unknown): error is DatabaseError {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"kind\" in error &&\n typeof (error as DatabaseError).kind === \"string\"\n );\n}\n\n/**\n * Database error constructor options.\n *\n * @public\n */\nexport interface DatabaseErrorOptions {\n /** Error classification */\n kind: DatabaseErrorKind;\n\n /** Error message */\n message: string;\n\n /** Database-specific error code */\n code?: string;\n\n /** Constraint name */\n constraint?: string;\n\n /** Table name */\n table?: string;\n\n /** Column name */\n column?: string;\n\n /** Detailed description */\n detail?: string;\n\n /** Resolution hint */\n hint?: string;\n\n /** Original error */\n cause?: Error;\n}\n\n/**\n * Create a DatabaseError instance.\n *\n * @remarks\n * Helper function to create properly structured DatabaseError objects.\n *\n * @param options - Error options\n * @returns DatabaseError instance\n *\n * @public\n */\nexport function createDatabaseError(\n options: DatabaseErrorOptions\n): DatabaseError {\n const error = new Error(options.message) as DatabaseError;\n error.name = \"DatabaseError\";\n error.kind = options.kind;\n\n if (options.code !== undefined) error.code = options.code;\n if (options.constraint !== undefined) error.constraint = options.constraint;\n if (options.table !== undefined) error.table = options.table;\n if (options.column !== undefined) error.column = options.column;\n if (options.detail !== undefined) error.detail = options.detail;\n if (options.hint !== undefined) error.hint = options.hint;\n if (options.cause !== undefined) error.cause = options.cause;\n\n return error;\n}\n"]}
1
+ {"version":3,"sources":["../../src/types/query.ts","../../src/types/error.ts"],"names":[],"mappings":";AAoCO,IAAM,eAAA,GAAkB;AAAA,EAC7B,GAAA;AAAA,EACA,IAAA;AAAA,EACA,GAAA;AAAA,EACA,GAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,QAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA;AAAA,EACA,SAAA;AAAA,EACA,aAAA;AAAA,EACA,SAAA;AAAA,EACA,aAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,UAAA;AAAA;AAAA;AAAA;AAAA,EAIA;AACF;;;ACyBO,SAAS,gBAAgB,KAAA,EAAwC;AACtE,EAAA,OACE,OAAO,UAAU,QAAA,IACjB,KAAA,KAAU,QACV,MAAA,IAAU,KAAA,IACV,OAAQ,KAAA,CAAwB,IAAA,KAAS,QAAA;AAE7C;AAYA,IAAM,uBAAA,GAAyC,MAAA,CAAO,GAAA,CAAI,oBAAoB,CAAA;AAkBvE,SAAS,mBAAmB,KAAA,EAAyB;AAC1D,EAAA,IACE,UAAU,IAAA,IACT,OAAO,UAAU,QAAA,IAAY,OAAO,UAAU,UAAA,EAC/C;AACA,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,OAAQ,KAAA,CAAkC,uBAAuB,CAAA,KAAM,IAAA;AACzE;AA+CO,SAAS,oBACd,OAAA,EACe;AACf,EAAA,MAAM,KAAA,GAAQ,IAAI,KAAA,CAAM,OAAA,CAAQ,OAAO,CAAA;AACvC,EAAA,KAAA,CAAM,IAAA,GAAO,eAAA;AACb,EAAA,KAAA,CAAM,OAAO,OAAA,CAAQ,IAAA;AAErB,EAAA,IAAI,OAAA,CAAQ,IAAA,KAAS,MAAA,EAAW,KAAA,CAAM,OAAO,OAAA,CAAQ,IAAA;AACrD,EAAA,IAAI,OAAA,CAAQ,UAAA,KAAe,MAAA,EAAW,KAAA,CAAM,aAAa,OAAA,CAAQ,UAAA;AACjE,EAAA,IAAI,OAAA,CAAQ,KAAA,KAAU,MAAA,EAAW,KAAA,CAAM,QAAQ,OAAA,CAAQ,KAAA;AACvD,EAAA,IAAI,OAAA,CAAQ,MAAA,KAAW,MAAA,EAAW,KAAA,CAAM,SAAS,OAAA,CAAQ,MAAA;AACzD,EAAA,IAAI,OAAA,CAAQ,MAAA,KAAW,MAAA,EAAW,KAAA,CAAM,SAAS,OAAA,CAAQ,MAAA;AACzD,EAAA,IAAI,OAAA,CAAQ,IAAA,KAAS,MAAA,EAAW,KAAA,CAAM,OAAO,OAAA,CAAQ,IAAA;AACrD,EAAA,IAAI,OAAA,CAAQ,KAAA,KAAU,MAAA,EAAW,KAAA,CAAM,QAAQ,OAAA,CAAQ,KAAA;AAEvD,EAAA,OAAO,KAAA;AACT","file":"index.mjs","sourcesContent":["/**\n * Query building type definitions for database-agnostic queries.\n *\n * @packageDocumentation\n */\n\nimport type { SqlParam } from \"./core\";\n\n/**\n * Every WHERE clause operator this package DECLARES, as a value.\n *\n * @remarks\n * Declared, not guaranteed executable. Membership here means a `WhereCondition`\n * carrying the operator type-checks — it does NOT mean the adapter can run it.\n * `OVERLAPS` is declared and unimplemented, and throws at build time, so a\n * validator written against this list will admit input the query layer then\n * rejects. Validate against it to catch a misspelled operator; do not read\n * acceptance here as a capability.\n *\n * - Standard comparison: =, !=, <, >, <=, >=\n * - Set operations: IN, NOT IN\n * - Pattern matching: LIKE, ILIKE (case-insensitive, PostgreSQL/emulated)\n * - NULL checks: IS NULL, IS NOT NULL\n * - Range: BETWEEN, NOT BETWEEN\n * - Substring: CONTAINS — a LITERAL match on a TEXT column; see below\n * - Declared but NOT implemented: OVERLAPS, which throws\n *\n * This list is the source of truth and {@link WhereOperator} is derived from it,\n * rather than the two being written out separately. A guard that has to enumerate\n * the operators — a validator over caller input, or a test asserting the builder\n * handles or refuses each one — can only do that from a runtime value, and a\n * hand-kept copy of the union would agree with it on the day it was written and\n * silently stop agreeing the next time a member is added.\n *\n * @public\n */\nexport const WHERE_OPERATORS = [\n \"=\",\n \"!=\",\n \"<\",\n \">\",\n \"<=\",\n \">=\",\n \"IN\",\n \"NOT IN\",\n \"LIKE\",\n \"ILIKE\",\n \"IS NULL\",\n \"IS NOT NULL\",\n \"BETWEEN\",\n \"NOT BETWEEN\",\n // Substring match on a TEXT column, with the value taken literally. Despite the name it is\n // not JSON containment, and it is not safe to point at a JSON column: the builder emits a\n // bare `LIKE` with no cast, so on PostgreSQL a `json`/`jsonb` column has no matching operator\n // and the statement ERRORS (`operator does not exist: jsonb ~~ text`). MySQL and SQLite\n // coerce, and there it searches the serialized text — which hits a key name as readily as a\n // value. Text columns only, and a search rather than a containment check.\n \"CONTAINS\",\n // Declared, never implemented — the builder throws `Unsupported operator: OVERLAPS`. Kept in\n // the union because removing it would be a breaking change to a published type; the refusal\n // is pinned by a test so implementing it has to come through here.\n \"OVERLAPS\",\n] as const;\n\n/**\n * Every WHERE clause operator this package declares. Derived from\n * {@link WHERE_OPERATORS}, and carrying the same caveat: a value of this type\n * type-checks, which is not the same as the adapter being able to execute it.\n *\n * @public\n */\nexport type WhereOperator = (typeof WHERE_OPERATORS)[number];\n\n/**\n * Individual WHERE condition.\n *\n * @remarks\n * Represents a single condition in a WHERE clause. For IS NULL and IS NOT NULL\n * operators, the value field is optional.\n *\n * @public\n */\nexport interface WhereCondition {\n /** Column name to filter on */\n column: string;\n\n /** Comparison operator */\n op: WhereOperator;\n\n /** Value(s) to compare against (optional for IS NULL/IS NOT NULL) */\n value?: SqlParam | SqlParam[];\n\n /** Second value for BETWEEN operator */\n valueTo?: SqlParam;\n}\n\n/**\n * Complex WHERE clause with logical operators.\n *\n * @remarks\n * Supports nested conditions with AND, OR, and NOT logical operators.\n * Can be recursively nested for complex queries.\n *\n * @example\n * ```typescript\n * const where: WhereClause = {\n * and: [\n * { column: \"status\", op: \"=\", value: \"published\" },\n * {\n * or: [\n * { column: \"author\", op: \"=\", value: \"john\" },\n * { column: \"author\", op: \"=\", value: \"jane\" }\n * ]\n * }\n * ]\n * };\n * ```\n *\n * @public\n */\nexport interface WhereClause {\n /** All conditions must be true (AND) */\n and?: (WhereCondition | WhereClause)[];\n\n /** At least one condition must be true (OR) */\n or?: (WhereCondition | WhereClause)[];\n\n /** Negate a condition (NOT) */\n not?: WhereCondition | WhereClause;\n}\n\n/**\n * ORDER BY specification for query results.\n *\n * @remarks\n * Controls the sorting of query results. NULL handling varies by database\n * but can be explicitly controlled with the nulls field.\n *\n * @public\n */\nexport interface OrderBySpec {\n /** Column name to sort by */\n column: string;\n\n /** Sort direction (default: asc) */\n direction?: \"asc\" | \"desc\";\n\n /** NULL value ordering (database-specific defaults vary) */\n nulls?: \"first\" | \"last\";\n}\n\n/**\n * JOIN specification for table joins.\n *\n * @remarks\n * Supports different types of JOINs. Note that complex joins may require\n * dialect-specific handling.\n *\n * @public\n */\nexport interface JoinSpec {\n /** Type of join */\n type: \"inner\" | \"left\" | \"right\" | \"full\";\n\n /** Table name to join */\n table: string;\n\n /** Join condition */\n on: {\n /** Column from the left table */\n leftColumn: string;\n /** Column from the right table */\n rightColumn: string;\n };\n\n /** Optional alias for the joined table */\n alias?: string;\n}\n","/**\n * Database error type definitions.\n *\n * @packageDocumentation\n */\n\n/**\n * Database error classification.\n *\n * @remarks\n * Categorizes database errors for consistent error handling across adapters.\n * Each adapter translates database-specific error codes to these kinds.\n *\n * @public\n */\nexport type DatabaseErrorKind =\n | \"connection\" // Connection/network errors\n | \"query\" // Syntax or execution errors\n | \"constraint\" // Generic constraint violation\n | \"unique_violation\" // Unique constraint violation\n | \"foreign_key_violation\" // Foreign key constraint violation\n | \"check_violation\" // Check constraint violation\n | \"not_null_violation\" // NOT NULL constraint violation\n | \"deadlock\" // Transaction deadlock\n | \"timeout\" // Query or connection timeout\n | \"serialization_failure\" // Serializable transaction conflict\n | \"unsupported_version\" // F17: DB version below minimum or unparseable at connect\n | \"unknown\"; // Unclassified error\n\n/**\n * Enhanced database error interface.\n *\n * @remarks\n * Extends the standard Error interface with database-specific context.\n * Adapters should throw errors implementing this interface for consistent\n * error handling.\n *\n * @example\n * ```typescript\n * try {\n * await adapter.insert('users', { email: 'duplicate@example.com' });\n * } catch (error) {\n * if (isDatabaseError(error) && error.kind === 'unique_violation') {\n * console.log(`Duplicate ${error.column} in ${error.table}`);\n * }\n * }\n * ```\n *\n * @public\n */\nexport interface DatabaseError extends Error {\n /** Error classification */\n kind: DatabaseErrorKind;\n\n /** Database-specific error code (e.g., \"23505\" for PostgreSQL unique violation) */\n code?: string;\n\n /** Constraint name that was violated (if applicable) */\n constraint?: string;\n\n /** Table name involved in the error */\n table?: string;\n\n /** Column name involved in the error */\n column?: string;\n\n /** Detailed error description from the database */\n detail?: string;\n\n /** Hint for resolving the error */\n hint?: string;\n\n /** Original error from the database driver */\n cause?: Error;\n}\n\n/**\n * Type guard for DatabaseError.\n *\n * @remarks\n * Checks if an error is a DatabaseError with proper typing.\n *\n * @param error - Error to check\n * @returns True if error is a DatabaseError\n *\n * @public\n */\nexport function isDatabaseError(error: unknown): error is DatabaseError {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"kind\" in error &&\n typeof (error as DatabaseError).kind === \"string\"\n );\n}\n\n/**\n * The brand every Nextly application error carries.\n *\n * Read through the global symbol registry rather than imported, because the\n * adapters must not depend on the package that defines the error: `Symbol.for`\n * resolves to the same symbol in every module instance, which is why the brand\n * exists in that form to begin with.\n *\n * @internal\n */\nconst APPLICATION_ERROR_BRAND: unique symbol = Symbol.for(\"nextly/NextlyError\");\n\n/**\n * Whether an error is the application's verdict rather than the database's\n * failure.\n *\n * Work running inside a transaction may throw to roll the write back — a\n * refused value, a permission denial — and such an error is not something the\n * driver produced. Classifying it as a database error replaces its code and its\n * payload with a generic one, so a caller that asked for a refusal is handed an\n * unexplained failure instead, and per-field validation detail is lost on the\n * way out.\n *\n * @param error - Error to check\n * @returns True if the error was raised by application code\n *\n * @public\n */\nexport function isApplicationError(error: unknown): boolean {\n if (\n error === null ||\n (typeof error !== \"object\" && typeof error !== \"function\")\n ) {\n return false;\n }\n return (error as Record<symbol, unknown>)[APPLICATION_ERROR_BRAND] === true;\n}\n\n/**\n * Database error constructor options.\n *\n * @public\n */\nexport interface DatabaseErrorOptions {\n /** Error classification */\n kind: DatabaseErrorKind;\n\n /** Error message */\n message: string;\n\n /** Database-specific error code */\n code?: string;\n\n /** Constraint name */\n constraint?: string;\n\n /** Table name */\n table?: string;\n\n /** Column name */\n column?: string;\n\n /** Detailed description */\n detail?: string;\n\n /** Resolution hint */\n hint?: string;\n\n /** Original error */\n cause?: Error;\n}\n\n/**\n * Create a DatabaseError instance.\n *\n * @remarks\n * Helper function to create properly structured DatabaseError objects.\n *\n * @param options - Error options\n * @returns DatabaseError instance\n *\n * @public\n */\nexport function createDatabaseError(\n options: DatabaseErrorOptions\n): DatabaseError {\n const error = new Error(options.message) as DatabaseError;\n error.name = \"DatabaseError\";\n error.kind = options.kind;\n\n if (options.code !== undefined) error.code = options.code;\n if (options.constraint !== undefined) error.constraint = options.constraint;\n if (options.table !== undefined) error.table = options.table;\n if (options.column !== undefined) error.column = options.column;\n if (options.detail !== undefined) error.detail = options.detail;\n if (options.hint !== undefined) error.hint = options.hint;\n if (options.cause !== undefined) error.cause = options.cause;\n\n return error;\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { S as SupportedDialect } from './core-CVO7WYDj.cjs';
2
- import { a as DatabaseError } from './error-um1d_3Uo.cjs';
2
+ import { a as DatabaseError } from './error-BrdknH2s.cjs';
3
3
 
4
4
  declare const NEXTLY_MIN_DB_VERSIONS: {
5
5
  readonly postgresql: {