@tursodatabase/serverless 0.2.1 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/compat.d.ts CHANGED
@@ -76,11 +76,15 @@ export interface ResultSet {
76
76
  * libSQL-compatible error class with error codes.
77
77
  */
78
78
  export declare class LibsqlError extends Error {
79
- /** Machine-readable error code */
79
+ /** Machine-readable error code (e.g., "SQLITE_CONSTRAINT") */
80
80
  code: string;
81
+ /** Extended error code with more specific information (e.g., "SQLITE_CONSTRAINT_PRIMARYKEY") */
82
+ extendedCode?: string;
81
83
  /** Raw numeric error code (if available) */
82
84
  rawCode?: number;
83
- constructor(message: string, code: string, rawCode?: number);
85
+ /** Original error that caused this error */
86
+ cause?: Error;
87
+ constructor(message: string, code: string, extendedCode?: string, rawCode?: number, cause?: Error);
84
88
  }
85
89
  /**
86
90
  * Interactive transaction interface (not implemented in serverless mode).
package/dist/compat.js CHANGED
@@ -1,13 +1,16 @@
1
1
  import { Session } from './session.js';
2
+ import { DatabaseError } from './error.js';
2
3
  /**
3
4
  * libSQL-compatible error class with error codes.
4
5
  */
5
6
  export class LibsqlError extends Error {
6
- constructor(message, code, rawCode) {
7
+ constructor(message, code, extendedCode, rawCode, cause) {
7
8
  super(message);
8
9
  this.name = 'LibsqlError';
9
10
  this.code = code;
11
+ this.extendedCode = extendedCode;
10
12
  this.rawCode = rawCode;
13
+ this.cause = cause;
11
14
  }
12
15
  }
13
16
  class LibSQLClient {
@@ -114,7 +117,10 @@ class LibSQLClient {
114
117
  return this.convertResult(result);
115
118
  }
116
119
  catch (error) {
117
- throw new LibsqlError(error.message, "EXECUTE_ERROR");
120
+ if (error instanceof LibsqlError) {
121
+ throw error;
122
+ }
123
+ throw mapDatabaseError(error, "EXECUTE_ERROR");
118
124
  }
119
125
  }
120
126
  async batch(stmts, mode) {
@@ -131,7 +137,10 @@ class LibSQLClient {
131
137
  return [this.convertResult(result)];
132
138
  }
133
139
  catch (error) {
134
- throw new LibsqlError(error.message, "BATCH_ERROR");
140
+ if (error instanceof LibsqlError) {
141
+ throw error;
142
+ }
143
+ throw mapDatabaseError(error, "BATCH_ERROR");
135
144
  }
136
145
  }
137
146
  async migrate(stmts) {
@@ -149,7 +158,10 @@ class LibSQLClient {
149
158
  await this.session.sequence(sql);
150
159
  }
151
160
  catch (error) {
152
- throw new LibsqlError(error.message, "EXECUTE_MULTIPLE_ERROR");
161
+ if (error instanceof LibsqlError) {
162
+ throw error;
163
+ }
164
+ throw mapDatabaseError(error, "EXECUTE_MULTIPLE_ERROR");
153
165
  }
154
166
  }
155
167
  async sync() {
@@ -190,3 +202,63 @@ class LibSQLClient {
190
202
  export function createClient(config) {
191
203
  return new LibSQLClient(config);
192
204
  }
205
+ // Known SQLite base error code names, used to split extended codes like
206
+ // "SQLITE_CONSTRAINT_PRIMARYKEY" into base ("SQLITE_CONSTRAINT") and extended.
207
+ const sqliteBaseErrorCodes = new Set([
208
+ "SQLITE_ERROR",
209
+ "SQLITE_INTERNAL",
210
+ "SQLITE_PERM",
211
+ "SQLITE_ABORT",
212
+ "SQLITE_BUSY",
213
+ "SQLITE_LOCKED",
214
+ "SQLITE_NOMEM",
215
+ "SQLITE_READONLY",
216
+ "SQLITE_INTERRUPT",
217
+ "SQLITE_IOERR",
218
+ "SQLITE_CORRUPT",
219
+ "SQLITE_NOTFOUND",
220
+ "SQLITE_FULL",
221
+ "SQLITE_CANTOPEN",
222
+ "SQLITE_PROTOCOL",
223
+ "SQLITE_EMPTY",
224
+ "SQLITE_SCHEMA",
225
+ "SQLITE_TOOBIG",
226
+ "SQLITE_CONSTRAINT",
227
+ "SQLITE_MISMATCH",
228
+ "SQLITE_MISUSE",
229
+ "SQLITE_NOLFS",
230
+ "SQLITE_AUTH",
231
+ "SQLITE_FORMAT",
232
+ "SQLITE_RANGE",
233
+ "SQLITE_NOTADB",
234
+ "SQLITE_NOTICE",
235
+ "SQLITE_WARNING",
236
+ ]);
237
+ /**
238
+ * Parse a protocol error code into base and extended codes.
239
+ *
240
+ * The server may send either a base code ("SQLITE_CONSTRAINT") or an extended
241
+ * code ("SQLITE_CONSTRAINT_PRIMARYKEY"). This function splits them so that
242
+ * `code` is always the base code and `extendedCode` carries the full detail.
243
+ */
244
+ function parseErrorCode(serverCode) {
245
+ if (sqliteBaseErrorCodes.has(serverCode)) {
246
+ return { code: serverCode };
247
+ }
248
+ // Try to find a base code prefix (e.g. "SQLITE_CONSTRAINT" in "SQLITE_CONSTRAINT_PRIMARYKEY")
249
+ for (const base of sqliteBaseErrorCodes) {
250
+ if (serverCode.startsWith(base + "_")) {
251
+ return { code: base, extendedCode: serverCode };
252
+ }
253
+ }
254
+ // Unknown code — return as-is
255
+ return { code: serverCode };
256
+ }
257
+ function mapDatabaseError(error, fallbackCode) {
258
+ if (error instanceof DatabaseError && error.code) {
259
+ const { code, extendedCode } = parseErrorCode(error.code);
260
+ return new LibsqlError(error.message, code, extendedCode, error.rawCode, error);
261
+ }
262
+ const cause = error instanceof Error ? error : undefined;
263
+ return new LibsqlError(error.message ?? String(error), fallbackCode, undefined, undefined, cause);
264
+ }
package/dist/error.d.ts CHANGED
@@ -1,3 +1,9 @@
1
1
  export declare class DatabaseError extends Error {
2
- constructor(message: string);
2
+ /** Machine-readable error code (e.g., "SQLITE_CONSTRAINT") */
3
+ code?: string;
4
+ /** Raw numeric error code */
5
+ rawCode?: number;
6
+ /** Original error that caused this error */
7
+ cause?: Error;
8
+ constructor(message: string, code?: string, rawCode?: number, cause?: Error);
3
9
  }
package/dist/error.js CHANGED
@@ -1,7 +1,10 @@
1
1
  export class DatabaseError extends Error {
2
- constructor(message) {
2
+ constructor(message, code, rawCode, cause) {
3
3
  super(message);
4
4
  this.name = 'DatabaseError';
5
+ this.code = code;
6
+ this.rawCode = rawCode;
7
+ this.cause = cause;
5
8
  Object.setPrototypeOf(this, DatabaseError.prototype);
6
9
  }
7
10
  }
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export { Connection, connect, type Config } from './connection.js';
2
2
  export { Statement } from './statement.js';
3
+ export { Session, type SessionConfig } from './session.js';
3
4
  export { DatabaseError } from './error.js';
4
5
  export { type Column, ENCRYPTION_KEY_HEADER } from './protocol.js';
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  // Turso serverless driver entry point
2
2
  export { Connection, connect } from './connection.js';
3
3
  export { Statement } from './statement.js';
4
+ export { Session } from './session.js';
4
5
  export { DatabaseError } from './error.js';
5
6
  export { ENCRYPTION_KEY_HEADER } from './protocol.js';
package/dist/session.js CHANGED
@@ -41,7 +41,7 @@ export class Session {
41
41
  if (response.results && response.results[0]) {
42
42
  const result = response.results[0];
43
43
  if (result.type === "error") {
44
- throw new DatabaseError(result.error?.message || 'Describe execution failed');
44
+ throw new DatabaseError(result.error?.message || 'Describe execution failed', result.error?.code);
45
45
  }
46
46
  if (result.response?.type === "describe" && result.response.result) {
47
47
  return result.response.result;
@@ -162,7 +162,7 @@ export class Session {
162
162
  break;
163
163
  case 'step_error':
164
164
  case 'error':
165
- throw new DatabaseError(entry.error?.message || 'SQL execution failed');
165
+ throw new DatabaseError(entry.error?.message || 'SQL execution failed', entry.error?.code);
166
166
  }
167
167
  }
168
168
  return {
@@ -235,7 +235,7 @@ export class Session {
235
235
  break;
236
236
  case 'step_error':
237
237
  case 'error':
238
- throw new DatabaseError(entry.error?.message || 'Batch execution failed');
238
+ throw new DatabaseError(entry.error?.message || 'Batch execution failed', entry.error?.code);
239
239
  }
240
240
  }
241
241
  return {
@@ -266,7 +266,7 @@ export class Session {
266
266
  if (response.results && response.results[0]) {
267
267
  const result = response.results[0];
268
268
  if (result.type === "error") {
269
- throw new DatabaseError(result.error?.message || 'Sequence execution failed');
269
+ throw new DatabaseError(result.error?.message || 'Sequence execution failed', result.error?.code);
270
270
  }
271
271
  }
272
272
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tursodatabase/serverless",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",