Skip to content

Split the Drizzle and Supabase integrations into their own packages (stack-drizzle, stack-supabase) #627

Description

@coderdan

Extract the Drizzle and Supabase integrations out of @cipherstash/stack into
their own packages, each depending on @cipherstash/stack and imported directly
— the shape @cipherstash/prisma-next already proves in production. This is
"PR3" of the original EQL v3 work plan; PR1 (the integration harness, #616) is
now merged, which is exactly the safety net this refactor wanted behind it.

Target shape

@cipherstash/stack            (core)
@cipherstash/stack-drizzle    deps: stack   ← src/drizzle (v2) + src/eql/v3/drizzle
@cipherstash/stack-supabase   deps: stack   ← src/supabase
@cipherstash/prisma-next      deps: stack   (existing precedent)

stack does not re-export the new packages, so no build cycle arises.

Why now

The two adapters are currently bolted into stack, inflating its bundle. Splitting
them mirrors prisma-next and lets the adapters version independently. Doing it
after the integration suite (#616) means the nine-module API promotion and the
two-package extraction land against tests that prove query correctness end to end.

Work involved

  • Promote the internal stack modules the adapters consume to public API.
    Per the plan: Supabase needs ~six (@/encryption/helpers,
    @/encryption/operations/base-operation, @/eql/v3/columns,
    @/eql/v3/domain-registry, @/types, @/utils/logger); Drizzle v3 needs
    ~three (@/types, @/schema/match-defaults,
    @/encryption/operations/base-operation). Note @/types is the internal
    src/types.ts, distinct from the published ./types (types-public).
    Re-verify this list at implementation time — it predates refactor(stack): restore erased EQL v3 envelope + Result types #618/test(stack): federate a Clerk M2M JWT for the identity suites; wire into CI #620/feat(stack): EQL v3 JSON support — types.Json + containment #621,
    which moved envelope/Result types around. If a module is judged too internal to
    expose, relocate the shared piece (e.g. into @cipherstash/schema or the test
    kit) rather than widening the surface.
  • Drop ./drizzle, ./supabase, and ./eql/v3/drizzle from stack's
    exports, typesVersions, and tsup.config.ts. The first two are published
    subpaths; the third is not. stack is on 0.x, so a minor bump carries the break
    under 0.x semver.
  • Move the integration suites from packages/stack/integration/{drizzle-v3,supabase}
    into the new packages. Because @cipherstash/test-kit is already a workspace
    package, this is a path change, not a rewrite.
  • Update the doc/skill references (~13 for @cipherstash/stack/drizzle, plus
    the Supabase reference docs and skills/stash-supabase / skills/stash-drizzle).
    These ship in the stash tarball — update in the same PR.
  • Complexity gate: fta-v3.yml's analyze:complexity scans src/eql/v3;
    update its path filter and add an equivalent gate in stack-drizzle so the
    moved code doesn't silently lose it.
  • Changesets for the removed subpaths (breaking) and the two new packages.

Risks / notes

  • Blast radius: promoting ~nine internal modules to public API + removing
    three subpaths + rewriting ~15 doc references. Make the "expose vs relocate"
    call per module before coding.
  • Two Drizzle implementations stay forked until @cipherstash/protect
    sunsets: @cipherstash/drizzle@3.x (peer-deps @cipherstash/protect@12,
    exports createProtectOperators) is a separate, diverged implementation from
    stack's in-tree src/drizzle (createEncryptionOperators). This split does
    not merge them. A comment at the top of both operator files noting the fork
    is worth adding.
  • Future (do not do now): once protect sunsets, @cipherstash/stack-drizzle
    could reclaim the @cipherstash/drizzle name in a major. Don't couple this work
    to that deprecation timeline.

Context: the original plan's "PR3: the adapter package split" section, and the
now-merged PR1 harness (#616) on the 1.0 candidate (#535).

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions