create-jant 0.3.26 → 0.3.28

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.
@@ -1,287 +0,0 @@
1
- # Jant Site
2
-
3
- A personal website/blog powered by [Jant](https://github.com/jant-me/jant).
4
-
5
- ## Option A: One-Click Deploy
6
-
7
- Deploy to Cloudflare instantly — no local setup required:
8
-
9
- [![Deploy to Cloudflare](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/jant-me/jant-starter)
10
-
11
- ### Deploy form fields
12
-
13
- | Field | What to do |
14
- | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
15
- | **Git account** | Select your GitHub account. A new repo will be created for you. |
16
- | **D1 database** | Keep "Create new". The default name is fine. |
17
- | **Database location hint** | Pick a region close to you (optional, Cloudflare auto-selects). |
18
- | **R2 bucket** | Keep "Create new". The default name is fine. Used for media uploads. |
19
- | **AUTH_SECRET** | Used for login session encryption. Keep the pre-filled value or generate your own with `openssl rand -base64 32`. |
20
- | **SITE_URL** | Change this to your production URL (e.g. `https://my-blog.example.com`). If you don't have a custom domain yet, leave it empty — you can set it later in the Cloudflare dashboard after you know your `*.workers.dev` URL. |
21
-
22
- ### After deploy
23
-
24
- 1. Visit your site at the URL shown in the Cloudflare dashboard (e.g. `https://<project>.<account>.workers.dev`)
25
- 2. Go to `/dash` to set up your admin account
26
- 3. If you set `SITE_URL` to a custom domain, add it in: Cloudflare dashboard → Workers & Pages → your worker → Settings → Domains & Routes → Add Custom Domain
27
- 4. If you left `SITE_URL` empty, set it to your `*.workers.dev` URL: Cloudflare dashboard → Workers & Pages → your worker → Settings → Variables and Secrets
28
-
29
- ### Develop locally
30
-
31
- ```bash
32
- # Clone the repo that was created for you
33
- git clone git@github.com:<your-username>/<your-repo>.git
34
- cd <your-repo>
35
- npm install
36
- npm run dev
37
- ```
38
-
39
- Visit http://localhost:9019. Changes pushed to `main` will auto-deploy.
40
-
41
- ## Option B: Create with CLI
42
-
43
- Set up a new project locally, then deploy manually:
44
-
45
- ```bash
46
- npm create jant my-site
47
- cd my-site
48
- npm run dev
49
- ```
50
-
51
- Visit http://localhost:9019. When you're ready to go live, continue with [Deploy to Cloudflare](#deploy-to-cloudflare) below.
52
-
53
- ### Deploy to Cloudflare
54
-
55
- #### 1. Prerequisites
56
-
57
- Install [Wrangler CLI](https://developers.cloudflare.com/workers/wrangler/install-and-update/) and log in:
58
-
59
- ```bash
60
- wrangler login
61
- ```
62
-
63
- #### 2. Create D1 Database
64
-
65
- Check the `database_name` in your `wrangler.toml` (defaults to `<your-project>-db`), then create it:
66
-
67
- ```bash
68
- wrangler d1 create <your-project>-db
69
- # Copy the database_id from the output!
70
- ```
71
-
72
- #### 3. Update Configuration
73
-
74
- Edit `wrangler.toml`:
75
-
76
- - Replace `database_id = "local"` with the ID from step 2
77
- - Set `SITE_URL` to your production URL (e.g. `https://example.com`)
78
-
79
- > R2 bucket is automatically created on first deploy — no manual setup needed.
80
- >
81
- > **Note:** Changing `database_id` resets your local development database (local data is stored per database ID). If you've already started local development, you'll need to go through the setup wizard again to create your admin account.
82
-
83
- #### 4. Set Production Secrets
84
-
85
- Generate a production secret and save it somewhere safe (you'll need it again for CI):
86
-
87
- ```bash
88
- # Generate a secret
89
- openssl rand -base64 32
90
-
91
- # Set it in Cloudflare
92
- wrangler secret put AUTH_SECRET
93
- # Paste the generated value when prompted
94
- ```
95
-
96
- > **Important:** This is separate from the `AUTH_SECRET` in `.dev.vars` (which is for local development only). Do not change the production secret after your site is live — it will invalidate all sessions. If you get locked out, use `npm run reset-password` to generate a password reset link.
97
-
98
- #### 5. Deploy
99
-
100
- ```bash
101
- # Apply database migrations and deploy
102
- npm run deploy
103
- ```
104
-
105
- Your site is now live at `https://<your-project>.<your-subdomain>.workers.dev`!
106
-
107
- #### 6. Custom Domain (Optional)
108
-
109
- 1. Go to [Cloudflare Dashboard](https://dash.cloudflare.com) → Workers & Pages
110
- 2. Select your worker → Settings → Domains & Routes
111
- 3. Click **Add -> Custom domain** and enter your domain
112
-
113
- ### GitHub Actions (CI/CD)
114
-
115
- A workflow file is included at `.github/workflows/deploy.yml`. Complete the [deployment](#deploy-to-cloudflare) first, then set up CI for automatic deployments.
116
-
117
- > Runtime secrets (`AUTH_SECRET`, S3 keys, etc.) are already stored in Cloudflare from the manual deployment step. CI only needs deployment credentials.
118
-
119
- #### 1. Push to GitHub
120
-
121
- Create a new repository on [GitHub](https://github.com/new), then commit and push your project:
122
-
123
- ```bash
124
- git add -A
125
- git commit -m "Initial setup"
126
- git remote add origin git@github.com:<your-username>/<your-repo>.git
127
- git push -u origin main
128
- ```
129
-
130
- #### 2. Create API Token
131
-
132
- 1. Go to [Cloudflare API Tokens](https://dash.cloudflare.com/profile/api-tokens)
133
- 2. Click **Create Token** → **Use template** next to **Edit Cloudflare Workers**
134
- 3. **Add D1 permission** (not in template by default):
135
- - Click **+ Add more** → **Account** → **D1** → **Edit**
136
-
137
- Your permissions should include:
138
-
139
- | Scope | Permission | Access |
140
- | ------- | ------------------ | ----------------------------- |
141
- | Account | Workers Scripts | Edit |
142
- | Account | Workers R2 Storage | Edit |
143
- | Account | **D1** | **Edit** ← Must add manually! |
144
- | Zone | Workers Routes | Edit |
145
-
146
- 4. Set **Account Resources** → **Include** → your account
147
- 5. Set **Zone Resources** → **Include** → **All zones from an account** → your account
148
- 6. **Create Token** and copy it
149
-
150
- #### 3. Add GitHub Secrets
151
-
152
- Go to your repo → **Settings** → **Secrets and variables** → **Actions**:
153
-
154
- | Secret Name | Value |
155
- | --------------- | ------------------------------------------------------------------------ |
156
- | `CF_API_TOKEN` | API token from above |
157
- | `CF_ACCOUNT_ID` | Your Cloudflare Account ID (found in dashboard URL or `wrangler whoami`) |
158
-
159
- #### 4. Enable Auto-Deploy
160
-
161
- Uncomment the push trigger in `.github/workflows/deploy.yml`:
162
-
163
- ```yaml
164
- on:
165
- push:
166
- branches:
167
- - main
168
- workflow_dispatch:
169
- ```
170
-
171
- Now every push to `main` will auto-deploy.
172
-
173
- #### Using Environments (Optional)
174
-
175
- For separate staging/production, update `.github/workflows/deploy.yml`:
176
-
177
- ```yaml
178
- jobs:
179
- deploy:
180
- uses: jant-me/jant/.github/workflows/deploy.yml@main
181
- with:
182
- environment: production # Uses [env.production] in wrangler.toml
183
- secrets:
184
- CF_API_TOKEN: ${{ secrets.CF_API_TOKEN }}
185
- CF_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }}
186
- ```
187
-
188
- ## Commands
189
-
190
- | Command | Description |
191
- | --------------------------- | ---------------------------------- |
192
- | `npm run dev` | Start development server |
193
- | `npm run build` | Build for production |
194
- | `npm run deploy` | Migrate, build, and deploy |
195
- | `npm run preview` | Preview production build |
196
- | `npm run typecheck` | Run TypeScript checks |
197
- | `npm run db:migrate:remote` | Apply database migrations (remote) |
198
-
199
- ## Environment Variables
200
-
201
- | Variable | Description | Location |
202
- | ------------- | ----------------------------------------- | ---------------- |
203
- | `AUTH_SECRET` | Secret key for authentication (32+ chars) | `.dev.vars` file |
204
- | `SITE_URL` | Your site's public URL | `wrangler.toml` |
205
-
206
- For all available variables (site name, language, R2 storage, image optimization, S3, demo mode, etc.), see the **[Configuration Guide](https://github.com/jant-me/jant/blob/main/docs/configuration.md)**.
207
-
208
- ## Customization
209
-
210
- ### Color Themes
211
-
212
- Pick a color theme from the dashboard: **Settings > Appearance**.
213
-
214
- ### Custom CSS
215
-
216
- Inject custom CSS from the dashboard: **Settings > Appearance > Custom CSS**. This CSS is applied with the highest priority, so you can override any built-in styles.
217
-
218
- ### CSS Design Tokens
219
-
220
- Override design tokens in your custom CSS to change the look and feel:
221
-
222
- ```css
223
- :root {
224
- --site-width: 720px;
225
- --card-radius: 0.5rem;
226
- --font-body: "Inter", system-ui, sans-serif;
227
- --avatar-size: 42px;
228
- }
229
- ```
230
-
231
- ### Data Attributes
232
-
233
- Target specific elements with stable data attributes:
234
-
235
- ```css
236
- /* Style only note-format posts */
237
- [data-format="note"] {
238
- border-left: 3px solid var(--primary);
239
- }
240
-
241
- /* Style the home page differently */
242
- [data-page="home"] {
243
- background: var(--muted);
244
- }
245
-
246
- /* Hide compose prompt for unauthenticated visitors */
247
- body:not([data-authenticated]) .compose-prompt {
248
- display: none;
249
- }
250
- ```
251
-
252
- ### Code-Level Customization
253
-
254
- Pass CSS variable overrides or custom color themes via `createApp()`:
255
-
256
- ```typescript
257
- import { createApp } from "@jant/core";
258
-
259
- export default createApp({
260
- cssVariables: {
261
- "--site-width": "720px",
262
- "--card-radius": "0.5rem",
263
- },
264
- });
265
- ```
266
-
267
- ## Updating
268
-
269
- ```bash
270
- # Update @jant/core to latest version
271
- npm install @jant/core@latest
272
-
273
- # Start dev server (auto-applies migrations locally)
274
- npm run dev
275
-
276
- # Deploy (includes remote migrations)
277
- npm run deploy
278
- ```
279
-
280
- > New versions of `@jant/core` may include database migrations. Check the [release notes](https://github.com/jant-me/jant/releases) for any breaking changes.
281
- >
282
- > **Dev dependencies** (vite, wrangler, tailwindcss, etc.) may also need updating. Compare your `devDependencies` with the [latest template](https://github.com/jant-me/jant/blob/main/templates/jant-site/package.json) and update if needed.
283
-
284
- ## Documentation
285
-
286
- - [Jant Documentation](https://jant.me/docs)
287
- - [GitHub Repository](https://github.com/jant-me/jant)
@@ -1,12 +0,0 @@
1
- # Secrets — do not commit this file
2
- #
3
- # Cloudflare Workers: copy to .dev.vars
4
- # VPS / Docker: copy to .env
5
-
6
- # AUTH_SECRET must be at least 32 characters
7
- # Generate one with: openssl rand -base64 32
8
- AUTH_SECRET=your-secret-key-at-least-32-chars-long
9
-
10
- # Required when STORAGE_DRIVER=s3:
11
- # S3_ACCESS_KEY_ID=your-access-key
12
- # S3_SECRET_ACCESS_KEY=your-secret-key
@@ -1,25 +0,0 @@
1
- # Deploy to Cloudflare Workers
2
- # Documentation: https://jant.me/docs/deployment
3
- #
4
- # Prerequisites:
5
- # 1. Complete manual deployment first (see README.md → Deploy to Cloudflare)
6
- # 2. Set GitHub secrets: CF_API_TOKEN and CF_ACCOUNT_ID
7
- #
8
- # Runtime secrets (AUTH_SECRET, S3 keys, etc.) are managed via
9
- # `wrangler secret put` and persist across deployments.
10
-
11
- name: Deploy
12
-
13
- on:
14
- # Uncomment to auto-deploy on push after configuring secrets:
15
- # push:
16
- # branches:
17
- # - main
18
- workflow_dispatch:
19
-
20
- jobs:
21
- deploy:
22
- uses: jant-me/jant/.github/workflows/deploy.yml@main
23
- secrets:
24
- CF_API_TOKEN: ${{ secrets.CF_API_TOKEN }}
25
- CF_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }}
@@ -1,27 +0,0 @@
1
- # Dependencies
2
- node_modules/
3
-
4
- # Build outputs
5
- dist/
6
- .swc/
7
-
8
- # Cloudflare
9
- .wrangler/
10
- .dev.vars
11
-
12
- # Environment
13
- .env
14
- .env.*
15
- !.env.example
16
-
17
- # IDE
18
- .idea/
19
- .vscode/*
20
- !.vscode/extensions.json
21
- !.vscode/settings.json
22
-
23
- # OS
24
- .DS_Store
25
-
26
- # Logs
27
- *.log
@@ -1,21 +0,0 @@
1
- #!/bin/sh
2
- basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
-
4
- case `uname` in
5
- *CYGWIN*|*MINGW*|*MSYS*)
6
- if command -v cygpath > /dev/null 2>&1; then
7
- basedir=`cygpath -w "$basedir"`
8
- fi
9
- ;;
10
- esac
11
-
12
- if [ -z "$NODE_PATH" ]; then
13
- export NODE_PATH="/home/runner/work/jant/jant/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/bin/node_modules:/home/runner/work/jant/jant/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/node_modules:/home/runner/work/jant/jant/node_modules/.pnpm/typescript@5.9.3/node_modules:/home/runner/work/jant/jant/node_modules/.pnpm/node_modules"
14
- else
15
- export NODE_PATH="/home/runner/work/jant/jant/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/bin/node_modules:/home/runner/work/jant/jant/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/node_modules:/home/runner/work/jant/jant/node_modules/.pnpm/typescript@5.9.3/node_modules:/home/runner/work/jant/jant/node_modules/.pnpm/node_modules:$NODE_PATH"
16
- fi
17
- if [ -x "$basedir/node" ]; then
18
- exec "$basedir/node" "$basedir/../typescript/bin/tsc" "$@"
19
- else
20
- exec node "$basedir/../typescript/bin/tsc" "$@"
21
- fi
@@ -1,21 +0,0 @@
1
- #!/bin/sh
2
- basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
-
4
- case `uname` in
5
- *CYGWIN*|*MINGW*|*MSYS*)
6
- if command -v cygpath > /dev/null 2>&1; then
7
- basedir=`cygpath -w "$basedir"`
8
- fi
9
- ;;
10
- esac
11
-
12
- if [ -z "$NODE_PATH" ]; then
13
- export NODE_PATH="/home/runner/work/jant/jant/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/bin/node_modules:/home/runner/work/jant/jant/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/node_modules:/home/runner/work/jant/jant/node_modules/.pnpm/typescript@5.9.3/node_modules:/home/runner/work/jant/jant/node_modules/.pnpm/node_modules"
14
- else
15
- export NODE_PATH="/home/runner/work/jant/jant/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/bin/node_modules:/home/runner/work/jant/jant/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/node_modules:/home/runner/work/jant/jant/node_modules/.pnpm/typescript@5.9.3/node_modules:/home/runner/work/jant/jant/node_modules/.pnpm/node_modules:$NODE_PATH"
16
- fi
17
- if [ -x "$basedir/node" ]; then
18
- exec "$basedir/node" "$basedir/../typescript/bin/tsserver" "$@"
19
- else
20
- exec node "$basedir/../typescript/bin/tsserver" "$@"
21
- fi
@@ -1,21 +0,0 @@
1
- #!/bin/sh
2
- basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
-
4
- case `uname` in
5
- *CYGWIN*|*MINGW*|*MSYS*)
6
- if command -v cygpath > /dev/null 2>&1; then
7
- basedir=`cygpath -w "$basedir"`
8
- fi
9
- ;;
10
- esac
11
-
12
- if [ -z "$NODE_PATH" ]; then
13
- export NODE_PATH="/home/runner/work/jant/jant/node_modules/.pnpm/vite@7.3.1_@types+node@22.19.10_jiti@2.6.1_lightningcss@1.30.2_tsx@4.21.0_yaml@2.8.2/node_modules/vite/bin/node_modules:/home/runner/work/jant/jant/node_modules/.pnpm/vite@7.3.1_@types+node@22.19.10_jiti@2.6.1_lightningcss@1.30.2_tsx@4.21.0_yaml@2.8.2/node_modules/vite/node_modules:/home/runner/work/jant/jant/node_modules/.pnpm/vite@7.3.1_@types+node@22.19.10_jiti@2.6.1_lightningcss@1.30.2_tsx@4.21.0_yaml@2.8.2/node_modules:/home/runner/work/jant/jant/node_modules/.pnpm/node_modules"
14
- else
15
- export NODE_PATH="/home/runner/work/jant/jant/node_modules/.pnpm/vite@7.3.1_@types+node@22.19.10_jiti@2.6.1_lightningcss@1.30.2_tsx@4.21.0_yaml@2.8.2/node_modules/vite/bin/node_modules:/home/runner/work/jant/jant/node_modules/.pnpm/vite@7.3.1_@types+node@22.19.10_jiti@2.6.1_lightningcss@1.30.2_tsx@4.21.0_yaml@2.8.2/node_modules/vite/node_modules:/home/runner/work/jant/jant/node_modules/.pnpm/vite@7.3.1_@types+node@22.19.10_jiti@2.6.1_lightningcss@1.30.2_tsx@4.21.0_yaml@2.8.2/node_modules:/home/runner/work/jant/jant/node_modules/.pnpm/node_modules:$NODE_PATH"
16
- fi
17
- if [ -x "$basedir/node" ]; then
18
- exec "$basedir/node" "$basedir/../vite/bin/vite.js" "$@"
19
- else
20
- exec node "$basedir/../vite/bin/vite.js" "$@"
21
- fi
@@ -1,21 +0,0 @@
1
- #!/bin/sh
2
- basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
-
4
- case `uname` in
5
- *CYGWIN*|*MINGW*|*MSYS*)
6
- if command -v cygpath > /dev/null 2>&1; then
7
- basedir=`cygpath -w "$basedir"`
8
- fi
9
- ;;
10
- esac
11
-
12
- if [ -z "$NODE_PATH" ]; then
13
- export NODE_PATH="/home/runner/work/jant/jant/node_modules/.pnpm/wrangler@4.63.0_@cloudflare+workers-types@4.20260207.0/node_modules/wrangler/bin/node_modules:/home/runner/work/jant/jant/node_modules/.pnpm/wrangler@4.63.0_@cloudflare+workers-types@4.20260207.0/node_modules/wrangler/node_modules:/home/runner/work/jant/jant/node_modules/.pnpm/wrangler@4.63.0_@cloudflare+workers-types@4.20260207.0/node_modules:/home/runner/work/jant/jant/node_modules/.pnpm/node_modules"
14
- else
15
- export NODE_PATH="/home/runner/work/jant/jant/node_modules/.pnpm/wrangler@4.63.0_@cloudflare+workers-types@4.20260207.0/node_modules/wrangler/bin/node_modules:/home/runner/work/jant/jant/node_modules/.pnpm/wrangler@4.63.0_@cloudflare+workers-types@4.20260207.0/node_modules/wrangler/node_modules:/home/runner/work/jant/jant/node_modules/.pnpm/wrangler@4.63.0_@cloudflare+workers-types@4.20260207.0/node_modules:/home/runner/work/jant/jant/node_modules/.pnpm/node_modules:$NODE_PATH"
16
- fi
17
- if [ -x "$basedir/node" ]; then
18
- exec "$basedir/node" "$basedir/../wrangler/bin/wrangler.js" "$@"
19
- else
20
- exec node "$basedir/../wrangler/bin/wrangler.js" "$@"
21
- fi
@@ -1,21 +0,0 @@
1
- #!/bin/sh
2
- basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
-
4
- case `uname` in
5
- *CYGWIN*|*MINGW*|*MSYS*)
6
- if command -v cygpath > /dev/null 2>&1; then
7
- basedir=`cygpath -w "$basedir"`
8
- fi
9
- ;;
10
- esac
11
-
12
- if [ -z "$NODE_PATH" ]; then
13
- export NODE_PATH="/home/runner/work/jant/jant/node_modules/.pnpm/wrangler@4.63.0_@cloudflare+workers-types@4.20260207.0/node_modules/wrangler/bin/node_modules:/home/runner/work/jant/jant/node_modules/.pnpm/wrangler@4.63.0_@cloudflare+workers-types@4.20260207.0/node_modules/wrangler/node_modules:/home/runner/work/jant/jant/node_modules/.pnpm/wrangler@4.63.0_@cloudflare+workers-types@4.20260207.0/node_modules:/home/runner/work/jant/jant/node_modules/.pnpm/node_modules"
14
- else
15
- export NODE_PATH="/home/runner/work/jant/jant/node_modules/.pnpm/wrangler@4.63.0_@cloudflare+workers-types@4.20260207.0/node_modules/wrangler/bin/node_modules:/home/runner/work/jant/jant/node_modules/.pnpm/wrangler@4.63.0_@cloudflare+workers-types@4.20260207.0/node_modules/wrangler/node_modules:/home/runner/work/jant/jant/node_modules/.pnpm/wrangler@4.63.0_@cloudflare+workers-types@4.20260207.0/node_modules:/home/runner/work/jant/jant/node_modules/.pnpm/node_modules:$NODE_PATH"
16
- fi
17
- if [ -x "$basedir/node" ]; then
18
- exec "$basedir/node" "$basedir/../wrangler/bin/wrangler.js" "$@"
19
- else
20
- exec node "$basedir/../wrangler/bin/wrangler.js" "$@"
21
- fi
@@ -1,7 +0,0 @@
1
- # Allow native dependencies to run build scripts
2
- # Required for: workerd (Cloudflare Workers), esbuild, swc, sharp
3
- onlyBuiltDependencies:
4
- - "@swc/core"
5
- - esbuild
6
- - sharp
7
- - workerd
@@ -1,84 +0,0 @@
1
- import { execSync } from "child_process";
2
- import { readFileSync, writeFileSync } from "fs";
3
- import { resolve, dirname } from "path";
4
- import { fileURLToPath } from "url";
5
-
6
- const __dirname = dirname(fileURLToPath(import.meta.url));
7
-
8
- function sqlValue(v) {
9
- if (v === null) return "NULL";
10
- if (typeof v === "number") return String(v);
11
- return "'" + String(v).replaceAll("'", "''") + "'";
12
- }
13
-
14
- function queryRemote(sql) {
15
- let stdout;
16
- try {
17
- stdout = execSync(
18
- `pnpm exec wrangler d1 execute DB --remote --config wrangler.demo.toml --command "${sql}" --json`,
19
- { encoding: "utf-8", cwd: resolve(__dirname, "..") }
20
- );
21
- } catch (err) {
22
- // Wrangler returns JSON errors on stdout even with non-zero exit codes
23
- const output = err.stdout || err.stderr || "";
24
- try {
25
- const errJson = JSON.parse(output.trim());
26
- if (errJson.error?.text) {
27
- console.error(`Wrangler error: ${errJson.error.text}`);
28
- process.exit(1);
29
- }
30
- } catch {
31
- // Not JSON, fall through
32
- }
33
- console.error(`Failed to query remote database: ${output || err.message}`);
34
- process.exit(1);
35
- }
36
- const parsed = JSON.parse(stdout);
37
- if (parsed.error?.text) {
38
- console.error(`Wrangler error: ${parsed.error.text}`);
39
- process.exit(1);
40
- }
41
- return parsed[0]?.results || [];
42
- }
43
-
44
- function dumpTable(name, query) {
45
- const rows = queryRemote(query || `SELECT * FROM ${name}`);
46
- return rows
47
- .map(
48
- (row) =>
49
- `INSERT INTO ${name} VALUES(${Object.values(row).map(sqlValue).join(",")});`
50
- )
51
- .join("\n");
52
- }
53
-
54
- const header = `-- =============================================================================
55
- -- Demo seed data for Jant (demo.jant.me)
56
- -- Exported from remote demo D1 database via: mise run demo-export
57
- -- Usage: mise run demo-reset
58
- -- =============================================================================
59
- `;
60
-
61
- // Read reset-demo.sql and include it at the top
62
- const resetSql = readFileSync(resolve(__dirname, "reset-demo.sql"), "utf-8");
63
-
64
- const tables = [
65
- // settings, user, account are preserved by reset-demo.sql — don't export
66
- ["posts", "SELECT * FROM posts WHERE deleted_at IS NULL"],
67
- ["pages"],
68
- ["collections"],
69
- ["nav_items"],
70
- ["media"],
71
- ];
72
-
73
- let sql = header;
74
- sql += "\n-- Reset (clear existing content)\n";
75
- sql += resetSql.replace(/^--.*\n/gm, "").trim() + "\n";
76
-
77
- for (const [name, query] of tables) {
78
- const data = dumpTable(name, query);
79
- if (data) sql += `\n-- ${name}\n${data}\n`;
80
- }
81
-
82
- const out = resolve(__dirname, "seed-demo.sql");
83
- writeFileSync(out, sql);
84
- console.log("Exported demo database to templates/jant-site/scripts/seed-demo.sql");
@@ -1,89 +0,0 @@
1
- import { createRequire } from "module";
2
- import { readFileSync, readdirSync, writeFileSync } from "fs";
3
- import { resolve, dirname } from "path";
4
- import { fileURLToPath } from "url";
5
-
6
- // Parse flags
7
- const args = process.argv.slice(2);
8
- const noMedia = args.includes("--no-media");
9
- const noAuth = args.includes("--no-auth");
10
- const outputIndex = args.indexOf("--output");
11
- const outputFile =
12
- outputIndex !== -1 ? args[outputIndex + 1] : "seed-local.sql";
13
-
14
- // better-sqlite3 is installed in packages/core
15
- const __dirname = dirname(fileURLToPath(import.meta.url));
16
- const coreRequire = createRequire(
17
- resolve(__dirname, "../../../packages/core/package.json")
18
- );
19
- const Database = coreRequire("better-sqlite3");
20
-
21
- const dbDir = resolve(
22
- __dirname,
23
- "../.wrangler/state/v3/d1/miniflare-D1DatabaseObject"
24
- );
25
- const files = readdirSync(dbDir).filter((f) => f.endsWith(".sqlite"));
26
- if (!files.length) {
27
- console.error("No local D1 database found. Run mise run dev first.");
28
- process.exit(1);
29
- }
30
-
31
- const db = new Database(resolve(dbDir, files[0]), { readonly: true });
32
-
33
- function sqlValue(v) {
34
- if (v === null) return "NULL";
35
- if (typeof v === "number") return String(v);
36
- return "'" + String(v).replaceAll("'", "''") + "'";
37
- }
38
-
39
- function dumpTable(name, query) {
40
- const rows = db.prepare(query || `SELECT * FROM ${name}`).all();
41
- return rows
42
- .map(
43
- (row) =>
44
- `INSERT INTO ${name} VALUES(${Object.values(row).map(sqlValue).join(",")});`
45
- )
46
- .join("\n");
47
- }
48
-
49
- const header = `-- =============================================================================
50
- -- ${noMedia ? "Seed data (without media)" : "Local development seed data"} for Jant
51
- -- Exported from local D1 database
52
- -- Usage: mise run db-seed
53
- -- =============================================================================
54
- `;
55
-
56
- const tables = [
57
- ...(!noAuth ? [["settings"], ["user"], ["account"]] : []),
58
- ["pages"],
59
- ["collections"],
60
- [
61
- "posts",
62
- "SELECT * FROM posts WHERE deleted_at IS NULL",
63
- ],
64
- ["nav_items"],
65
- ];
66
-
67
- // Include media table only when --no-media is not set
68
- if (!noMedia) {
69
- tables.push(["media"]);
70
- }
71
-
72
- let sql = header;
73
-
74
- // When --no-auth, embed reset statements so everything runs in a single D1 import
75
- if (noAuth) {
76
- const resetSql = readFileSync(resolve(__dirname, "reset-demo.sql"), "utf-8");
77
- sql += "\n-- Reset (clear existing content)\n";
78
- sql += resetSql.replace(/^--.*\n/gm, "").trim() + "\n";
79
- }
80
-
81
- for (const [name, query] of tables) {
82
- const data = dumpTable(name, query);
83
- if (data) sql += `\n-- ${name}\n${data}\n`;
84
- }
85
-
86
- const out = resolve(__dirname, outputFile);
87
- writeFileSync(out, sql);
88
- db.close();
89
- console.log(`Exported to templates/jant-site/scripts/${outputFile}`);
@@ -1,20 +0,0 @@
1
- -- Reset script for Jant demo site (demo.jant.me) (v2 schema)
2
- -- Clears content data while preserving users/settings/schema
3
- -- Usage: mise run demo-reset (runs this then seed-demo.sql)
4
-
5
- -- Clear FTS index first (to avoid trigger issues)
6
- DELETE FROM posts_fts;
7
-
8
- -- Clear main tables (order matters for FK constraints)
9
- DELETE FROM nav_items;
10
- DELETE FROM media;
11
- DELETE FROM posts;
12
- DELETE FROM pages;
13
- DELETE FROM collections;
14
- DELETE FROM redirects;
15
-
16
- -- Sessions, users, accounts, and settings are preserved
17
- -- (seed-demo.sql only contains content data)
18
-
19
- -- Reset auto-increment counters
20
- DELETE FROM sqlite_sequence WHERE name IN ('posts', 'pages', 'collections', 'nav_items', 'redirects');