Releases: cipherstash/stack
Release list
stash@1.0.0-rc.3
Minor Changes
-
0811330: Add
stash eql migration— generate an EQL v3 install migration for your ORM
instead of running the SQL directly against the database (stash eql install).
Migration-first is the preferred path: the install lands in your migration history
and ships to every environment through the ORM's own migrate step.stash eql migration --drizzle # Drizzle custom migration stash eql migration --drizzle --supabase # also grants eql_v3 to anon/authenticated/service_role
The migration carries the CLI's bundled v3 install SQL (one source of truth) plus
thecs_migrationstracking schema, so a singledrizzle-kit migratecovers
everythingstash encrypt …needs.--supabaseappends theeql_v3+
eql_v3_internalrole grants for PostgREST/RLS access.--prismais registered but not available yet — the Prisma Next migration
emitter is a follow-up (tracked in #690) that will let
prisma-next drop its baked install baseline. It fails with a pointer for now. -
d20e48a:
stash initis honest non-interactively — it no longer reports success for a
setup that didn't fully complete.- Fails on version skew. A non-interactive run can't reconcile an
already-installed@cipherstash/*package that's older than this CLI
expects (it won't mutate an install without consent), so instead of warning
and proceeding — scaffolding against mismatched packages and then claiming
success — it now refuses with a non-zero exit and the exact align command.
Interactive runs still offer to align. A newer install stays a warn (the
install is likely fine; update the CLI instead). - No false "Setup complete". If the EQL extension isn't installed at the
end — and the integration isn't one that installs it out-of-band — the
summary reads "Setup incomplete" and init exits non-zero, pointing at
stash eql install. Integrations that install EQL via a migration are
reported honestly rather than as failures: Prisma Next (installs it via
migration apply) and the Drizzle flow, which generates an EQL migration
and now says "EQL migration generated — apply it withdrizzle-kit migrate"
instead of claiming the extension is already installed. - Honest checkmarks. The summary no longer claims "Database connection
verified" (init resolves a URL but doesn't open a connection) — it now says
"Database URL resolved" — and only shows "Encryption client scaffolded" when
a client was actually written (skipped for Prisma Next). - No false "skills loaded". The agent handoff prompt only points at the
skills directory when skills were actually copied (a stripped build installs
none), instead of telling the agent to read files that aren't there.
- Fails on version skew. A non-interactive run can't reconcile an
-
3a86939: EQL v3 support for the encryption rollout lifecycle (#648). The
stash encrypt *commands (and@cipherstash/migrateunderneath) now resolve a
column's EQL version and its encrypted counterpart from the Postgres domain
types — the EQL v3 types are self-describing, so the<col>_encrypted
naming is a convention only, never enforced or relied upon — and follow the
right lifecycle, no new flags:encrypt backfillworks on v3 columns unchanged (the engine was always
version-agnostic; pass anEncryptionV3client and real v3 envelopes land
in the concreteeql_v3_*domain column — verified live against a real
database, including the domain CHECK and a decrypt round-trip). The
manifest records the detected version, the encrypted column's name, and the
v3 target phase, and the command prints v3-appropriate next steps.encrypt cutoveron a backfilled v3 column reports "not applicable"
(exit 0) with guidance: v3 has no rename cut-over — the application
switches to the encrypted column by name. Before backfill completes it
exits 1 and says to finish the backfill instead of instructing the switch.
On a database with noeql_v2_configurationtable (a v3-only install) the
v2 path now explains that instead of surfacing a raw Postgres error.encrypt dropis version-aware: v3 runs from thebackfilledphase,
verifies live coverage (refuses to generate the migration while any row
still has the plaintext set and the encrypted column NULL — the
countUnencryptedcheck), and drops the ORIGINAL plaintext column (there
is no<col>_plaintextunder v3); v2 behaviour is unchanged. The generated
v3 migration re-verifies coverage at apply time — it locks the table,
re-counts, and aborts without dropping if plaintext-only rows appeared
after generation. And because dropping is the one irreversible step, it
requires a positively asserted plaintext↔ciphertext pairing (the
manifest's recordedencryptedColumnor the naming convention): a match
found only by being the table's sole EQL column is refused with
instructions, and an ambiguous table (several EQL columns, none
identifiable) fails closed listing the candidates — as doescutover.encrypt statusclassifies each column from the observed domain type
(manifest as fallback), showsv3in the EQL column, and no longer raises
the v2-onlynot-registered/plaintext-col-missingdrift flags for v3
columns.stash status's quest ladder and thestash initagent handoff
prompt teach the version-appropriate next step (no more "run cutover" on
v3 columns).- New
@cipherstash/migrateexports:classifyEqlDomain,
resolveEncryptedColumn,pickEncryptedColumn,listEncryptedColumns
(domain-type resolution — case-exact for quoted/mixed-case table names),
countEncrypted/countUnencrypted(coverage counts), and manifest
eqlVersion+encryptedColumnfields.EqlVersionis numeric (2 | 3),
matching the manifest and the installer. Resolved columns carryvia: 'hint' | 'convention' | 'sole'so callers can tell a positively asserted
pairing from a by-elimination guess. - Fixed:
encrypt cutover/encrypt dropprecondition failures now actually
exit 1 — the early-return guards previously skipped the exit-code path
entirely, so failed preconditions exited 0. (This also applies to v2
preconditions: scripted pipelines that relied on the erroneous exit 0 will
now see the documented exit 1.)
The
stash-cliandstash-encryptionskills and the@cipherstash/migrate
README document the two lifecycles (v2: backfill → cutover → drop;
v3: backfill → switch-by-name → drop). -
b0634df:
stash plan --complete-rolloutis now automatable and has an honest exit code.
It skips the production-deploy gate, so it needs explicit consent — previously
that was an interactive prompt with no bypass, so a non-interactive run
auto-cancelled (default-no) and exited 0 without drafting a plan, leaving
automation to assume a plan existed.- New
--yesflag confirms the gate-skip without a prompt (for CI/agents). - Without
--yes, a non-interactive--complete-rolloutrun now refuses
with a non-zero exit and points at--yes, instead of silently succeeding. - Interactive behaviour is unchanged (default-no confirm).
- New
-
f188c7a:
stash envnow works: it mints deployment credentials from your device-code
session and prints them as env vars — no dashboard copy-paste. The command
creates a fresh ZeroKMS client and a member-role CipherStash access key (named
via--name; the role is pinned in the request and verified on the response —
the CLI deliberately cannot mint admin keys), then emitsCS_WORKSPACE_CRN,
CS_CLIENT_ID,CS_CLIENT_KEY, andCS_CLIENT_ACCESS_KEY.Output goes to stdout by default — and stdout is pipe-clean (progress UI is on
stderr), sostash env --name x > prod.envand pipes into secret stores are
safe.--write [path]writes a file instead (default.env.production.local,
enforced mode 0600 even when overwriting), confirming before overwriting and
refusing non-interactively — always before anything is minted, so a refusal
never discards the shown-exactly-once access key.--jsonemits NDJSON; with
--writethe confirmation event is deliberately secret-free. API responses
are schema-validated so a service change can never printundefinedinto a
credentials file. Creating access keys requires the admin role in the
workspace.This is also the supported credential path for WASM/edge local development
(Supabase Edge Functions, Cloudflare Workers, Deno), where the runtime cannot
read the~/.cipherstashdevice profile: mint a key and feed it via
supabase functions serve --env-fileor the platform's secret store.The
STASH_EXPERIMENTAL_ENV_CMDgate is removed. -
8872d1e:
stash init,stash plan, andstash implno longer crash on a Prisma Next
project.SKILL_MAPwas missing aprisma-nextentry, so the skills-install
and AGENTS.md-builder steps hitSKILL_MAP[integration]→undefinedand threw
"not iterable" for any repo the CLI detected as Prisma Next. The entry is added
and both consumers now resolve skills through askillsFor()helper that
degrades an unmapped integration to the base skill set instead of crashing
(tsupships without type-checking, so theRecord<Integration>type alone
didn't protect the build).Ships a new
stash-prisma-nextagent skill documenting the EQL v3 Prisma
Next surface — the domain-named encrypted column types (EncryptedTextSearch,
EncryptedDoubleOrd, …),cipherstashFromStackV3wiring, the runtime value
envelopes, theeql*query operators, and EQL installation via
prisma-next migration apply. It is installed for Prisma Next projects and
inlined intoAGENTS.mdfor editor agents.stash eql installnow refuses to run in a Prisma Next project (pointing you
at `prisma-next migration app...
@cipherstash/wizard@1.0.0-rc.3
Patch Changes
- 8b2551a: Fix "Failed to load native binding" on project-local installs of the CLI/SDK
(npm).@cipherstash/authwas pinned at 0.41.0 while the six
@cipherstash/auth-*platform bindings declared in stack/stash/wizard's
optionalDependencies were pinned at 0.42.0. Because auth pins its bindings as
exact-version optional peer dependencies, the skew made npm nest per-consumer
binding copies that the hoistedauthpackage could not resolve — any command
or import touching auth then died at startup. All seven packages now move in
lockstep at 0.42.0, Dependabot is barred from bumping any of them
independently, and a supply-chain CI test fails on any future skew.
@cipherstash/stack@1.0.0-rc.3
Patch Changes
- 8b2551a: Fix "Failed to load native binding" on project-local installs of the CLI/SDK
(npm).@cipherstash/authwas pinned at 0.41.0 while the six
@cipherstash/auth-*platform bindings declared in stack/stash/wizard's
optionalDependencies were pinned at 0.42.0. Because auth pins its bindings as
exact-version optional peer dependencies, the skew made npm nest per-consumer
binding copies that the hoistedauthpackage could not resolve — any command
or import touching auth then died at startup. All seven packages now move in
lockstep at 0.42.0, Dependabot is barred from bumping any of them
independently, and a supply-chain CI test fails on any future skew.
@cipherstash/stack-supabase@1.0.0-rc.3
@cipherstash/stack-drizzle@1.0.0-rc.3
Patch Changes
-
b8cb599: Fix invalid DDL from
drizzle-kit generate/pushfor EQL v3 encrypted columns.
A v3 column declared its SQL type as the schema-qualified domain
(public.eql_v3_text_search), but drizzle-kit wraps a custom type's whole name
in a single pair of double quotes — emitting"public.eql_v3_text_search", which
Postgres reads as one dotted identifier and rejects withtype "public.eql_v3_text_search" does not exist. Generated migrations had to be
hand-repaired.The v3 column now emits the unqualified domain (
eql_v3_text_search), which
drizzle-kit renders as the valid"eql_v3_text_search"and which resolves via the
search path (the domains live inpublic). This matches how the v2
encryptedTypesurface already declares its type, and how drizzle-kit reads the
type back during apushintrospection diff, so the two sides no longer disagree.
Builder recovery still yields the canonicalpublic.eql_v3_*identity, so
operators and schema extraction are unchanged.The bundled
stash-drizzleskill is updated to describe the unqualified generated
type and the search-path requirement (hence thestashbump — the skill ships in
its tarball). -
Updated dependencies [8b2551a]
- @cipherstash/stack@1.0.0-rc.3
@cipherstash/prisma-next@1.0.0-rc.3
Minor Changes
-
a75513b: Breaking: EQL v3 columns are now authored through concrete per-domain constructors — the constructor you choose is the capability set. The legacy boolean-option surface (
EncryptedString({ equality, freeTextSearch, orderAndRange })) is not carried into v3.- New per-domain constructors, one per exposed
public.eql_v3_*domain:- Text:
EncryptedText(storage),EncryptedTextEq,EncryptedTextOrd(eq + order/range),EncryptedTextMatch(free-text),EncryptedTextSearch(eq + free-text + order/range). - Scalars (Integer, Smallint, BigInt, Numeric, Real, Double, Date, Timestamp):
Encrypted<Fam>(storage),Encrypted<Fam>Eq,Encrypted<Fam>Ord. EncryptedBoolean— storage-only (public.eql_v3_boolean); there is no boolean equality constructor.EncryptedJson— searchable encrypted JSONB (public.eql_v3_json,ste_vec), queried witheqlJsonContains(@>containment). Selector querying (comparing the value at a JSONPath) is tracked in #677.
- Text:
- Impossible capability combinations have no constructor (e.g. text equality + free-text without order/range) — they are unrepresentable, not runtime errors.
- BigInt is a first-class v3 family (
EncryptedBigInt/EncryptedBigIntEq/EncryptedBigIntOrd, JSbigintplaintext, backed bypublic.eql_v3_bigint*). - Use the
*V2constructors (EncryptedStringV2,EncryptedDoubleV2,EncryptedBigIntV2,EncryptedDateV2,EncryptedBooleanV2,EncryptedJsonV2) to keep EQL v2 columns. A client is v2 or v3 — the two runtime descriptors are never co-registered. - New
@cipherstash/prisma-next/v3entry point:cipherstashFromStackV3({ contractJson })builds the v3 runtime descriptor, bulk-encrypt middleware, and a stackEncryptionV3client from the emitted contract. - Query operators use an EQL-derived vocabulary (
eqlEq,eqlNeq,eqlIn,eqlNotIn,eqlGt,eqlGte,eqlLt,eqlLte,eqlBetween,eqlNotBetween,eqlJsonContains; ordering viaeqlAsc/eqlDesc), lowering to the same-namedeql_v3.*functions with operands cast to the domain's query type ($n::eql_v3.query_<domain>); ordering useseql_v3.ord_term/eql_v3.ord_term_oreby the column's ordering flavour. The domains arepublic.eql_v3_*; the operator functions live in theeql_v3schema. (The v2 surface keeps itscipherstash*names.) - Free-text search is
eqlMatch— fuzzy bloom token matching (eql_v3.contains), deliberately NOT named after SQLILIKE: matching is case-insensitive, order/multiplicity-insensitive, and one-sided (may false-positive). Two guards run before encryption: SQL wildcards are normalised (leading/trailing%stripped; interior%or any_rejected), and needles the column's match index cannot answer (empty / below the tokenizer length) are rejected via the sharedmatchNeedleErrorguard. There is no negated match operator — negating a may-false-positive bloom test would silently drop matching rows. - A new baseline migration
20260601T0100_install_eql_v3_bundle(invariantcipherstash:install-eql-v3-bundle-v1) installs thepublic.eql_v3_*domains andeql_v3.*functions from the pinned@cipherstash/eqlrelease. Regenerate contracts and run migrations after changing constructors. - The v3 ORM surface is fully wired end-to-end (proven by converting
examples/prisma):- The generated
contract.d.tstype surface covers every v3 codec id:CodecTypesgains all 40cipherstash/eql-v3/*@1entries (envelope outputs —number-castAs domains decode to the newEncryptedNumber— plus trait-accurate operator visibility), andQueryOperationTypesgains theeql*operator set, surfaced on v3 columns via type-levelcipherstash:v3-*marker traits (the v2cipherstash*methods never appear on v3 columns, and vice-versa). Storage-only domains (includingEncryptedBoolean) surface no operator methods at the type level, matching the runtime gate. - The v3 runtime descriptor now presents the pack id (
cipherstash) with v3's own version, sopostgres<Contract>({ extensions })accepts contracts emitted by the cipherstash extension pack instead of failing withRUNTIME.MISSING_EXTENSION_PACK. - Every v3 codec id registers a control-plane
expandNativeTypehook that strips thepublic.qualifier —prisma-next migration plannow rendersCREATE TABLEcolumns as bare domain names (eql_v3_bigint_ord), matching what introspection reports, with noadd_search_configops (v3 domains carry their own index metadata). NoonFieldEventis registered for v3. - The v3 bundle baseline migration op is reclassified
data(it is a contract-shape-neutral self-edge; the aggregate integrity checker rejects self-edges without a data-class op), unblockingprisma-next migration plan/migratein consuming apps.
- The generated
- New per-domain constructors, one per exposed
-
4923c0a: Breaking (v3 authoring surface): the EQL v3 PSL column constructors drop
theEncryptedprefix to line up with the stack / Drizzletypes.*catalog —
thecipherstash.namespace already disambiguates. So
cipherstash.EncryptedTextSearch()→cipherstash.TextSearch(),
cipherstash.EncryptedDoubleOrd()→cipherstash.DoubleOrd(),
cipherstash.EncryptedBoolean()→cipherstash.Boolean(), etc.The v3 one-call setup function is renamed
cipherstashFromStackV3→
cipherstashFromStack(v3 is the default), and the existing v2 setup function
becomescipherstashFromStackV2.The camelCase TS-authoring factory exports move in lockstep:
encryptedTextSearch→textSearch,encryptedDoubleOrd→doubleOrd, etc.
(a property test enforces the PSL and TS names agree modulo first-letter case).Unchanged: the runtime value envelopes (
EncryptedString,EncryptedNumber,
EncryptedBoolean, …), thecipherstash.*V2legacy column constructors, the
generatedcontract.json/ codec ids, and theeql*query operators.The
stash-prisma-nextskill is updated to the new names (skills ship in the
stashtarball). -
a2f80ea: Source the EQL v3 install SQL from
@cipherstash/eqlat runtime instead of
baking it into the baseline migration.@cipherstash/eqlis now a runtime dependency, pinned exact (3.0.0) to match
the release@cipherstash/stackencodes its v3 domain types against — the
two must move together, so an EQL upgrade is a coordinated version bump, not a
float. The v3 baseline migration no longer embeds the ~1.7 MB install bundle in
itsops.json: the committed op carries a placeholder, and the extension
descriptor injectsreadInstallSql()from the installed@cipherstash/eqlwhen
it is built, and recomputes the content-addressed migration hash from the
injected operations before Prisma Next materialises the package.The win over baking: bumping the pinned
@cipherstash/eqlno longer requires
re-running the maintainer emit loop to regenerate a 1.7 MBops.json— it is a
one-line version bump plus a rebuild. This mirrors how thestashCLI already
sources the v3 SQL.No change to user-facing behaviour: EQL still installs as part of
prisma-next migration apply. Safe because the v3 baseline is an
invariant-only self-edge — the install SQL never contributes to the
contract-space hash. Injection matches the placeholder by value and fails loudly
if it is absent, so a drift between the emit source and the injector can never
silently ship an empty install.
Patch Changes
- Updated dependencies [8b2551a]
- @cipherstash/stack@1.0.0-rc.3
@cipherstash/migrate@1.0.0-rc.1
Minor Changes
-
3a86939: EQL v3 support for the encryption rollout lifecycle (#648). The
stash encrypt *commands (and@cipherstash/migrateunderneath) now resolve a
column's EQL version and its encrypted counterpart from the Postgres domain
types — the EQL v3 types are self-describing, so the<col>_encrypted
naming is a convention only, never enforced or relied upon — and follow the
right lifecycle, no new flags:encrypt backfillworks on v3 columns unchanged (the engine was always
version-agnostic; pass anEncryptionV3client and real v3 envelopes land
in the concreteeql_v3_*domain column — verified live against a real
database, including the domain CHECK and a decrypt round-trip). The
manifest records the detected version, the encrypted column's name, and the
v3 target phase, and the command prints v3-appropriate next steps.encrypt cutoveron a backfilled v3 column reports "not applicable"
(exit 0) with guidance: v3 has no rename cut-over — the application
switches to the encrypted column by name. Before backfill completes it
exits 1 and says to finish the backfill instead of instructing the switch.
On a database with noeql_v2_configurationtable (a v3-only install) the
v2 path now explains that instead of surfacing a raw Postgres error.encrypt dropis version-aware: v3 runs from thebackfilledphase,
verifies live coverage (refuses to generate the migration while any row
still has the plaintext set and the encrypted column NULL — the
countUnencryptedcheck), and drops the ORIGINAL plaintext column (there
is no<col>_plaintextunder v3); v2 behaviour is unchanged. The generated
v3 migration re-verifies coverage at apply time — it locks the table,
re-counts, and aborts without dropping if plaintext-only rows appeared
after generation. And because dropping is the one irreversible step, it
requires a positively asserted plaintext↔ciphertext pairing (the
manifest's recordedencryptedColumnor the naming convention): a match
found only by being the table's sole EQL column is refused with
instructions, and an ambiguous table (several EQL columns, none
identifiable) fails closed listing the candidates — as doescutover.encrypt statusclassifies each column from the observed domain type
(manifest as fallback), showsv3in the EQL column, and no longer raises
the v2-onlynot-registered/plaintext-col-missingdrift flags for v3
columns.stash status's quest ladder and thestash initagent handoff
prompt teach the version-appropriate next step (no more "run cutover" on
v3 columns).- New
@cipherstash/migrateexports:classifyEqlDomain,
resolveEncryptedColumn,pickEncryptedColumn,listEncryptedColumns
(domain-type resolution — case-exact for quoted/mixed-case table names),
countEncrypted/countUnencrypted(coverage counts), and manifest
eqlVersion+encryptedColumnfields.EqlVersionis numeric (2 | 3),
matching the manifest and the installer. Resolved columns carryvia: 'hint' | 'convention' | 'sole'so callers can tell a positively asserted
pairing from a by-elimination guess. - Fixed:
encrypt cutover/encrypt dropprecondition failures now actually
exit 1 — the early-return guards previously skipped the exit-code path
entirely, so failed preconditions exited 0. (This also applies to v2
preconditions: scripted pipelines that relied on the erroneous exit 0 will
now see the documented exit 1.)
The
stash-cliandstash-encryptionskills and the@cipherstash/migrate
README document the two lifecycles (v2: backfill → cutover → drop;
v3: backfill → switch-by-name → drop).
stash@1.0.0-rc.2
Patch Changes
-
6fcb967:
stash initnow pins the packages it installs (@cipherstash/stack, the
integration adapter, andstashitself) to the exact versions this CLI
release was built alongside, instead of installing bare package names that
resolve through npm dist-tags (#661). During a pre-release window dist-tags
lag or point at placeholders, so an unpinnedinitcould silently deliver a
different release than the CLI driving the setup — stale@cipherstash/stack,
or an empty placeholder adapter — breaking/v3imports out of the box. The
versions are embedded at build time from the release train itself
(src/release-train.ts, the single source both the build and the runtime
check against), so they can never disagree with what was published together.Init also now surfaces version skew on already-installed packages —
unconditionally, before any prompt or early exit, including when the install
is declined or partially fails. Interactively it offers to align the skewed
packages in the same confirm as the missing installs (keepingstasha dev
dependency); non-interactively it never mutates an existing install — it
warns and prints the exact align commands. A package whose manifest exists
but can't be read (an aborted install) is reported as skew, not treated as
matching. All other install guidance is pinned the same way: the
missing-package hints,.cipherstash/context.json'sinstallCommand, the
install-eqlmanual note, the native-module recovery hint (previously
stash@latest), and thestash wizardone-shot spawn (previously an
unpinnednpx @cipherstash/wizard). Thestash-cliskill documents the
behaviour, and the other bundled skills' manual install commands now carry a
verify-what-resolved note. -
d803914: Two guards for the release-train version embed (#661 follow-up):
Direction-aware version skew.
stash initnow distinguishes an installed
package that is behind this CLI release (offered alignment / the pinned
install command, as before) from one that is newer than the release expects.
A newer install no longer produces a downgrade command — init prints the exact
stashupdate command instead (release-train lockstep guarantees that version
exists), and when missing packages are about to be installed alongside newer
ones it says the pairing may not match and to updatestashfirst. Unreadable
or malformed manifest versions always count as behind (a broken install should
be offered the reinstall fix, never "looks newer, leave it").Version lockstep. The release-train packages (
stash,
@cipherstash/stack,@cipherstash/stack-drizzle,
@cipherstash/stack-supabase,@cipherstash/prisma-next,
@cipherstash/wizard) are now a Changesetsfixedgroup: a release of any of
them republishes all of them at the same version, so the CLI's embedded
version map can never go stale against the packages it pins (previously a
runtime-package-only release would have left the published CLI embedding —
and recommending — outdated versions). A test now asserts the fixed group
stays exactly equal to the release train. -
413ca39: The legacy
@cipherstash/drizzlepackage (the@cipherstash/protect-based
Drizzle integration) is removed from the repository and the release train —
@cipherstash/protectis sunsetting at Stack 1.0, and the package's successor
is@cipherstash/stack-drizzle. Already-published versions remain installable
from npm (deprecated, pointing here); the git history preserves the source for
any emergency maintenance. Thestash-drizzleskill and the
@cipherstash/stack-drizzleREADME now state the deprecation explicitly so
nobody (human or agent) installs the legacy package by mistake.- @cipherstash/migrate@1.0.0-rc.0
@cipherstash/wizard@1.0.0-rc.2
Patch Changes
- daa25b8:
@cipherstash/wizardnow versions in lockstep with the Stack release train
(stash,@cipherstash/stack, and the adapters) via a Changesetsfixed
group — thestashCLI executes the wizard by exact version, so the two must
always release together. This moves the package from its previous0.5.x
line onto the shared train version; no API changes.
@cipherstash/stack@1.0.0-rc.2
Minor Changes
-
b085f66:
@cipherstash/stack/wasm-inlinenow exposesencryptQueryand
encryptQueryBulkonWasmEncryptionClient(#662) — searchable encryption
is reachable on Deno/edge runtimes. Previously the WASM entry exposed only
encrypt/decrypt/isEncrypted, so encrypted WHERE-clause search was
architecturally impossible on the edge even though the underlying protect-ffi
WASM build carries the capability.The new methods mint ciphertext-free EQL v3 query terms — equality,
free-text match, ORE range, and JSON containment/selector — with the same
index-type resolution as the native client (explicitqueryType, or
inference from the column's configured indexes). Cast the term to the
column'seql_v3.query_<domain>type in SQL to reach the indexed operators.
Errors throw, consistent with the WASM surface'sencrypt/decrypt; the
bulk form is position-stable (nullvalues pass through asnull).