feat(database): add @bunny.net/database-client, a fetch-only SQL client - #154
feat(database): add @bunny.net/database-client, a fetch-only SQL client#154jamie-at-bunny wants to merge 5 commits into
Conversation
|
@codex review |
🦋 Changeset detectedLatest commit: 9790c82 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Greptile SummaryThe PR adds and publishes
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains.
|
| Filename | Overview |
|---|---|
| packages/database-client/src/client.ts | Implements the public database, statement, batch, and execution APIs over the stateless pipeline transport. |
| packages/database-client/src/protocol.ts | Implements URL normalization, Hrana value encoding and decoding, HTTP transport, and response validation. |
| packages/database-client/src/env.ts | Adds guarded environment-variable access for runtime configuration. |
| packages/database-client/package.json | Defines the compiled package exports, build scripts, publish contents, and public npm configuration. |
| .github/workflows/release.yml | Adds independent version detection, build, and npm publication for the database client. |
| packages/database-client/examples/smoke.ts | Exercises the client against a live database across its documented runtime path. |
Sequence Diagram
sequenceDiagram
participant App as Server-side application
participant Client as database-client
participant DB as Bunny Database
App->>Client: connect(config)
App->>Client: prepare(sql).bind(values)
Client->>DB: POST /v2/pipeline
DB-->>Client: Hrana result
Client-->>App: rows and write metadata
Reviews (5): Last reviewed commit: "refactor(database-client): read env thro..." | Re-trigger Greptile
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c238a154b0
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Package isn't hooked up to releases just yet. I want to replace |
# Conflicts: # packages/cli/src/commands/sites/deploy.test.ts
…ithout --allow-env (#155) * docs(database-client): tidy README and comments, drop the D1 shorthand - remove the truncated sentence at the end of the security section - fold the intro's dangling dependency claim into the sentence - explain the unsafe-integer rejection in active voice - collapse a stacked comment in env.ts to one line - describe the API surface in AGENTS.md without the D1 comparison * fix(database-client): treat unreadable env vars as unset under Deno without --allow-env Deno 2's node-compat process.env throws NotCapable on read just like Deno.env.get, but only the latter was guarded, so readEnv crashed instead of falling through to connect()'s clearer missing-URL error. One module-scope sniff type and one try now cover both globals, and env.test.ts locks in the degrade-to-unset behavior with throwing stubs.
Every runtime this client targets exposes process.env, Deno included, so the Deno.env.get branch and the globalThis runtime sniff were carrying no weight. readEnv() now reads process.env directly, and the examples use process.env instead of importing readEnv. The permission tolerance from #155 stays: reading can throw rather than return undefined when Deno runs without --allow-env, so readEnv still catches and reports the variable as unset. Verified that connect() with no arguments under `deno run --allow-net` still raises URL_MISSING with its usual message rather than a NotCapable crash. --allow-env is still required for Deno to read process.env, so the example's invocation line is unchanged. Behaviour is unchanged for consumers, so the existing changeset still covers it. Live smoke passes on Bun and Deno.
Adds
@bunny.net/database-client, a small SQL client for Bunny Database aimed at server-side application code rather than the CLI.It speaks hrana-over-HTTP (
POST /v3/pipeline) using onlyfetch, so the same source runs on Edge Scripting (Deno), Bun, and Node. No dependencies.Why not just use
@libsql/clientBunny Database runs sqld, which serves hrana v2/v3 over plain HTTP. That is JSON over
fetch, so a client needs no libSQL dependency at all. Dropping it means one fewer thing to keep in step and a surface we can shape for Bunny rather than inherit.Shape
Modelled on Cloudflare D1 rather than libSQL, since there is no backwards compatibility to preserve here:
Deliberately stateless
batonis always null and every request closes its own session, so there is no connection pool, no session pinning, and nothing to tear down when an edge isolate is discarded.That rules out interactive transactions and cross-call
TEMPtables.batch()covers atomicity instead, wrapping its steps inBEGIN/COMMIT/ROLLBACKwith per-step conditions. There is also no cursor streaming and no automatic retries: a failed write cannot be retried safely unless the caller knows whether it landed.Server-side only
An auth token authorizes the connection rather than the query, and this client sends raw SQL. Read-only tokens narrow the damage but still expose every row of every table, and SQLite has no row-level security to fall back on. The README leads with that and shows the Edge Script proxy pattern instead of documenting the client as browser-compatible.
Types
Integers decode to
numberwhile exactly representable and widen tobigintpast 2^53 rather than silently rounding. Values SQLite cannot store are rejected at bind time instead of being coerced, andDategets its own message pointing at.toISOString()or.getTime().Verification
fetch, no network required.examples/smoke.tsruns the client against a live database and passes identically on Bun and Deno. It creates and drops its own tables and leaves nothing behind.--allow-env(fix(database-client): treat unreadable env vars as unset under Deno without --allow-env #155).Release
release.ymlgains apublish-database-clientjob, gated on a version bump detected vianpm view. The package has no workspace dependencies, so it publishes with plainnpm publish.