create-astroid 0.2.0 → 0.3.0
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 -3
- package/package.json +3 -3
- package/template/scripts/seed-editors.mjs +2 -2
- package/template/src/auth.ts +14 -8
package/index.mjs
CHANGED
|
@@ -389,7 +389,11 @@ async function main() {
|
|
|
389
389
|
let authMigrationOk = false;
|
|
390
390
|
try {
|
|
391
391
|
const { generateAuthSchemaSql } = await import("louise-toolkit/auth");
|
|
392
|
-
|
|
392
|
+
// The EDITOR instance's tables — `louise_`-prefixed (the editor convention),
|
|
393
|
+
// leaving the unprefixed `user`/`session` names free for a second/portal
|
|
394
|
+
// instance. Must match the `tablePrefix` in src/auth.ts and the `louise_user`
|
|
395
|
+
// table the generated `editorsRoute` reads.
|
|
396
|
+
write(dir, "migrations/0001_auth.sql", generateAuthSchemaSql({ tablePrefix: "louise_" }));
|
|
393
397
|
// The portal's own auth tables. A SECOND set, prefixed — the two instances
|
|
394
398
|
// share one D1 but never a row, so a portal account can't sign into the
|
|
395
399
|
// studio and an editor doesn't appear in the portal. Without this migration
|
|
@@ -406,7 +410,7 @@ async function main() {
|
|
|
406
410
|
write(
|
|
407
411
|
dir,
|
|
408
412
|
"migrations/0001_auth.sql",
|
|
409
|
-
"-- Better Auth tables — generate after install:\n-- pnpm exec louise gen-auth-schema --out migrations/0001_auth.sql\n",
|
|
413
|
+
"-- Better Auth tables (editor, louise_ prefix) — generate after install:\n-- pnpm exec louise gen-auth-schema --table-prefix louise_ --out migrations/0001_auth.sql\n",
|
|
410
414
|
);
|
|
411
415
|
// Same stub for the portal's prefixed set. Without it a portal scaffold
|
|
412
416
|
// looks complete, builds, and fails on the first sign-in with a missing
|
|
@@ -441,7 +445,7 @@ async function main() {
|
|
|
441
445
|
: [
|
|
442
446
|
" # generate the Better Auth migration (it could not be written at scaffold",
|
|
443
447
|
" # time — `louise` is on your path once the install above finishes):",
|
|
444
|
-
" pnpm exec louise gen-auth-schema --out migrations/0001_auth.sql",
|
|
448
|
+
" pnpm exec louise gen-auth-schema --table-prefix louise_ --out migrations/0001_auth.sql",
|
|
445
449
|
...(config.portal?.enabled
|
|
446
450
|
? [
|
|
447
451
|
" pnpm exec louise gen-auth-schema --table-prefix portal_ \\",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-astroid",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
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",
|
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@better-auth/passkey": "^1.6.23",
|
|
34
34
|
"better-auth": "^1.6.23",
|
|
35
|
-
"
|
|
36
|
-
"
|
|
35
|
+
"louise-toolkit": "0.17.0",
|
|
36
|
+
"astroidjs": "0.3.0"
|
|
37
37
|
},
|
|
38
38
|
"engines": {
|
|
39
39
|
"node": ">=24.0.0"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// Seed the first editor(s) — an admin `
|
|
2
|
+
// Seed the first editor(s) — an admin `louise_user` row per OWNER_EMAIL / ENGINEER_EMAIL.
|
|
3
3
|
// A row here IS an editor and IS the magic-link allowlist, so this bootstraps
|
|
4
4
|
// access before anyone can sign in. Idempotent (INSERT OR IGNORE on unique email).
|
|
5
5
|
// After this, add more editors from the Users panel (never by editing env).
|
|
@@ -46,7 +46,7 @@ for (const email of emails) {
|
|
|
46
46
|
const id = randomUUID();
|
|
47
47
|
const name = email.split("@")[0];
|
|
48
48
|
const sql =
|
|
49
|
-
"INSERT OR IGNORE INTO
|
|
49
|
+
"INSERT OR IGNORE INTO louise_user " +
|
|
50
50
|
"(id, name, email, emailVerified, createdAt, updatedAt, role, firstName, lastName) VALUES " +
|
|
51
51
|
`(${q(id)}, ${q(name)}, ${q(email)}, 1, ${q(now)}, ${q(now)}, 'admin', NULL, NULL);`;
|
|
52
52
|
console.log(`Seeding editor ${email} (${target}) …`);
|
package/template/src/auth.ts
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
// The auth seam Astroid's generated worker.ts + middleware.ts import
|
|
2
2
|
// (`resolveEditor`), plus the Better Auth catch-all the /api/auth route calls.
|
|
3
3
|
//
|
|
4
|
-
// DB-managed editors: an admin `
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
4
|
+
// DB-managed editors: an admin `louise_user` row IS an editor. The editor
|
|
5
|
+
// instance's tables are `louise_`-prefixed (the editor convention), leaving the
|
|
6
|
+
// unprefixed `user`/`session` names free for a second/portal instance. That
|
|
7
|
+
// table is BOTH the role source and the magic-link allowlist — `resolveAdmins`
|
|
8
|
+
// reads it, so only an existing editor's email can request a sign-in link. Seed
|
|
9
|
+
// the first editor with `pnpm seed:editors`; add more from the Users panel
|
|
10
|
+
// (editorsRoute), never by editing env. Magic-link + passkey come from
|
|
11
|
+
// `getLouiseAuth`; no passwords.
|
|
9
12
|
|
|
10
13
|
import { astroidMailTheme, magicLinkEmail } from "astroidjs";
|
|
11
14
|
import { env } from "cloudflare:workers";
|
|
@@ -26,10 +29,10 @@ const BRAND = "__BRAND_NAME__";
|
|
|
26
29
|
// second argument to override any slot.
|
|
27
30
|
const MAIL_THEME = astroidMailTheme(astroidConfig);
|
|
28
31
|
|
|
29
|
-
/** The DB-managed editor allowlist: every admin `
|
|
32
|
+
/** The DB-managed editor allowlist: every admin `louise_user` row. */
|
|
30
33
|
async function resolveAdmins(): Promise<string[]> {
|
|
31
34
|
const { results } = await env.DB.prepare(
|
|
32
|
-
"SELECT email FROM
|
|
35
|
+
"SELECT email FROM louise_user WHERE role = 'admin'",
|
|
33
36
|
).all<{ email: string }>();
|
|
34
37
|
return results.map((r) => r.email);
|
|
35
38
|
}
|
|
@@ -39,13 +42,16 @@ function renderMagicLinkEmail({ url, toEmail }: { url: string; toEmail: string }
|
|
|
39
42
|
return magicLinkEmail(MAIL_THEME, { url, toEmail });
|
|
40
43
|
}
|
|
41
44
|
|
|
42
|
-
/** The request-scoped Better Auth instance (magic-link + passkey, DB allowlist).
|
|
45
|
+
/** The request-scoped Better Auth instance (magic-link + passkey, DB allowlist).
|
|
46
|
+
* `tablePrefix: "louise_"` namespaces the editor's Better Auth tables so a
|
|
47
|
+
* second (portal) instance can take the unprefixed `user`/`session` names. */
|
|
43
48
|
function getAuth(request: Request): Promise<LouiseAuth> {
|
|
44
49
|
return getLouiseAuth(env, new URL(request.url).origin, {
|
|
45
50
|
rpName: BRAND,
|
|
46
51
|
mailFrom: { email: env.MAIL_FROM, name: BRAND },
|
|
47
52
|
renderMagicLinkEmail,
|
|
48
53
|
resolveAdmins,
|
|
54
|
+
tablePrefix: "louise_",
|
|
49
55
|
});
|
|
50
56
|
}
|
|
51
57
|
|