d1-kyt 0.9.4 → 0.9.5
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/README.md +35 -4
- package/dist/cli.js +1 -1
- package/package.json +1 -1
- package/skills/use-d1-kyt/SKILL.md +13 -3
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Type-safe [Cloudflare D1](https://developers.cloudflare.com/d1/) toolkit built on [Kysely](https://kysely.dev/) and [Valibot](https://valibot.dev/). Define your schema once in Valibot — get SQL migrations and fully-typed queries with no code generation.
|
|
4
4
|
|
|
5
5
|
```typescript
|
|
6
|
-
import { defineTable, InferDB, createQueryBuilder, queryAll, queryFirst
|
|
6
|
+
import { defineTable, defineIndex, InferDB, createQueryBuilder, queryAll, queryFirst } from 'd1-kyt';
|
|
7
7
|
import * as v from 'valibot';
|
|
8
8
|
|
|
9
9
|
export const users = defineTable('users', {
|
|
@@ -18,9 +18,10 @@ export const posts = defineTable('posts', {
|
|
|
18
18
|
authorId: v.pipe(v.number(), v.integer()),
|
|
19
19
|
}, {
|
|
20
20
|
foreignKeys: [{ columns: ['authorId'], references: users }],
|
|
21
|
-
indexes: [{ columns: ['title'], unique: true }],
|
|
22
21
|
});
|
|
23
22
|
|
|
23
|
+
export const postsTitleIdx = defineIndex(posts, ['title'], { unique: true });
|
|
24
|
+
|
|
24
25
|
export type DB = InferDB<{ users: typeof users; posts: typeof posts }>;
|
|
25
26
|
export const db = createQueryBuilder<DB>();
|
|
26
27
|
|
|
@@ -127,7 +128,13 @@ export const posts = defineTable('posts', {
|
|
|
127
128
|
title: v.string(),
|
|
128
129
|
categoryId: v.pipe(v.number(), v.integer()),
|
|
129
130
|
}, {
|
|
130
|
-
foreignKeys: [{
|
|
131
|
+
foreignKeys: [{
|
|
132
|
+
columns: ['categoryId'],
|
|
133
|
+
references: categories,
|
|
134
|
+
refColumns: ['id'], // optional — defaults to the referenced table's PK
|
|
135
|
+
onDelete: 'CASCADE', // CASCADE | SET NULL | RESTRICT | NO ACTION
|
|
136
|
+
onUpdate: 'NO ACTION',
|
|
137
|
+
}],
|
|
131
138
|
});
|
|
132
139
|
```
|
|
133
140
|
|
|
@@ -141,6 +148,30 @@ deptId: v.optional(v.pipe(v.number(), v.integer())) // ✓ nullable allows inli
|
|
|
141
148
|
|
|
142
149
|
---
|
|
143
150
|
|
|
151
|
+
## Indexes
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
// Basic unique index
|
|
155
|
+
export const postsSlugIdx = defineIndex(posts, ['slug'], { unique: true });
|
|
156
|
+
|
|
157
|
+
// Composite index
|
|
158
|
+
export const postsAuthorViewsIdx = defineIndex(posts, ['authorId', 'views']);
|
|
159
|
+
|
|
160
|
+
// Partial index — only indexes rows matching the WHERE clause
|
|
161
|
+
export const postsPublishedIdx = defineIndex(posts, ['createdAt'], {
|
|
162
|
+
where: 'published = 1',
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
// Custom index name
|
|
166
|
+
export const postsSearchIdx = defineIndex(posts, ['title'], {
|
|
167
|
+
name: 'posts_title_fts_idx',
|
|
168
|
+
});
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Columns are type-checked against the table definition at compile time.
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
144
175
|
## CLI
|
|
145
176
|
|
|
146
177
|
```bash
|
|
@@ -197,7 +228,7 @@ await queryAll(env.DB, query, undefined, []); // disable all checks
|
|
|
197
228
|
| Export | Description |
|
|
198
229
|
|--------|-------------|
|
|
199
230
|
| `defineTable(name, columns, opts?)` | Define a table; returns `SchemaTable` with `$inferSelect` / `$inferInsert` |
|
|
200
|
-
| `defineIndex(table, columns, opts?)` | Define an index
|
|
231
|
+
| `defineIndex(table, columns, opts?)` | Define an index; columns are type-checked. `opts`: `unique`, `name`, `where` (partial index) |
|
|
201
232
|
| `defineTrigger(name, opts)` | Define a custom trigger |
|
|
202
233
|
| `InferDB<Tables>` | Infer a Kysely-compatible `DB` type |
|
|
203
234
|
|
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
3
3
|
import { dirname, join, resolve } from 'node:path';
|
|
4
|
-
const VERSION = '0.9.
|
|
4
|
+
const VERSION = '0.9.5';
|
|
5
5
|
const HELP = `
|
|
6
6
|
d1-kyt v${VERSION} - Opinionated Cloudflare D1 + Kysely toolkit
|
|
7
7
|
|
package/package.json
CHANGED
|
@@ -16,7 +16,7 @@ schema.ts → schema:diff → .sql migration → wrangler apply → type
|
|
|
16
16
|
## 1. Define Schema
|
|
17
17
|
|
|
18
18
|
```typescript
|
|
19
|
-
import { defineTable } from 'd1-kyt';
|
|
19
|
+
import { defineTable, defineIndex } from 'd1-kyt';
|
|
20
20
|
import * as v from 'valibot';
|
|
21
21
|
|
|
22
22
|
export const posts = defineTable(
|
|
@@ -33,10 +33,20 @@ export const posts = defineTable(
|
|
|
33
33
|
categoryId: v.pipe(v.number(), v.integer()),
|
|
34
34
|
},
|
|
35
35
|
{
|
|
36
|
-
foreignKeys: [{
|
|
37
|
-
|
|
36
|
+
foreignKeys: [{
|
|
37
|
+
columns: ['categoryId'],
|
|
38
|
+
references: categories,
|
|
39
|
+
refColumns: ['id'], // optional, defaults to referenced table's PK
|
|
40
|
+
onDelete: 'CASCADE', // CASCADE | SET NULL | RESTRICT | NO ACTION
|
|
41
|
+
onUpdate: 'NO ACTION', // same options
|
|
42
|
+
}],
|
|
38
43
|
}
|
|
39
44
|
);
|
|
45
|
+
|
|
46
|
+
// Indexes are defined separately with defineIndex (NOT inside defineTable options)
|
|
47
|
+
export const postsSlugIdx = defineIndex(posts, ['slug'], { unique: true });
|
|
48
|
+
export const postsPublishedIdx = defineIndex(posts, ['views'], { where: 'published = 1' }); // partial index
|
|
49
|
+
export const postsCustomIdx = defineIndex(posts, ['title'], { name: 'posts_title_search_idx' });
|
|
40
50
|
```
|
|
41
51
|
|
|
42
52
|
**Column type mapping:**
|