create-astroid 0.7.3 → 0.7.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 CHANGED
@@ -58,11 +58,11 @@ pnpm create astroid [directory] [options]
58
58
  cd my-site
59
59
  pnpm install
60
60
  pnpm exec wrangler d1 create <name> # then paste the ids into wrangler.jsonc
61
- pnpm doctor # validates config, bindings, generated files
61
+ pnpm run doctor # validates config, bindings, generated files
62
62
  pnpm dev
63
63
  ```
64
64
 
65
- `pnpm doctor` flags any binding id you haven't filled in yet, plus generated
65
+ `pnpm run doctor` flags any binding id you haven't filled in yet, plus generated
66
66
  files that have drifted from the config.
67
67
 
68
68
  ## How the pieces relate
package/index.mjs CHANGED
@@ -14,7 +14,6 @@
14
14
  // uses, so a fresh project is already in sync.
15
15
 
16
16
  import { existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
17
- import { createRequire } from "node:module";
18
17
  import { basename, dirname, join, resolve } from "node:path";
19
18
  import { createInterface } from "node:readline/promises";
20
19
  import { fileURLToPath } from "node:url";
@@ -32,6 +31,7 @@ import {
32
31
  generateAstroidSecretsEnv,
33
32
  generateAstroidWrangler,
34
33
  } from "astroidjs";
34
+ import { toolkitRanges } from "./toolkit-ranges.mjs";
35
35
 
36
36
  const TEMPLATE_DIR = join(dirname(fileURLToPath(import.meta.url)), "template");
37
37
 
@@ -87,67 +87,6 @@ const slugify = (s) =>
87
87
  .replace(/^-+|-+$/g, "")
88
88
  .slice(0, 40);
89
89
 
90
- // --- toolkit versions ------------------------------------------------------
91
-
92
- /**
93
- * The `astroidjs` + `louise-toolkit` ranges to write into the scaffold.
94
- *
95
- * DERIVED from this package's own resolved dependencies rather than hard-coded
96
- * in template/package.json. A literal there is a second place to remember on
97
- * every release, and when it rots the failure is silent and total: the template
98
- * imported `astroidjs/astro` while pinning `^0.1.0`, a range whose newest match
99
- * had no such export, so every scaffolded project died before Astro loaded its
100
- * config. CI could not see it—the clean-room smoke test pins both packages to
101
- * tarballs via pnpm `overrides`, which is exactly what erases these ranges.
102
- *
103
- * Three shapes reach the `declared` value, and all three have to end up as one
104
- * caret range:
105
- *
106
- * - `workspace:*`—a sibling in this repo (`astroidjs`). Falls back to the
107
- * version of the copy actually resolved on disk, which is what the scaffold
108
- * would install anyway. `pnpm pack` rewrites these to a concrete version, so
109
- * a PUBLISHED create-astroid never carries one.
110
- * - an exact version—what `pnpm pack` leaves behind for a former
111
- * `workspace:*`.
112
- * - an already-caretted range—what an external dependency is written as now
113
- * that `louise-toolkit` and `@louise-toolkit/astro` live in another repo.
114
- *
115
- * That last one is why `stripRange` exists. Prefixing `^` onto `^0.27.0` yields
116
- * `^^0.27.0`, which npm rejects as invalid, and every scaffolded project would
117
- * fail at `pnpm install` before anything type-checked. It cost nothing to guard
118
- * and would have been invisible until the first scaffold after the repo split.
119
- *
120
- * Caret on a 0.x is minor-locked (`^0.2.0` := `>=0.2.0 <0.3.0`), which is the
121
- * behaviour we want while the toolkit is pre-1.0 and marks breaking changes as
122
- * minors: patches flow, a breaking minor does not.
123
- */
124
- /** `^1.2.3` / `~1.2.3` / `>=1.2.3` → `1.2.3`. See {@link toolkitRanges}. */
125
- function stripRange(version) {
126
- return String(version).replace(/^[\^~]|^>=\s*/, "");
127
- }
128
-
129
- function toolkitRanges() {
130
- const req = createRequire(import.meta.url);
131
- const self = JSON.parse(readFileSync(new URL("./package.json", import.meta.url), "utf8"));
132
- const ranges = {};
133
- for (const name of ["astroidjs", "louise-toolkit", "@louise-toolkit/astro"]) {
134
- const declared = self.dependencies?.[name];
135
- let version = declared && !declared.startsWith("workspace:") ? declared : undefined;
136
- if (!version) {
137
- // Both packages export `./package.json`, so this resolves the real copy.
138
- version = JSON.parse(readFileSync(req.resolve(`${name}/package.json`), "utf8")).version;
139
- }
140
- if (!version) {
141
- throw new Error(
142
- `create-astroid could not determine the ${name} version to scaffold with. ` +
143
- "This is a packaging fault — please file an issue rather than editing the scaffold by hand.",
144
- );
145
- }
146
- ranges[name] = `^${stripRange(version)}`;
147
- }
148
- return ranges;
149
- }
150
-
151
90
  async function prompt(question, fallback) {
152
91
  if (!process.stdin.isTTY) return fallback;
153
92
  const rl = createInterface({ input: process.stdin, output: process.stdout });
@@ -561,7 +500,7 @@ async function main() {
561
500
  " OWNER_EMAIL=you@example.com pnpm seed:editors",
562
501
  " # develop / ship:",
563
502
  " pnpm dev # astroid dev (regenerates, then astro dev)",
564
- " pnpm doctor # validate config + bindings",
503
+ " pnpm run doctor # validate config + bindings (`run` is required)",
565
504
  " wrangler deploy",
566
505
  "",
567
506
  ].join("\n"),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-astroid",
3
- "version": "0.7.3",
3
+ "version": "0.7.5",
4
4
  "description": "Scaffold a new Astroid site — an editable, multi-editor Astro app on Cloudflare Workers — in one command.",
5
5
  "keywords": [
6
6
  "astro",
@@ -23,7 +23,8 @@
23
23
  },
24
24
  "files": [
25
25
  "index.mjs",
26
- "template"
26
+ "template",
27
+ "toolkit-ranges.mjs"
27
28
  ],
28
29
  "type": "module",
29
30
  "publishConfig": {
@@ -32,9 +33,9 @@
32
33
  "dependencies": {
33
34
  "@better-auth/passkey": "^1.7.2",
34
35
  "@louise-toolkit/astro": "^0.2.3",
36
+ "astroidjs": "0.14.0",
35
37
  "better-auth": "^1.7.2",
36
- "louise-toolkit": "^0.31.1",
37
- "astroidjs": "0.14.0"
38
+ "louise-toolkit": "^0.31.1"
38
39
  },
39
40
  "engines": {
40
41
  "node": ">=26.0.0"
@@ -99,7 +99,7 @@ editable. Body HTML is sanitized on every save.
99
99
  Once provisioned, shipping changes is just:
100
100
 
101
101
  ```sh
102
- pnpm doctor # validate config, bindings, and generated-file freshness
102
+ pnpm run doctor # validate config, bindings, and generated-file freshness
103
103
  wrangler deploy # or: pnpm astroid deploy
104
104
  ```
105
105
 
@@ -36,8 +36,10 @@ jobs:
36
36
  # Validate the config, bindings, and that the generated
37
37
  # src/schema.ts · src/worker.ts · src/middleware.ts trio is still in sync
38
38
  # with astroid.config.ts. A fast fail before the heavier steps.
39
+ # `run` is load-bearing: `doctor` is a pnpm built-in, so a bare
40
+ # `pnpm doctor` runs pnpm's own self-check and never reaches Astroid's.
39
41
  - name: Doctor
40
- run: pnpm doctor
42
+ run: pnpm run doctor
41
43
 
42
44
  # No-ops on a fresh scaffold; runs automatically once you add a `lint`
43
45
  # script (oxlint/biome) — same for `test` (vitest) further down.
@@ -44,7 +44,7 @@ wrangler kv namespace create DRAFTS
44
44
  ## Deploy
45
45
 
46
46
  ```sh
47
- pnpm doctor # validate config, bindings, and the generated files
47
+ pnpm run doctor # validate config, bindings, and the generated files
48
48
  wrangler deploy
49
49
  ```
50
50
 
@@ -35,11 +35,11 @@
35
35
  "daisyui": "^5.6.18",
36
36
  "drizzle-kit": "^0.31.10",
37
37
  "tailwindcss": "^4.1.0",
38
- "typescript": "^5.9.3",
38
+ "typescript": "^6.0.3",
39
39
  "wrangler": "^4.110.0"
40
40
  },
41
41
  "engines": {
42
42
  "node": ">=24.0.0"
43
43
  },
44
- "packageManager": "pnpm@11.13.0"
44
+ "packageManager": "pnpm@12.6.0"
45
45
  }
@@ -0,0 +1,70 @@
1
+ // Copyright (c) 2026 BowenLabs. Astroid is MIT licensed.
2
+ //
3
+ // The toolkit version ranges create-astroid writes into a new project. A module
4
+ // of its own so the test suite can import it without running the scaffolder.
5
+
6
+ import { readFileSync } from "node:fs";
7
+ import { createRequire } from "node:module";
8
+
9
+ /**
10
+ * The `astroidjs` + `louise-toolkit` ranges to write into the scaffold: a caret
11
+ * on the version of each package that create-astroid actually RESOLVED, which is
12
+ * the version the scaffold was built against.
13
+ *
14
+ * DERIVED rather than hard-coded in template/package.json. A literal there is a
15
+ * second place to remember on every release, and when it rots the failure is
16
+ * silent and total: the template imported `astroidjs/astro` while pinning
17
+ * `^0.1.0`, a range whose newest match had no such export, so every scaffolded
18
+ * project died before Astro loaded its config. CI could not see it—the
19
+ * clean-room smoke test pins `astroidjs` to a tarball via pnpm `overrides`,
20
+ * which is exactly what erases the declared range.
21
+ *
22
+ * Always the resolved version, never create-astroid's own DECLARED range. In the
23
+ * monorepo the two were the same thing: `pnpm pack` turned `workspace:*` into an
24
+ * exact version. Once the toolkit moved to another repo, create-astroid declared
25
+ * it as a caret range (`^0.31.0`), and reading that wrote the range's FLOOR
26
+ * rather than the version the generators and the auth migration had just run
27
+ * against. `scripts/ci/checks/scaffold-versions.mjs` holds the scaffold to the
28
+ * resolved version, so the moment a toolkit patch shipped (0.31.1) the two
29
+ * disagreed and the smoke test failed on every PR with no code change.
30
+ *
31
+ * A published `version` is always exact, so the caret goes straight on; there is
32
+ * no range to strip. The floor moves with each patch, which is the point: a new
33
+ * project starts from the newest patch it was built against. Caret on a 0.x is
34
+ * minor-locked (`^0.2.0` := `>=0.2.0 <0.3.0`), which is the behavior we want
35
+ * while the toolkit is pre-1.0 and marks breaking changes as minors: patches
36
+ * flow, a breaking minor does not.
37
+ *
38
+ * @param {(name: string) => string | undefined} [resolveVersion] Reads a
39
+ * package's installed version. Tests pass their own; the default asks Node.
40
+ * @returns {Record<string, string>} Package name to caret range.
41
+ */
42
+ export function toolkitRanges(resolveVersion = installedVersion) {
43
+ /** @type {Record<string, string>} */
44
+ const ranges = {};
45
+ for (const name of ["astroidjs", "louise-toolkit", "@louise-toolkit/astro"]) {
46
+ const version = resolveVersion(name);
47
+ if (!version) {
48
+ throw new Error(
49
+ `create-astroid could not determine the ${name} version to scaffold with. ` +
50
+ "This is a packaging fault — please file an issue rather than editing the scaffold by hand.",
51
+ );
52
+ }
53
+ ranges[name] = `^${version}`;
54
+ }
55
+ return ranges;
56
+ }
57
+
58
+ /**
59
+ * The version of the copy of `name` that create-astroid itself resolves. Rooted
60
+ * at `import.meta.url`, which is already the real path, so it sees the sibling
61
+ * packages pnpm places beside create-astroid rather than guessing at hoisting.
62
+ *
63
+ * @param {string} name
64
+ * @returns {string | undefined}
65
+ */
66
+ function installedVersion(name) {
67
+ const req = createRequire(import.meta.url);
68
+ // All three packages export `./package.json`, so this reads the real copy.
69
+ return JSON.parse(readFileSync(req.resolve(`${name}/package.json`), "utf8")).version;
70
+ }