Version Packages#555
Conversation
aedd211 to
7f67e11
Compare
5308a4d to
410c266
Compare
07f4ab1 to
8145936
Compare
92fd4a4 to
af103cd
Compare
3a1fc82 to
6eddeb4
Compare
freshtonic
left a comment
There was a problem hiding this comment.
Reviewed as a release PR: changeset sync, bump-level semantics, changelog fidelity, and publish safety — rather than line-by-line code review, since every hunk is changesets-generated.
Checks that pass:
- In sync with main. Consumes exactly the 13 changesets currently on
main(refreshed by the bot after #569 merged this morning); no stragglers, none missing. - Bump levels match declarations.
@cipherstash/stack0.18.0→0.19.0 (5×minor),stash0.16.0→0.17.0 (4×minor + 1×patch),@cipherstash/wizard0.3.0→0.4.0, patch bumps elsewhere. TheAuthError→AuthFailurerename and theconfig.strategy→authStrategyrename ship as minors on 0.x packages — consistent with 0.x semver, both keep deprecated aliases/are called out in the changelog, so no objection. - Publish safety. New external floors exist on npm:
@cipherstash/protect-ffi0.28.0 and@cipherstash/auth0.41.0 are both published. I also verified protect-ffi v0.28.0 does NOT include the unreleased bigint work (protectjs-ffi #120 merged to theeql_v3branch, not main; the 0.28.0 release notes cover only auth-0.41 Result support) — so stack@0.19.0 does not silently changecast_as: 'bigint'decrypt semantics via the pin bump. - Non-publishable workspaces (
e2e,examples/*,packages/bench) are allprivate: true; their version bumps are inert.
One cosmetic nit (non-blocking): the eql-v3-supabase entry in packages/stack/CHANGELOG.md says the v3 envelope production "rides on @cipherstash/protect-ffi 0.27", but 0.19.0 ships pinned to 0.28.0 (bumped by the auth-0.41 changeset consumed in the same release). Each entry is accurate for its own change at authoring time — classic changesets staleness — and the auth entry further down documents the 0.28 floor, but a reader skimming only the supabase entry could pin the wrong version. Fine to merge as-is; optionally edit that changeset on main first if you want the release notes internally consistent.
Approving.
This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.
Releases
stash@0.17.0
Minor Changes
cc62407: Add EQL v3 Supabase support, baselined on the
eql-3.0.0-alpha.2release.@cipherstash/stack/supabasegainsencryptedSupabaseV3— the EQL v3counterpart of
encryptedSupabasefor schemas authored with@cipherstash/stack/eql/v3. The public surface and call shape are identicalto v2 (same filter methods,
withLockContext,audit); only the schema typeand wire encoding differ.
The v3 surface is the
eql-3.0.0-alpha.2release artifact: domains useSQL-standard type names (
eql_v3.integer_ord,eql_v3.timestamp_ord,eql_v3.boolean, … mirrored bytypes.IntegerOrd,types.TimestampOrd,types.Boolean, …), SEM internals live in a separateeql_v3_internalschema (grant it roles, never expose it — only
eql_v3goes in Supabase'sExposed schemas), and envelopes are versioned
v: 3. Envelope productionrides on
@cipherstash/protect-ffi0.27, which takes aneqlVersionso thesame client emits v2 or v3 payloads per schema.
Adapter behaviour:
eql_v3.*domains (raw jsonb payloads,no composite wrap), with JS property → DB column name resolution and
Datereconstruction from
cast_ason decrypted rows;eql_v3.*domain CHECK requires the storage keys, and the SQL operators coerce their
operand into the domain, so a term-only operand is rejected today. This is
a tracked workaround (Linear CIP-3402), not the design: a full-envelope
operand carries a real decryptable ciphertext plus all of the column's
index terms, and PostgREST filters travel in GET query strings, so operands
can land in URL logs, proxies, and Supabase request logs (query terms are
index-terms-only by design). The fix is an EQL-side term-only scalar query
envelope (the scalar analog of
eql_v3.jsonb_query);like/ilikeon encrypted columns are emitted as PostgRESTcs(bloom-filter
@>) — the v3 domains define no LIKE operator. Substringsearch currently also requires
include_original: falseon the matchindex; that requirement is a symptom of the same interim full-envelope
operand and goes away with CIP-3402;
types.Boolean) and null filtervalues are rejected at the type level and at runtime.
The v3 builder's default row type is exactly the table's inferred plaintext
shape (no index-signature widening — widening would disable the storage-only
filter guard). Filtering or inserting plaintext passthrough columns requires
an explicit row type:
es.from<typeof users, UserRow>('users', users).The CLI gains an EQL v3 path:
stash eql install --eql-version 3installs thevendored
eql-3.0.0-alpha.2bundle (--supabaseselects the opclass-strippedvariant and applies the role grants for both
eql_v3andeql_v3_internal);stash db upgradealso accepts--eql-version, andstash db statusreportsv2 and v3 installs independently. The v2
SUPABASE_PERMISSIONS_SQLblock isnow generated from a shared
supabasePermissionsSql(schemaName)helper, withSUPABASE_PERMISSIONS_SQL_V3covering the v3 schemas.eb94ac8: Add guards for missing native binaries. When npm skips the platform-specific
optional dependency (a known npm bug), stash now prints actionable fix
guidance instead of a raw
MODULE_NOT_FOUNDstack trace. Adds a newstash doctorcommand that diagnoses the runtime and native modules and workseven when a binary is missing.
64fdeb2: Rename
stash db install,stash db upgrade, andstash db statustostash eql install,stash eql upgrade, andstash eql status. Thesecommands manage the EQL extension itself, so they now live under a dedicated
eqlcommand group. The olddbspellings keep working as deprecatedaliases that print a warning pointing at the new names. All help text,
hints, generated migration headers, and wizard steps now reference the
eqlcommands.5e23384: Add a command-descriptor registry and
stash manifest --json— a structured,versioned command surface for the docs generator and agents to consume instead
of scraping
--help.stash manifest --jsonemits{ name, version, groups[] }, where each commandcarries its summary, optional long description, examples, and flags.
versioncomes from the CLI's own
package.json, so a page generated from the manifestis always stamped with the version it describes.
stash manifest(no flag) prints a grouped, human-readable command list.src/cli/registry.ts) is intended to become the single source oftruth for command metadata. This is phase 1 of
docs/plans/cli-help-and-manifest.md; it is additive —bin/main.tsstillhand-maintains the
HELPstring that renders--help, so until the documentedfollow-on renders
--helpfrom the registry the two are kept in sync by hand.72a3356: Add non-interactive / agent-friendly affordances so
stash initandstash auth logincan run without a TTY (agents, CI, pipes). All changes areadditive — interactive behaviour in a real terminal is unchanged.
--region <slug>/STASH_REGIONonstash auth loginandstash initskip the interactive region picker. An unknown or missing region in a
non-TTY context now exits with an actionable message instead of hanging on
the picker (region resolution mirrors the
DATABASE_URLresolver'sTTY && !CIgate).stash auth login --jsonemits newline-delimited device-code events. Thefirst event (
authorization_required) carries the verification URL, so anagent can trigger auth and hand the browser step to a human — only a human
completes it in the browser.
--no-opensuppresses the browser launch.stash auth regionslists the regions valid for--region/STASH_REGION;stash auth regions --jsonemits[{ slug, label }]for programmatic use.Patch Changes
aa9c4b1: Documentation: refresh package READMEs after the protectjs → stack repository rename. Fixed repository and license links, replaced dead in-repo docs links with cipherstash.com/docs URLs, rewrote the incorrect @cipherstash/nextjs README, and added guidance pointing new projects to @cipherstash/stack.
a5f5422: Bump
@cipherstash/auth(and its per-platform native bindings) from0.40.0to0.41.0, and migrate to its newResult-returning API.What changed in
@cipherstash/auth0.41. Every fallible auth operation now returns a@byteslice/resultResult<T, AuthFailure>({ data }on success,{ failure }on error) instead of throwing. This covers strategy construction (AccessKeyStrategy.create,OidcFederationStrategy.create,AutoStrategy.detect,DeviceSessionStrategy.fromProfile),getToken(), and the device-code flow (beginDeviceCodeFlow,pollForToken,openInBrowser,bindClientDevice). Consumers now writeif (result.failure) …and readresult.datarather thantry/catch. TheAuthErrortype was renamed toAuthFailure— a discriminated union keyed bytype("NOT_AUTHENTICATED","WORKSPACE_MISMATCH", …), replacing the olderror.codestring.@cipherstash/stack(breaking type surface).AuthErroris renamed toAuthFailurein the public re-exports from@cipherstash/stack.AuthErrorCodeandTokenResultare unchanged. Anyone importingAuthErrorfrom@cipherstash/stackmust switch toAuthFailure.resolveStrategy, used by@cipherstash/stack/wasm-inline'sEncryption()) now unwraps theResultfromAccessKeyStrategy.create. A construction failure (e.g. an invalid CRN or access key) throws a descriptive[encryption]error naming theAuthFailure.typeinstead of surfacing the raw auth error.@cipherstash/protect-ffifrom0.27.0to0.28.0. auth0.41'sgetToken()returns the token inside aResultenvelope; protect-ffi0.28unwraps it (.data.token) inside its WASMnewClient, whereas0.27read.tokenoff the envelope and gotundefined— which failed the WASM encrypt/decrypt round-trip withtoken field is not a string.0.28is the floor for the WASM path under auth0.41.stash(CLI) and@cipherstash/wizard. Internal auth call sites (stash auth login, device binding,initauth check, and the wizard's token acquisition / prerequisite check) were updated to unwrapResultand branch onfailure.type. Behaviour is preserved — auth failures still surface the same way to end users; no CLI/wizard API changed.@cipherstash/stack@0.19.0
Minor Changes
cc62407: Add EQL v3 Supabase support, baselined on the
eql-3.0.0-alpha.2release.@cipherstash/stack/supabasegainsencryptedSupabaseV3— the EQL v3counterpart of
encryptedSupabasefor schemas authored with@cipherstash/stack/eql/v3. The public surface and call shape are identicalto v2 (same filter methods,
withLockContext,audit); only the schema typeand wire encoding differ.
The v3 surface is the
eql-3.0.0-alpha.2release artifact: domains useSQL-standard type names (
eql_v3.integer_ord,eql_v3.timestamp_ord,eql_v3.boolean, … mirrored bytypes.IntegerOrd,types.TimestampOrd,types.Boolean, …), SEM internals live in a separateeql_v3_internalschema (grant it roles, never expose it — only
eql_v3goes in Supabase'sExposed schemas), and envelopes are versioned
v: 3. Envelope productionrides on
@cipherstash/protect-ffi0.27, which takes aneqlVersionso thesame client emits v2 or v3 payloads per schema.
Adapter behaviour:
eql_v3.*domains (raw jsonb payloads,no composite wrap), with JS property → DB column name resolution and
Datereconstruction from
cast_ason decrypted rows;eql_v3.*domain CHECK requires the storage keys, and the SQL operators coerce their
operand into the domain, so a term-only operand is rejected today. This is
a tracked workaround (Linear CIP-3402), not the design: a full-envelope
operand carries a real decryptable ciphertext plus all of the column's
index terms, and PostgREST filters travel in GET query strings, so operands
can land in URL logs, proxies, and Supabase request logs (query terms are
index-terms-only by design). The fix is an EQL-side term-only scalar query
envelope (the scalar analog of
eql_v3.jsonb_query);like/ilikeon encrypted columns are emitted as PostgRESTcs(bloom-filter
@>) — the v3 domains define no LIKE operator. Substringsearch currently also requires
include_original: falseon the matchindex; that requirement is a symptom of the same interim full-envelope
operand and goes away with CIP-3402;
types.Boolean) and null filtervalues are rejected at the type level and at runtime.
The v3 builder's default row type is exactly the table's inferred plaintext
shape (no index-signature widening — widening would disable the storage-only
filter guard). Filtering or inserting plaintext passthrough columns requires
an explicit row type:
es.from<typeof users, UserRow>('users', users).The CLI gains an EQL v3 path:
stash eql install --eql-version 3installs thevendored
eql-3.0.0-alpha.2bundle (--supabaseselects the opclass-strippedvariant and applies the role grants for both
eql_v3andeql_v3_internal);stash db upgradealso accepts--eql-version, andstash db statusreportsv2 and v3 installs independently. The v2
SUPABASE_PERMISSIONS_SQLblock isnow generated from a shared
supabasePermissionsSql(schemaName)helper, withSUPABASE_PERMISSIONS_SQL_V3covering the v3 schemas.5e4f354: Add the EQL v3
text_searchauthoring DSL on a new@cipherstash/stack/eql/v3subpath (
types.TextSearch, v3encryptedTable/buildEncryptConfig). The v3builders emit the existing
EncryptConfigshape, so encryption, payloads, andquery paths are unchanged at runtime.
Also widens the public client types (
EncryptionClientConfig.schemas,EncryptOptions,SearchTerm/EncryptQueryOptions) to a structural contract soboth v2 and v3 builders are accepted by
Encryption/encrypt/decrypt/encryptQuery. This is a backward-compatible widening — existing v2 usage isunaffected. The structural contracts themselves (
BuildableColumn,BuildableQueryColumn,BuildableV3QueryableColumn,BuildableTable,BuildableTableColumns) and theencryptModelreturn-type mapper(
EncryptedFromBuildableTable) are exported from@cipherstash/stack/typessoconsumers can name them.
4ceefed: Add a strongly-typed EQL v3 client surface on a new
@cipherstash/stack/v3subpath (
EncryptionV3,typedClient,TypedEncryptionClient). It re-exportsthe v3
typesnamespace and table API (from@cipherstash/stack/eql/v3), so asingle import provides everything needed to author and use a v3 schema.
Every method derives its types from the concrete
table/columnbuilderarguments:
encrypt/encryptQuerypin the plaintext to the column's domain type(
text → string,int8 → bigint,timestamptz → Date, …).encryptQueryconstrainsqueryTypeto the column's capabilities and rejectsstorage-only columns at compile time.
encryptModel/bulkEncryptModelsvalidate schema-column fields against theirinferred plaintext type (passthrough fields are untouched) and return a precise
encrypted model.
decryptModel/bulkDecryptModelsreturn the precise plaintext model,reconstructing
Date/bigintvalues from the encrypt-configcast_as.Because the typed methods bind to the concrete branded v3 classes, a hand-rolled
structural table/column is rejected — closing the soundness gap where a non-branded
table could be encrypted at runtime while typed as plaintext.
Runtime behaviour is unchanged: the encrypt/query paths return the same operations
as the base client; only the model-decrypt paths add a per-column
Date/bigintreconstruction step. The v2 client surface (
Encryption) is untouched.cb34d71: Add EQL v3 schema builders for all generated SQL domains under
@cipherstash/stack/eql/v3, exposed as thetypesnamespace (one member per EQL v3 domain, e.g.types.TextEq/types.Int4Ord/types.Timestamptz), including explicit query capability metadata (getQueryCapabilities()/isQueryable()) and v3 table support in model encryption helpers (encryptModel/bulkEncryptModels).Also widen the accepted plaintext input type for
encrypt/encryptQueryto includeDateandbigint(via the newPlaintexttype), so v3date/timestamptz/int8domains can be encrypted and queried with their natural JavaScript values.90d19fb: Rename the encryption client's auth strategy config field from
config.strategytoconfig.authStrategyto make its purpose clear, and expand theEncryption()TypeDoc with a full authentication and keysets walkthrough.config.authStrategyis the new, documented field for supplying an auth strategy (OidcFederationStrategy,AccessKeyStrategy, or any{ getToken() }object).config.strategyis retained as a deprecated alias — passing it still works and forwards to the client, but logs a one-time runtime deprecation warning. When both are set,authStrategywins (and the deprecation warning still fires so the leftover field gets cleaned up).Migration: rename
config.strategy→config.authStrategy. No behavioural change beyond the deprecation warning; the field is forwarded to protect-ffi'sstrategyoption exactly as before.The
Encryption()TypeDoc now documents the defaultautostrategy (env vars → local dev profile vianpx stash auth login), the fourCS_*production/CI variables, custom strategies (AccessKeyStrategy,OidcFederationStrategy), lock context, and keysets for multi-tenant isolation.The
@cipherstash/stack/wasm-inlineentry (Deno / Edge / Workers / Bun) gets the same rename so the Node and WASM interfaces stay in sync:WasmClientConfig.authStrategyis the documented field,strategyis a deprecated alias that still works and warns at runtime.a5f5422: Bump
@cipherstash/auth(and its per-platform native bindings) from0.40.0to0.41.0, and migrate to its newResult-returning API.What changed in
@cipherstash/auth0.41. Every fallible auth operation now returns a@byteslice/resultResult<T, AuthFailure>({ data }on success,{ failure }on error) instead of throwing. This covers strategy construction (AccessKeyStrategy.create,OidcFederationStrategy.create,AutoStrategy.detect,DeviceSessionStrategy.fromProfile),getToken(), and the device-code flow (beginDeviceCodeFlow,pollForToken,openInBrowser,bindClientDevice). Consumers now writeif (result.failure) …and readresult.datarather thantry/catch. TheAuthErrortype was renamed toAuthFailure— a discriminated union keyed bytype("NOT_AUTHENTICATED","WORKSPACE_MISMATCH", …), replacing the olderror.codestring.@cipherstash/stack(breaking type surface).AuthErroris renamed toAuthFailurein the public re-exports from@cipherstash/stack.AuthErrorCodeandTokenResultare unchanged. Anyone importingAuthErrorfrom@cipherstash/stackmust switch toAuthFailure.resolveStrategy, used by@cipherstash/stack/wasm-inline'sEncryption()) now unwraps theResultfromAccessKeyStrategy.create. A construction failure (e.g. an invalid CRN or access key) throws a descriptive[encryption]error naming theAuthFailure.typeinstead of surfacing the raw auth error.@cipherstash/protect-ffifrom0.27.0to0.28.0. auth0.41'sgetToken()returns the token inside aResultenvelope; protect-ffi0.28unwraps it (.data.token) inside its WASMnewClient, whereas0.27read.tokenoff the envelope and gotundefined— which failed the WASM encrypt/decrypt round-trip withtoken field is not a string.0.28is the floor for the WASM path under auth0.41.stash(CLI) and@cipherstash/wizard. Internal auth call sites (stash auth login, device binding,initauth check, and the wizard's token acquisition / prerequisite check) were updated to unwrapResultand branch onfailure.type. Behaviour is preserved — auth failures still surface the same way to end users; no CLI/wizard API changed.35b9ed6: Bump
@cipherstash/protect-ffito0.26.0and@cipherstash/authto0.40.0, and replace the lock-context token ceremony with a strategy-based approach for identity-bound encryption.protect-ffi
0.26.0supersedes0.25.0. The public API is unchanged from0.25(internal fixes only). As in0.25,serviceTokenis gone from the encrypt / decrypt / query option types; auth flows through the client's strategy / credentials, and lock contexts travel aslockContext.identityClaim. The WASM-inline path takes a single options object with the auth strategy nested understrategy, andEncryption()config usesworkspaceCrn(CS_WORKSPACE_CRN) as the single source of truth —CS_REGIONis no longer consulted. On that pathworkspaceCrnis required only alongside anaccessKey(it derives the region); with a pre-builtstrategyit is optional, since the strategy already carries the CRN.Strategy-based, identity-bound encryption.
OidcFederationStrategyfederates an end user's third-party OIDC JWT (Clerk, Supabase, Auth0, …) into a CTS service token. As of@cipherstash/auth0.40it takes aworkspaceCrn(region derived from the CRN), matchingAccessKeyStrategy. Pass it asconfig.strategyso every ZeroKMS request authenticates as that user, then bind the data key to a claim with.withLockContext({ identityClaim }):This replaces the old ceremony (
new LockContext()→await lc.identify(jwt)→.withLockContext(lc)), which relied on a per-operation CTS token that protect-ffi removed in0.25..withLockContext()now accepts a plain{ identityClaim }object (as well as aLockContext) and no longer requires a CTS token or anidentify()call — it carries the identity claim only.LockContext.identify()/getLockContext()are deprecated (kept for backwards compatibility); the strategy handles token acquisition.@cipherstash/stack(OidcFederationStrategy,AccessKeyStrategy,AutoStrategy,DeviceSessionStrategy) and from@cipherstash/stack/wasm-inline(OidcFederationStrategy,AccessKeyStrategy) so integrators don't need a separate@cipherstash/authinstall.AuthStrategyremains re-exported for the structural type.Migrating
region→workspaceCrn(WASM-inline). If you previously passedregion(or relied onCS_REGION) to the WASM-inlineEncryption()path, replace it with your workspace CRN: setworkspaceCrnin config (orCS_WORKSPACE_CRNin the environment) to the value shown in the CipherStash dashboard (crn:<region>.aws:<workspace-id>— it embeds the region, which is now derived from it).regionis ignored if passed.Lock-context enforcement is now server-side only. Because the client no longer resolves a per-user CTS token at
withLockContexttime, it also cannot fail fast there: a wrong or missing identity claim surfaces as a ZeroKMS decryption failure (the data key simply doesn't unlock), not as a client-side error before the request. The cryptographic guarantee is unchanged — enforcement happens in ZeroKMS — but anyone relying on the old client-side throw for early feedback should assert on the operation'sfailureresult instead.Existing credential / env behaviour is preserved when
config.strategyis omitted.Patch Changes
@cipherstash/wizard@0.4.0
Minor Changes
stash db install,stash db upgrade, andstash db statustostash eql install,stash eql upgrade, andstash eql status. Thesecommands manage the EQL extension itself, so they now live under a dedicated
eqlcommand group. The olddbspellings keep working as deprecatedaliases that print a warning pointing at the new names. All help text,
hints, generated migration headers, and wizard steps now reference the
eqlcommands.Patch Changes
a5f5422: Bump
@cipherstash/auth(and its per-platform native bindings) from0.40.0to0.41.0, and migrate to its newResult-returning API.What changed in
@cipherstash/auth0.41. Every fallible auth operation now returns a@byteslice/resultResult<T, AuthFailure>({ data }on success,{ failure }on error) instead of throwing. This covers strategy construction (AccessKeyStrategy.create,OidcFederationStrategy.create,AutoStrategy.detect,DeviceSessionStrategy.fromProfile),getToken(), and the device-code flow (beginDeviceCodeFlow,pollForToken,openInBrowser,bindClientDevice). Consumers now writeif (result.failure) …and readresult.datarather thantry/catch. TheAuthErrortype was renamed toAuthFailure— a discriminated union keyed bytype("NOT_AUTHENTICATED","WORKSPACE_MISMATCH", …), replacing the olderror.codestring.@cipherstash/stack(breaking type surface).AuthErroris renamed toAuthFailurein the public re-exports from@cipherstash/stack.AuthErrorCodeandTokenResultare unchanged. Anyone importingAuthErrorfrom@cipherstash/stackmust switch toAuthFailure.resolveStrategy, used by@cipherstash/stack/wasm-inline'sEncryption()) now unwraps theResultfromAccessKeyStrategy.create. A construction failure (e.g. an invalid CRN or access key) throws a descriptive[encryption]error naming theAuthFailure.typeinstead of surfacing the raw auth error.@cipherstash/protect-ffifrom0.27.0to0.28.0. auth0.41'sgetToken()returns the token inside aResultenvelope; protect-ffi0.28unwraps it (.data.token) inside its WASMnewClient, whereas0.27read.tokenoff the envelope and gotundefined— which failed the WASM encrypt/decrypt round-trip withtoken field is not a string.0.28is the floor for the WASM path under auth0.41.stash(CLI) and@cipherstash/wizard. Internal auth call sites (stash auth login, device binding,initauth check, and the wizard's token acquisition / prerequisite check) were updated to unwrapResultand branch onfailure.type. Behaviour is preserved — auth failures still surface the same way to end users; no CLI/wizard API changed.17f4745: Add
@anthropic-ai/sdk^0.106.0as a direct dependency so theauto-installed peer of
@anthropic-ai/claude-agent-sdkresolves to a releasepatched against GHSA-p7fg-763f-g4gf, instead of the vulnerable 0.81.0 the
peer range alone would select. The wizard never imports the SDK directly —
this is a peer-resolution pin only; no behaviour change.
@cipherstash/drizzle@3.0.3
Patch Changes
@cipherstash/nextjs@4.1.1
Patch Changes
@cipherstash/prisma-next@0.3.2
Patch Changes
@cipherstash/protect@12.0.1
Patch Changes
@cipherstash/protect-dynamodb@12.0.1
Patch Changes
@cipherstash/schema@3.0.1
Patch Changes
@cipherstash/e2e@0.0.1
Patch Changes
@cipherstash/basic-example@1.2.13
Patch Changes
@cipherstash/prisma-next-example@0.0.5
Patch Changes
@cipherstash/bench@0.0.4
Patch Changes