create-jant 0.3.27 → 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.
package/dist/index.js CHANGED
@@ -9,8 +9,8 @@ import path from "path";
9
9
  import { fileURLToPath } from "url";
10
10
  var __filename = fileURLToPath(import.meta.url);
11
11
  var __dirname = path.dirname(__filename);
12
- var CORE_VERSION = "0.3.27";
13
- var TEMPLATE_DIR = fs.existsSync(path.resolve(__dirname, "../template")) ? path.resolve(__dirname, "../template") : path.resolve(__dirname, "../../../templates/jant-site");
12
+ var CORE_VERSION = "0.3.28";
13
+ var TEMPLATE_DIR = fs.existsSync(path.resolve(__dirname, "../template")) ? path.resolve(__dirname, "../template") : path.resolve(__dirname, "../../../sites/demo");
14
14
  function isValidProjectName(name) {
15
15
  return /^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/.test(name);
16
16
  }
@@ -40,9 +40,6 @@ function detectPackageManager() {
40
40
  function formatRunCmd(pm, script) {
41
41
  return pm === "npm" ? `npm run ${script}` : `${pm} ${script}`;
42
42
  }
43
- function formatAddCmd(pm, pkg) {
44
- return pm === "npm" ? `npm install ${pkg}` : `${pm} add ${pkg}`;
45
- }
46
43
  function runCommand(cmd, cwd) {
47
44
  try {
48
45
  execSync(cmd, { stdio: "ignore", cwd });
@@ -51,67 +48,54 @@ function runCommand(cmd, cwd) {
51
48
  return false;
52
49
  }
53
50
  }
54
- function processMarkers(content, vars) {
55
- content = content.replace(
56
- /\s*(?:\/\/|#)\s*@create-jant:\s*@remove-start[\s\S]*?(?:\/\/|#)\s*@create-jant:\s*@remove-end\n?/g,
57
- ""
58
- );
59
- content = content.replace(
60
- /^.*(?:\/\/|#)\s*@create-jant:\s*@remove\s*\n?/gm,
61
- ""
62
- );
63
- content = content.replace(
64
- /^(.+=\s*)"[^"]*"\s*(?:\/\/|#)\s*@create-jant:\s*"([^"]*)"/gm,
65
- (_, prefix, template) => {
66
- const value = template.replace(
51
+ function processAnnotations(content, vars) {
52
+ const lines = content.split("\n");
53
+ const result = [];
54
+ let removing = false;
55
+ for (const line of lines) {
56
+ if (line.trim() === "# @create-jant: @remove-start") {
57
+ removing = true;
58
+ continue;
59
+ }
60
+ if (line.trim() === "# @create-jant: @remove-end") {
61
+ removing = false;
62
+ continue;
63
+ }
64
+ if (removing) continue;
65
+ if (line.includes("# @create-jant: @remove")) {
66
+ continue;
67
+ }
68
+ const replaceMatch = line.match(/^(.+?)\s*#\s*@create-jant:\s*"(.*)"$/);
69
+ if (replaceMatch) {
70
+ const prefix = replaceMatch[1];
71
+ const newValue = replaceMatch[2];
72
+ const interpolated = newValue.replace(
67
73
  /\$\{(\w+)\}/g,
68
- (__, key) => vars[key] ?? ""
74
+ (_, key) => vars[key] ?? ""
69
75
  );
70
- return `${prefix}"${value}"`;
76
+ const valueMatch = prefix.match(/^(\s*\S+\s*=\s*)"[^"]*"(.*)$/);
77
+ if (valueMatch) {
78
+ result.push(`${valueMatch[1]}"${interpolated}"${valueMatch[2]}`);
79
+ } else {
80
+ result.push(prefix);
81
+ }
82
+ continue;
71
83
  }
72
- );
73
- return content;
84
+ result.push(line);
85
+ }
86
+ return result.join("\n");
74
87
  }
75
88
  async function copyTemplate(config) {
76
89
  const { projectName, targetDir, packageManager } = config;
77
90
  await fs.copy(TEMPLATE_DIR, targetDir, {
78
91
  filter: (src) => {
79
92
  const basename = path.basename(src);
80
- if (basename.startsWith(".DS_Store")) return false;
81
93
  if (basename === "node_modules") return false;
82
94
  if (basename === ".wrangler") return false;
83
- if (basename === ".swc") return false;
84
95
  if (basename === ".dev.vars") return false;
85
- if (basename === "pnpm-lock.yaml") return false;
86
- if (basename === "yarn.lock") return false;
87
- if (basename === "package-lock.json") return false;
88
- if (basename === "bun.lockb") return false;
89
- if (basename === "pnpm-workspace.yaml") return false;
90
- if (basename === "dist") return false;
91
- if (basename === "wrangler.demo.toml") return false;
92
- if (basename === "reset-demo.sql") return false;
93
- if (basename === "seed-demo.sql") return false;
94
- if (basename === "reset-local.sql") return false;
95
- if (basename === "seed-local.sql") return false;
96
- if (basename === "export-demo.mjs") return false;
97
- if (basename === "export-seed.mjs") return false;
98
96
  return true;
99
97
  }
100
98
  });
101
- const secretsExampleFile = ".dev.vars.example";
102
- const secretsFile = ".dev.vars";
103
- const renames = [
104
- ["_gitignore", ".gitignore"],
105
- ["_env.example", secretsExampleFile],
106
- ["_github", ".github"]
107
- ];
108
- for (const [from, to] of renames) {
109
- const fromPath = path.join(targetDir, from);
110
- const toPath = path.join(targetDir, to);
111
- if (await fs.pathExists(fromPath)) {
112
- await fs.rename(fromPath, toPath);
113
- }
114
- }
115
99
  const pkgPath = path.join(targetDir, "package.json");
116
100
  if (await fs.pathExists(pkgPath)) {
117
101
  const pkg = await fs.readJson(pkgPath);
@@ -119,17 +103,14 @@ async function copyTemplate(config) {
119
103
  if (pkg.dependencies?.["@jant/core"] === "workspace:*") {
120
104
  pkg.dependencies["@jant/core"] = `^${CORE_VERSION}`;
121
105
  }
122
- delete pkg.scripts["dev:debug"];
123
- if (packageManager !== "pnpm") {
106
+ if (packageManager !== "pnpm" && pkg.scripts) {
124
107
  delete pkg.packageManager;
125
- if (pkg.scripts) {
126
- for (const [key, value] of Object.entries(pkg.scripts)) {
127
- if (typeof value === "string") {
128
- pkg.scripts[key] = value.replace(
129
- /pnpm run (\S+)/g,
130
- (_, script) => formatRunCmd(packageManager, script)
131
- );
132
- }
108
+ for (const [key, value] of Object.entries(pkg.scripts)) {
109
+ if (typeof value === "string") {
110
+ pkg.scripts[key] = value.replace(
111
+ /pnpm run (\S+)/g,
112
+ (_, script) => formatRunCmd(packageManager, script)
113
+ );
133
114
  }
134
115
  }
135
116
  }
@@ -138,7 +119,10 @@ async function copyTemplate(config) {
138
119
  const wranglerPath = path.join(targetDir, "wrangler.toml");
139
120
  if (await fs.pathExists(wranglerPath)) {
140
121
  let content = await fs.readFile(wranglerPath, "utf-8");
141
- content = processMarkers(content, { name: projectName });
122
+ content = processAnnotations(content, { name: projectName });
123
+ if (config.s3) {
124
+ content = content.replace(/\n\[\[r2_buckets\]\][^[]*/s, "\n");
125
+ }
142
126
  await fs.writeFile(wranglerPath, content, "utf-8");
143
127
  }
144
128
  const authSecret = generateAuthSecret();
@@ -147,19 +131,6 @@ async function copyTemplate(config) {
147
131
  AUTH_SECRET=${authSecret}
148
132
  `;
149
133
  if (config.s3) {
150
- if (await fs.pathExists(wranglerPath)) {
151
- let wContent = await fs.readFile(wranglerPath, "utf-8");
152
- wContent = wContent.replace(
153
- /^# STORAGE_DRIVER = "s3"/m,
154
- 'STORAGE_DRIVER = "s3"'
155
- );
156
- wContent = wContent.replace(/^# S3_ENDPOINT = /m, "S3_ENDPOINT = ");
157
- wContent = wContent.replace(/^# S3_BUCKET = /m, "S3_BUCKET = ");
158
- wContent = wContent.replace(/^# S3_REGION = /m, "S3_REGION = ");
159
- wContent = wContent.replace(/^# S3_PUBLIC_URL = /m, "S3_PUBLIC_URL = ");
160
- wContent = wContent.replace(/\n\[\[r2_buckets\]\][^[]*/s, "\n");
161
- await fs.writeFile(wranglerPath, wContent, "utf-8");
162
- }
163
134
  devVarsContent += `
164
135
  # S3-compatible storage credentials
165
136
  S3_ACCESS_KEY_ID=
@@ -167,37 +138,10 @@ S3_SECRET_ACCESS_KEY=
167
138
  `;
168
139
  }
169
140
  await fs.writeFile(
170
- path.join(targetDir, secretsFile),
141
+ path.join(targetDir, ".dev.vars"),
171
142
  devVarsContent,
172
143
  "utf-8"
173
144
  );
174
- const viteConfigPath = path.join(targetDir, "vite.config.ts");
175
- if (await fs.pathExists(viteConfigPath)) {
176
- let content = await fs.readFile(viteConfigPath, "utf-8");
177
- content = processMarkers(content, {});
178
- await fs.writeFile(viteConfigPath, content, "utf-8");
179
- }
180
- const readmePath = path.join(targetDir, "README.md");
181
- if (packageManager !== "npm" && await fs.pathExists(readmePath)) {
182
- let readme = await fs.readFile(readmePath, "utf-8");
183
- readme = readme.replace(
184
- /npm install (\S+)/g,
185
- (_, pkg) => formatAddCmd(packageManager, pkg)
186
- );
187
- readme = readme.replace(/npm install/g, `${packageManager} install`);
188
- readme = readme.replace(
189
- /npm run (\S+)/g,
190
- (_, script) => formatRunCmd(packageManager, script)
191
- );
192
- readme = readme.replace(/npm create/g, `${packageManager} create`);
193
- await fs.writeFile(readmePath, readme, "utf-8");
194
- }
195
- if (packageManager === "pnpm") {
196
- const wsSource = path.join(TEMPLATE_DIR, "pnpm-workspace.yaml");
197
- if (await fs.pathExists(wsSource)) {
198
- await fs.copy(wsSource, path.join(targetDir, "pnpm-workspace.yaml"));
199
- }
200
- }
201
145
  }
202
146
  async function main() {
203
147
  console.log();
@@ -209,12 +153,12 @@ async function main() {
209
153
  if (args[0]) {
210
154
  projectName = args[0];
211
155
  } else if (opts.yes) {
212
- projectName = "jant-site";
156
+ projectName = "my-jant-site";
213
157
  } else {
214
158
  const result = await p.text({
215
159
  message: "What is your project name?",
216
- placeholder: "jant-site",
217
- defaultValue: "jant-site",
160
+ placeholder: "my-jant-site",
161
+ defaultValue: "my-jant-site",
218
162
  validate: (value) => {
219
163
  if (!value) return "Project name is required";
220
164
  const sanitized = toValidProjectName(value);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-jant",
3
- "version": "0.3.27",
3
+ "version": "0.3.28",
4
4
  "description": "Create a new Jant project",
5
5
  "type": "module",
6
6
  "bin": {
@@ -53,8 +53,7 @@
53
53
  "build": "tsup src/index.ts --format esm --clean --outDir dist",
54
54
  "dev": "tsup src/index.ts --format esm --watch",
55
55
  "typecheck": "tsc --noEmit",
56
- "copy-template": "rm -rf template && cp -r ../../templates/jant-site template",
57
- "prepare-template": "node scripts/prepare-template.js",
56
+ "copy-template": "rm -rf template && rsync -a --exclude node_modules --exclude .wrangler --exclude .dev.vars ../../sites/demo/ template/",
58
57
  "inject-version": "node -e \"const fs=require('fs');const v=require('../core/package.json').version;const f='dist/index.js';fs.writeFileSync(f,fs.readFileSync(f,'utf8').replace('__JANT_CORE_VERSION__',v))\"",
59
58
  "test-template": "node scripts/test-template.js"
60
59
  }
@@ -0,0 +1,3 @@
1
+ import { createApp } from "@jant/core";
2
+
3
+ export default createApp();
@@ -1,36 +1,15 @@
1
1
  {
2
- "name": "jant-site",
3
- "version": "0.0.1",
2
+ "name": "jant-demo",
4
3
  "private": true,
5
4
  "type": "module",
6
- "packageManager": "pnpm@10.28.2",
7
5
  "scripts": {
8
- "dev": "pnpm run db:migrate:local && vite dev",
9
- "dev:debug": "pnpm run db:migrate:local && vite dev --port 19019",
10
- "build": "vite build",
11
- "deploy": "pnpm run db:migrate:remote && pnpm run build && wrangler deploy",
12
- "preview": "vite preview",
13
- "typecheck": "tsc --noEmit",
14
- "db:migrate:local": "yes | wrangler d1 migrations apply DB --local",
15
- "db:migrate:remote": "wrangler d1 migrations apply DB --remote",
16
- "jant": "jant",
17
- "reset-password": "node scripts/reset-password.mjs"
6
+ "dev": "wrangler d1 migrations apply DB --local && wrangler dev",
7
+ "deploy": "wrangler d1 migrations apply DB --remote && wrangler deploy"
18
8
  },
19
9
  "dependencies": {
20
10
  "@jant/core": "workspace:*"
21
11
  },
22
12
  "devDependencies": {
23
- "@cloudflare/vite-plugin": "^1.22.1",
24
- "@cloudflare/workers-types": "^4.20260131.0",
25
- "@lingui/swc-plugin": "^5.10.1",
26
- "@swc/core": "^1.15.11",
27
- "@tailwindcss/vite": "^4.1.18",
28
- "@types/node": "^22.15.4",
29
- "hono": "^4.11.9",
30
- "tailwindcss": "^4.1.18",
31
- "typescript": "^5.9.3",
32
- "unplugin-swc": "^1.5.9",
33
- "vite": "^7.3.1",
34
13
  "wrangler": "^4.61.1"
35
14
  }
36
15
  }
@@ -1,11 +1,16 @@
1
- name = "jant-site" # @create-jant: "${name}"
2
- main = "src/index.ts"
1
+ name = "jant-demo" # @create-jant: "${name}"
2
+ main = "index.js"
3
3
  compatibility_date = "2026-01-20"
4
4
  compatibility_flags = ["nodejs_compat"]
5
5
  account_id = "03e7294bdb3750ed5a0d6afef6d770e4" # @create-jant: @remove
6
6
 
7
+ [assets]
8
+ directory = "./node_modules/@jant/core/dist/client"
9
+
10
+ # @create-jant: @remove-start
7
11
  [dev]
8
12
  port = 9019
13
+ # @create-jant: @remove-end
9
14
 
10
15
  # ============================================
11
16
  # Environment Variables
@@ -14,54 +19,56 @@ port = 9019
14
19
  # Sensitive secrets (like AUTH_SECRET) should be:
15
20
  # - Local dev: .dev.vars file (not committed)
16
21
  # - Production: wrangler secret put AUTH_SECRET
17
- # See docs/configuration.md for full details
22
+ # Full details: https://github.com/jant-me/jant/blob/main/docs/configuration.md
18
23
 
19
24
  [vars]
20
25
  # Required: Your site's public URL (e.g. https://my-blog.example.com)
21
- SITE_URL = ""
26
+ # https://github.com/jant-me/jant/blob/main/docs/configuration.md#required
27
+ SITE_URL = "https://demo.jant.me" # @create-jant: ""
22
28
 
23
29
  # Optional: Site configuration
24
- # These can be overridden in dashboard settings (/dash/settings)
25
- # If not set, values from database settings table are used
30
+ # You can also set these in the dashboard UI at /dash/settings
31
+ # https://github.com/jant-me/jant/blob/main/docs/configuration.md#dashboard-settings
26
32
  # SITE_NAME = "My Blog"
27
33
  # SITE_DESCRIPTION = "A personal blog powered by Jant"
28
34
  # SITE_LANGUAGE = "en"
29
35
 
30
36
  # Optional: Timeline page size (default: 20)
31
- # PAGE_SIZE = "5"
37
+ # PAGE_SIZE = "20"
32
38
 
33
- # Recommended: R2 public URL for media access
34
- # Without this, media files are proxied through your Worker (slower, uses more CPU).
35
- # With this, media is served directly from Cloudflare's CDN (faster, lower cost).
36
- # Set up: Cloudflare Dashboard → R2 → Your Bucket → Settings → Public access
39
+ # Optional: R2 Storage (for media uploads)
40
+ # https://github.com/jant-me/jant/blob/main/docs/configuration.md#r2-default
37
41
  # R2_PUBLIC_URL = "https://cdn.example.com"
38
42
  R2_PUBLIC_URL = "https://demo-media.jant.me" # @create-jant: @remove
39
43
 
40
44
  # Optional: Cloudflare Image Transformations
41
45
  # For automatic thumbnail generation and image optimization
42
- # Use the same domain as R2_PUBLIC_URL (or SITE_URL if R2_PUBLIC_URL is not set)
43
- # IMAGE_TRANSFORM_URL = "https://media.yourdomain.com/cdn-cgi/image"
46
+ # https://github.com/jant-me/jant/blob/main/docs/configuration.md#image-transformations-optional
47
+ # IMAGE_TRANSFORM_URL = "https://example.com/cdn-cgi/image"
48
+ IMAGE_TRANSFORM_URL = "https://demo-media.jant.me/cdn-cgi/image" # @create-jant: @remove
49
+
50
+ # @create-jant: @remove-start
51
+ DEMO_EMAIL = "demo@jant.me"
52
+ DEMO_PASSWORD = "demodemo"
53
+ # @create-jant: @remove-end
54
+
55
+ [[d1_databases]]
56
+ binding = "DB"
57
+ database_name = "jant-demo-db" # @create-jant: "${name}-db"
58
+ database_id = "76329154-291d-4580-af73-aa77397649f1" # @create-jant: "local"
59
+ migrations_dir = "node_modules/@jant/core/src/db/migrations"
44
60
 
45
- # Optional: Demo mode (pre-fill sign-in credentials)
46
- # DEMO_EMAIL = "demo@example.com"
47
- # DEMO_PASSWORD = "demo123"
61
+ [[r2_buckets]]
62
+ binding = "R2"
63
+ bucket_name = "jant-demo-media" # @create-jant: "${name}-media"
64
+ remote = true # @create-jant: @remove
48
65
 
49
66
  # Optional: S3-compatible storage (alternative to R2)
50
67
  # Set STORAGE_DRIVER = "s3" and configure the options below.
51
68
  # When using S3, the [[r2_buckets]] section can be removed.
69
+ # https://github.com/jant-me/jant/blob/main/docs/configuration.md#s3-compatible-storage
52
70
  # STORAGE_DRIVER = "s3"
53
71
  # S3_ENDPOINT = "https://s3.example.com"
54
72
  # S3_BUCKET = "my-bucket"
55
73
  # S3_REGION = "us-east-1"
56
74
  # S3_PUBLIC_URL = "https://cdn.example.com"
57
-
58
- [[d1_databases]]
59
- binding = "DB"
60
- database_name = "jant-site-db" # @create-jant: "${name}-db"
61
- database_id = "local"
62
- migrations_dir = "../../packages/core/src/db/migrations" # @create-jant: "node_modules/@jant/core/src/db/migrations"
63
-
64
- [[r2_buckets]]
65
- binding = "R2"
66
- bucket_name = "jant-demo-media" # @create-jant: "${name}-media"
67
- remote = true # @create-jant: @remove
@@ -1 +0,0 @@
1
- {}