Database driver (totalum-sdk/d1)
import … from 'totalum-sdk/d1' — or the same namespace on totalum from 'totalum-sdk'. Install, configuration and errors: Totalum SDK.
The project's SQL database (Cloudflare D1, SQLite), used through Drizzle: drizzle(totalumD1()). totalumD1()
returns a D1Database that finds the database wherever the code runs — the TOTALUM_DB binding inside the preview
and the published app, the local database under next dev, and an HTTPS connection with the project key in a script
or on a laptop — so the same code works everywhere. The database is the project's own: no other project can reach it.
import { drizzle } from 'drizzle-orm/d1';
import { totalumD1 } from 'totalum-sdk/d1';
export const db = drizzle(totalumD1());| Method or type | What it does |
|---|---|
totalumD1 | The project's own database as a D1Database, wherever the code runs: the bound TOTALUM_DB inside a Worker (the preview and the published app), Turso when the environment moved there, the local D1 that initOpenNextCloudflareForDev() binds under next dev, and an HTTPS client to the Totalum API everywhere else (a script, a laptop: with TOTALUM_PROJECT_KEY). |
isTotalumD1Error | Whether e is a database error (a TotalumD1Error): a SQL error, a refusal of the driver, or the Totalum API's answer to a statement. |
READ_YOUR_WRITES_COOKIE | The name of the cookie withTotalumSession sets for 10 s after a write (__tlm_d1_w): while the browser holds it, its reads go to the primary database, so a user always sees what they just saved. |
withTotalumSession | Wraps one request of the app's Worker entry (the template does it for you) so reads use the nearest read replica and writes stay consistent for the user who made them. |
D1Database | The project's database, as totalumD1() returns it: Cloudflare's D1Database interface, so drizzle(totalumD1()) works, and you can also run SQL by hand with prepare/batch. |
D1DatabaseSession | A session for read replicas, from db.withSession(): its statements see a consistent view, and its bookmark can continue the view in a later request. |
D1ExecResult | What db.exec() returns. |
D1PreparedStatement | A prepared SQL statement, from db.prepare(sql): bind its parameters, then run it with first, all, run or raw. |
D1Result | What run(), all() and each batch() statement return: the rows and the statement's metadata. |
TotalumD1ClientCode | The codes the database driver itself throws (before or without the Totalum API): no key, an unsupported call, a statement of another instance in a batch, the network, an unreadable answer. |
TotalumD1Error | The database TotalumError: message is D1_ERROR: …-shaped so it reads like a native failure — byte-identical to the binding's message when the failure is SQLite's. |
TotalumD1ErrorCode | Deprecated: Since 1.0.0: use TotalumErrorCode (the same type). |
TotalumD1Options | The options of totalumD1(). |
#totalumD1
totalumD1(options?: TotalumD1Options): D1DatabaseThe project's own database as a D1Database, wherever the code runs: the bound TOTALUM_DB inside a Worker (the
preview and the published app), Turso when the environment moved there, the local D1 that
initOpenNextCloudflareForDev() binds under next dev, and an HTTPS client to the Totalum API everywhere else (a
script, a laptop: with TOTALUM_PROJECT_KEY). Detection happens on the first statement, never at call time, so
drizzle(totalumD1()) at module scope is fine. A transient failure of a read is retried for you.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
options | TotalumD1Options | no | The key, API URL and environment for the HTTPS path, migrate mode, or an explicit binding. |
options.mode | 'query' | 'migrate' | no | 'migrate' (scripts/migrate.ts only) sends x-totalum-migrate: 1 and enables exec(); default 'query'. |
options.destructive | boolean | no | Migrate mode only: sends x-totalum-migrate-destructive: 1. |
options.binding | D1Database | no | An explicit binding wins over detection (plain Workers: env.TOTALUM_DB; tests: a Miniflare D1). |
options.transport | 'auto' | 'https' | no | 'https' forces the HTTPS path even inside a Worker (the conformance corpus); default 'auto'. |
options.key | string | no | Project key tlm_pk_…; default TOTALUM_PROJECT_KEY. Server-side only. |
options.apiUrl | string | no | The Totalum API's URL: default TOTALUM_SDK_API_URL, else https://sdk-api.totalum.app. |
options.env | 'dev' | 'live' | no | Sent as x-totalum-env on every call (the database it targets, and dev vs live usage); default TOTALUM_ENV, else live. |
Returns D1Database — The database: pass it to drizzle(), or use prepare/batch directly.
Errors — besides the errors every call can throw:
| Code | HTTP | When |
|---|---|---|
SDK_NOT_CONFIGURED | — | Thrown by the first statement when no binding is found and TOTALUM_PROJECT_KEY is unset. |
Examples
// src/db/index.ts
import { drizzle } from 'drizzle-orm/d1';
import { totalumD1 } from 'totalum-sdk/d1';
import * as schema from './schema';
export const db = drizzle(totalumD1(), { schema });
// anywhere on the server
const latest = await db.select().from(schema.orders).orderBy(desc(schema.orders.createdAt)).limit(5);// plain SQL, from a script (npx tsx scripts/count-users.ts) — over HTTPS with TOTALUM_PROJECT_KEY
const row = await totalumD1().prepare('SELECT COUNT(*) AS n FROM users').first();Result:
{ "n": 128 }#isTotalumD1Error
isTotalumD1Error(e: unknown): booleanWhether e is a database error (a TotalumD1Error): a SQL error, a refusal of the driver, or the Totalum API's
answer to a statement.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
e | unknown | yes | Anything caught. |
Returns boolean — true for a TotalumD1Error (then e.errorCode, e.message are typed).
Example
try {
await db.insert(users).values({ email });
} catch (e) {
if (isTotalumD1Error(e) && e.message.includes('UNIQUE constraint failed')) return { error: 'Email already used' };
throw e;
}#READ_YOUR_WRITES_COOKIE
const READ_YOUR_WRITES_COOKIE: '__tlm_d1_w'The name of the cookie withTotalumSession sets for 10 s after a write (__tlm_d1_w): while the browser holds it,
its reads go to the primary database, so a user always sees what they just saved. Exported for apps that clear or
inspect it.
Example
import { READ_YOUR_WRITES_COOKIE } from 'totalum-sdk/d1';
const fresh = request.headers.get('cookie')?.includes(`${READ_YOUR_WRITES_COOKIE}=`);#withTotalumSession
withTotalumSession(request: Request, env: E, run: (env: E) => Promise<Response>): Promise<Response>Wraps one request of the app's Worker entry (the template does it for you) so reads use the nearest read replica
and writes stay consistent for the user who made them. In detail: a GET/HEAD reads through a
first-unconstrained session — the nearest replica — unless the browser wrote in the last 10 s; any other method
uses the plain binding (writes go to the primary; measured faster than any session) and its response sets the short
cookie that sends that browser's next reads to the primary. A replica read that takes over REPLICA_READ_TIMEOUT_MS
is answered by the primary instead, and the rest of that request reads the primary. A mutation's pure read the primary
does not answer in that time is asked again on the primary (one call stalled while the database answered
others; a sign-up waited on its first SELECT until the Worker was cancelled). run receives the env to hand to the
app, whose totalumD1() reads TOTALUM_DB from it on every statement. No D1 binding (Turso, a laptop): run(env)
unchanged.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
request | Request | yes | The incoming request. |
env | E | yes | The Worker's env (with the TOTALUM_DB binding). |
run | (env: E) => Promise<Response> | yes | Handles the request with the env to use (its TOTALUM_DB may be a session). |
Returns Promise<Response> — The response, with the short read-your-writes cookie after a write.
Errors — besides the errors every call can throw:
| Code | HTTP | When |
|---|---|---|
SQL_ERROR | — | Whatever run throws is passed on unchanged. |
Example
// worker.ts (the template's entry)
import { withTotalumSession } from 'totalum-sdk/d1';
import handler from './.open-next/worker.js';
export default {
fetch: (request: Request, env: Env, ctx: ExecutionContext) =>
withTotalumSession(request, env, (env) => handler.fetch(request, env, ctx)),
};#D1Database
The project's database, as totalumD1() returns it: Cloudflare's D1Database interface, so drizzle(totalumD1())
works, and you can also run SQL by hand with prepare/batch.
#db.prepare
db.prepare(sql: string): D1PreparedStatementPrepares one SQL statement (with ? placeholders); run it with first, all, run or raw. Nothing runs
until then.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
sql | string | yes | The SQL text. Several statements separated by ; run together, atomically. |
Returns D1PreparedStatement — The prepared statement.
Example
const db = totalumD1();
const user = await db.prepare('SELECT * FROM users WHERE id = ?').bind(42).first();#db.batch
db.batch(statements: D1PreparedStatement[]): Promise<D1Result[]>Runs several statements in one round trip, as one atomic unit: all apply or none (D1 has no BEGIN/COMMIT; this
is its transaction). Drizzle's db.batch([...]) uses it.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
statements | D1PreparedStatement[] | yes | Statements prepared by this database. |
Returns Promise<D1Result[]> — One result per statement, in order.
Each item:
| Field | Type | Always present | Description |
|---|---|---|---|
results | T[] | yes | The rows, as objects keyed by column name (empty for a statement that returns none). |
success | true | yes | Always true: a failure throws instead. |
meta | { duration, size_after, rows_read, rows_written, last_row_id, changed_db, changes, served_by_region?, served_by_primary? } | yes | Timing, rows read and written, changes and the last inserted rowid. |
meta.duration | number | yes | How long the statement took in the database, in ms. |
meta.size_after | number | yes | The database's size after the statement, in bytes. |
meta.rows_read | number | yes | Rows the statement read (what makes a query slow: add an index when it is high). |
meta.rows_written | number | yes | Rows the statement wrote. |
meta.last_row_id | number | yes | The rowid of the last inserted row (INSERT without RETURNING). |
meta.changed_db | boolean | yes | Whether the database changed. |
meta.changes | number | yes | Rows inserted, updated or deleted. |
meta.served_by_region | string | no | The region that answered (with read replicas). |
meta.served_by_primary | boolean | no | Whether the primary database answered (false for a read replica). |
Errors — besides the errors every call can throw:
| Code | HTTP | When |
|---|---|---|
SQL_ERROR | — | A statement failed; none was applied. |
BATCH_FOREIGN_STATEMENT | — | A statement prepared by another totalumD1() instance. |
Example
const [debit, credit] = await db.batch([
db.prepare('UPDATE accounts SET balance = balance - ? WHERE id = ?').bind(50, 1),
db.prepare('UPDATE accounts SET balance = balance + ? WHERE id = ?').bind(50, 2),
]);Result:
[
{ "success": true, "meta": { "changes": 1, … }, "results": [] },
{ "success": true, "meta": { "changes": 1, … }, "results": [] }
]#db.exec
db.exec(sql: string): Promise<D1ExecResult>Runs a SQL script (several statements, no parameters): only in migrate mode, totalumD1({ mode: 'migrate' }) from
scripts/migrate.ts. For data, use prepare or batch.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
sql | string | yes | The script. |
Returns Promise<D1ExecResult> — How many statements ran and how long they took.
| Field | Type | Always present | Description |
|---|---|---|---|
count | number | yes | How many statements ran. |
duration | number | yes | Their total time in ms. |
Errors — besides the errors every call can throw:
| Code | HTTP | When |
|---|---|---|
EXEC_REQUIRES_MIGRATE_MODE | — | Called outside migrate mode. |
SQL_ERROR | — | A statement failed. |
Example
const db = totalumD1({ mode: 'migrate' });
await db.exec('CREATE TABLE IF NOT EXISTS notes (id INTEGER PRIMARY KEY, body TEXT NOT NULL);');Result:
{ "count": 1, "duration": 0.42 }#db.dump
db.dump(): Promise<ArrayBuffer>Not available: always throws NOT_SUPPORTED. Database backups are in the project's settings in Totalum.
Returns Promise<ArrayBuffer> — Never resolves.
Errors — besides the errors every call can throw:
| Code | HTTP | When |
|---|---|---|
NOT_SUPPORTED | — | Always. |
Example
await db.dump(); // throws TotalumD1Error NOT_SUPPORTED#db.withSession
db.withSession(constraintOrBookmark?: string): D1DatabaseSessionA session for read replicas: 'first-unconstrained' reads from the nearest replica, 'first-primary' starts at
the primary, a bookmark continues a previous session. The template already wraps each request with
withTotalumSession, so app code rarely needs this. Over HTTPS and on Turso the session is the database itself.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
constraintOrBookmark | string | no | 'first-unconstrained', 'first-primary' or a bookmark from getBookmark(). |
Returns D1DatabaseSession — The session.
Example
const session = db.withSession('first-unconstrained');
const { results } = await session.prepare('SELECT * FROM products LIMIT 20').all();#D1DatabaseSession
A session for read replicas, from db.withSession(): its statements see a consistent view, and its bookmark can
continue the view in a later request.
#dbSession.prepare
dbSession.prepare(sql: string): D1PreparedStatementPrepares a statement in this session.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
sql | string | yes | One SQL statement with ? placeholders. |
Returns D1PreparedStatement — The prepared statement.
Example
const session = db.withSession('first-unconstrained');
const posts = await session.prepare('SELECT * FROM posts ORDER BY id DESC LIMIT 10').all();#dbSession.batch
dbSession.batch(statements: D1PreparedStatement[]): Promise<D1Result[]>Runs several statements in this session, as one atomic batch.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
statements | D1PreparedStatement[] | yes | Statements prepared by this session. |
Returns Promise<D1Result[]> — One result per statement.
Each item:
| Field | Type | Always present | Description |
|---|---|---|---|
results | T[] | yes | The rows, as objects keyed by column name (empty for a statement that returns none). |
success | true | yes | Always true: a failure throws instead. |
meta | { duration, size_after, rows_read, rows_written, last_row_id, changed_db, changes, served_by_region?, served_by_primary? } | yes | Timing, rows read and written, changes and the last inserted rowid. |
meta.duration | number | yes | How long the statement took in the database, in ms. |
meta.size_after | number | yes | The database's size after the statement, in bytes. |
meta.rows_read | number | yes | Rows the statement read (what makes a query slow: add an index when it is high). |
meta.rows_written | number | yes | Rows the statement wrote. |
meta.last_row_id | number | yes | The rowid of the last inserted row (INSERT without RETURNING). |
meta.changed_db | boolean | yes | Whether the database changed. |
meta.changes | number | yes | Rows inserted, updated or deleted. |
meta.served_by_region | string | no | The region that answered (with read replicas). |
meta.served_by_primary | boolean | no | Whether the primary database answered (false for a read replica). |
Errors — besides the errors every call can throw:
| Code | HTTP | When |
|---|---|---|
SQL_ERROR | — | A statement failed; none was applied. |
Example
const [users, posts] = await session.batch([session.prepare('SELECT * FROM users'), session.prepare('SELECT * FROM posts')]);#dbSession.getBookmark
dbSession.getBookmark(): string | nullThe session's bookmark after its last statement: pass it to withSession(bookmark) in a later request to read at
least that state. null before the first statement, and always over HTTPS and on Turso (one database, no
replicas).
Returns string \| null — The bookmark, or null.
Example
const bookmark = session.getBookmark();Result:
"0000002a-00000003-00004f5e-7a4ce4bd3c0e9b0e1f2c3d4e5f60718"#D1ExecResult
What db.exec() returns.
| Field | Type | Always present | Description |
|---|---|---|---|
count | number | yes | How many statements ran. |
duration | number | yes | Their total time in ms. |
#D1PreparedStatement
A prepared SQL statement, from db.prepare(sql): bind its parameters, then run it with first, all, run or
raw. Nothing runs until one of those is awaited.
#stmt.bind
stmt.bind(...values: unknown[]): D1PreparedStatementBinds the values of the statement's ? placeholders, in order, and returns a new statement (the original is
unchanged). Values: strings, numbers, booleans (stored as 1/0), null, ArrayBuffer/Uint8Array (BLOB).
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
values | unknown[] | yes | One value per ?, in order. |
Returns D1PreparedStatement — A statement with those parameters.
Example
const stmt = db.prepare('SELECT * FROM users WHERE email = ? AND active = ?').bind('ana@example.com', 1);#stmt.first
stmt.first(colName?: string): Promise<T | null>Runs the statement and returns the first row (or one column of it), or null when there is none.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
colName | string | no | Return only this column's value. |
Returns Promise<T \| null> — The first row, that column's value, or null.
Errors — besides the errors every call can throw:
| Code | HTTP | When |
|---|---|---|
SQL_ERROR | — | SQLite refused the statement (message is SQLite's, as D1_ERROR: …). |
Example
const user = await db.prepare('SELECT id, name FROM users WHERE email = ?').bind('ana@example.com').first();
const count = await db.prepare('SELECT COUNT(*) AS n FROM users').first<number>('n');Result:
user = { id: 42, name: 'Ana' } count = 128#stmt.run
stmt.run(): Promise<D1Result>Runs a statement that changes data (INSERT, UPDATE, DELETE, DDL) and returns its metadata (changes,
last_row_id) — and its rows, with RETURNING.
Returns Promise<D1Result> — The result: results (rows of a RETURNING) and meta.
| Field | Type | Always present | Description |
|---|---|---|---|
results | T[] | yes | The rows, as objects keyed by column name (empty for a statement that returns none). |
success | true | yes | Always true: a failure throws instead. |
meta | { duration, size_after, rows_read, rows_written, last_row_id, changed_db, changes, served_by_region?, served_by_primary? } | yes | Timing, rows read and written, changes and the last inserted rowid. |
meta.duration | number | yes | How long the statement took in the database, in ms. |
meta.size_after | number | yes | The database's size after the statement, in bytes. |
meta.rows_read | number | yes | Rows the statement read (what makes a query slow: add an index when it is high). |
meta.rows_written | number | yes | Rows the statement wrote. |
meta.last_row_id | number | yes | The rowid of the last inserted row (INSERT without RETURNING). |
meta.changed_db | boolean | yes | Whether the database changed. |
meta.changes | number | yes | Rows inserted, updated or deleted. |
meta.served_by_region | string | no | The region that answered (with read replicas). |
meta.served_by_primary | boolean | no | Whether the primary database answered (false for a read replica). |
Errors — besides the errors every call can throw:
| Code | HTTP | When |
|---|---|---|
SQL_ERROR | — | SQLite refused the statement (a constraint, a syntax error). |
Example
const r = await db.prepare('INSERT INTO users (email, name) VALUES (?, ?)').bind('ana@example.com', 'Ana').run();Result:
{
"success": true,
"meta": { "duration": 0.31, "size_after": 12288, "rows_read": 1, "rows_written": 1, "last_row_id": 42, "changed_db": true, "changes": 1 },
"results": []
}#stmt.all
stmt.all(): Promise<D1Result>Runs a query and returns every row.
Returns Promise<D1Result> — The result: results (the rows) and meta.
| Field | Type | Always present | Description |
|---|---|---|---|
results | T[] | yes | The rows, as objects keyed by column name (empty for a statement that returns none). |
success | true | yes | Always true: a failure throws instead. |
meta | { duration, size_after, rows_read, rows_written, last_row_id, changed_db, changes, served_by_region?, served_by_primary? } | yes | Timing, rows read and written, changes and the last inserted rowid. |
meta.duration | number | yes | How long the statement took in the database, in ms. |
meta.size_after | number | yes | The database's size after the statement, in bytes. |
meta.rows_read | number | yes | Rows the statement read (what makes a query slow: add an index when it is high). |
meta.rows_written | number | yes | Rows the statement wrote. |
meta.last_row_id | number | yes | The rowid of the last inserted row (INSERT without RETURNING). |
meta.changed_db | boolean | yes | Whether the database changed. |
meta.changes | number | yes | Rows inserted, updated or deleted. |
meta.served_by_region | string | no | The region that answered (with read replicas). |
meta.served_by_primary | boolean | no | Whether the primary database answered (false for a read replica). |
Errors — besides the errors every call can throw:
| Code | HTTP | When |
|---|---|---|
SQL_ERROR | — | SQLite refused the statement. |
Example
const { results } = await db.prepare("SELECT 'Ana' AS name, 42 AS age").all();Result:
{
"success": true,
"meta": { "served_by_region": "WEUR", "served_by_primary": true, "duration": 0.1934, "changes": 0, "last_row_id": 0, "changed_db": false, "size_after": 12288, "rows_read": 0, "rows_written": 0 },
"results": [{ "name": "Ana", "age": 42 }]
}#stmt.raw
stmt.raw(options: { columnNames }): Promise<[string[], ...T[]]>
stmt.raw(options?: { columnNames? }): Promise<T[]>Runs a query and returns the rows as arrays of values (no column names), or with columnNames: true the names
first.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
options | { columnNames? } | no | { columnNames: true } puts the column names first. |
options.columnNames | boolean | no | true: the first array is the column names. |
Returns Promise<T[]> — The rows as arrays.
Errors — besides the errors every call can throw:
| Code | HTTP | When |
|---|---|---|
SQL_ERROR | — | SQLite refused the statement. |
Example
const rows = await db.prepare('SELECT id, name FROM users LIMIT 2').raw({ columnNames: true });Result:
[["id", "name"], [41, "Bob"], [42, "Ana"]]#D1Result
What run(), all() and each batch() statement return: the rows and the statement's metadata.
| Field | Type | Always present | Description |
|---|---|---|---|
results | T[] | yes | The rows, as objects keyed by column name (empty for a statement that returns none). |
success | true | yes | Always true: a failure throws instead. |
meta | { duration, size_after, rows_read, rows_written, last_row_id, changed_db, changes, served_by_region?, served_by_primary? } | yes | Timing, rows read and written, changes and the last inserted rowid. |
meta.duration | number | yes | How long the statement took in the database, in ms. |
meta.size_after | number | yes | The database's size after the statement, in bytes. |
meta.rows_read | number | yes | Rows the statement read (what makes a query slow: add an index when it is high). |
meta.rows_written | number | yes | Rows the statement wrote. |
meta.last_row_id | number | yes | The rowid of the last inserted row (INSERT without RETURNING). |
meta.changed_db | boolean | yes | Whether the database changed. |
meta.changes | number | yes | Rows inserted, updated or deleted. |
meta.served_by_region | string | no | The region that answered (with read replicas). |
meta.served_by_primary | boolean | no | Whether the primary database answered (false for a read replica). |
#TotalumD1ClientCode
The codes the database driver itself throws (before or without the Totalum API): no key, an unsupported call, a statement of another instance in a batch, the network, an unreadable answer.
| Value | Meaning |
|---|---|
'SDK_NOT_CONFIGURED' | No binding was found and TOTALUM_PROJECT_KEY is unset. |
'NOT_SUPPORTED' | The call is not available (dump()). |
'BATCH_FOREIGN_STATEMENT' | batch() got a statement prepared by another totalumD1() instance. |
'NETWORK_ERROR' | The Totalum API could not be reached (HTTPS path). |
'RESPONSE_PARSE_ERROR' | The answer was not the expected JSON (HTTPS path). |
#TotalumD1Error
The database TotalumError: message is D1_ERROR: …-shaped so it reads like a native failure —
byte-identical to the binding's message when the failure is SQLite's.
| Member | Type | Description |
|---|---|---|
name | string | 'TotalumD1Error', or 'Error' for SQLite's own failures (as the native binding throws them). |
| Method | Description |
|---|---|
TotalumD1Error.client(errorCode, message) → TotalumD1Error | A client-side refusal (D1_ERROR: <code>: <message>). |
TotalumD1Error.engine(sqliteMessage, options?) → TotalumD1Error | SQLite's own failure, as the binding throws it: name Error, message D1_ERROR: <sqlite>, cause an Error with SQLite's words — so String(err), err.message and String(err.cause) read the same on every path. Still a TotalumD1Error (errorCode SQL_ERROR) for code that checks. |
TotalumD1Error.fromWire(errors, status, requestId) → TotalumD1Error | The Totalum API error envelope → typed error; SQL_ERROR is rebuilt as the binding's own error from sqliteMessage. |
#TotalumD1ErrorCode
Deprecated. Since 1.0.0: use TotalumErrorCode (the same type).
Deprecated: Since 1.0.0: use TotalumErrorCode (the same type).
type TotalumD1ErrorCode = 'SERVICE_UNAUTHORIZED' | 'SERVICE_REPLAY' | 'ACTOR_MISMATCH' | 'PAYLOAD_TOO_LARGE' | 'VALIDATION_ERROR' | 'PROJECT_NOT_FOUND' | 'PROJECT_NOT_READY' | 'OPERATION_IN_PROGRESS' | … // 421 values#TotalumD1Options
The options of totalumD1(). key, apiUrl and env (HTTPS path only) resolve exactly as in every other namespace.
| Name | Type | Required | Description |
|---|---|---|---|
mode | 'query' | 'migrate' | no | 'migrate' (scripts/migrate.ts only) sends x-totalum-migrate: 1 and enables exec(); default 'query'. |
destructive | boolean | no | Migrate mode only: sends x-totalum-migrate-destructive: 1. |
binding | D1Database | no | An explicit binding wins over detection (plain Workers: env.TOTALUM_DB; tests: a Miniflare D1). |
transport | 'auto' | 'https' | no | 'https' forces the HTTPS path even inside a Worker (the conformance corpus); default 'auto'. |
key | string | no | Project key tlm_pk_…; default TOTALUM_PROJECT_KEY. Server-side only. |
apiUrl | string | no | The Totalum API's URL: default TOTALUM_SDK_API_URL, else https://sdk-api.totalum.app. |
env | 'dev' | 'live' | no | Sent as x-totalum-env on every call (the database it targets, and dev vs live usage); default TOTALUM_ENV, else live. |
