Database
Server-only. flarelink.from(table) returns a chainable that resolves on await. It needs the service key, so it only works where the key is safe (your server) — never the browser. Every result has the same shape:
Query builder
The builder is immutable — each method returns a fresh object, so it's safe to compose partial queries and branch off them. Awaiting is the terminal step that fires the request.
Raw SQL escape hatch
For IN (…), ranges (> / < / LIKE), OR, joins, transactions — use the tagged template. Interpolated values become bind params; there's no way for a value to inject SQL.
A flarelink.sql\`…\` call runs as a single D1 batch, so a multi-statement template (BEGIN; …; COMMIT;) is atomic. The values you interpolate are coerced for D1's bind contract: null/undefined → null, primitives pass through, objects/arrays are JSON.stringify'd for you.
Limits & gotchas
- Builder
.where()supports equality + AND only. Anything more dynamic (IN, ranges,OR, joins) goes throughflarelink.sql\`…\`. - Identifiers (table + column names) must match
/^[A-Za-z_][A-Za-z0-9_]*$/— anything else throwsINVALID_IDENTIFIERbefore the request is sent. - Flarelink's auth tables share the same D1:
user,account,verification,flarelink_config. Avoid those names for your own tables — you can read them like any other (flarelink.from('user')), but the dashboard locks writes to them. - All queries hit the single D1 bound to your auth Worker. Multi-D1 routing and browser-side queries with row-level security are deferred — see Architecture.
- No
batch([...])API yet; useflarelink.sql\`…\`for multi-statement transactions. Errors are typed — see Error reference.
Need to create the tables you're querying? See Your schema & migrations.