Skip to content

feat(stack): add fluent EQL v3 schema API#560

Draft
tobyhede wants to merge 4 commits into
feat/eql-v3-text-search-schemafrom
eql-v3-fluent-api
Draft

feat(stack): add fluent EQL v3 schema API#560
tobyhede wants to merge 4 commits into
feat/eql-v3-text-search-schemafrom
eql-v3-fluent-api

Conversation

@tobyhede

@tobyhede tobyhede commented Jul 6, 2026

Copy link
Copy Markdown
Contributor
import { Encryption } from "@cipherstash/stack";
import { encrypted, encryptedTable } from "@cipherstash/stack/eql/v3";

// 1. Define your schema with fluent SQL-style capabilities
const users = encryptedTable("users", {
  email: encrypted.text("email").equality().freeTextSearch().orderAndRange(),
  age: encrypted.integer("age").equality(),
  createdAt: encrypted.timestamp("created_at").orderAndRange(),
});

// 2. Initialize the client
const client = await Encryption({ schemas: [users] });

// 3. Encrypt
const encryptResult = await client.encrypt("secret@example.com", {
  column: users.email,
  table: users,
});
if (encryptResult.failure) {
  // Handle errors your way
}

// 4. Decrypt
const decryptResult = await client.decrypt(encryptResult.data);
// decryptResult.data => "secret@example.com"

Adds a fluent EQL v3 schema authoring API on top of the generated domain builders from #535. Instead of choosing a concrete generated type such as types.TextSearch("email"), callers can start from the storage type and opt into query capabilities with SQL-aligned methods:

encrypted.text("email").equality().freeTextSearch().orderAndRange()
encrypted.integer("age").equality()
encrypted.timestamp("created_at").orderAndRange()
encrypted.boolean("active")

What changed

  • Adds the encrypted namespace to @cipherstash/stack/eql/v3.
  • Maps fluent chains onto the existing concrete EQL v3 builders, preserving the same emitted encrypt config.
  • Supports text search option tuning through fluent chains, including match-first upgrades like .freeTextSearch(opts).equality().
  • Keeps compile-time capability gating: unsupported chains such as encrypted.integer("age").freeTextSearch() are rejected.
  • Adds changesets for the published @cipherstash/stack API additions and match-option preservation fix.

Validation

  • pnpm exec vitest run __tests__/schema-v3.test.ts
  • CodeRabbit review against feat/eql-v3-text-search-schema: 0 issues

Notes

This PR is stacked on #535 (feat/eql-v3-text-search-schema) and only adds the fluent authoring layer plus regression coverage for preserving freeTextSearch(opts) across upgraded text fluent chains.

@changeset-bot

changeset-bot Bot commented Jul 6, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: ee77e20

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 6 packages
Name Type
@cipherstash/stack Minor
@cipherstash/bench Patch
@cipherstash/prisma-next Patch
@cipherstash/basic-example Patch
@cipherstash/prisma-next-example Patch
@cipherstash/e2e Patch

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

@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3d4e49fc-5730-455c-848b-ad2bbdfdaa12

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch eql-v3-fluent-api

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant