Skip to content

feat(drizzle): add definition lifecycle - #85

Merged
ian-pascoe merged 4 commits into
mainfrom
feat/drizzle-definition-lifecycle
Aug 12, 2026
Merged

feat(drizzle): add definition lifecycle#85
ian-pascoe merged 4 commits into
mainfrom
feat/drizzle-definition-lifecycle

Conversation

@ian-pascoe

@ian-pascoe ian-pascoe commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add the publishable @commissary/drizzle package with connection-free PostgreSQL, MySQL, and SQLite Store and Thread Store definition factories
  • implement lower-tier Record and direct Drizzle table inputs, table/column overrides, static and generated schemas, hooks, relations, PostgreSQL enums, deterministic diagnostics, and exact catalog inference
  • add package documentation, a minor Changeset, package/archive/import checks, and cross-runtime conformance coverage
  • keep live database binding and adapter conformance out of scope, as specified by Implement the shared Drizzle definition lifecycle #64

Closes #64.

Verification

  • pnpm run verify
  • pnpm --filter @commissary/drizzle typecheck
  • pnpm --filter @commissary/drizzle test
  • pnpm --filter @commissary/drizzle build
  • pnpm --filter @commissary/drizzle pack:check
  • pnpm run check:imports
  • pnpm run conformance:node
  • pnpm run conformance:bun
  • pnpm run conformance:deno
  • pnpm run conformance:browser
  • pnpm run conformance:cloudflare
  • all Drizzle compatibility and package-interface prototypes compile and run

Release

  • I added tests for changed behavior, or explained why no test is needed.
  • I updated documentation for changed public behavior, or no update is needed.
  • I added a Changeset, or explained why this change needs the no-changeset label.

No-Changeset reason, if applicable: N/A

Summary by CodeRabbit

  • New Features

    • Added @commissary/drizzle with typed, connection-free Store and Thread Store definitions.
    • Added PostgreSQL, MySQL, and SQLite support, including tables, schemas, relations, enums, defaults, hooks, and overrides.
    • Added structured validation errors and SQL utilities.
  • Documentation

    • Added installation, usage, compatibility, package, and licensing guidance.
  • Updates

    • Renamed the schema configuration option to schemaGenerators.
  • Release

    • Prepared a minor release for @commissary/drizzle.

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@ian-pascoe, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 46 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 259b6261-ef8c-4333-b91e-24bedd7dc07f

📥 Commits

Reviewing files that changed from the base of the PR and between 57015ed and 1769ccc.

📒 Files selected for processing (1)
  • packages/drizzle/test/definition-lifecycle.test.ts
📝 Walkthrough

Walkthrough

Changes

The pull request adds @commissary/drizzle with connection-free PostgreSQL, MySQL, and SQLite Store definition factories. It adds shared validation, schema generation, dialect adapters, Thread Store composition, lifecycle tests, documentation, and package integrity checks.

Drizzle definition lifecycle

Layer / File(s) Summary
Package surface and definition contracts
packages/drizzle/src/definition-contracts.ts, packages/drizzle/src/definition-types.ts, packages/drizzle/src/definition-state.ts, packages/drizzle/src/drizzle-sql.ts, packages/drizzle/src/index.ts, packages/drizzle/package.json
Adds public contracts, typed definition composition, immutable aggregate errors, SQL helpers, package exports, metadata, documentation, and TypeScript configuration.
Shared definition runtime
packages/drizzle/src/definition-runtime.ts
Validates records, tables, overrides, schemas, hooks, relations, generated fields, and Core composition. It returns records, a flat schema, and runtime state.
Dialect table adapters
packages/drizzle/src/postgres-definition.ts, packages/drizzle/src/mysql-definition.ts, packages/drizzle/src/sqlite-definition.ts
Adds dialect-specific tables, columns, defaults, generated expressions, codecs, primary keys, references, identity handling, enum assets, and validation.
Typed Store factories
packages/drizzle/src/postgres.ts, packages/drizzle/src/mysql.ts, packages/drizzle/src/sqlite.ts
Adds typed generic and Thread Store contracts and synchronous factories for all three dialects.
Lifecycle validation
packages/drizzle/test/definition-lifecycle.test.ts
Tests tables, relations, enums, schema generators, overrides, generated values, hooks, Core composition, dialect errors, runtime errors, and compile-time constraints.
Repository integration and package validation
scripts/*, docs/specs/*, packages/store/prototypes/*, README.md, .changeset/*
Validates package exports, root-module isolation, declaration contents, archive targets, and runtime conformance. It also renames the schema-generator option to schemaGenerators.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant DrizzleStoreFactory
  participant SharedDefinitionRuntime
  participant DialectAdapter
  participant DefinitionResult
  Caller->>DrizzleStoreFactory: call define(...)
  DrizzleStoreFactory->>SharedDefinitionRuntime: pass options and store kind
  SharedDefinitionRuntime->>DialectAdapter: materialize tables and dialect assets
  DialectAdapter-->>SharedDefinitionRuntime: return tables, references, and metadata
  SharedDefinitionRuntime-->>DrizzleStoreFactory: return validated records and flat schema
  DrizzleStoreFactory-->>Caller: return connection-free Store definition
Loading

Poem

I’m a rabbit with schemas tucked under my ear,
Three dialects now hop from definition to clear.
Tables bloom softly, hooks keep time,
Errors line up in an ordered rhyme.
No connection needed—just define and go,
Through PostgreSQL, MySQL, SQLite flow.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.54% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: adding the Drizzle definition lifecycle.
Description check ✅ Passed The description includes the required summary, verification commands, release checklist, tests, documentation, and Changeset details.
Linked Issues check ✅ Passed The changes address issue #64 by adding the package, three dialect factories, lifecycle capabilities, diagnostics, documentation, and required validation tooling.
Out of Scope Changes check ✅ Passed The changes remain within scope and support the requested package, lifecycle, documentation, validation, and schema-generators rename.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/drizzle-definition-lifecycle

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 13

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/drizzle/src/definition-runtime.ts`:
- Around line 1854-1857: Validate tableParts before constructing tableStatement,
accepting only one or two non-empty parts and throwing a clear error for empty,
overlong, or otherwise invalid input. Keep the existing one-part and two-part
SQL construction unchanged after validation.
- Around line 905-916: Split the combined condition in the generated-schema
validation around first, second, and structuralJsonEqual into separate
diagnostics: report when either parsed value is not JSON-compatible, and reserve
the existing “must produce a stable JSON value” diagnostic for two JSON values
that differ structurally. Preserve the current issue path and continuation
behavior for both cases.
- Around line 1619-1735: Add a lifecycle test for a thread-store definition that
triggers both host-record validation and Core composition failures. Assert the
complete ordered error.issues sequence, including the invalid-drizzle-override
issue at ["records"], and preserve the expected ordering of all host and Core
issues.
- Around line 842-866: Update the representative selection around
standardJsonSchemaInputRepresentative and structuralSchemaInputRepresentative to
detect tuple schemas and construct a non-empty candidate from their required
items before falling back to generic candidates. Ensure
z.tuple([z.literal("x")]) produces a valid representative and no longer reaches
the incompatible-generated-schema error, while preserving existing minLength
handling for long strings; add a static regression test covering this tuple
write schema.
- Around line 462-502: Add regression coverage for the write-schema fallback
using Zod 4.4.3, Zod 3.25.76, and Valibot 1.4.2, exercising each library’s
schema introspection path through structuralSchemaInputRepresentative. Add a
concise comment above structuralSchemaInputRepresentative documenting its
dependency on the version-sensitive Zod def/_def and Valibot pipe structures, so
dependency updates prompt review of these tests.

In `@packages/drizzle/src/definition-types.ts`:
- Around line 613-636: Replace the inline import types in both
DrizzleHooksConfig branches with the existing top-level ThreadRecordDefinitions
import, add RecordOverrides to the existing `@commissary/store` type import, and
use that imported symbol at the affected override references. Apply the same
import cleanup to the RecordDefinition reference in postgres.ts.

In `@packages/drizzle/src/drizzle-sql.ts`:
- Around line 18-23: Update the makePlaceholder callback passed to
compileSqlStatement in drizzleSql so it throws a clear error instead of
returning the literal "?". Preserve the existing never-parameter handling and
ensure any unexpected parameter fragment fails deterministically during SQL
definition.

In `@packages/drizzle/src/mysql-definition.ts`:
- Around line 53-56: Update mysqlTypeSql’s enum value serialization to escape
backslashes as well as single quotes when backslash escapes are enabled, using
the configured DDL SQL mode to avoid doubling them under NO_BACKSLASH_ESCAPES.
Preserve the existing quote escaping and enum formatting.
- Around line 183-204: Align codec installation with native builder selection
across all adapters: in packages/drizzle/src/mysql-definition.ts:183-204, extend
installMysqlAutoIncrementCodec to cover onUpdate === "current-timestamp"
columns; in packages/drizzle/src/postgres-definition.ts:147-154, verify whether
enum codecs are identity mappings and extend installPostgresIdentityCodec when
they are not; in packages/drizzle/src/sqlite-definition.ts:74-88, verify rowid
codec identity and add a matching installation pass when needed. Prefer deriving
installation targets directly from each dialect’s column-builder selection so
native-builder coverage cannot drift.

In `@packages/drizzle/src/postgres-definition.ts`:
- Around line 292-296: Update the asset-key mapping in the enum resolution flow
around enumValues to read schema and name directly from resolvedEnum,
eliminating the resolution.enums.find lookup and the unqualified entity.enumName
fallback; produce the same qualified key format as postgresEnumKey and
finishPostgresAssets.
- Around line 370-380: In the conflicting-definition branch of the materialized
enum collection logic, replace the second result entry with an
invalid-drizzle-enum diagnostic describing the differing enum value tuples and
identifying the affected enum or column path. Do not add the duplicate physical
key to result; preserve the existing behavior for identical definitions and
first-time keys.

In `@packages/drizzle/src/sqlite-definition.ts`:
- Around line 160-165: Extract the duplicated reverse column lookup into a
shared helper in definition-runtime.ts that accepts the columns map and
primary-key column list and returns logical field names. Update
getPrimaryKeyFields in packages/drizzle/src/sqlite-definition.ts#L160-L165,
packages/drizzle/src/mysql-definition.ts#L291-L296, and
packages/drizzle/src/postgres-definition.ts#L421-L426 to call the helper while
retaining each adapter’s dialect-specific config reading.

In `@packages/drizzle/test/definition-lifecycle.test.ts`:
- Around line 341-351: Update the remaining failure tests in
definition-lifecycle.test.ts to capture validation issues with
captureDrizzleIssueLocations instead of asserting only DrizzleDefinitionError.
For each referenced test, assert the exact issue codes, paths, and ordering
expected for the malformed or unsupported input, following the existing enum
tests as the pattern and preserving the non-JSON generator case’s expected
locations.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 50448bd2-f69a-4fe9-8d90-6afb0d7ee955

📥 Commits

Reviewing files that changed from the base of the PR and between 4d3ce8c and 1d2b689.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (26)
  • .changeset/tidy-hounds-spark.md
  • README.md
  • package.json
  • packages/drizzle/CONTEXT.md
  • packages/drizzle/LICENSE
  • packages/drizzle/README.md
  • packages/drizzle/package.json
  • packages/drizzle/src/definition-contracts.ts
  • packages/drizzle/src/definition-runtime.ts
  • packages/drizzle/src/definition-state.ts
  • packages/drizzle/src/definition-types.ts
  • packages/drizzle/src/drizzle-sql.ts
  • packages/drizzle/src/index.ts
  • packages/drizzle/src/mysql-definition.ts
  • packages/drizzle/src/mysql.ts
  • packages/drizzle/src/postgres-definition.ts
  • packages/drizzle/src/postgres.ts
  • packages/drizzle/src/sqlite-definition.ts
  • packages/drizzle/src/sqlite.ts
  • packages/drizzle/test/definition-lifecycle.test.ts
  • packages/drizzle/tsconfig.build.json
  • packages/drizzle/tsconfig.json
  • scripts/check-built-imports.mjs
  • scripts/check-package-archive.mjs
  • scripts/check-package-archive.test.mjs
  • scripts/runtime-conformance-suite.mjs

Comment thread packages/drizzle/src/definition-runtime.ts
Comment thread packages/drizzle/src/definition-runtime.ts
Comment thread packages/drizzle/src/definition-runtime.ts
Comment thread packages/drizzle/src/definition-runtime.ts
Comment thread packages/drizzle/src/definition-runtime.ts
Comment thread packages/drizzle/src/mysql-definition.ts Outdated
Comment thread packages/drizzle/src/postgres-definition.ts
Comment thread packages/drizzle/src/postgres-definition.ts
Comment thread packages/drizzle/src/sqlite-definition.ts
Comment thread packages/drizzle/test/definition-lifecycle.test.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/drizzle/test/definition-lifecycle.test.ts`:
- Around line 380-389: Refactor the unsupported schema-family test around
DrizzleSqliteStore.define to use captureDrizzleIssueLocations for a single
invocation and assertion. Remove the duplicate try/catch, DrizzleDefinitionError
instance check, and direct error.issues mapping while preserving the expected
unsupported-schema-family code and schemaGenerators path.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 0cf2744d-818a-4f27-a85e-17dc9b75fbab

📥 Commits

Reviewing files that changed from the base of the PR and between 1d2b689 and 57015ed.

📒 Files selected for processing (15)
  • docs/specs/drizzle-mysql-store.md
  • docs/specs/drizzle-package-interface.md
  • docs/specs/drizzle-postgres-store.md
  • docs/specs/drizzle-store.md
  • packages/drizzle/README.md
  • packages/drizzle/src/definition-runtime.ts
  • packages/drizzle/src/definition-types.ts
  • packages/drizzle/src/drizzle-sql.ts
  • packages/drizzle/src/mysql-definition.ts
  • packages/drizzle/src/postgres-definition.ts
  • packages/drizzle/src/postgres.ts
  • packages/drizzle/test/definition-lifecycle.test.ts
  • packages/store/prototypes/complete-sql-drizzle-specification.prototype.ts
  • packages/store/prototypes/drizzle-package-interface.prototype.ts
  • packages/store/prototypes/shared-drizzle-definition-lifecycle.prototype.ts

Comment thread packages/drizzle/test/definition-lifecycle.test.ts Outdated
@ian-pascoe
ian-pascoe merged commit 2324e85 into main Aug 12, 2026
9 checks passed
@ian-pascoe
ian-pascoe deleted the feat/drizzle-definition-lifecycle branch August 12, 2026 14:52
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.

Implement the shared Drizzle definition lifecycle

1 participant