Usage and constraints
Usage and constraints
Section titled “Usage and constraints”Scope and imports
Section titled “Scope and imports”The root exports SDK-independent types, resource services, search helpers, decimal wrapping and cache identity. Import database adapters from explicit subpaths. Optional peers are not needed to import the root. Install a provider’s SDK when using that provider; the Supabase declarations require its SDK’s real types. No connection is opened by importing an adapter. The application supplies clients, driver bindings, credentials, server endpoints and authorization.
DataAccessAdapter works with named collections and records. StorageAdapter
works with object keys and binary data; it lives in universal-storage. Neither
package directly depends on the other. Attachment callbacks in resource services
are extension points, not a database/storage transaction implementation.
Filters, query options and backend differences
Section titled “Filters, query options and backend differences”Filter is a TypeScript Record<string, unknown>, not a runtime validator. The
caller must validate and allowlist fields/operators, bound payload size, query
cost, result limits and resource names before accepting untrusted API requests.
SQL identifiers must come from trusted application configuration; value binding
does not make arbitrary identifiers safe. Do not expose raw adapters to a model
or public HTTP client without an application validation/authorization layer.
- SQLite/D1 accept simple identifiers and scalar bindings (JSON objects/arrays
require caller conversion). Their implemented filter operators are
$eq,$neq,$gt,$gte,$lt,$lte,$inand$nin. Null equality becomes SQLIS NULL/IS NOT NULL. Regex, logical$or/$andand other unsupported operators throw. There is no generic join/populate support. - Mongo HTTP operations require a matching application server implementation. This is a request protocol, not automatic deployment or a direct MongoDB client.
- Supabase REST uses PostgREST and configured database relations. GraphQL requires pg_graphql and matching GraphQL field/collection names; select fields explicitly.
- Neon supports comparisons,
$in/$nin,$regex/$ilikeand nonempty$and/$or. Supabase REST supports comparisons, lists,$regex(substring ILIKE),$ilikeand nonempty$and;$oris rejected. GraphQL supports comparisons,$inand POSIX$regex;$ninand logical groups are rejected. Null equality/inequality uses the pg_graphqlisenum. Unknown operators, invalid operands, undefined/nonfinite values and empty groups throw before executing the query; they are never discarded. - Neon quotes qualified segments separately. Limit/skip for Neon must be nonnegative safe integers. An empty
$inmatches nothing; an empty$ninexcludes nothing. SQL null equality/inequality uses IS NULL/IS NOT NULL. Backend null-in-list behavior remains provider-specific. createTableSearchHandleremits$orand$ilike; use it only with a backend that supports both. It does not expand an adapter’s supported operators.
QueryOptions is extensible, so its TypeScript shape is not a portability guarantee.
signal, projection, populate, pagination, count and bulk operations differ by
adapter. Check optional method availability. createResourceService.bulkCreate
and .bulkUpdate throw when their underlying optional operations are absent.
Bulk fallbacks may make multiple independent requests; no cross-backend atomicity,
rollback, transaction or uniform concurrency guarantee is provided.
defaultQueryOptions applies to the service’s find method; per-call options win.
Other service methods forward their per-call options. Resource services do not
apply schema validation, permission checks, or a database migration automatically.
Credentials and cache boundaries
Section titled “Credentials and cache boundaries”Keep DB passwords, privileged Supabase keys and direct DB connection strings on the server. A browser-facing API must enforce its own permissions, tenant boundary and database access rules. An injected token callback/fetch is a transport hook, not an authorization implementation. Tests use mocks and in-memory SQLite; they cannot verify a consumer’s real DB permissions or cloud deployment.
Cache identities are runtime-local. An adapter instance gets a distinct identity.
An explicit cacheScope deliberately shares cached data with other adapters using
that scope. Include the tenant/access boundary and rotate it when the authorized
user or role changes. Never use raw credentials as a cache key. No cache client,
React provider or global cache is supplied here.
Schema, decimal data and attachments
Section titled “Schema, decimal data and attachments”The package does not depend on AJV/Zod or data-engine. Validate JSON Schema in
application code, or use engine’s /integrations/supabase Supabase integration.
That integration depends on data-access, never the reverse.
BigNumberDataAccessAdapter receives a compatible decimal constructor and explicit
field rules; it does not install a decimal SDK. Validate decimal scale/rounding
requirements for the application. HTTP JSON cannot transport JavaScript bigint
without an explicit conversion.
Attachment metadata is application-neutral. The optional second metadata type
parameter of ResourceService/createResourceService lets applications specialize
it. Project detail IDs/codes are defined by private app-core, not this package.
File upload and record updates can fail independently; the application decides
cleanup and retry behavior.
Tests and publication
Section titled “Tests and publication”Run bun run verify: source+test typecheck, package boundaries, unit/mock tests,
real in-memory SQLite, ESM/CJS build and an isolated packed consumer on Node/Bun.
Consumer tests check SDK-free import/type use, provider SDK declarations, browser
bundling of SDK-independent entry points, and all export targets. No production
DB credentials or real external service are used.
The unified site reads local package Markdown from the same public monorepo checkout. One root lockfile and Changesets workflow manage development and releases.
Verified TypeScript / SDK versions
Section titled “Verified TypeScript / SDK versions”SDK-independent packed entry points are checked with TypeScript 6.0.3, without
Node ambient types. All provider entries with the real Supabase 2.118 SDK are
checked with TypeScript 5.7.3 and strict declaration checking (skipLibCheck: false).
Supabase auth-js 2.118’s WebAuthn declarations conflict with TypeScript 6.0.3 DOM
PublicKeyCredential.toJSON types. This is a known SDK/browser type compatibility
limit, not a failure of record CRUD. Do not claim strict TS 6 + that SDK is supported;
verify newer SDK/compiler combinations before updating this compatibility matrix.
Oracle Duality View follows the same fail-before-execution filter policy as Direct SQL. It supports the listed comparison/list/regex operators, rejects logical groups, uses IS NULL/IS NOT NULL for equality, and validates collection names, sort paths and limit/skip. Collections may be schema-qualified; column/JSON paths consist only of named [A-Za-z_][A-Za-z0-9_]* segments. Array indexes and raw SQL/JSON-path expressions are unsupported. Do not pass user-controlled resource names without a host allowlist. Direct create/update/replace use generated bind names, so ordinary columns named target_id, ret_id or value_0 retain their values. Empty create/update data is rejected. Both Oracle count implementations return numeric 0 for empty results. Real target-version and permission checks remain the host’s responsibility.
Oracle SQL/Duality View/ORDS/function adapters are private premium integrations.
Use bun run test:containers for real PostgreSQL CRUD through NeonAdapter queryFn.