Add SDD architecture docs for dbtype
Phase 0 architecture specification following the alkdev documentation pattern from @alkdev/flowgraph. Documents the validated architecture (UJSX elements → Type.Module → Drizzle hosts) based on e2e probe results. Docs added: - README: Project overview, architecture, current state - architecture/README: Index, design decisions, relationships - architecture/schema: Type.Module as bundle, construction, serialization - architecture/hosts: HostConfig per dialect, column mapping, symbolic defaults - architecture/elements: UJSX element types, props, function components - architecture/module: Module mechanics, format registration, diffing - architecture/repo-adapter: from-dbtype operations adapter (phase 2) - architecture/build-distribution: Package structure, exports - architecture/open-questions: 10 open questions across all topics - ADRs 001-005: UJSX as IR, Type.Module, HostConfig, format, repo adapter
This commit is contained in:
93
README.md
93
README.md
@@ -1,73 +1,70 @@
|
||||
# @alkdev/dbtype
|
||||
|
||||
Schema-first multi-dialect TypeBox/Drizzle bridge — define once, validate and deploy anywhere.
|
||||
Schema-first multi-dialect database type system. Define your schema once as a UJSX element tree, validate it with TypeBox, and render it to any Drizzle dialect.
|
||||
|
||||
Based on [drizzle-typebox](https://github.com/drizzle-team/drizzle-orm/tree/main/drizzle-typebox) by the Drizzle Team, adapted for use with `@alkdev/typebox` (a maintained fork of `@sinclair/typebox`).
|
||||
Based on [drizzle-typebox](https://github.com/drizzle-team/drizzle-orm/tree/main/drizzle-typebox) by the Drizzle Team, adapted for use with `@alkdev/typebox` and `@alkdev/ujsx`.
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
npm install @alkdev/dbtype
|
||||
npm install @alkdev/typebox
|
||||
npm install drizzle-orm
|
||||
npm install @alkdev/dbtype @alkdev/typebox @alkdev/ujsx
|
||||
npm install drizzle-orm # peer dependency, only the dialects you use
|
||||
```
|
||||
|
||||
## Features
|
||||
## Architecture
|
||||
|
||||
- Create select schemas for tables, views, and enums
|
||||
- Create insert and update schemas for tables
|
||||
- Supports all dialects: PostgreSQL, MySQL, and SQLite
|
||||
- Custom TypeBox instance support via `createSchemaFactory`
|
||||
See [docs/architecture/README.md](docs/architecture/README.md) for the full architecture specification.
|
||||
|
||||
## Usage
|
||||
### Core Principle
|
||||
|
||||
```ts
|
||||
import { pgEnum, pgTable, serial, text, timestamp } from 'drizzle-orm/pg-core';
|
||||
import { createInsertSchema, createSelectSchema, createUpdateSchema } from '@alkdev/dbtype';
|
||||
import { Type } from '@alkdev/typebox';
|
||||
import { Value } from '@alkdev/typebox/value';
|
||||
**The element tree is the schema. The module is the bundle. The host is the dialect.**
|
||||
|
||||
const users = pgTable('users', {
|
||||
id: serial('id').primaryKey(),
|
||||
name: text('name').notNull(),
|
||||
email: text('email').notNull(),
|
||||
role: text('role', { enum: ['admin', 'user'] }).notNull(),
|
||||
createdAt: timestamp('created_at').notNull().defaultNow(),
|
||||
});
|
||||
- UJSX elements (`<table>`, `<column>`) define schemas with composable function components
|
||||
- `Type.Module` holds all tables, relations, and derived schemas with automatic `Type.Ref` resolution
|
||||
- `HostConfig` renders the same tree to `sqliteTable`, `pgTable`, or `mysqlTable`
|
||||
|
||||
// Schema for inserting a user
|
||||
const insertUserSchema = createInsertSchema(users);
|
||||
### Quick Example
|
||||
|
||||
// Schema for updating a user
|
||||
const updateUserSchema = createUpdateSchema(users);
|
||||
```tsx
|
||||
import { Type, FormatRegistry } from '@alkdev/typebox'
|
||||
import { Value } from '@alkdev/typebox/value'
|
||||
import { h, createComponent } from '@alkdev/ujsx'
|
||||
|
||||
// Schema for selecting a user
|
||||
const selectUserSchema = createSelectSchema(users);
|
||||
// Register custom format validators
|
||||
FormatRegistry.Set('uuid', (v) => /^[0-9a-f]{8}-[0-9a-f]{4}-...$/i.test(v))
|
||||
|
||||
// Overriding fields
|
||||
const insertUserSchema = createInsertSchema(users, {
|
||||
role: Type.String(),
|
||||
});
|
||||
// Composable column components
|
||||
const IdColumn = createComponent('IdColumn', () =>
|
||||
h('column', { name: 'id', type: 'uuid', primaryKey: true, default: 'uuid' })
|
||||
)
|
||||
|
||||
// Refining fields
|
||||
const insertUserSchema = createInsertSchema(users, {
|
||||
id: (schema) => Type.Number({ ...schema, minimum: 0 }),
|
||||
role: Type.String(),
|
||||
});
|
||||
const AuditColumns = createComponent('AuditColumns', () => [
|
||||
h('column', { name: 'createdAt', type: 'timestamp', notNull: true, default: 'now' }),
|
||||
h('column', { name: 'updatedAt', type: 'timestamp', notNull: true, default: 'now' }),
|
||||
])
|
||||
|
||||
// Validation
|
||||
const isUserValid: boolean = Value.Check(insertUserSchema, {
|
||||
name: 'John Doe',
|
||||
email: 'johndoe@test.com',
|
||||
role: 'admin',
|
||||
});
|
||||
// Define a table
|
||||
const UsersEl = h('table', { name: 'users' },
|
||||
h(IdColumn, {}),
|
||||
h('column', { name: 'name', type: 'string', notNull: true }),
|
||||
h('column', { name: 'email', type: 'string', notNull: true }),
|
||||
h(AuditColumns, {}),
|
||||
)
|
||||
|
||||
// Extract to Type.Module for validation
|
||||
const { name, schema } = extractTable(UsersEl)
|
||||
const M = Type.Module({ Users: schema, UsersRelations: Type.Object({ tasks: Type.Array(Type.Ref('Tasks')) }) })
|
||||
const Users = M.Import('Users')
|
||||
|
||||
Value.Check(Users, { id: '...', name: 'alice', email: 'a@b.com', createdAt: 1, updatedAt: 1 })
|
||||
// → true
|
||||
```
|
||||
|
||||
## Differences from drizzle-typebox
|
||||
## Current State
|
||||
|
||||
- Uses `@alkdev/typebox` instead of `@sinclair/typebox`
|
||||
- Standalone package (no monorepo dependency)
|
||||
- Published as `@alkdev/dbtype` on npm
|
||||
**Phase 0: Exploration** — Architecture probing complete, implementation not started.
|
||||
|
||||
The current `src/` contains the forked drizzle-typebox code. The new architecture (UJSX elements, Type.Module, HostConfig) is designed and validated but not yet implemented.
|
||||
|
||||
## Attribution
|
||||
|
||||
|
||||
Reference in New Issue
Block a user