@beignet/provider-db-drizzle 0.0.25 → 0.0.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/README.md +8 -0
- package/package.json +4 -2
- package/skills/database-provider/SKILL.md +190 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @beignet/provider-db-drizzle
|
|
2
2
|
|
|
3
|
+
## 0.0.26
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 104302c: Refresh package-shipped TanStack Intent skills and add package skills for Drizzle database providers, Better Auth, React Hook Form, and React uploads.
|
|
8
|
+
|
|
3
9
|
## 0.0.25
|
|
4
10
|
|
|
5
11
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -72,6 +72,14 @@ bun add @beignet/provider-db-drizzle @beignet/core drizzle-orm mysql2
|
|
|
72
72
|
Doctor also checks standard Drizzle config, schema exports, database scripts,
|
|
73
73
|
seed/reset entrypoints, and provider registration drift in generated apps.
|
|
74
74
|
|
|
75
|
+
## Agent skills
|
|
76
|
+
|
|
77
|
+
This package ships a TanStack Intent skill for coding agents:
|
|
78
|
+
`@beignet/provider-db-drizzle#database-provider`. Load it when wiring Drizzle
|
|
79
|
+
providers, schema placement, Drizzle config, `DbPort` typing, repository
|
|
80
|
+
adapters, Unit of Work, audit, idempotency, outbox tables, migrations,
|
|
81
|
+
seed/reset helpers, devtools query instrumentation, or database doctor drift.
|
|
82
|
+
|
|
75
83
|
## Setup
|
|
76
84
|
|
|
77
85
|
### 1. Define your schema
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@beignet/provider-db-drizzle",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.26",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Drizzle ORM database providers for Beignet — typed DbPort, unit of work, audit logs, outbox, and idempotency for SQLite (libSQL/Turso), Postgres, and MySQL.",
|
|
6
6
|
"exports": {
|
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
"!src/**/*.test.ts",
|
|
36
36
|
"!src/**/*.test.tsx",
|
|
37
37
|
"!src/**/*.test-d.ts",
|
|
38
|
+
"skills",
|
|
38
39
|
"README.md",
|
|
39
40
|
"CHANGELOG.md"
|
|
40
41
|
],
|
|
@@ -60,7 +61,8 @@
|
|
|
60
61
|
"database",
|
|
61
62
|
"ports",
|
|
62
63
|
"hex",
|
|
63
|
-
"hexagonal"
|
|
64
|
+
"hexagonal",
|
|
65
|
+
"tanstack-intent"
|
|
64
66
|
],
|
|
65
67
|
"license": "MIT",
|
|
66
68
|
"repository": {
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: database-provider
|
|
3
|
+
description: "Wire Beignet Drizzle database providers with @beignet/provider-db-drizzle: SQLite/libSQL, Postgres, MySQL, schema placement, Drizzle config, provider registration, DbPort typing, repository adapters, Unit of Work, audit, idempotency, outbox tables, migrations, seed/reset helpers, devtools query instrumentation, and doctor drift. Use when adding, fixing, or reviewing Beignet database provider setup."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Beignet Drizzle Database Provider
|
|
7
|
+
|
|
8
|
+
Use this skill when working in an app that depends on
|
|
9
|
+
`@beignet/provider-db-drizzle`. Read local `AGENTS.md`, `beignet.config.*`,
|
|
10
|
+
`drizzle.config.*`, `infra/db/`, `server/providers.ts`, and the nearest
|
|
11
|
+
repository adapter before changing database code.
|
|
12
|
+
|
|
13
|
+
## Backend Choice
|
|
14
|
+
|
|
15
|
+
Use the provider subpath that matches the selected database:
|
|
16
|
+
|
|
17
|
+
- SQLite/libSQL/Turso: `@beignet/provider-db-drizzle/sqlite`
|
|
18
|
+
- Postgres/node-postgres: `@beignet/provider-db-drizzle/postgres`
|
|
19
|
+
- MySQL/mysql2: `@beignet/provider-db-drizzle/mysql`
|
|
20
|
+
|
|
21
|
+
Switching backends should change driver install, provider subpath, Drizzle
|
|
22
|
+
schema dialect, connection env var, and infra adapters. Contracts, use cases,
|
|
23
|
+
policies, routes, and UI should keep depending on app-owned ports.
|
|
24
|
+
|
|
25
|
+
## App-Owned Schema
|
|
26
|
+
|
|
27
|
+
Keep Drizzle schema and migrations in the app, normally:
|
|
28
|
+
|
|
29
|
+
```txt
|
|
30
|
+
infra/db/schema/
|
|
31
|
+
drizzle/
|
|
32
|
+
drizzle.config.ts
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Feature use cases must not import Drizzle schema or provider packages. Put SQL
|
|
36
|
+
mapping in `infra/<feature>/` or `infra/db/` adapters, then expose app-owned
|
|
37
|
+
repository interfaces from `features/<feature>/ports.ts`.
|
|
38
|
+
|
|
39
|
+
When audit, idempotency, or outbox need provider-owned SQL tables, generate the
|
|
40
|
+
Beignet table exports into the app schema, then run the normal migration flow:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
beignet db schema generate
|
|
44
|
+
beignet db generate
|
|
45
|
+
beignet db migrate
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Use `--tables audit,idempotency,outbox` when adopting a subset.
|
|
49
|
+
|
|
50
|
+
## Provider Registration
|
|
51
|
+
|
|
52
|
+
Create the backend provider in `server/providers.ts` or a nearby infra module
|
|
53
|
+
and register it before app-local providers that require `ctx.ports.db`.
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
import { createDrizzleSqliteProvider } from "@beignet/provider-db-drizzle/sqlite";
|
|
57
|
+
import * as schema from "@/infra/db/schema";
|
|
58
|
+
|
|
59
|
+
const drizzleSqliteProvider = createDrizzleSqliteProvider({ schema });
|
|
60
|
+
|
|
61
|
+
export const providers = [drizzleSqliteProvider] as const;
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Provider env vars:
|
|
65
|
+
|
|
66
|
+
- SQLite: `SQLITE_DB_URL`, optional `SQLITE_DB_AUTH_TOKEN`
|
|
67
|
+
- Postgres: `POSTGRES_DB_URL`
|
|
68
|
+
- MySQL: `MYSQL_DB_URL`
|
|
69
|
+
|
|
70
|
+
`beignet doctor --strict` checks required env, provider registration,
|
|
71
|
+
Drizzle config, schema exports, scripts, seed/reset entrypoints, and
|
|
72
|
+
registration drift in generated apps.
|
|
73
|
+
|
|
74
|
+
## Port Typing
|
|
75
|
+
|
|
76
|
+
Type the provider-contributed `db` port in app ports, then infer runtime ports
|
|
77
|
+
from the registered providers.
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
import type { DbPort } from "@beignet/provider-db-drizzle/sqlite";
|
|
81
|
+
import type { InferProviderPorts } from "@beignet/core/providers";
|
|
82
|
+
import type * as schema from "@/infra/db/schema";
|
|
83
|
+
import type { providers } from "@/server/providers";
|
|
84
|
+
|
|
85
|
+
export type AppPorts = {
|
|
86
|
+
db: DbPort<typeof schema>;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
export type AppRuntimePorts = AppPorts & InferProviderPorts<typeof providers>;
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Use `ctx.ports.db.drizzle` inside infra and provider wiring. Keep ordinary app
|
|
93
|
+
behavior behind repository, audit, outbox, idempotency, and Unit of Work ports.
|
|
94
|
+
|
|
95
|
+
## Repositories
|
|
96
|
+
|
|
97
|
+
Repository factories should accept a root database or transaction client from
|
|
98
|
+
the matching provider subpath:
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
import { eq } from "drizzle-orm";
|
|
102
|
+
import type { DrizzleSqliteDatabase } from "@beignet/provider-db-drizzle/sqlite";
|
|
103
|
+
import type { TodoRepository } from "@/features/todos/ports";
|
|
104
|
+
import * as schema from "@/infra/db/schema";
|
|
105
|
+
|
|
106
|
+
export function createTodoRepository(
|
|
107
|
+
db: DrizzleSqliteDatabase<typeof schema>,
|
|
108
|
+
): TodoRepository {
|
|
109
|
+
return {
|
|
110
|
+
async findById(id) {
|
|
111
|
+
const [row] = await db
|
|
112
|
+
.select()
|
|
113
|
+
.from(schema.todos)
|
|
114
|
+
.where(eq(schema.todos.id, id))
|
|
115
|
+
.limit(1);
|
|
116
|
+
|
|
117
|
+
return row ?? null;
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Collect repositories in an infra factory and contribute them through an
|
|
124
|
+
app-local provider when they depend on `ctx.ports.db`.
|
|
125
|
+
|
|
126
|
+
## Unit Of Work
|
|
127
|
+
|
|
128
|
+
Use the backend `createDrizzleXUnitOfWork(...)` helper when a use case needs
|
|
129
|
+
business writes, audit rows, idempotency records, outbox records, or domain
|
|
130
|
+
events to commit together.
|
|
131
|
+
|
|
132
|
+
Build every transaction-scoped port from the transaction client:
|
|
133
|
+
|
|
134
|
+
```ts
|
|
135
|
+
uow: createDrizzleSqliteUnitOfWork({
|
|
136
|
+
db: ports.db.drizzle,
|
|
137
|
+
eventBus: ports.eventBus,
|
|
138
|
+
createTransactionPorts: (tx, events) => ({
|
|
139
|
+
...createRepositories(tx),
|
|
140
|
+
events,
|
|
141
|
+
audit: createDrizzleSqliteAuditLogPort(tx),
|
|
142
|
+
idempotency: createDrizzleSqliteIdempotencyPort(tx),
|
|
143
|
+
outbox: createDrizzleSqliteOutboxPort(tx),
|
|
144
|
+
}),
|
|
145
|
+
});
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Root ports are useful for reads and background work. They do not participate in
|
|
149
|
+
the current transaction unless rebuilt from `tx`.
|
|
150
|
+
|
|
151
|
+
## Gotchas
|
|
152
|
+
|
|
153
|
+
- The provider installs `ctx.ports.db`; the app still owns schema,
|
|
154
|
+
migrations, repository interfaces, seed/reset scripts, and Drizzle config.
|
|
155
|
+
- `ctx.ports.db.drizzle` is an infra escape hatch. Do not make it the normal
|
|
156
|
+
dependency for contracts, use cases, policies, routes, or UI.
|
|
157
|
+
- Register Drizzle before app-local providers that call `ports.db.drizzle` in
|
|
158
|
+
`setup(...)`.
|
|
159
|
+
- The legacy `ctx.ports.db.db` alias may exist, but new app code should use
|
|
160
|
+
`drizzle`.
|
|
161
|
+
- Operational ports must be rebuilt from `tx` when they need to commit with
|
|
162
|
+
the business write.
|
|
163
|
+
|
|
164
|
+
## Operational Ports
|
|
165
|
+
|
|
166
|
+
- Audit: use `createDrizzleXAuditLogPort(...)`; wrap with
|
|
167
|
+
`createInstrumentedAuditLog(...)` or ambient audit helpers when the app needs
|
|
168
|
+
actor/request defaults and devtools events.
|
|
169
|
+
- Idempotency: use `createDrizzleXIdempotencyPort(...)` with
|
|
170
|
+
`runIdempotently(...)` when replay safety must survive process restarts.
|
|
171
|
+
- Outbox: use `createDrizzleXOutboxPort(...)`, record inside the transaction,
|
|
172
|
+
and drain from a worker, cron route, or explicit outbox drain route.
|
|
173
|
+
|
|
174
|
+
Generate and migrate the backing tables before booting code that depends on
|
|
175
|
+
these ports.
|
|
176
|
+
|
|
177
|
+
## Testing
|
|
178
|
+
|
|
179
|
+
Use repository fakes for pure use-case tests. Use isolated Drizzle databases
|
|
180
|
+
for SQL mapping, transactions, migration assumptions, durable idempotency,
|
|
181
|
+
audit rows, and outbox rows.
|
|
182
|
+
|
|
183
|
+
After database provider changes, run from the app root:
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
beignet lint
|
|
187
|
+
beignet doctor --strict
|
|
188
|
+
bun run test
|
|
189
|
+
bun run typecheck
|
|
190
|
+
```
|