@@ -77,10 +77,10 @@ db.addEventListener("upgradeneeded", (e) => {
7777 id: z .string ().uuid ().db .primary ().db .auto (),
7878 email: z .string ().email ().db .unique (),
7979 name: z .string (),
80- avatar: z .string ().optional (), // new field
80+ avatar: z .string ().optional (), // new field
8181 });
82- await db .ensureTable (Users ); // adds missing columns/indexes
83- await db .ensureConstraints (Users ); // applies new constraints on existing data
82+ await db .ensureTable (Users ); // adds missing columns/indexes
83+ await db .ensureConstraints (Users ); // applies new constraints on existing data
8484 }
8585 })());
8686});
@@ -205,7 +205,7 @@ const Users = table("users", {
205205
206206// id and createdAt are optional - auto-generated if not provided
207207const user = await db .insert (Users , {name: " Alice" });
208- user .id ; // "550e8400-e29b-41d4-a716-446655440000"
208+ user .id ; // "550e8400-e29b-41d4-a716-446655440000"
209209user .createdAt ; // 2024-01-15T10:30:00.000Z
210210```
211211
@@ -256,7 +256,7 @@ const settings = await db.insert(Settings, {
256256
257257// On read: JSON strings are parsed back to objects/arrays
258258settings .config .theme ; // "dark" (object, not string)
259- settings .tags [0 ]; // "admin" (array, not string)
259+ settings .tags [0 ]; // "admin" (array, not string)
260260```
261261
262262** Custom encoding/decoding:**
@@ -319,14 +319,16 @@ const posts = await db.all([Posts, Users.active])`
319319` ;
320320```
321321
322- ** Compound indexes** via table options:
322+ ** Compound indexes and unique constraints ** via table options:
323323``` typescript
324324const Posts = table (" posts" , {
325325 id: z .string ().db .primary (),
326326 authorId: z .string (),
327+ slug: z .string (),
327328 createdAt: z .date (),
328329}, {
329330 indexes: [[" authorId" , " createdAt" ]],
331+ unique: [[" authorId" , " slug" ]], // unique together
330332});
331333```
332334
@@ -373,16 +375,16 @@ type Post = Row<typeof Posts>;
373375// Post includes: id, title, authorId, titleUpper, tags
374376
375377const posts = await db .all ([Posts , Users , PostTags , Tags ])`
376- JOIN "users" ON ${Users .on (Posts )}
377- LEFT JOIN "post_tags" ON ${PostTags .cols .postId } = ${Posts .cols .id }
378- LEFT JOIN "tags" ON ${Tags .on (PostTags )}
378+ JOIN ${ Users } ON ${Users .on (Posts )}
379+ LEFT JOIN ${ PostTags } ON ${PostTags .cols .postId } = ${Posts .cols .id }
380+ LEFT JOIN ${ Tags } ON ${Tags .on (PostTags )}
379381` ;
380382
381383const post = posts [0 ];
382384post .titleUpper ; // "HELLO WORLD" — typed as string
383- post .tags ; // ["javascript", "typescript"] — traverses relationships
384- Object .keys (post ); // ["id", "title", "authorId", "author"] (no derived props)
385- JSON .stringify (post ); // Excludes derived properties (non-enumerable)
385+ post .tags ; // ["javascript", "typescript"] — traverses relationships
386+ Object .keys (post ); // ["id", "title", "authorId", "author"] (no derived props)
387+ JSON .stringify (post ); // Excludes derived properties (non-enumerable)
386388```
387389
388390Derived properties:
@@ -394,9 +396,9 @@ Derived properties:
394396
395397** Partial selects** with ` pick() ` :
396398``` typescript
397- const UserSummary = Users .pick (" id" , " name" );
399+ const UserSummaries = Users .pick (" id" , " name" );
398400const posts = await db .all ([Posts , UserSummary ])`
399- JOIN "users" ON ${UserSummary .on (Posts )}
401+ JOIN ${ UserSummaries } ON ${UserSummary .on (Posts )}
400402` ;
401403// posts[0].author has only id and name
402404```
@@ -989,41 +991,41 @@ Override with `.db.type("CUSTOM")` when using custom encode/decode.
989991``` typescript
990992import {
991993 // Zod (extended with .db namespace)
992- z , // Re-exported Zod with .db already available
994+ z , // Re-exported Zod with .db already available
995+ extendZod , // Extend a separate Zod instance (advanced)
993996
994997 // Table and view definition
995- table , // Create a table definition from Zod schema
996- view , // Create a read-only view from a table
997- isTable , // Type guard for Table objects
998- isView , // Type guard for View objects
999- extendZod , // Extend a separate Zod instance (advanced)
998+ table , // Create a table definition from Zod schema
999+ view , // Create a read-only view from a table
1000+ isTable , // Type guard for Table objects
1001+ isView , // Type guard for View objects
10001002
10011003 // Database
1002- Database , // Main database class
1003- Transaction , // Transaction context (passed to transaction callbacks)
1004- DatabaseUpgradeEvent , // Event object for "upgradeneeded" handler
1004+ Database , // Main database class
1005+ Transaction , // Transaction context (passed to transaction callbacks)
1006+ DatabaseUpgradeEvent , // Event object for "upgradeneeded" handler
10051007
10061008 // SQL builtins (for .db.inserted() / .db.updated())
1007- NOW , // CURRENT_TIMESTAMP alias
1008- TODAY , // CURRENT_DATE alias
1009- CURRENT_TIMESTAMP , // SQL CURRENT_TIMESTAMP
1010- CURRENT_DATE , // SQL CURRENT_DATE
1011- CURRENT_TIME , // SQL CURRENT_TIME
1009+ NOW , // CURRENT_TIMESTAMP alias
1010+ TODAY , // CURRENT_DATE alias
1011+ CURRENT_TIMESTAMP , // SQL CURRENT_TIMESTAMP
1012+ CURRENT_DATE , // SQL CURRENT_DATE
1013+ CURRENT_TIME , // SQL CURRENT_TIME
10121014
10131015 // Errors
1014- DatabaseError , // Base error class
1015- ValidationError , // Schema validation failed
1016- TableDefinitionError , // Invalid table definition
1017- MigrationError , // Migration failed
1018- MigrationLockError , // Failed to acquire migration lock
1019- QueryError , // SQL execution failed
1020- NotFoundError , // Entity not found
1021- AlreadyExistsError , // Unique constraint violated
1016+ DatabaseError , // Base error class
1017+ ValidationError , // Schema validation failed
1018+ TableDefinitionError , // Invalid table definition
1019+ MigrationError , // Migration failed
1020+ MigrationLockError , // Failed to acquire migration lock
1021+ QueryError , // SQL execution failed
1022+ NotFoundError , // Entity not found
1023+ AlreadyExistsError , // Unique constraint violated
10221024 ConstraintViolationError , // Database constraint violated
1023- ConnectionError , // Connection failed
1024- TransactionError , // Transaction failed
1025- isDatabaseError , // Type guard for DatabaseError
1026- hasErrorCode , // Check error code
1025+ ConnectionError , // Connection failed
1026+ TransactionError , // Transaction failed
1027+ isDatabaseError , // Type guard for DatabaseError
1028+ hasErrorCode , // Check error code
10271029} from " @b9g/zen" ;
10281030```
10291031
@@ -1032,34 +1034,34 @@ import {
10321034``` typescript
10331035import type {
10341036 // Table types
1035- Table , // Table definition object
1036- PartialTable , // Table created via .pick()
1037- DerivedTable , // Table with derived fields via .derive()
1038- TableOptions , // Options for table()
1039- ReferenceInfo , // Foreign key reference metadata
1040- CompoundReference , // Compound foreign key reference
1037+ Table , // Table definition object
1038+ PartialTable , // Table created via .pick()
1039+ DerivedTable , // Table with derived fields via .derive()
1040+ TableOptions , // Options for table()
1041+ ReferenceInfo , // Foreign key reference metadata
1042+ CompoundReference , // Compound foreign key reference
10411043
10421044 // Field types
1043- FieldMeta , // Field metadata for form generation
1044- FieldType , // Field type enum
1045- FieldDBMeta , // Database-specific field metadata
1045+ FieldMeta , // Field metadata for form generation
1046+ FieldType , // Field type enum
1047+ FieldDBMeta , // Database-specific field metadata
10461048
10471049 // Type inference
1048- Row , // Infer row type from Table (after read)
1049- Insert , // Infer insert type from Table (respects defaults/.db.auto())
1050- Update , // Infer update type from Table (all fields optional)
1050+ Row , // Infer row type from Table (after read)
1051+ Insert , // Infer insert type from Table (respects defaults/.db.auto())
1052+ Update , // Infer update type from Table (all fields optional)
10511053
10521054 // Fragment types
1053- SetValues , // Values accepted by Table.set()
1054- SQLTemplate , // SQL template object (return type of set(), on(), etc.)
1055- SQLDialect , // "sqlite" | "postgresql" | "mysql"
1055+ SetValues , // Values accepted by Table.set()
1056+ SQLTemplate , // SQL template object (return type of set(), on(), etc.)
1057+ SQLDialect , // "sqlite" | "postgresql" | "mysql"
10561058
10571059 // Driver types
1058- Driver , // Driver interface for adapters
1059- TaggedQuery , // Tagged template query function
1060+ Driver , // Driver interface for adapters
1061+ TaggedQuery , // Tagged template query function
10601062
10611063 // Error types
1062- DatabaseErrorCode , // Error code string literals
1064+ DatabaseErrorCode , // Error code string literals
10631065} from " @b9g/zen" ;
10641066```
10651067
0 commit comments