create-astroid 0.3.1 → 0.3.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.
- package/index.mjs +22 -8
- package/package.json +4 -4
- package/template/README.md +14 -0
- package/template/_github/workflows/ci.yml +54 -0
- package/template/package.json +2 -1
package/index.mjs
CHANGED
|
@@ -34,9 +34,15 @@ import {
|
|
|
34
34
|
|
|
35
35
|
const TEMPLATE_DIR = join(dirname(fileURLToPath(import.meta.url)), "template");
|
|
36
36
|
|
|
37
|
-
// Files whose leading `_` is stripped on copy (npm strips real
|
|
38
|
-
// published package, so they ship as `_gitignore` /
|
|
39
|
-
|
|
37
|
+
// Files (and dirs) whose leading `_` is stripped on copy (npm strips real
|
|
38
|
+
// dotfiles from a published package, so they ship as `_gitignore` /
|
|
39
|
+
// `_env.example` / `_github/…`). Applied per entry in `copyTemplate`, so a
|
|
40
|
+
// directory renames too — `_github` becomes `.github` and its contents follow.
|
|
41
|
+
const DOTFILE_RENAMES = {
|
|
42
|
+
_gitignore: ".gitignore",
|
|
43
|
+
"_env.example": ".env.example",
|
|
44
|
+
_github: ".github",
|
|
45
|
+
};
|
|
40
46
|
|
|
41
47
|
// Archetype → default editable home sections. Imported from astroidjs rather
|
|
42
48
|
// than duplicated here: as a literal in this file it could name a section that
|
|
@@ -68,7 +74,12 @@ function parseArgs(argv) {
|
|
|
68
74
|
}
|
|
69
75
|
|
|
70
76
|
const slugify = (s) =>
|
|
71
|
-
s
|
|
77
|
+
s
|
|
78
|
+
.trim()
|
|
79
|
+
.toLowerCase()
|
|
80
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
81
|
+
.replace(/^-+|-+$/g, "")
|
|
82
|
+
.slice(0, 40);
|
|
72
83
|
|
|
73
84
|
// --- toolkit versions ------------------------------------------------------
|
|
74
85
|
|
|
@@ -252,17 +263,20 @@ async function main() {
|
|
|
252
263
|
const dirArg = positionals[0] ?? flags.dir;
|
|
253
264
|
const rawName = flags.name || (dirArg ? basename(resolve(dirArg)) : undefined);
|
|
254
265
|
const name = await prompt("Brand / site name", rawName || "My Astroid Site");
|
|
255
|
-
const key = slugify(
|
|
266
|
+
const key = slugify(
|
|
267
|
+
flags.key || (await prompt("Project key (slug)", slugify(name) || "my-site")),
|
|
268
|
+
);
|
|
256
269
|
const dir = resolve(dirArg || (await prompt("Directory", key)) || key);
|
|
257
|
-
const archetypeRaw = (
|
|
270
|
+
const archetypeRaw = (
|
|
271
|
+
flags.archetype || (await prompt(`Archetype (${ARCHETYPES.join("/")})`, "marketing"))
|
|
272
|
+
).toLowerCase();
|
|
258
273
|
const archetype = ARCHETYPES.includes(archetypeRaw) ? archetypeRaw : "marketing";
|
|
259
274
|
const color = flags.color || (await prompt("Brand color (hex)", "#5b4bff"));
|
|
260
275
|
const host = flags.host && flags.host !== true ? flags.host : undefined;
|
|
261
276
|
// The customer PORTAL is opt-in via --portal, but a storefront IMPLIES one — a
|
|
262
277
|
// shop has customers who sign in, reorder, and track orders — so enable it there
|
|
263
278
|
// by default. (Commerce below stays opt-in: infra a marketing site shouldn't carry.)
|
|
264
|
-
const portal =
|
|
265
|
-
flags.portal === true || flags.portal === "true" || archetype === "storefront";
|
|
279
|
+
const portal = flags.portal === true || flags.portal === "true" || archetype === "storefront";
|
|
266
280
|
// The map module is opt-in and pulls real weight (maplibre-gl is ~1 MB), so
|
|
267
281
|
// it is never on by default.
|
|
268
282
|
const map = flags.map === true || flags.map === "true";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-astroid",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
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",
|
|
@@ -18,7 +18,6 @@
|
|
|
18
18
|
"url": "git+https://github.com/bowenlabs/louise-toolkit.git",
|
|
19
19
|
"directory": "packages/create-astroid"
|
|
20
20
|
},
|
|
21
|
-
"type": "module",
|
|
22
21
|
"bin": {
|
|
23
22
|
"create-astroid": "./index.mjs"
|
|
24
23
|
},
|
|
@@ -26,14 +25,15 @@
|
|
|
26
25
|
"index.mjs",
|
|
27
26
|
"template"
|
|
28
27
|
],
|
|
28
|
+
"type": "module",
|
|
29
29
|
"publishConfig": {
|
|
30
30
|
"access": "public"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@better-auth/passkey": "^1.6.23",
|
|
34
34
|
"better-auth": "^1.6.23",
|
|
35
|
-
"
|
|
36
|
-
"
|
|
35
|
+
"louise-toolkit": "0.19.0",
|
|
36
|
+
"astroidjs": "0.4.0"
|
|
37
37
|
},
|
|
38
38
|
"engines": {
|
|
39
39
|
"node": ">=24.0.0"
|
package/template/README.md
CHANGED
|
@@ -103,6 +103,20 @@ pnpm doctor # validate config, bindings, and generated-file freshness
|
|
|
103
103
|
wrangler deploy # or: pnpm astroid deploy
|
|
104
104
|
```
|
|
105
105
|
|
|
106
|
+
## Taking payments
|
|
107
|
+
|
|
108
|
+
Storefront sites (`--commerce square`) are scaffolded with a server-authoritative
|
|
109
|
+
payment route at `src/pages/api/checkout.ts` and a `<SquareCard>` input. **Keep
|
|
110
|
+
its sequence** — extend it (shipping, tax, an order row, a receipt), don't replace
|
|
111
|
+
it. It re-prices every line from the D1 catalog mirror (the client's price is a
|
|
112
|
+
_staleness check_, never an input to the charge — accept a `unitPrice` from the
|
|
113
|
+
request body and anyone buys anything for a penny) and derives the Square
|
|
114
|
+
idempotency key from the verified cart **and** the cart id. Hand-rolling
|
|
115
|
+
`createPayment` without a stable, cart-scoped idempotency key is the failure this
|
|
116
|
+
route exists to prevent: a double-clicked Pay button charges twice, and a
|
|
117
|
+
constant (or omitted) key lets two customers' identical carts collide into a
|
|
118
|
+
single charge.
|
|
119
|
+
|
|
106
120
|
## Layout
|
|
107
121
|
|
|
108
122
|
| Path | What |
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
# Cancel superseded runs on the same ref (a force-push mid-run).
|
|
9
|
+
concurrency:
|
|
10
|
+
group: ci-${{ github.ref }}
|
|
11
|
+
cancel-in-progress: true
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
build:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
env:
|
|
17
|
+
# corepack pins pnpm from `packageManager` in package.json; in CI it must
|
|
18
|
+
# fetch that version without an interactive prompt.
|
|
19
|
+
COREPACK_ENABLE_DOWNLOAD_PROMPT: 0
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v4
|
|
22
|
+
|
|
23
|
+
- uses: actions/setup-node@v4
|
|
24
|
+
with:
|
|
25
|
+
node-version: 24
|
|
26
|
+
|
|
27
|
+
# pnpm via corepack, pinned by `packageManager` — the same version you
|
|
28
|
+
# develop with, so `--frozen-lockfile` below always matches the committed
|
|
29
|
+
# pnpm-lock.yaml. (Commit that lockfile; this step relies on it.)
|
|
30
|
+
- name: Enable pnpm (corepack)
|
|
31
|
+
run: corepack enable
|
|
32
|
+
|
|
33
|
+
- name: Install
|
|
34
|
+
run: pnpm install --frozen-lockfile
|
|
35
|
+
|
|
36
|
+
# Validate the config, bindings, and that the generated
|
|
37
|
+
# src/schema.ts · src/worker.ts · src/middleware.ts trio is still in sync
|
|
38
|
+
# with astroid.config.ts. A fast fail before the heavier steps.
|
|
39
|
+
- name: Doctor
|
|
40
|
+
run: pnpm doctor
|
|
41
|
+
|
|
42
|
+
# No-ops on a fresh scaffold; runs automatically once you add a `lint`
|
|
43
|
+
# script (oxlint/biome) — same for `test` (vitest) further down.
|
|
44
|
+
- name: Lint
|
|
45
|
+
run: pnpm run --if-present lint
|
|
46
|
+
|
|
47
|
+
- name: Type-check
|
|
48
|
+
run: pnpm check
|
|
49
|
+
|
|
50
|
+
- name: Test
|
|
51
|
+
run: pnpm run --if-present test
|
|
52
|
+
|
|
53
|
+
- name: Build
|
|
54
|
+
run: pnpm build
|