create-astroid 0.7.2 → 0.7.4
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/index.mjs +7 -62
- package/package.json +6 -5
- package/toolkit-ranges.mjs +70 -0
- package/template/seed/home.seed.sql +0 -61
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";
|
|
@@ -23,6 +22,7 @@ import {
|
|
|
23
22
|
ASTROID_MAP_DEPENDENCIES,
|
|
24
23
|
defineAstroid,
|
|
25
24
|
generateAstroidEnvBindings,
|
|
25
|
+
generateAstroidHomeSeed,
|
|
26
26
|
generateAstroidPortalLocals,
|
|
27
27
|
generateAstroidProject,
|
|
28
28
|
generateAstroidCheckoutEnv,
|
|
@@ -31,6 +31,7 @@ import {
|
|
|
31
31
|
generateAstroidSecretsEnv,
|
|
32
32
|
generateAstroidWrangler,
|
|
33
33
|
} from "astroidjs";
|
|
34
|
+
import { toolkitRanges } from "./toolkit-ranges.mjs";
|
|
34
35
|
|
|
35
36
|
const TEMPLATE_DIR = join(dirname(fileURLToPath(import.meta.url)), "template");
|
|
36
37
|
|
|
@@ -86,67 +87,6 @@ const slugify = (s) =>
|
|
|
86
87
|
.replace(/^-+|-+$/g, "")
|
|
87
88
|
.slice(0, 40);
|
|
88
89
|
|
|
89
|
-
// --- toolkit versions ------------------------------------------------------
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* The `astroidjs` + `louise-toolkit` ranges to write into the scaffold.
|
|
93
|
-
*
|
|
94
|
-
* DERIVED from this package's own resolved dependencies rather than hard-coded
|
|
95
|
-
* in template/package.json. A literal there is a second place to remember on
|
|
96
|
-
* every release, and when it rots the failure is silent and total: the template
|
|
97
|
-
* imported `astroidjs/astro` while pinning `^0.1.0`, a range whose newest match
|
|
98
|
-
* had no such export, so every scaffolded project died before Astro loaded its
|
|
99
|
-
* config. CI could not see it—the clean-room smoke test pins both packages to
|
|
100
|
-
* tarballs via pnpm `overrides`, which is exactly what erases these ranges.
|
|
101
|
-
*
|
|
102
|
-
* Three shapes reach the `declared` value, and all three have to end up as one
|
|
103
|
-
* caret range:
|
|
104
|
-
*
|
|
105
|
-
* - `workspace:*`—a sibling in this repo (`astroidjs`). Falls back to the
|
|
106
|
-
* version of the copy actually resolved on disk, which is what the scaffold
|
|
107
|
-
* would install anyway. `pnpm pack` rewrites these to a concrete version, so
|
|
108
|
-
* a PUBLISHED create-astroid never carries one.
|
|
109
|
-
* - an exact version—what `pnpm pack` leaves behind for a former
|
|
110
|
-
* `workspace:*`.
|
|
111
|
-
* - an already-caretted range—what an external dependency is written as now
|
|
112
|
-
* that `louise-toolkit` and `@louise-toolkit/astro` live in another repo.
|
|
113
|
-
*
|
|
114
|
-
* That last one is why `stripRange` exists. Prefixing `^` onto `^0.27.0` yields
|
|
115
|
-
* `^^0.27.0`, which npm rejects as invalid, and every scaffolded project would
|
|
116
|
-
* fail at `pnpm install` before anything type-checked. It cost nothing to guard
|
|
117
|
-
* and would have been invisible until the first scaffold after the repo split.
|
|
118
|
-
*
|
|
119
|
-
* Caret on a 0.x is minor-locked (`^0.2.0` := `>=0.2.0 <0.3.0`), which is the
|
|
120
|
-
* behaviour we want while the toolkit is pre-1.0 and marks breaking changes as
|
|
121
|
-
* minors: patches flow, a breaking minor does not.
|
|
122
|
-
*/
|
|
123
|
-
/** `^1.2.3` / `~1.2.3` / `>=1.2.3` → `1.2.3`. See {@link toolkitRanges}. */
|
|
124
|
-
function stripRange(version) {
|
|
125
|
-
return String(version).replace(/^[\^~]|^>=\s*/, "");
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
function toolkitRanges() {
|
|
129
|
-
const req = createRequire(import.meta.url);
|
|
130
|
-
const self = JSON.parse(readFileSync(new URL("./package.json", import.meta.url), "utf8"));
|
|
131
|
-
const ranges = {};
|
|
132
|
-
for (const name of ["astroidjs", "louise-toolkit", "@louise-toolkit/astro"]) {
|
|
133
|
-
const declared = self.dependencies?.[name];
|
|
134
|
-
let version = declared && !declared.startsWith("workspace:") ? declared : undefined;
|
|
135
|
-
if (!version) {
|
|
136
|
-
// Both packages export `./package.json`, so this resolves the real copy.
|
|
137
|
-
version = JSON.parse(readFileSync(req.resolve(`${name}/package.json`), "utf8")).version;
|
|
138
|
-
}
|
|
139
|
-
if (!version) {
|
|
140
|
-
throw new Error(
|
|
141
|
-
`create-astroid could not determine the ${name} version to scaffold with. ` +
|
|
142
|
-
"This is a packaging fault — please file an issue rather than editing the scaffold by hand.",
|
|
143
|
-
);
|
|
144
|
-
}
|
|
145
|
-
ranges[name] = `^${stripRange(version)}`;
|
|
146
|
-
}
|
|
147
|
-
return ranges;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
90
|
async function prompt(question, fallback) {
|
|
151
91
|
if (!process.stdin.isTTY) return fallback;
|
|
152
92
|
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
@@ -446,6 +386,11 @@ async function main() {
|
|
|
446
386
|
for (const file of generateAstroidProject(config)) write(dir, file.path, file.contents);
|
|
447
387
|
write(dir, "wrangler.jsonc", generateAstroidWrangler(config));
|
|
448
388
|
|
|
389
|
+
// 3a. The home page seed, built from the config's own `sections`. It used to be
|
|
390
|
+
// a fixed template file that seeded the marketing sections for every
|
|
391
|
+
// archetype, and token substitution can't escape a brand name for SQL.
|
|
392
|
+
write(dir, "seed/home.seed.sql", generateAstroidHomeSeed(config));
|
|
393
|
+
|
|
449
394
|
// 3b. Every scaffold-once module file this config implies—the queue seam and
|
|
450
395
|
// webhook receivers, the portfolio gallery page, the PWA service worker +
|
|
451
396
|
// manifest + headers, the map tile route + embed, the portal's second auth
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-astroid",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.4",
|
|
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": {
|
|
@@ -31,10 +32,10 @@
|
|
|
31
32
|
},
|
|
32
33
|
"dependencies": {
|
|
33
34
|
"@better-auth/passkey": "^1.7.2",
|
|
34
|
-
"@louise-toolkit/astro": "^0.2.
|
|
35
|
+
"@louise-toolkit/astro": "^0.2.3",
|
|
35
36
|
"better-auth": "^1.7.2",
|
|
36
|
-
"louise-toolkit": "^0.31.
|
|
37
|
-
"astroidjs": "0.
|
|
37
|
+
"louise-toolkit": "^0.31.1",
|
|
38
|
+
"astroidjs": "0.14.0"
|
|
38
39
|
},
|
|
39
40
|
"engines": {
|
|
40
41
|
"node": ">=26.0.0"
|
|
@@ -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
|
+
}
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
-- Seed the editable home page (slug `home`) that src/pages/index.astro renders.
|
|
2
|
-
-- Idempotent. Apply once after migrations:
|
|
3
|
-
-- wrangler d1 execute DB --file seed/home.seed.sql --remote
|
|
4
|
-
-- (drop --remote for the local dev D1)
|
|
5
|
-
--
|
|
6
|
-
-- `sections` is the page-builder array — the same shape the on-canvas editor
|
|
7
|
-
-- reads and the server validates against the section catalog on write. Each item
|
|
8
|
-
-- is `{"_type": …, …fields, "_settings": {…}}`, and `_settings` holds TOKENS
|
|
9
|
-
-- (colorway/align), never CSS, so a re-theme needs no content change.
|
|
10
|
-
--
|
|
11
|
-
-- Seeding it is deliberate: an empty array renders an empty page, and a blank
|
|
12
|
-
-- canvas is a worse first run than having something real to click on and edit.
|
|
13
|
-
--
|
|
14
|
-
-- Full-text search (the editor's Pages search) is kept in sync on PUBLISH, so a
|
|
15
|
-
-- row inserted with raw SQL like this is NOT in the index until you either
|
|
16
|
-
-- publish an edit to it or backfill once with `POST /api/louise/pages/reindex`
|
|
17
|
-
-- (signed in). The page renders fine either way — only in-editor search is
|
|
18
|
-
-- affected.
|
|
19
|
-
--
|
|
20
|
-
-- To override just the <head> title/description (not the on-page H1), add
|
|
21
|
-
-- `seo_title` / `seo_description` columns below. `seo_title` is run through the
|
|
22
|
-
-- config's title template, which already appends the brand — so set the page
|
|
23
|
-
-- part only ("Pricing"), not "Pricing | __BRAND_NAME__".
|
|
24
|
-
INSERT OR IGNORE INTO pages (slug, title, body, sections, status, sort_order, created_at, updated_at)
|
|
25
|
-
VALUES (
|
|
26
|
-
'home',
|
|
27
|
-
'__BRAND_NAME__',
|
|
28
|
-
'<p>Welcome to __BRAND_NAME__. Sign in at <code>/login</code>, switch on edit mode, and change this text in place — then hit Publish.</p>',
|
|
29
|
-
json_array(
|
|
30
|
-
json_object(
|
|
31
|
-
'_type', 'hero',
|
|
32
|
-
'heading', '__BRAND_NAME__',
|
|
33
|
-
'subheading', 'Edit this in place — sign in, switch on edit mode, and type.',
|
|
34
|
-
'ctaLabel', 'Get in touch',
|
|
35
|
-
'ctaHref', '/contact',
|
|
36
|
-
'_settings', json_object('colorway', 'base', 'align', 'center')
|
|
37
|
-
),
|
|
38
|
-
json_object(
|
|
39
|
-
'_type', 'featureGrid',
|
|
40
|
-
'heading', 'What we do',
|
|
41
|
-
'items', json_array(
|
|
42
|
-
json_object('title', 'First thing', 'body', 'Describe it here.'),
|
|
43
|
-
json_object('title', 'Second thing', 'body', 'And this one.'),
|
|
44
|
-
json_object('title', 'Third thing', 'body', 'And this one too.')
|
|
45
|
-
),
|
|
46
|
-
'_settings', json_object('colorway', 'base')
|
|
47
|
-
),
|
|
48
|
-
json_object(
|
|
49
|
-
'_type', 'cta',
|
|
50
|
-
'heading', 'Ready when you are',
|
|
51
|
-
'body', 'Swap this copy for your own.',
|
|
52
|
-
'ctaLabel', 'Contact us',
|
|
53
|
-
'ctaHref', '/contact',
|
|
54
|
-
'_settings', json_object('colorway', 'brand', 'align', 'center')
|
|
55
|
-
)
|
|
56
|
-
),
|
|
57
|
-
'published',
|
|
58
|
-
0,
|
|
59
|
-
unixepoch(),
|
|
60
|
-
unixepoch()
|
|
61
|
-
);
|