astroidjs 0.12.1 → 0.14.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.
Files changed (136) hide show
  1. package/README.md +42 -42
  2. package/bin/astroid.mjs +35 -29
  3. package/dist/analytics/index.d.ts +3 -3
  4. package/dist/analytics/index.js +11 -11
  5. package/dist/astro/csp.d.ts +5 -5
  6. package/dist/astro/csp.js +6 -6
  7. package/dist/astro/index.js +1 -1
  8. package/dist/auth/index.d.ts +2 -2
  9. package/dist/auth/index.js +5 -5
  10. package/dist/commerce/adapters.d.ts +6 -6
  11. package/dist/commerce/adapters.js +9 -9
  12. package/dist/commerce/checkout-scaffold.d.ts +5 -5
  13. package/dist/commerce/checkout-scaffold.js +27 -27
  14. package/dist/commerce/checkout.d.ts +12 -12
  15. package/dist/commerce/checkout.js +7 -7
  16. package/dist/commerce/loader.d.ts +2 -2
  17. package/dist/commerce/loader.js +3 -3
  18. package/dist/commerce/mirror.d.ts +4 -4
  19. package/dist/commerce/mirror.js +12 -12
  20. package/dist/commerce/roles.d.ts +10 -10
  21. package/dist/commerce/roles.js +13 -13
  22. package/dist/commerce/secrets.d.ts +9 -9
  23. package/dist/commerce/secrets.js +9 -9
  24. package/dist/commerce/sync.d.ts +7 -7
  25. package/dist/commerce/sync.js +5 -5
  26. package/dist/components/sections.d.ts +9 -9
  27. package/dist/components/sections.js +12 -12
  28. package/dist/config.d.ts +89 -62
  29. package/dist/config.js +18 -18
  30. package/dist/email/inquiry.d.ts +2 -2
  31. package/dist/email/inquiry.js +1 -1
  32. package/dist/email/send.d.ts +4 -4
  33. package/dist/email/send.js +7 -7
  34. package/dist/email/templates.js +3 -3
  35. package/dist/email/theme.d.ts +1 -1
  36. package/dist/email/theme.js +4 -4
  37. package/dist/errors.d.ts +1 -1
  38. package/dist/errors.js +1 -1
  39. package/dist/index.js +1 -1
  40. package/dist/map/pmtiles.d.ts +5 -5
  41. package/dist/map/pmtiles.js +5 -5
  42. package/dist/map/scaffold.d.ts +2 -2
  43. package/dist/map/scaffold.js +8 -8
  44. package/dist/map/style.d.ts +4 -4
  45. package/dist/map/style.js +1 -1
  46. package/dist/portal/config.d.ts +3 -3
  47. package/dist/portal/config.js +11 -10
  48. package/dist/portal/guard.d.ts +4 -4
  49. package/dist/portal/guard.js +4 -4
  50. package/dist/portal/nav.js +2 -2
  51. package/dist/portal/scaffold.d.ts +4 -4
  52. package/dist/portal/scaffold.js +13 -13
  53. package/dist/portal/session.d.ts +11 -5
  54. package/dist/portal/session.js +10 -5
  55. package/dist/portfolio/scaffold.d.ts +1 -1
  56. package/dist/portfolio/scaffold.js +8 -8
  57. package/dist/project/actions.d.ts +1 -1
  58. package/dist/project/actions.js +18 -12
  59. package/dist/project/generate.d.ts +4 -4
  60. package/dist/project/generate.js +26 -26
  61. package/dist/project/index.d.ts +1 -0
  62. package/dist/project/index.js +2 -1
  63. package/dist/project/scaffold.d.ts +2 -2
  64. package/dist/project/scaffold.js +69 -13
  65. package/dist/project/seed.d.ts +22 -0
  66. package/dist/project/seed.js +214 -0
  67. package/dist/pwa/generate.d.ts +11 -11
  68. package/dist/pwa/generate.js +19 -19
  69. package/dist/queues/consumer.d.ts +3 -3
  70. package/dist/queues/consumer.js +2 -2
  71. package/dist/queues/messages.d.ts +4 -4
  72. package/dist/queues/messages.js +2 -2
  73. package/dist/queues/scaffold.d.ts +4 -4
  74. package/dist/queues/scaffold.js +17 -17
  75. package/dist/queues/webhook.d.ts +5 -5
  76. package/dist/queues/webhook.js +3 -3
  77. package/dist/realtime/scaffold.d.ts +4 -4
  78. package/dist/realtime/scaffold.js +12 -12
  79. package/dist/schema/collections.d.ts +42 -11
  80. package/dist/schema/collections.js +43 -42
  81. package/dist/schema/framework.d.ts +1 -1
  82. package/dist/schema/framework.js +2 -2
  83. package/dist/schema/generate.js +6 -6
  84. package/dist/schema/index.js +1 -1
  85. package/dist/secrets.d.ts +6 -6
  86. package/dist/secrets.js +6 -6
  87. package/dist/security/csp-origins.d.ts +1 -1
  88. package/dist/security/csp-origins.js +3 -3
  89. package/dist/security/rate-rules.d.ts +2 -2
  90. package/dist/security/rate-rules.js +8 -8
  91. package/dist/seo/resolve.d.ts +5 -5
  92. package/dist/seo/resolve.js +2 -2
  93. package/dist/seo/routes.d.ts +5 -5
  94. package/dist/seo/routes.js +3 -3
  95. package/dist/seo/structured-data.d.ts +6 -6
  96. package/dist/seo/structured-data.js +7 -7
  97. package/dist/status.d.ts +5 -5
  98. package/dist/status.js +7 -7
  99. package/dist/tenancy/index.d.ts +3 -3
  100. package/dist/tenancy/index.js +11 -11
  101. package/dist/worker/generate.d.ts +2 -2
  102. package/dist/worker/generate.js +91 -57
  103. package/dist/worker/index.js +1 -1
  104. package/dist/worker/routes.js +11 -11
  105. package/dist/workflow/advance.d.ts +3 -3
  106. package/dist/workflow/advance.js +6 -6
  107. package/dist/workflow/config.d.ts +4 -4
  108. package/dist/workflow/config.js +4 -4
  109. package/dist/workflow/generate.d.ts +2 -2
  110. package/dist/workflow/generate.js +11 -11
  111. package/package.json +3 -4
  112. package/src/components/Collection.tsx +5 -5
  113. package/src/components/Editable.astro +9 -9
  114. package/src/components/JustifiedGallery.astro +8 -8
  115. package/src/components/MediaSlot.astro +12 -12
  116. package/src/components/PortalShell.astro +4 -4
  117. package/src/components/RegisterSW.astro +3 -3
  118. package/src/components/Section.astro +8 -8
  119. package/src/components/Sections.astro +6 -6
  120. package/src/components/Seo.astro +3 -3
  121. package/src/components/StageBar.astro +3 -3
  122. package/src/components/StructuredData.astro +2 -2
  123. package/src/components/justify.ts +9 -9
  124. package/src/components/media-meta.ts +10 -10
  125. package/src/components/sections/AboutIntro.astro +1 -1
  126. package/src/components/sections/Contact.astro +1 -1
  127. package/src/components/sections/Cta.astro +1 -1
  128. package/src/components/sections/Faq.astro +1 -1
  129. package/src/components/sections/FeatureGrid.astro +2 -2
  130. package/src/components/sections/Hero.astro +1 -1
  131. package/src/components/sections/PricingTiers.astro +1 -1
  132. package/src/components/sections/ProductGrid.astro +1 -1
  133. package/src/components/sections/SplitImage.astro +1 -1
  134. package/src/components/sections/Steps.astro +1 -1
  135. package/src/components/sections/Testimonial.astro +1 -1
  136. package/src/components/sections.ts +17 -17
@@ -1,17 +1,17 @@
1
1
  // Copyright (c) 2026 BowenLabs. Astroid is MIT licensed.
2
2
  //
3
- // JSON-LD structured data — the `@graph` that describes the business to rich
3
+ // JSON-LD structured data—the `@graph` that describes the business to rich
4
4
  // results and AI answer surfaces.
5
5
  //
6
6
  // Everything here is generic except the business `@type`, which is the one thing
7
- // that genuinely differs per site — so it comes from the archetype, with a
7
+ // that genuinely differs per site—so it comes from the archetype, with a
8
8
  // config escape hatch for the many cases where schema.org has a more specific
9
9
  // subtype (a coffee shop is a `CafeOrCoffeeShop`, not a bare `Store`).
10
10
  /**
11
11
  * The schema.org `@type` each archetype describes its owner with. These are
12
12
  * intentionally the broad parent types: pick a subtype (`CafeOrCoffeeShop`,
13
13
  * `ArtGallery`, `HomeAndConstructionBusiness`) via `seo.businessType` when you
14
- * know one — a more specific type is strictly better for rich results.
14
+ * know one—a more specific type is strictly better for rich results.
15
15
  */
16
16
  export const ARCHETYPE_BUSINESS_TYPE = {
17
17
  marketing: "Organization",
@@ -49,8 +49,8 @@ function sameAs(links) {
49
49
  * Build the JSON-LD `@graph` for a page: the business node, a `WebSite` node,
50
50
  * and the page's own entity when there is one.
51
51
  *
52
- * The business gets a stable `@id` (`<origin>/#business`) so other nodes — a
53
- * product's `seller`, a future `Article` author — can reference it by id
52
+ * The business gets a stable `@id` (`<origin>/#business`) so other nodes—a
53
+ * product's `seller`, a future `Article` author—can reference it by id
54
54
  * instead of restating it.
55
55
  */
56
56
  export function astroidStructuredData(input) {
@@ -91,8 +91,8 @@ export function astroidStructuredData(input) {
91
91
  *
92
92
  * `application/ld+json` is data, not executable script, so `script-src` doesn't
93
93
  * govern it and no CSP hash is needed. But `JSON.stringify` does **not** escape
94
- * `<`, so any value folded into the graph that contains a literal `</script>` —
95
- * a product description, an artist statement, anything editor-authored — would
94
+ * `<`, so any value folded into the graph that contains a literal `</script>`—a
95
+ * product description, an artist statement, anything editor-authored—would
96
96
  * close the tag early and inject markup straight into `<head>`. Escaping the
97
97
  * HTML-significant characters as `\uXXXX` keeps the payload valid JSON while
98
98
  * making it impossible to break out of the element.
package/dist/status.d.ts CHANGED
@@ -4,7 +4,7 @@ import type { SecretSource } from "./secrets.js";
4
4
  /**
5
5
  * Secrets every Astroid site has, independent of which modules are on.
6
6
  *
7
- * `SESSION_SECRET` is here but is NOT a dormancy gate — it fails closed off
7
+ * `SESSION_SECRET` is here but is NOT a dormancy gate—it fails closed off
8
8
  * localhost (see `getSessionSecret`), because an unsigned session isn't a
9
9
  * feature to switch off. It's listed so the scaffold seeds and types it.
10
10
  */
@@ -19,7 +19,7 @@ export interface AstroidModuleReport {
19
19
  configured: boolean;
20
20
  /** Unprovisioned secret/binding names, in declaration order. */
21
21
  missing: string[];
22
- /** What the module does in this state — the sentence a banner prints. */
22
+ /** What the module does in this state—the sentence a banner prints. */
23
23
  detail: string;
24
24
  }
25
25
  /**
@@ -27,7 +27,7 @@ export interface AstroidModuleReport {
27
27
  *
28
28
  * The scaffold uses this twice: to seed `.dev.vars`/`.env.example` with the
29
29
  * placeholder sentinel, and to type the matching `CloudflareEnv` members. A
30
- * module that isn't enabled contributes nothing — a declaration is a promise,
30
+ * module that isn't enabled contributes nothing—a declaration is a promise,
31
31
  * and a marketing site shouldn't be told to provision a Square token.
32
32
  */
33
33
  export declare function astroidSecretNames(config: AstroidConfig): Record<string, string[]>;
@@ -45,7 +45,7 @@ export type AstroidStatusEnv = MailerEnv & Record<string, SecretSource | unknown
45
45
  export declare function astroidModuleStatus(config: AstroidConfig, env: AstroidStatusEnv): Promise<AstroidModuleReport[]>;
46
46
  /**
47
47
  * The report as a printable block. One line per module, missing names spelled
48
- * out — "commerce is off" sends someone reading source; "commerce is dormant —
49
- * set SQUARE_ACCESS_TOKEN" does not.
48
+ * out—"commerce is off" sends someone reading source; "commerce is dormant—set
49
+ * SQUARE_ACCESS_TOKEN" does not.
50
50
  */
51
51
  export declare function describeAstroidStatus(reports: AstroidModuleReport[]): string;
package/dist/status.js CHANGED
@@ -1,12 +1,12 @@
1
1
  // Copyright (c) 2026 BowenLabs. Astroid is MIT licensed.
2
2
  //
3
- // The module status report — "what is actually switched on right now".
3
+ // The module status report—"what is actually switched on right now".
4
4
  //
5
5
  // `secrets.ts` gives one module its gate. This composes every enabled module's
6
6
  // gate into one answer, which is what the dormant-until-provisioned convention
7
7
  // needs to be usable rather than merely available: a fresh scaffold boots with
8
8
  // nothing provisioned, and the failure mode that convention exists to avoid is
9
- // not a crash — it's a developer wondering for twenty minutes why the contact
9
+ // not a crash—it's a developer wondering for twenty minutes why the contact
10
10
  // form "works" but no mail arrives.
11
11
  //
12
12
  // So the deal is: dormant is fine, dormant AND SILENT is not. Two consumers of
@@ -22,7 +22,7 @@ import { EMAIL_SECRET_NAMES, resolveMailerStatus } from "./email/send.js";
22
22
  /**
23
23
  * Secrets every Astroid site has, independent of which modules are on.
24
24
  *
25
- * `SESSION_SECRET` is here but is NOT a dormancy gate — it fails closed off
25
+ * `SESSION_SECRET` is here but is NOT a dormancy gate—it fails closed off
26
26
  * localhost (see `getSessionSecret`), because an unsigned session isn't a
27
27
  * feature to switch off. It's listed so the scaffold seeds and types it.
28
28
  */
@@ -36,7 +36,7 @@ export const ASTROID_CORE_SECRET_NAMES = [
36
36
  *
37
37
  * The scaffold uses this twice: to seed `.dev.vars`/`.env.example` with the
38
38
  * placeholder sentinel, and to type the matching `CloudflareEnv` members. A
39
- * module that isn't enabled contributes nothing — a declaration is a promise,
39
+ * module that isn't enabled contributes nothing—a declaration is a promise,
40
40
  * and a marketing site shouldn't be told to provision a Square token.
41
41
  */
42
42
  export function astroidSecretNames(config) {
@@ -47,7 +47,7 @@ export function astroidSecretNames(config) {
47
47
  const commerce = commerceSecretNames(config.commerce);
48
48
  if (commerce.length > 0)
49
49
  groups.commerce = commerce;
50
- // The CWV read-back's API credentials. Collection needs none of this — only
50
+ // The CWV read-back's API credentials. Collection needs none of this—only
51
51
  // querying the p75 back out does, because the Analytics Engine SQL API is
52
52
  // account-scoped and has no binding.
53
53
  groups.vitals = [...ASTROID_VITALS_SECRET_NAMES];
@@ -96,8 +96,8 @@ export async function astroidModuleStatus(config, env) {
96
96
  }
97
97
  /**
98
98
  * The report as a printable block. One line per module, missing names spelled
99
- * out — "commerce is off" sends someone reading source; "commerce is dormant —
100
- * set SQUARE_ACCESS_TOKEN" does not.
99
+ * out—"commerce is off" sends someone reading source; "commerce is dormant—set
100
+ * SQUARE_ACCESS_TOKEN" does not.
101
101
  */
102
102
  export function describeAstroidStatus(reports) {
103
103
  if (reports.length === 0)
@@ -30,7 +30,7 @@ export declare function tenancyZone(tenancy: TenancyConfig): string;
30
30
  *
31
31
  * `null` covers four distinct cases that all mean "not a tenant": the apex
32
32
  * itself (a wildcard does not match its own apex), a host outside the pattern
33
- * (a preview domain, `localhost`), a reserved label, and an app label — which
33
+ * (a preview domain, `localhost`), a reserved label, and an app label—which
34
34
  * has its own static rewrite via {@link appPrefix} instead of a lookup.
35
35
  *
36
36
  * Exported and pure so a site can unit-test its own reserved list without
@@ -39,7 +39,7 @@ export declare function tenancyZone(tenancy: TenancyConfig): string;
39
39
  export declare function tenantLabel(host: string, tenancy: TenancyConfig): string | null;
40
40
  /**
41
41
  * The internal path prefix an app host rewrites to, or `null` when the host is
42
- * not an app host — `appPrefix("studio.example.com", …)` → `"/studio"` under
42
+ * not an app host—`appPrefix("studio.example.com", …)` → `"/studio"` under
43
43
  * `apps: { studio: "/studio" }`.
44
44
  *
45
45
  * Static by design: an app exists whether or not any tenant does, so there is
@@ -49,7 +49,7 @@ export declare function tenantLabel(host: string, tenancy: TenancyConfig): strin
49
49
  */
50
50
  export declare function appPrefix(host: string, tenancy: TenancyConfig): string | null;
51
51
  /**
52
- * The scaffold-once `src/tenancy.ts` — the seam holding every decision Astroid
52
+ * The scaffold-once `src/tenancy.ts`—the seam holding every decision Astroid
53
53
  * refuses to make for a site.
54
54
  *
55
55
  * Written once and then yours: what a label resolves to, whether the lookup is
@@ -3,7 +3,7 @@
3
3
  // Wildcard host dispatch: the parts that are the same for every site, and
4
4
  // nothing that decides anything.
5
5
  //
6
- // Astroid owns two things a site cannot own on its own — the wildcard Worker
6
+ // Astroid owns two things a site cannot own on its own—the wildcard Worker
7
7
  // route (`hosts` can only express custom domains) and the single middleware file
8
8
  // Astro permits. What a subdomain MEANS, whether the lookup is cached, and what
9
9
  // an unknown host should do are all site policy, and live in the scaffolded
@@ -38,7 +38,7 @@ export function tenancyZone(tenancy) {
38
38
  return tenancy.zone ?? tenancy.hostPattern.replace(/^\*\./, "");
39
39
  }
40
40
  /**
41
- * The single subdomain label under the wildcard, before any policy — or `null`
41
+ * The single subdomain label under the wildcard, before any policy—or `null`
42
42
  * for the apex, an off-pattern host, or a dotted label. Shared by
43
43
  * {@link tenantLabel} and {@link appPrefix} so their host handling (port,
44
44
  * case, one-level-only) cannot drift.
@@ -51,7 +51,7 @@ function hostLabel(host, tenancy) {
51
51
  return null;
52
52
  const label = hostname.slice(0, -(suffix.length + 1));
53
53
  // Only a single label counts. `a.b.example.com` under `*.example.com` is
54
- // not `a.b` — Cloudflare's wildcard matches one level, and treating a dotted
54
+ // not `a.b`—Cloudflare's wildcard matches one level, and treating a dotted
55
55
  // string as a slug would put a `/` in a rewrite path.
56
56
  if (!label || label.includes("."))
57
57
  return null;
@@ -63,7 +63,7 @@ function hostLabel(host, tenancy) {
63
63
  *
64
64
  * `null` covers four distinct cases that all mean "not a tenant": the apex
65
65
  * itself (a wildcard does not match its own apex), a host outside the pattern
66
- * (a preview domain, `localhost`), a reserved label, and an app label — which
66
+ * (a preview domain, `localhost`), a reserved label, and an app label—which
67
67
  * has its own static rewrite via {@link appPrefix} instead of a lookup.
68
68
  *
69
69
  * Exported and pure so a site can unit-test its own reserved list without
@@ -79,7 +79,7 @@ export function tenantLabel(host, tenancy) {
79
79
  }
80
80
  /**
81
81
  * The internal path prefix an app host rewrites to, or `null` when the host is
82
- * not an app host — `appPrefix("studio.example.com", …)` → `"/studio"` under
82
+ * not an app host—`appPrefix("studio.example.com", …)` → `"/studio"` under
83
83
  * `apps: { studio: "/studio" }`.
84
84
  *
85
85
  * Static by design: an app exists whether or not any tenant does, so there is
@@ -95,7 +95,7 @@ export function appPrefix(host, tenancy) {
95
95
  return label ? (apps[label] ?? null) : null;
96
96
  }
97
97
  /**
98
- * The scaffold-once `src/tenancy.ts` — the seam holding every decision Astroid
98
+ * The scaffold-once `src/tenancy.ts`—the seam holding every decision Astroid
99
99
  * refuses to make for a site.
100
100
  *
101
101
  * Written once and then yours: what a label resolves to, whether the lookup is
@@ -110,7 +110,7 @@ export function generateAstroidTenancy(config) {
110
110
  const prefix = tenancy.rewritePrefix ?? ASTROID_TENANT_PREFIX;
111
111
  const example = (tenancy.hostPattern ?? "*.example.com").replace(/^\*\./, "");
112
112
  return [
113
- "// Scaffolded once by astroidjs — yours to edit.",
113
+ "// Scaffolded once by astroidjs—yours to edit.",
114
114
  "//",
115
115
  "// What a subdomain MEANS. The generated middleware has already decided this",
116
116
  "// host is a tenant candidate (it matches your wildcard and is not reserved);",
@@ -128,17 +128,17 @@ export function generateAstroidTenancy(config) {
128
128
  "/**",
129
129
  " * Resolve a subdomain label to a tenant, or `null` if there isn't one.",
130
130
  " *",
131
- " * `null` falls through to the ordinary site — which is a real choice, not a",
131
+ " * `null` falls through to the ordinary site—which is a real choice, not a",
132
132
  " * default: a stranger's subdomain then renders your homepage. If that is wrong",
133
133
  ' * for this project, set `tenancy.unknown: "404"` in astroid.config.ts and the',
134
- " * generated middleware refuses the host instead — unambiguously not a page.",
134
+ " * generated middleware refuses the host instead—unambiguously not a page.",
135
135
  " *",
136
136
  " * This runs on EVERY request to a tenant host, so a database lookup here is a",
137
- " * query per request. Cache it — a module-scope Map is enough within an isolate,",
137
+ " * query per request. Cache it—a module-scope Map is enough within an isolate,",
138
138
  " * KV if the tenant set is large or changes without a deploy.",
139
139
  " */",
140
140
  "export async function resolveTenant(label: string): Promise<Tenant | null> {",
141
- ` // TODO(astroid): look \`label\` up — a D1 table, a KV entry, or a literal map`,
141
+ ` // TODO(astroid): look \`label\` up—a D1 table, a KV entry, or a literal map`,
142
142
  ` // while the set is small. Example: acme.${example} → { slug: "acme" }.`,
143
143
  " return { slug: label };",
144
144
  "}",
@@ -14,7 +14,7 @@ export declare function generateAstroidWorker(config: AstroidConfig): string;
14
14
  * session + sticky `?louise` edit mode → content-freshness + security headers) via
15
15
  * `createLouiseMiddleware`.
16
16
  *
17
- * The rate rules are NOT emitted as literals here — the file calls
17
+ * The rate rules are NOT emitted as literals here—the file calls
18
18
  * `astroidRateRules(astroidConfig)`, so the set stays real data in the package
19
19
  * (testable, and a `match` predicate survives, which a serialized literal could
20
20
  * not). Enabling a portal or commerce in the config adds that surface's rules
@@ -24,7 +24,7 @@ export declare function generateAstroidWorker(config: AstroidConfig): string;
24
24
  * Astro emits a hash-based `content-security-policy` response header on every SSR
25
25
  * page and owns `script-src`. The `cspStyleSrc` below tells
26
26
  * `createLouiseMiddleware` to rewrite that header's `style-src` to
27
- * `'self' 'unsafe-inline'` — a hash-based `style-src` would, per spec, void the
27
+ * `'self' 'unsafe-inline'`—a hash-based `style-src` would, per spec, void the
28
28
  * `'unsafe-inline'` that Louise's data-driven `style=""` carriers and the
29
29
  * editor's runtime-injected `<style>` require. Script hashes are left verbatim,
30
30
  * and the inlined `data:` brand font is auto-allowed.