@jxsuite/create 0.28.0 → 0.28.3

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.
Files changed (3) hide show
  1. package/generate.ts +46 -39
  2. package/index.ts +3 -3
  3. package/package.json +1 -1
package/generate.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  /** Shared project generation logic. Used by both the CLI scaffolder and the Studio server endpoint. */
2
2
 
3
- import { mkdir, writeFile, cp } from "node:fs/promises";
4
- import { join, dirname } from "node:path";
5
- import { fileURLToPath } from "node:url";
3
+ import { cp, mkdir, writeFile } from "node:fs/promises";
4
+ import { join } from "node:path";
5
+
6
6
  import { existsSync } from "node:fs";
7
7
 
8
- const __dirname = dirname(fileURLToPath(import.meta.url));
8
+ const __dirname = import.meta.dirname;
9
9
  const TEMPLATE_DIR = join(__dirname, "template");
10
10
 
11
11
  export interface ProjectOptions {
@@ -15,7 +15,7 @@ export interface ProjectOptions {
15
15
  adapter?: "static" | "cloudflare-pages" | "cloudflare-workers" | "node" | "bun";
16
16
  }
17
17
 
18
- const CF_ADAPTERS = ["cloudflare-pages", "cloudflare-workers"];
18
+ const CF_ADAPTERS = new Set(["cloudflare-pages", "cloudflare-workers"]);
19
19
 
20
20
  /**
21
21
  * Generate a new Jx project at the given path.
@@ -38,19 +38,19 @@ export async function generateProject(destPath: string, opts: ProjectOptions) {
38
38
  await mkdir(join(destPath, "public"), { recursive: true });
39
39
  await mkdir(join(destPath, "content"), { recursive: true });
40
40
 
41
- const projectJson = buildProjectJson({ name, description, url, adapter });
42
- const packageJson = buildPackageJson({ name, description, adapter });
41
+ const projectJson = buildProjectJson({ adapter, description, name, url });
42
+ const packageJson = buildPackageJson({ adapter, description, name });
43
43
 
44
44
  const writes = [
45
- writeFile(join(destPath, "project.json"), JSON.stringify(projectJson, null, "\t") + "\n"),
46
- writeFile(join(destPath, "package.json"), JSON.stringify(packageJson, null, " ") + "\n"),
45
+ writeFile(join(destPath, "project.json"), `${JSON.stringify(projectJson, null, "\t")}\n`),
46
+ writeFile(join(destPath, "package.json"), `${JSON.stringify(packageJson, null, " ")}\n`),
47
47
  cp(join(TEMPLATE_DIR, "gitignore"), join(destPath, ".gitignore")),
48
48
  cp(join(TEMPLATE_DIR, "layouts"), join(destPath, "layouts"), { recursive: true }),
49
49
  cp(join(TEMPLATE_DIR, "pages"), join(destPath, "pages"), { recursive: true }),
50
50
  ];
51
51
 
52
- if (adapter && CF_ADAPTERS.includes(adapter)) {
53
- const wranglerJsonc = buildWranglerJsonc({ slug: packageJson.name, adapter });
52
+ if (adapter && CF_ADAPTERS.has(adapter)) {
53
+ const wranglerJsonc = buildWranglerJsonc({ adapter, slug: packageJson.name });
54
54
  writes.push(writeFile(join(destPath, "wrangler.jsonc"), wranglerJsonc));
55
55
  }
56
56
 
@@ -58,52 +58,52 @@ export async function generateProject(destPath: string, opts: ProjectOptions) {
58
58
  }
59
59
 
60
60
  /**
61
- * Build a wrangler.jsonc for Cloudflare adapters. Includes the Images binding so `images.service:
62
- * "cloudflare"` works out of the box.
61
+ * Build a wrangler.jsonc for Cloudflare adapters.
63
62
  *
64
63
  * @param {{ slug: string; adapter: string }} opts
65
64
  */
66
65
  function buildWranglerJsonc({ slug, adapter }: { slug: string; adapter: string }) {
67
66
  const compatibilityDate = new Date().toISOString().slice(0, 10);
68
67
 
68
+ // Nodejs_compat: server functions routinely pull in Node-flavored npm packages
69
69
  const config =
70
70
  adapter === "cloudflare-workers"
71
71
  ? {
72
- name: slug,
73
- main: "./dist/worker.js",
72
+ assets: { binding: "ASSETS", directory: "./dist" },
74
73
  compatibility_date: compatibilityDate,
75
- assets: { directory: "./dist", binding: "ASSETS" },
76
- images: { binding: "IMAGES" },
74
+ compatibility_flags: ["nodejs_compat"],
75
+ main: "./dist/worker.js",
76
+ name: slug,
77
77
  }
78
78
  : {
79
- name: slug,
80
79
  compatibility_date: compatibilityDate,
80
+ compatibility_flags: ["nodejs_compat"],
81
+ name: slug,
81
82
  pages_build_output_dir: "./dist",
82
- images: { binding: "IMAGES" },
83
83
  };
84
84
 
85
- return JSON.stringify(config, null, "\t") + "\n";
85
+ return `${JSON.stringify(config, null, "\t")}\n`;
86
86
  }
87
87
 
88
88
  /** @param {ProjectOptions} opts */
89
89
  function buildProjectJson({ name, description, url, adapter }: ProjectOptions) {
90
90
  const $head = [
91
91
  {
92
+ attributes: { content: "width=device-width, initial-scale=1", name: "viewport" },
92
93
  tagName: "meta",
93
- attributes: { name: "viewport", content: "width=device-width, initial-scale=1" },
94
94
  },
95
95
  ];
96
96
 
97
97
  if (description) {
98
98
  $head.push({
99
+ attributes: { content: description, name: "description" },
99
100
  tagName: "meta",
100
- attributes: { name: "description", content: description },
101
101
  });
102
102
  }
103
103
 
104
104
  const build: { outDir: string; format: string; trailingSlash: string; adapter?: string } = {
105
- outDir: "./dist",
106
105
  format: "directory",
106
+ outDir: "./dist",
107
107
  trailingSlash: "always",
108
108
  };
109
109
 
@@ -112,12 +112,6 @@ function buildProjectJson({ name, description, url, adapter }: ProjectOptions) {
112
112
  }
113
113
 
114
114
  return {
115
- name,
116
- url: url || "https://example.com",
117
- defaults: {
118
- layout: "./layouts/base.json",
119
- lang: "en",
120
- },
121
115
  $head,
122
116
  $media: {
123
117
  "--": "1280px",
@@ -125,14 +119,20 @@ function buildProjectJson({ name, description, url, adapter }: ProjectOptions) {
125
119
  "--md": "(max-width: 768px)",
126
120
  "--sm": "(max-width: 640px)",
127
121
  },
122
+ build,
123
+ defaults: {
124
+ lang: "en",
125
+ layout: "./layouts/base.json",
126
+ },
127
+ name,
128
128
  style: {
129
- margin: "0",
130
- padding: "0",
129
+ color: "#1a1a1a",
131
130
  fontFamily: "system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif",
132
131
  lineHeight: "1.6",
133
- color: "#1a1a1a",
132
+ margin: "0",
133
+ padding: "0",
134
134
  },
135
- build,
135
+ url: url || "https://example.com",
136
136
  };
137
137
  }
138
138
 
@@ -148,9 +148,10 @@ function buildPackageJson({
148
148
  }) {
149
149
  const slug = name
150
150
  .toLowerCase()
151
- .replace(/[^a-z0-9]+/g, "-")
152
- .replace(/^-|-$/g, "");
151
+ .replaceAll(/[^a-z0-9]+/g, "-")
152
+ .replaceAll(/^-|-$/g, "");
153
153
 
154
+ const dependencies: Record<string, string> = {};
154
155
  const devDependencies: Record<string, string> = {
155
156
  "@jxsuite/compiler": "^0.19.0",
156
157
  "@jxsuite/runtime": "^0.19.0",
@@ -161,18 +162,24 @@ function buildPackageJson({
161
162
  dev: "jx dev",
162
163
  };
163
164
 
164
- if (adapter && CF_ADAPTERS.includes(adapter)) {
165
+ if (adapter && adapter !== "static") {
166
+ // The generated server worker imports hono; wrangler/node/bun resolve it from node_modules
167
+ dependencies["hono"] = "^4";
168
+ }
169
+
170
+ if (adapter && CF_ADAPTERS.has(adapter)) {
165
171
  devDependencies["wrangler"] = "^4";
166
172
  scripts.deploy =
167
173
  adapter === "cloudflare-workers" ? "wrangler deploy" : "wrangler pages deploy dist";
168
174
  }
169
175
 
170
176
  return {
171
- name: slug,
172
- private: true,
173
177
  description: description || "",
178
+ devDependencies,
174
179
  license: "MIT",
180
+ name: slug,
181
+ private: true,
175
182
  scripts,
176
- devDependencies,
183
+ ...(Object.keys(dependencies).length > 0 && { dependencies }),
177
184
  };
178
185
  }
package/index.ts CHANGED
@@ -7,10 +7,10 @@
7
7
 
8
8
  import { createInterface } from "node:readline/promises";
9
9
  import { stdin, stdout } from "node:process";
10
- import { resolve, basename } from "node:path";
10
+ import { basename, resolve } from "node:path";
11
11
  import { generateProject } from "./generate";
12
12
 
13
- const dest = process.argv[2];
13
+ const [dest] = process.argv.slice(2);
14
14
  if (!dest) {
15
15
  console.error("Usage: bun create @jxsuite <directory>");
16
16
  process.exit(1);
@@ -45,7 +45,7 @@ const adapterMap = {
45
45
  };
46
46
  const adapter = adapterMap[adapterChoice] || "static";
47
47
 
48
- await generateProject(destPath, { name, description, url, adapter });
48
+ await generateProject(destPath, { adapter, description, name, url });
49
49
 
50
50
  console.log(`
51
51
  Project created at ${destPath}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jxsuite/create",
3
- "version": "0.28.0",
3
+ "version": "0.28.3",
4
4
  "description": "Scaffold a new Jx project",
5
5
  "license": "MIT",
6
6
  "repository": {