@netlify/agent-runner-cli 1.30.0 → 1.30.1-broken.0
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 +6 -5
- package/dist/bin-local.d.ts +1 -0
- package/dist/bin-local.js +301 -0
- package/dist/bin.js +225 -78
- package/dist/index.d.ts +64 -12
- package/dist/index.js +211 -77
- package/dist/scripts/scaffold.d.ts +2 -0
- package/dist/scripts/scaffold.js +13 -0
- package/dist/skills/frontend-design/SKILL.md +86 -0
- package/dist/skills/general-database/SKILL.md +45 -0
- package/dist/skills/netlify-ai-gateway/SKILL.md +411 -0
- package/dist/skills/netlify-blobs/SKILL.md +421 -0
- package/dist/skills/netlify-database/SKILL.md +423 -0
- package/dist/skills/netlify-edge-functions/SKILL.md +478 -0
- package/dist/skills/netlify-forms/SKILL.md +358 -0
- package/dist/skills/netlify-forms/scripts/enable.cjs +12 -0
- package/dist/skills/netlify-functions/SKILL.md +478 -0
- package/dist/skills/netlify-identity/SKILL.md +632 -0
- package/dist/skills/netlify-identity/scripts/enable.cjs +12 -0
- package/dist/skills/netlify-image-cdn/SKILL.md +244 -0
- package/package.json +40 -28
- package/scripts/scenarios/install-skills.mjs +57 -0
- package/scripts/scenarios/netlify-deploy.mjs +311 -0
- package/scripts/scenarios/prewarm-template-mirror.mjs +69 -0
- package/patches/@google+gemini-cli+0.1.17.patch +0 -87
|
@@ -0,0 +1,423 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: netlify-database
|
|
3
|
+
description: Use Netlify Database to store application data — records, collections, lists, user data, or any structured information. Provides a fully managed Postgres database. Use for CRUD operations, queryable data, or anything you would naturally model as rows in a table. Use Blobs only for files, binary assets, or cached responses.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Netlify Database
|
|
7
|
+
|
|
8
|
+
Netlify Database is a fully managed Postgres database built into the Netlify platform. It handles provisioning, migrations,
|
|
9
|
+
and database branching automatically. There is no setup beyond installing the `@netlify/database` package.
|
|
10
|
+
|
|
11
|
+
Prefer Netlify Database over Netlify Blobs for any application data — records, collections, lists, user-generated content,
|
|
12
|
+
or anything you would store as rows. Use Blobs only for files, binary assets (images, video), or cached responses.
|
|
13
|
+
|
|
14
|
+
## CRITICAL: Use the `@beta` dist-tag for Drizzle
|
|
15
|
+
|
|
16
|
+
The Netlify Database adapter for Drizzle ORM only exists on the `beta` release line of `drizzle-orm`. You MUST install
|
|
17
|
+
both `drizzle-orm` and `drizzle-kit` from the `@beta` dist-tag — the default `latest` versions do not include the
|
|
18
|
+
Netlify Database adapter and will fail.
|
|
19
|
+
|
|
20
|
+
This affects:
|
|
21
|
+
- `npm install` commands: always install `drizzle-orm@beta` and `drizzle-kit@beta` (never `drizzle-orm` or
|
|
22
|
+
`drizzle-kit` without the tag).
|
|
23
|
+
- Import paths: use `drizzle-orm`, `drizzle-orm/pg-core`, and `drizzle-orm/netlify-db` as normal. No package
|
|
24
|
+
name rewriting is needed — the `@beta` tag only affects the installed version, not the imports.
|
|
25
|
+
|
|
26
|
+
If you forget the `@beta` tag, `drizzle-kit generate` will error with a message about being outdated, or the
|
|
27
|
+
`drizzle-orm/netlify-db` import will fail to resolve.
|
|
28
|
+
|
|
29
|
+
## CRITICAL: Database schema changes always require migrations
|
|
30
|
+
|
|
31
|
+
Any code change that assumes a different database schema (adding tables, adding columns, renaming fields, changing types,
|
|
32
|
+
adding indexes, etc.) will only work if a corresponding migration exists in `netlify/database/migrations/`. Without a
|
|
33
|
+
migration, the database schema will not change and the application will break at runtime.
|
|
34
|
+
|
|
35
|
+
This applies regardless of whether you are using Drizzle ORM or the native `@netlify/database` driver:
|
|
36
|
+
- **With Drizzle ORM**: Update the schema definition, then run `npx drizzle-kit generate`
|
|
37
|
+
- **With native driver**: Write a new SQL migration file in `netlify/database/migrations/`
|
|
38
|
+
|
|
39
|
+
Never consider a schema change complete without a corresponding migration file.
|
|
40
|
+
|
|
41
|
+
## Setup with Drizzle ORM (recommended)
|
|
42
|
+
|
|
43
|
+
This is the recommended approach. It gives you type-safe schema definitions, a query builder, and automatic migration
|
|
44
|
+
generation.
|
|
45
|
+
|
|
46
|
+
### Step 1: Install packages
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npm install @netlify/database drizzle-orm@beta
|
|
50
|
+
npm install -D drizzle-kit@beta
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Step 2: Create the schema file
|
|
54
|
+
|
|
55
|
+
Create `db/schema.ts` at the project root. Define all your tables here using Drizzle's schema builder.
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
// db/schema.ts
|
|
59
|
+
import { pgTable, serial, text, timestamp, integer } from "drizzle-orm/pg-core";
|
|
60
|
+
|
|
61
|
+
export const users = pgTable("users", {
|
|
62
|
+
id: serial().primaryKey(),
|
|
63
|
+
name: text().notNull(),
|
|
64
|
+
email: text().notNull().unique(),
|
|
65
|
+
createdAt: timestamp("created_at").defaultNow(),
|
|
66
|
+
});
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
When adding tables with foreign keys:
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
export const posts = pgTable("posts", {
|
|
73
|
+
id: serial().primaryKey(),
|
|
74
|
+
title: text().notNull(),
|
|
75
|
+
content: text().notNull().default(""),
|
|
76
|
+
authorId: integer("author_id").notNull().references(() => users.id),
|
|
77
|
+
createdAt: timestamp("created_at").defaultNow(),
|
|
78
|
+
});
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
IMPORTANT: Use snake_case strings for column names (e.g. `"created_at"`, `"author_id"`) to match Postgres conventions.
|
|
82
|
+
The Drizzle column variable names can be camelCase.
|
|
83
|
+
|
|
84
|
+
### Step 3: Create the database client
|
|
85
|
+
|
|
86
|
+
Create `db/index.ts`. This file initializes the Drizzle client with the native Netlify Database adapter.
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
// db/index.ts
|
|
90
|
+
import { drizzle } from "drizzle-orm/netlify-db";
|
|
91
|
+
import * as schema from "./schema.js";
|
|
92
|
+
|
|
93
|
+
export const db = drizzle({ schema });
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
The connection is configured automatically — no connection string needed.
|
|
97
|
+
|
|
98
|
+
### Step 4: Configure Drizzle Kit
|
|
99
|
+
|
|
100
|
+
Create `drizzle.config.ts` at the project root. The `out` property MUST be set to `netlify/database/migrations` for
|
|
101
|
+
Netlify to automatically apply migrations.
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
// drizzle.config.ts
|
|
105
|
+
import { defineConfig } from "drizzle-kit";
|
|
106
|
+
|
|
107
|
+
export default defineConfig({
|
|
108
|
+
dialect: "postgresql",
|
|
109
|
+
schema: "./db/schema.ts",
|
|
110
|
+
out: "netlify/database/migrations",
|
|
111
|
+
});
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Step 5: Generate migrations
|
|
115
|
+
|
|
116
|
+
Every time you change the schema, run `drizzle-kit generate`:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
npx drizzle-kit generate
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
This creates SQL migration files in `netlify/database/migrations/`.
|
|
123
|
+
|
|
124
|
+
### Step 6: Use the database in functions
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
// netlify/functions/api.ts
|
|
128
|
+
import type { Config } from "@netlify/functions";
|
|
129
|
+
import { db } from "../../db/index.js";
|
|
130
|
+
import { users } from "../../db/schema.js";
|
|
131
|
+
|
|
132
|
+
export default async (req: Request) => {
|
|
133
|
+
if (req.method === "GET") {
|
|
134
|
+
const allUsers = await db.select().from(users);
|
|
135
|
+
return Response.json(allUsers);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (req.method === "POST") {
|
|
139
|
+
const { name, email } = await req.json();
|
|
140
|
+
const [user] = await db.insert(users).values({ name, email }).returning();
|
|
141
|
+
return Response.json(user, { status: 201 });
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return new Response("Method not allowed", { status: 405 });
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
export const config: Config = {
|
|
148
|
+
path: "/api/users",
|
|
149
|
+
};
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Drizzle ORM query reference
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
import { eq, desc, and, or, like, sql } from "drizzle-orm";
|
|
156
|
+
import { db } from "./db/index.js";
|
|
157
|
+
import { users, posts } from "./db/schema.js";
|
|
158
|
+
|
|
159
|
+
// Select all
|
|
160
|
+
const allUsers = await db.select().from(users);
|
|
161
|
+
|
|
162
|
+
// Select with condition
|
|
163
|
+
const user = await db.select().from(users).where(eq(users.id, 1));
|
|
164
|
+
|
|
165
|
+
// Select with ordering
|
|
166
|
+
const sorted = await db.select().from(users).orderBy(desc(users.createdAt));
|
|
167
|
+
|
|
168
|
+
// Select with limit
|
|
169
|
+
const first10 = await db.select().from(users).limit(10);
|
|
170
|
+
|
|
171
|
+
// Select specific columns
|
|
172
|
+
const names = await db.select({ name: users.name }).from(users);
|
|
173
|
+
|
|
174
|
+
// Insert one row
|
|
175
|
+
const [inserted] = await db.insert(users).values({ name: "Ada", email: "ada@example.com" }).returning();
|
|
176
|
+
|
|
177
|
+
// Insert multiple rows
|
|
178
|
+
await db.insert(users).values([
|
|
179
|
+
{ name: "Ada", email: "ada@example.com" },
|
|
180
|
+
{ name: "Bob", email: "bob@example.com" },
|
|
181
|
+
]);
|
|
182
|
+
|
|
183
|
+
// Update
|
|
184
|
+
await db.update(users).set({ name: "Ada Lovelace" }).where(eq(users.id, 1));
|
|
185
|
+
|
|
186
|
+
// Delete
|
|
187
|
+
await db.delete(users).where(eq(users.id, 1));
|
|
188
|
+
|
|
189
|
+
// Join
|
|
190
|
+
const postsWithAuthors = await db
|
|
191
|
+
.select()
|
|
192
|
+
.from(posts)
|
|
193
|
+
.innerJoin(users, eq(posts.authorId, users.id));
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## Setup with native driver (alternative)
|
|
197
|
+
|
|
198
|
+
Use this when you prefer raw SQL or don't want Drizzle ORM.
|
|
199
|
+
|
|
200
|
+
### Install
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
npm install @netlify/database
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Query with `db.sql`
|
|
207
|
+
|
|
208
|
+
```typescript
|
|
209
|
+
import { getDatabase } from "@netlify/database";
|
|
210
|
+
|
|
211
|
+
const db = getDatabase();
|
|
212
|
+
|
|
213
|
+
// Select
|
|
214
|
+
const users = await db.sql`SELECT * FROM users`;
|
|
215
|
+
|
|
216
|
+
// Select with parameters (automatically parameterized)
|
|
217
|
+
const user = await db.sql`SELECT * FROM users WHERE id = ${userId}`;
|
|
218
|
+
|
|
219
|
+
// Insert with RETURNING
|
|
220
|
+
const [newUser] = await db.sql`
|
|
221
|
+
INSERT INTO users (name, email)
|
|
222
|
+
VALUES (${"Ada"}, ${"ada@example.com"})
|
|
223
|
+
RETURNING *
|
|
224
|
+
`;
|
|
225
|
+
|
|
226
|
+
// Update
|
|
227
|
+
await db.sql`UPDATE users SET name = ${"Ada Lovelace"} WHERE id = ${1}`;
|
|
228
|
+
|
|
229
|
+
// Delete
|
|
230
|
+
await db.sql`DELETE FROM users WHERE id = ${1}`;
|
|
231
|
+
|
|
232
|
+
// Bulk insert
|
|
233
|
+
const data = db.sql.values([
|
|
234
|
+
["Ada", "ada@example.com"],
|
|
235
|
+
["Bob", "bob@example.com"],
|
|
236
|
+
]);
|
|
237
|
+
await db.sql`INSERT INTO users (name, email) VALUES ${data}`;
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### Transactions with `db.pool`
|
|
241
|
+
|
|
242
|
+
```typescript
|
|
243
|
+
const db = getDatabase();
|
|
244
|
+
|
|
245
|
+
const client = await db.pool.connect();
|
|
246
|
+
try {
|
|
247
|
+
await client.query("BEGIN");
|
|
248
|
+
await client.query("INSERT INTO users (name, email) VALUES ($1, $2)", ["Ada", "ada@example.com"]);
|
|
249
|
+
await client.query("INSERT INTO posts (author_id, title) VALUES ($1, $2)", [1, "First post"]);
|
|
250
|
+
await client.query("COMMIT");
|
|
251
|
+
} catch (e) {
|
|
252
|
+
await client.query("ROLLBACK");
|
|
253
|
+
throw e;
|
|
254
|
+
} finally {
|
|
255
|
+
client.release();
|
|
256
|
+
}
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### Write migrations manually
|
|
260
|
+
|
|
261
|
+
When using the native driver, write SQL migration files by hand in `netlify/database/migrations/`.
|
|
262
|
+
|
|
263
|
+
Each migration is a SQL file named `<number>_<slug>.sql`:
|
|
264
|
+
|
|
265
|
+
```
|
|
266
|
+
netlify/database/migrations/
|
|
267
|
+
├── 20260417143022_create-users.sql
|
|
268
|
+
├── 20260418091500_add-posts.sql
|
|
269
|
+
└── 20260419112330_create-comments.sql
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
Example migration:
|
|
273
|
+
|
|
274
|
+
```sql
|
|
275
|
+
-- netlify/database/migrations/20260417143022_create-users.sql
|
|
276
|
+
CREATE TABLE users (
|
|
277
|
+
id SERIAL PRIMARY KEY,
|
|
278
|
+
name TEXT NOT NULL,
|
|
279
|
+
email TEXT UNIQUE NOT NULL,
|
|
280
|
+
created_at TIMESTAMP DEFAULT NOW()
|
|
281
|
+
);
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
Rules for migration names:
|
|
285
|
+
- `number` is any sequence of digits (e.g. `001`, `0001`, or a Unix timestamp)
|
|
286
|
+
- `slug` contains only lowercase letters, numbers, hyphens, and underscores
|
|
287
|
+
- Migrations are sorted lexicographically and applied in order
|
|
288
|
+
- NEVER modify a migration file once it has been applied to any database (local, preview, or production).
|
|
289
|
+
Unapplied migration files can be freely deleted and regenerated; see "Iterating on migrations within a
|
|
290
|
+
session" below.
|
|
291
|
+
|
|
292
|
+
## Migrations: how they work
|
|
293
|
+
|
|
294
|
+
IMPORTANT: You must NEVER apply migrations yourself. Your job is only to CREATE migration files — either by running
|
|
295
|
+
`npx drizzle-kit generate` (when using Drizzle ORM) or by writing SQL files in `netlify/database/migrations/` (when using
|
|
296
|
+
the native driver). The Netlify platform applies migrations automatically at the right point in the deploy lifecycle.
|
|
297
|
+
Do NOT run `drizzle-kit migrate`, `drizzle-kit push`, or execute migration SQL directly against the database.
|
|
298
|
+
|
|
299
|
+
Netlify applies migrations automatically during deploys:
|
|
300
|
+
|
|
301
|
+
- **Production deploys:** Applied immediately before the deploy is published. A failure blocks publishing.
|
|
302
|
+
- **Deploy previews:** Applied on every new deploy, immediately before it becomes available. A failure fails the deploy.
|
|
303
|
+
|
|
304
|
+
Migrations MUST be in `netlify/database/migrations/` to be applied automatically.
|
|
305
|
+
|
|
306
|
+
Two formats are supported:
|
|
307
|
+
1. SQL files directly in the directory (e.g. `20260417143022_create-users.sql`)
|
|
308
|
+
2. Subdirectories containing a `migration.sql` file (e.g. `20260417143022_create-users/migration.sql`)
|
|
309
|
+
|
|
310
|
+
## Database branches
|
|
311
|
+
|
|
312
|
+
- **Production deploys** access the main database only.
|
|
313
|
+
- **Deploy previews** get their own isolated database branch with a copy of production data.
|
|
314
|
+
- Changes in a deploy preview's branch never affect the production database.
|
|
315
|
+
- You do NOT need to do anything to enable branching — it is automatic.
|
|
316
|
+
- A preview branch persists across multiple runs in the same session. Migrations you applied in an earlier run
|
|
317
|
+
remain applied when a later run starts, and any test data you inserted persists too. This matters when iterating
|
|
318
|
+
on migrations — see "Iterating on migrations within a session" below.
|
|
319
|
+
|
|
320
|
+
## Inspecting migration state
|
|
321
|
+
|
|
322
|
+
The current database state — which migrations are already applied to your preview branch, and which migration
|
|
323
|
+
files exist on disk but haven't been applied yet — is included in your context at the start of the run, under
|
|
324
|
+
the "Current Netlify Database state" heading. Read that list before planning any migration work. You do not
|
|
325
|
+
need to run `netlify db status` at the start of a task to get this information.
|
|
326
|
+
|
|
327
|
+
If you need to re-check state mid-session — typically after generating a new migration, applying migrations, or
|
|
328
|
+
running `netlify db migrations reset` — run:
|
|
329
|
+
|
|
330
|
+
```bash
|
|
331
|
+
netlify db status
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
The command targets your preview database branch automatically (`NETLIFY_DB_BRANCH` is pre-set).
|
|
335
|
+
|
|
336
|
+
It reports:
|
|
337
|
+
- **Applied**: migrations that have been applied to the branch
|
|
338
|
+
- **Pending**: migration files that exist locally but have not been applied
|
|
339
|
+
- **Missing on disk**: migrations applied on the server but not present locally (drift — this is a serious
|
|
340
|
+
state; never intentionally create it)
|
|
341
|
+
- **Out of order**: pending migrations whose prefix sorts before an already-applied migration. The platform
|
|
342
|
+
rejects these, so fix via the "Rule of thumb" below (reset + regenerate). If `drizzle-kit generate` then
|
|
343
|
+
reports no changes, the out-of-order files were redundant and deleting them was the complete fix.
|
|
344
|
+
|
|
345
|
+
## Iterating on migrations within a session
|
|
346
|
+
|
|
347
|
+
A single agent session can run multiple times, and all runs share one preview database branch. When you realize
|
|
348
|
+
a migration from an earlier run needs to change, the correct action depends on whether the migration has been
|
|
349
|
+
applied to the database yet.
|
|
350
|
+
|
|
351
|
+
### Rule of thumb
|
|
352
|
+
|
|
353
|
+
- If a migration has been **applied** to any database (local dev DB, preview branch, or production), treat it
|
|
354
|
+
as immutable. Roll forward with a new migration that applies the correction. This is always safe.
|
|
355
|
+
- If a migration is **not yet applied** anywhere (it's only on disk), don't edit it in place. Run
|
|
356
|
+
`netlify db migrations reset` to delete it, update `db/schema.ts` to reflect your new intent, then run
|
|
357
|
+
`npx drizzle-kit generate` to produce a fresh migration. Editing SQL or snapshot files directly can
|
|
358
|
+
desync Drizzle Kit's internal state and produce broken migrations on the next generate.
|
|
359
|
+
|
|
360
|
+
### `netlify db migrations reset` — cleaning up unapplied migrations
|
|
361
|
+
|
|
362
|
+
`netlify db migrations reset` deletes local migration files that have **not yet been applied** to your preview
|
|
363
|
+
branch. Applied migrations and their data are left alone.
|
|
364
|
+
|
|
365
|
+
```bash
|
|
366
|
+
netlify db migrations reset
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
Typical use: after a rebase pulls in new migrations from main, you may have locally-generated migrations that
|
|
370
|
+
now conflict with or duplicate main's work. Running `netlify db migrations reset` clears those unapplied files
|
|
371
|
+
so you can regenerate cleanly.
|
|
372
|
+
|
|
373
|
+
The command is safe — it cannot remove migrations that have been applied, so it cannot produce a broken
|
|
374
|
+
database state.
|
|
375
|
+
|
|
376
|
+
## Connecting to the database
|
|
377
|
+
|
|
378
|
+
Use `netlify db connect` to query the database directly for troubleshooting or inspecting the current schema. Always use
|
|
379
|
+
the `--query` flag for one-shot execution — do NOT use interactive mode.
|
|
380
|
+
|
|
381
|
+
```bash
|
|
382
|
+
# Inspect the current schema
|
|
383
|
+
netlify db connect --query "SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'"
|
|
384
|
+
|
|
385
|
+
# Check columns on a table
|
|
386
|
+
netlify db connect --query "SELECT column_name, data_type, is_nullable FROM information_schema.columns WHERE table_name = 'users'"
|
|
387
|
+
|
|
388
|
+
# Read data
|
|
389
|
+
netlify db connect --query "SELECT * FROM users LIMIT 10"
|
|
390
|
+
|
|
391
|
+
# Get results as JSON
|
|
392
|
+
netlify db connect --query "SELECT * FROM users LIMIT 10" --json
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
The database connection is read-only. You can use it to inspect the schema and read data, but you cannot insert, update,
|
|
396
|
+
or delete rows.
|
|
397
|
+
|
|
398
|
+
**CRITICAL: NEVER run DDL statements (CREATE, ALTER, DROP, TRUNCATE) or any other schema-mutating queries through
|
|
399
|
+
`netlify db connect`.** The only supported way to change the database schema is through migration files in
|
|
400
|
+
`netlify/database/migrations/`. Running DDL directly will cause the migration state to diverge from the actual schema,
|
|
401
|
+
leading to unpredictable and broken behavior.
|
|
402
|
+
|
|
403
|
+
## Common mistakes to avoid
|
|
404
|
+
|
|
405
|
+
1. **Wrong migration output directory**: Drizzle Kit defaults to `drizzle/`. You MUST set
|
|
406
|
+
`out: "netlify/database/migrations"` in `drizzle.config.ts`. If migrations are in the wrong directory, they will not
|
|
407
|
+
be applied.
|
|
408
|
+
|
|
409
|
+
2. **Forgetting the `@beta` dist-tag**: The Netlify Database adapter only exists on `drizzle-orm@beta` and
|
|
410
|
+
`drizzle-kit@beta`. Installing `drizzle-orm` or `drizzle-kit` without the `@beta` tag pulls the `latest` releases,
|
|
411
|
+
which lack the adapter and will fail. Always install with `drizzle-orm@beta` and `drizzle-kit@beta`.
|
|
412
|
+
|
|
413
|
+
3. **Missing `.js` extension in imports**: When using TypeScript with ES modules, import paths should include the `.js`
|
|
414
|
+
extension (e.g. `from "./schema.js"`, `from "../../db/index.js"`).
|
|
415
|
+
|
|
416
|
+
4. **Creating tables with raw SQL when using Drizzle**: If you use Drizzle ORM, define all tables in `db/schema.ts`
|
|
417
|
+
and generate migrations with `drizzle-kit generate`. Do not write raw `CREATE TABLE` SQL — the schema file is the
|
|
418
|
+
source of truth.
|
|
419
|
+
|
|
420
|
+
5. **Misunderstanding `netlify db migrations reset`**: This command only deletes migration files that have
|
|
421
|
+
**not yet been applied** to your preview branch. It cannot undo an already-applied migration — to change
|
|
422
|
+
something that's already applied, you must roll forward with a new migration.
|
|
423
|
+
|