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,7 +1,7 @@
1
1
  import type { CatalogItem } from "./sync.js";
2
2
  /** A product as the site renders it: the mirror row, decoded. */
3
3
  export interface CatalogProduct extends CatalogItem {
4
- /** Public URL segment — owner-owned, stable across provider renames. */
4
+ /** Public URL segment—owner-owned, stable across provider renames. */
5
5
  slug: string;
6
6
  status: "draft" | "published";
7
7
  sortOrder: number;
@@ -55,7 +55,7 @@ export declare function readCatalogItem(slug: string, options: CatalogReadOption
55
55
  * );
56
56
  * ```
57
57
  *
58
- * Identical for every provider — which is the whole point.
58
+ * Identical for every provider—which is the whole point.
59
59
  */
60
60
  export declare function astroidCatalogLoaderConfig(options: CatalogReadOptions & {
61
61
  name?: string;
@@ -3,8 +3,8 @@
3
3
  // The catalog read, and the Live Content Collection loader over it.
4
4
  //
5
5
  // `defineCatalogLoader` (@louise-toolkit/astro) already owns the Astro-facing
6
- // plumbing. What each site then hand-wrote was the layer underneath — "read my
7
- // catalog out of D1" — and because that layer was per-site, so was the drift.
6
+ // plumbing. What each site then hand-wrote was the layer underneath—"read my
7
+ // catalog out of D1"—and because that layer was per-site, so was the drift.
8
8
  // It doesn't need to be: once the mirror table's shape is fixed (see mirror.ts),
9
9
  // reading it is the same query whatever provider filled it in.
10
10
  //
@@ -73,7 +73,7 @@ export async function readCatalogItem(slug, options) {
73
73
  * );
74
74
  * ```
75
75
  *
76
- * Identical for every provider — which is the whole point.
76
+ * Identical for every provider—which is the whole point.
77
77
  */
78
78
  export function astroidCatalogLoaderConfig(options) {
79
79
  return {
@@ -25,8 +25,8 @@ export interface CatalogMirrorConfig {
25
25
  }
26
26
  /**
27
27
  * Columns Astroid always PULLS, overwriting each sync. Fixed rather than
28
- * configurable because they're the intersection of what every provider returns —
29
- * a project that wants a provider-specific field puts it in `owned` and fills it
28
+ * configurable because they're the intersection of what every provider returns—a
29
+ * project that wants a provider-specific field puts it in `owned` and fills it
30
30
  * itself, which also stops the sync from clobbering it.
31
31
  */
32
32
  export declare const PULLED_COLUMNS: readonly ["name", "price", "images", "variants", "externalSlug", "syncedAt"];
@@ -44,7 +44,7 @@ export declare function astroidCatalogMirror(config: AstroidConfig): Required<Pi
44
44
  /**
45
45
  * Drizzle source for the catalog table.
46
46
  *
47
- * `externalId` is unique — it's the sync's idempotency key, so a webhook and the
47
+ * `externalId` is unique—it's the sync's idempotency key, so a webhook and the
48
48
  * cron re-sync racing on the same product can only ever collide into one row.
49
49
  */
50
50
  export declare function generateCatalogTable(config: AstroidConfig): string | null;
@@ -57,7 +57,7 @@ export declare function generateCatalogTable(config: AstroidConfig): string | nu
57
57
  *
58
58
  * It has to exist at all because nothing else creates this table. `--commerce`
59
59
  * put `products` in `src/schema.ts` and the queue seam told you to sync into it,
60
- * but no migration anywhere in the toolkit created it — so the first catalog
60
+ * but no migration anywhere in the toolkit created it—so the first catalog
61
61
  * sync hit a missing table, and (because `astroidCatalogSync` swallows per-item
62
62
  * errors) reported success while writing nothing. The documented fallback,
63
63
  * `drizzle-kit generate`, could not help: the template ships a hand-authored
@@ -3,7 +3,7 @@
3
3
  // The catalog mirror: an external provider is the source of truth, D1 is the
4
4
  // editable overlay on top of it.
5
5
  //
6
- // Every consuming site landed on the same split — a set of fields PULLED from
6
+ // Every consuming site landed on the same split—a set of fields PULLED from
7
7
  // the provider and overwritten on every sync, and a disjoint set the owner edits
8
8
  // which must survive every sync. Get that boundary wrong in either direction and
9
9
  // you either clobber the owner's copy on the next cron tick, or serve a price
@@ -12,13 +12,13 @@
12
12
  // What the sites did NOT agree on is how much to store, and it turns out to be
13
13
  // one primitive with two settings rather than two designs:
14
14
  //
15
- // mirror — pulled + owned columns both live in D1 (themidwestartist.com).
15
+ // mirror: pulled + owned columns both live in D1 (themidwestartist.com).
16
16
  // Reads are one local query. The catalog can be stale between syncs.
17
- // overlay — only the owned columns live in D1, keyed by the provider's id.
17
+ // overlay: only the owned columns live in D1, keyed by the provider's id.
18
18
  // The catalog is read live from the provider and joined at read
19
19
  // time: never stale, but every read costs a provider round-trip
20
20
  // (cache accordingly).
21
- // live — Astroid manages NO catalog table at all: the catalog is read live
21
+ // live: Astroid manages NO catalog table at all: the catalog is read live
22
22
  // from the provider (cached), and any owner-side overlay table is
23
23
  // the SITE's own (coracle.coffee's `product_display_meta`, declared
24
24
  // in schema.site.ts and joined in the site's loader). Use when the
@@ -28,8 +28,8 @@
28
28
  // nor migration. One generator serves all three and a project switches by one word.
29
29
  /**
30
30
  * Columns Astroid always PULLS, overwriting each sync. Fixed rather than
31
- * configurable because they're the intersection of what every provider returns —
32
- * a project that wants a provider-specific field puts it in `owned` and fills it
31
+ * configurable because they're the intersection of what every provider returns—a
32
+ * project that wants a provider-specific field puts it in `owned` and fills it
33
33
  * itself, which also stops the sync from clobbering it.
34
34
  */
35
35
  export const PULLED_COLUMNS = [
@@ -54,7 +54,7 @@ export const BUILT_IN_OWNED = {
54
54
  type: "text",
55
55
  values: ["draft", "published"],
56
56
  default: "draft",
57
- note: "New remote items land as draft — nothing goes live until someone says so.",
57
+ note: "New remote items land as draft—nothing goes live until someone says so.",
58
58
  },
59
59
  sortOrder: { type: "real", default: 0 },
60
60
  featured: { type: "boolean", default: false },
@@ -66,7 +66,7 @@ export function astroidCatalogMirror(config) {
66
66
  return {
67
67
  mode: mirror.mode ?? "mirror",
68
68
  table: mirror.table ?? "products",
69
- // Built-ins first so a project can override one (e.g. widen `status`)
69
+ // Built-ins first so a project can override one (for example, widen `status`)
70
70
  // without restating the rest.
71
71
  owned: { ...BUILT_IN_OWNED, ...mirror.owned },
72
72
  };
@@ -99,7 +99,7 @@ function ownedColumnSource(key, col) {
99
99
  /**
100
100
  * Drizzle source for the catalog table.
101
101
  *
102
- * `externalId` is unique — it's the sync's idempotency key, so a webhook and the
102
+ * `externalId` is unique—it's the sync's idempotency key, so a webhook and the
103
103
  * cron re-sync racing on the same product can only ever collide into one row.
104
104
  */
105
105
  export function generateCatalogTable(config) {
@@ -114,11 +114,11 @@ export function generateCatalogTable(config) {
114
114
  p(`// The catalog ${mode}. The provider is the source of truth; these rows are`);
115
115
  p(mode === "mirror"
116
116
  ? "// a local copy plus the owner's edits. Pulled columns are overwritten every"
117
- : "// the owner's edits only — catalog fields are read live from the provider.");
117
+ : "// the owner's edits only—catalog fields are read live from the provider.");
118
118
  p("// sync; owned columns are preserved. See astroidCatalogUpsert.");
119
119
  p(`export const ${camel(table)} = sqliteTable(${JSON.stringify(table)}, {`);
120
120
  p(' id: integer("id").primaryKey({ autoIncrement: true }),');
121
- p(" // The provider's id for this item — the sync's idempotency key.");
121
+ p(" // The provider's id for this item—the sync's idempotency key.");
122
122
  p(' externalId: text("external_id").notNull().unique(),');
123
123
  if (mode === "mirror") {
124
124
  p(" // --- PULLED: overwritten on every sync, never hand-edit ---");
@@ -172,7 +172,7 @@ function ownedColumnSql(key, col) {
172
172
  *
173
173
  * It has to exist at all because nothing else creates this table. `--commerce`
174
174
  * put `products` in `src/schema.ts` and the queue seam told you to sync into it,
175
- * but no migration anywhere in the toolkit created it — so the first catalog
175
+ * but no migration anywhere in the toolkit created it—so the first catalog
176
176
  * sync hit a missing table, and (because `astroidCatalogSync` swallows per-item
177
177
  * errors) reported success while writing nothing. The documented fallback,
178
178
  * `drizzle-kit generate`, could not help: the template ships a hand-authored
@@ -3,14 +3,14 @@ import type { CommerceConfig, CommerceProvider } from "../config.js";
3
3
  export type CommerceRole = "storefront" | "invoicing" | "pos";
4
4
  /**
5
5
  * Which roles each provider can serve, derived from the surface its
6
- * `louise-toolkit/commerce/*` client actually exposes — not from what the
6
+ * `louise-toolkit/commerce/*` client actually exposes—not from what the
7
7
  * vendor's full API could theoretically do.
8
8
  *
9
9
  * square catalog + orders + payments, `createInvoice`/`publishInvoice`,
10
10
  * AND locations + per-location price overrides + inventory counts
11
11
  * stripe invoices + payment intents; NO catalog
12
- * fourthwall catalog + cart; NO invoicing, and NO locations or inventory —
13
- * its Platform API is create-only for products, so it cannot
12
+ * fourthwall catalog + cart; NO invoicing, and NO locations or inventory—*
13
+ its Platform API is create-only for products, so it cannot
14
14
  * model stock held at a place
15
15
  *
16
16
  * Square alone can serve `pos`, and that is a fact about the clients rather than
@@ -27,8 +27,8 @@ export interface ResolvedCommerceRoles {
27
27
  /**
28
28
  * Resolve a `commerce` block into role assignments.
29
29
  *
30
- * The `provider` shorthand assigns to the provider's *natural* role — the one it
31
- * can serve — so `{ provider: "square" }` is a storefront and
30
+ * The `provider` shorthand assigns to the provider's *natural* role—the one it
31
+ * can serve—so `{ provider: "square" }` is a storefront and
32
32
  * `{ provider: "stripe" }` is invoicing. Guessing "storefront" for both would
33
33
  * produce a storefront with no catalog API behind it.
34
34
  */
@@ -36,17 +36,17 @@ export declare function astroidCommerceRoles(commerce: CommerceConfig | undefine
36
36
  /** Every distinct provider this project talks to, in a stable order. */
37
37
  export declare function astroidCommerceProviders(commerce: CommerceConfig | undefined): CommerceProvider[];
38
38
  /**
39
- * True when this project sells in person — the switch for locations,
39
+ * True when this project sells in person—the switch for locations,
40
40
  * per-location pricing and inventory.
41
41
  */
42
42
  export declare const hasPos: (commerce: CommerceConfig | undefined) => boolean;
43
43
  /**
44
- * True when Square is used with more than one Location, i.e. the location id
44
+ * True when Square is used with more than one Location, that is, the location id
45
45
  * comes from the request rather than the environment.
46
46
  *
47
47
  * Deliberately independent of which ROLE Square fills: a project could run
48
- * multi-location invoicing without a `pos` storefront, and the consequence —
49
- * no ambient `SQUARE_LOCATION_ID` — is the same either way.
48
+ * multi-location invoicing without a `pos` storefront, and the consequence—no
49
+ * ambient `SQUARE_LOCATION_ID`—is the same either way.
50
50
  */
51
51
  export declare const hasMultiLocation: (commerce: CommerceConfig | undefined) => boolean;
52
52
  /** True when this project sells anything at all. */
@@ -54,7 +54,7 @@ export declare const hasStorefront: (commerce: CommerceConfig | undefined) => bo
54
54
  /**
55
55
  * Reject a role assignment the provider's client cannot serve. Called from
56
56
  * `defineAstroid`, so `invoicing: "fourthwall"` fails at config load with a
57
- * message naming the alternatives — rather than at runtime, on the first
57
+ * message naming the alternatives—rather than at runtime, on the first
58
58
  * invoice, as a missing function.
59
59
  */
60
60
  export declare function assertCommerceRoles(commerce: CommerceConfig | undefined): void;
@@ -4,28 +4,28 @@
4
4
  //
5
5
  // The obvious model is one commerce provider per site. It's wrong, and the
6
6
  // toolkit's own clients prove it: `louise-toolkit/commerce/stripe` has no
7
- // catalog API whatsoever — it exposes invoices, customers, and payment intents.
7
+ // catalog API whatsoever—it exposes invoices, customers, and payment intents.
8
8
  // `fourthwall` is the mirror image: a catalog and a cart, no invoicing. Square
9
9
  // happens to do both. A single `CommerceProvider` abstraction that assumed
10
10
  // catalog + checkout would therefore have a permanent hole wherever Stripe sits.
11
11
  //
12
12
  // That's not hypothetical. themidwestartist.com runs Stripe for **invoicing**
13
- // (commissions, originals) alongside Fourthwall for the **storefront** (merch) —
14
- // two providers, one site, each doing the half it can do.
13
+ // (commissions, originals) alongside Fourthwall for the **storefront**
14
+ // (merch)—two providers, one site, each doing the half it can do.
15
15
  //
16
16
  // So a project assigns providers to roles, and Astroid validates the assignment
17
17
  // against what each provider's client can actually serve.
18
18
  import { AstroidConfigError } from "../errors.js";
19
19
  /**
20
20
  * Which roles each provider can serve, derived from the surface its
21
- * `louise-toolkit/commerce/*` client actually exposes — not from what the
21
+ * `louise-toolkit/commerce/*` client actually exposes—not from what the
22
22
  * vendor's full API could theoretically do.
23
23
  *
24
24
  * square catalog + orders + payments, `createInvoice`/`publishInvoice`,
25
25
  * AND locations + per-location price overrides + inventory counts
26
26
  * stripe invoices + payment intents; NO catalog
27
- * fourthwall catalog + cart; NO invoicing, and NO locations or inventory —
28
- * its Platform API is create-only for products, so it cannot
27
+ * fourthwall catalog + cart; NO invoicing, and NO locations or inventory—*
28
+ its Platform API is create-only for products, so it cannot
29
29
  * model stock held at a place
30
30
  *
31
31
  * Square alone can serve `pos`, and that is a fact about the clients rather than
@@ -40,8 +40,8 @@ export const PROVIDER_ROLES = {
40
40
  /**
41
41
  * Resolve a `commerce` block into role assignments.
42
42
  *
43
- * The `provider` shorthand assigns to the provider's *natural* role — the one it
44
- * can serve — so `{ provider: "square" }` is a storefront and
43
+ * The `provider` shorthand assigns to the provider's *natural* role—the one it
44
+ * can serve—so `{ provider: "square" }` is a storefront and
45
45
  * `{ provider: "stripe" }` is invoicing. Guessing "storefront" for both would
46
46
  * produce a storefront with no catalog API behind it.
47
47
  */
@@ -69,17 +69,17 @@ export function astroidCommerceProviders(commerce) {
69
69
  return [...new Set([storefront, invoicing, pos].filter((p) => !!p))];
70
70
  }
71
71
  /**
72
- * True when this project sells in person — the switch for locations,
72
+ * True when this project sells in person—the switch for locations,
73
73
  * per-location pricing and inventory.
74
74
  */
75
75
  export const hasPos = (commerce) => Boolean(astroidCommerceRoles(commerce).pos);
76
76
  /**
77
- * True when Square is used with more than one Location, i.e. the location id
77
+ * True when Square is used with more than one Location, that is, the location id
78
78
  * comes from the request rather than the environment.
79
79
  *
80
80
  * Deliberately independent of which ROLE Square fills: a project could run
81
- * multi-location invoicing without a `pos` storefront, and the consequence —
82
- * no ambient `SQUARE_LOCATION_ID` — is the same either way.
81
+ * multi-location invoicing without a `pos` storefront, and the consequence—no
82
+ * ambient `SQUARE_LOCATION_ID`—is the same either way.
83
83
  */
84
84
  export const hasMultiLocation = (commerce) => commerce?.square?.locations === "multi";
85
85
  /** True when this project sells anything at all. */
@@ -87,7 +87,7 @@ export const hasStorefront = (commerce) => Boolean(astroidCommerceRoles(commerce
87
87
  /**
88
88
  * Reject a role assignment the provider's client cannot serve. Called from
89
89
  * `defineAstroid`, so `invoicing: "fourthwall"` fails at config load with a
90
- * message naming the alternatives — rather than at runtime, on the first
90
+ * message naming the alternatives—rather than at runtime, on the first
91
91
  * invoice, as a missing function.
92
92
  */
93
93
  export function assertCommerceRoles(commerce) {
@@ -6,7 +6,7 @@ import { type CommerceRole } from "./roles.js";
6
6
  *
7
7
  * `credentials` is what the provider's `louise-toolkit/commerce/*` client needs
8
8
  * to make a call at all; `webhook` is the signing secret its receiver verifies
9
- * with. They're separable on purpose — a site can receive verified webhooks
9
+ * with. They're separable on purpose—a site can receive verified webhooks
10
10
  * before it has finished provisioning API access, and the reverse is the normal
11
11
  * state of a brand-new integration.
12
12
  *
@@ -32,7 +32,7 @@ export declare const COMMERCE_PROVIDER_SETUP: Record<CommerceProvider, string>;
32
32
  * Only Square varies, and only on one name. `SQUARE_LOCATION_ID` is required
33
33
  * for a single-location project because Square's orders and payments endpoints
34
34
  * refuse a request without one. Under `square.locations: "multi"` the location
35
- * is a property of the *request* — which merchant's storefront is this? — so an
35
+ * is a property of the *request*—which merchant's storefront is this?—so an
36
36
  * ambient id is not just unnecessary, it is dangerous: any code path that
37
37
  * defaulted to it would ring one merchant's sale against another merchant's
38
38
  * books, and the sale would look perfectly successful while doing it.
@@ -53,11 +53,11 @@ export declare function commerceSecretNames(commerce: CommerceConfig | undefined
53
53
  /** One provider's resolved gate. */
54
54
  export interface ProviderStatus {
55
55
  provider: CommerceProvider;
56
- /** Which role(s) this provider fills for the project. */
56
+ /** Which roles this provider fills for the project. */
57
57
  roles: CommerceRole[];
58
- /** API credentials — false means no live call can be made. */
58
+ /** API credentials—false means no live call can be made. */
59
59
  credentials: ModuleSecrets<string>;
60
- /** Webhook signing secret — false means the receiver answers 503. */
60
+ /** Webhook signing secret—false means the receiver answers 503. */
61
61
  webhook: ModuleSecrets<string>;
62
62
  /** True only when both halves resolved. */
63
63
  configured: boolean;
@@ -66,7 +66,7 @@ export interface ProviderStatus {
66
66
  export interface CommerceStatus {
67
67
  /** True when the project has commerce configured AND every provider is live. */
68
68
  configured: boolean;
69
- /** True when the project declares no commerce at all — not the same as dormant. */
69
+ /** True when the project declares no commerce at all—not the same as dormant. */
70
70
  enabled: boolean;
71
71
  providers: ProviderStatus[];
72
72
  /** Every unprovisioned secret name across all providers, in declaration order. */
@@ -93,8 +93,8 @@ export declare function resolveCommerceStatus(commerce: CommerceConfig | undefin
93
93
  *
94
94
  * `CommerceStatus.configured` is an all-or-nothing aggregate (`every`), which is
95
95
  * the right answer for "is the whole module ready" and the wrong one for gating
96
- * a single call site. A two-provider project — Fourthwall for the storefront,
97
- * Square for invoicing — reads `configured: false` the moment either half is
96
+ * a single call site. A two-provider project—Fourthwall for the storefront,
97
+ * Square for invoicing—reads `configured: false` the moment either half is
98
98
  * unprovisioned, so gating the working Fourthwall checkout on the aggregate
99
99
  * would silently simulate it because SQUARE's secrets are still placeholders.
100
100
  *
@@ -103,7 +103,7 @@ export declare function resolveCommerceStatus(commerce: CommerceConfig | undefin
103
103
  export declare function providerConfigured(status: CommerceStatus, provider: CommerceProvider): boolean;
104
104
  /**
105
105
  * Is the provider filling this ROLE live? The role-shaped question, for code
106
- * that cares about the capability rather than the vendor — "can I take a
106
+ * that cares about the capability rather than the vendor—"can I take a
107
107
  * checkout?" rather than "is Square up?".
108
108
  */
109
109
  export declare function roleConfigured(status: CommerceStatus, role: CommerceRole): boolean;
@@ -3,7 +3,7 @@
3
3
  // What each commerce provider needs before it can do anything, and the gate
4
4
  // derived from it.
5
5
  //
6
- // The rest of this module is deliberately credential-free — the adapters are
6
+ // The rest of this module is deliberately credential-free—the adapters are
7
7
  // pure, the mirror and the loader only touch D1, and `verifyCheckout` takes a
8
8
  // price lookup rather than a token. That's the right shape: it keeps the parts
9
9
  // testable and lets the caller own how the fetch happens.
@@ -13,7 +13,7 @@
13
13
  // the commerce half of the dormant-until-provisioned convention (#252): the
14
14
  // names below are the single source of truth for what a provider requires, so
15
15
  // the wrangler generator can seed them, `astroid doctor` can report them, and a
16
- // storefront can decide between a live catalog and a simulated one — all from
16
+ // storefront can decide between a live catalog and a simulated one—all from
17
17
  // one declaration instead of three hand-maintained lists.
18
18
  //
19
19
  // The webhook secret lives here too, rather than beside the verifier in
@@ -26,7 +26,7 @@ import { astroidCommerceProviders, astroidCommerceRoles, hasMultiLocation, } fro
26
26
  *
27
27
  * `credentials` is what the provider's `louise-toolkit/commerce/*` client needs
28
28
  * to make a call at all; `webhook` is the signing secret its receiver verifies
29
- * with. They're separable on purpose — a site can receive verified webhooks
29
+ * with. They're separable on purpose—a site can receive verified webhooks
30
30
  * before it has finished provisioning API access, and the reverse is the normal
31
31
  * state of a brand-new integration.
32
32
  *
@@ -39,7 +39,7 @@ export const COMMERCE_PROVIDER_SECRETS = {
39
39
  // leaves checkout broken rather than dormant. Requiring both is what makes
40
40
  // "configured" mean "can actually take money".
41
41
  //
42
- // UNLESS the project is multi-location — see `commerceProviderCredentials`.
42
+ // UNLESS the project is multi-location—see `commerceProviderCredentials`.
43
43
  square: {
44
44
  credentials: ["SQUARE_ACCESS_TOKEN", "SQUARE_LOCATION_ID"],
45
45
  webhook: "SQUARE_WEBHOOK_SECRET",
@@ -50,7 +50,7 @@ export const COMMERCE_PROVIDER_SECRETS = {
50
50
  },
51
51
  // Fourthwall's storefront token is public-safe (it's sent as a query param
52
52
  // from the browser in their own SDK), but it is still provisioned, so it
53
- // follows the same gate — an absent token means no catalog.
53
+ // follows the same gate—an absent token means no catalog.
54
54
  fourthwall: {
55
55
  credentials: ["FOURTHWALL_STOREFRONT_TOKEN"],
56
56
  webhook: "FOURTHWALL_WEBHOOK_SECRET",
@@ -75,7 +75,7 @@ export const COMMERCE_PROVIDER_SETUP = {
75
75
  * Only Square varies, and only on one name. `SQUARE_LOCATION_ID` is required
76
76
  * for a single-location project because Square's orders and payments endpoints
77
77
  * refuse a request without one. Under `square.locations: "multi"` the location
78
- * is a property of the *request* — which merchant's storefront is this? — so an
78
+ * is a property of the *request*—which merchant's storefront is this?—so an
79
79
  * ambient id is not just unnecessary, it is dangerous: any code path that
80
80
  * defaulted to it would ring one merchant's sale against another merchant's
81
81
  * books, and the sale would look perfectly successful while doing it.
@@ -157,8 +157,8 @@ export async function resolveCommerceStatus(commerce, env) {
157
157
  *
158
158
  * `CommerceStatus.configured` is an all-or-nothing aggregate (`every`), which is
159
159
  * the right answer for "is the whole module ready" and the wrong one for gating
160
- * a single call site. A two-provider project — Fourthwall for the storefront,
161
- * Square for invoicing — reads `configured: false` the moment either half is
160
+ * a single call site. A two-provider project—Fourthwall for the storefront,
161
+ * Square for invoicing—reads `configured: false` the moment either half is
162
162
  * unprovisioned, so gating the working Fourthwall checkout on the aggregate
163
163
  * would silently simulate it because SQUARE's secrets are still placeholders.
164
164
  *
@@ -169,7 +169,7 @@ export function providerConfigured(status, provider) {
169
169
  }
170
170
  /**
171
171
  * Is the provider filling this ROLE live? The role-shaped question, for code
172
- * that cares about the capability rather than the vendor — "can I take a
172
+ * that cares about the capability rather than the vendor—"can I take a
173
173
  * checkout?" rather than "is Square up?".
174
174
  */
175
175
  export function roleConfigured(status, role) {
@@ -7,7 +7,7 @@ export interface CatalogItem {
7
7
  price: number;
8
8
  images?: string[];
9
9
  variants?: unknown;
10
- /** The provider's own slug, when it has one — for re-fetching a single item. */
10
+ /** The provider's own slug, when it has one—for re-fetching a single item. */
11
11
  externalSlug?: string;
12
12
  }
13
13
  /** The D1 surface the sync needs. Structural, so a real `D1Database` fits. */
@@ -21,7 +21,7 @@ export interface SyncDatabase {
21
21
  }
22
22
  export interface CatalogSyncOptions {
23
23
  db: SyncDatabase;
24
- /** Mirror table name — must match the generated schema. */
24
+ /** Mirror table name—must match the generated schema. */
25
25
  table: string;
26
26
  /**
27
27
  * `overlay` mode writes only the key and `synced_at`: the catalog fields live
@@ -32,7 +32,7 @@ export interface CatalogSyncOptions {
32
32
  slugify?: (item: CatalogItem) => string;
33
33
  }
34
34
  export interface CatalogSyncResult {
35
- /** Rows created — new products, landing as `draft`. */
35
+ /** Rows created—new products, landing as `draft`. */
36
36
  created: number;
37
37
  /** Rows whose pulled fields were refreshed. */
38
38
  updated: number;
@@ -41,7 +41,7 @@ export interface CatalogSyncResult {
41
41
  /**
42
42
  * One error per failed item, in order, for logging.
43
43
  *
44
- * Capped — a catalog-wide failure would otherwise build an array as long as
44
+ * Capped—a catalog-wide failure would otherwise build an array as long as
45
45
  * the catalog just to describe the same fault N times.
46
46
  */
47
47
  errors: {
@@ -54,7 +54,7 @@ export declare function defaultSlug(value: string): string;
54
54
  /**
55
55
  * Upsert one item. Returns whether it created a row.
56
56
  *
57
- * The UPDATE branch lists pulled columns ONLY — see the note at the top of this
57
+ * The UPDATE branch lists pulled columns ONLY—see the note at the top of this
58
58
  * file. In `overlay` mode there are no pulled columns, so an existing row is
59
59
  * touched only to stamp `synced_at`.
60
60
  */
@@ -67,7 +67,7 @@ export declare function astroidCatalogUpsert(item: CatalogItem, options: Catalog
67
67
  * Items are written one at a time and a single failure doesn't abandon the rest:
68
68
  * a partial catalog is strictly better than a stale one, and the next cron tick
69
69
  * retries whatever didn't land. Rows whose product has vanished upstream are
70
- * left alone — deciding whether a missing item is delisted or just a failed page
70
+ * left alone—deciding whether a missing item is delisted or just a failed page
71
71
  * of an API response is the project's call, not the sync's, and unpublishing
72
72
  * someone's whole catalog on a bad response is unrecoverable.
73
73
  *
@@ -79,7 +79,7 @@ export declare function astroidCatalogUpsert(item: CatalogItem, options: Catalog
79
79
  * with nothing in `wrangler tail`. Throwing when nothing at all landed is what
80
80
  * makes the queue's retry and DLQ do their job.
81
81
  *
82
- * Partial failures do NOT throw — they come back in `failed`/`errors` for the
82
+ * Partial failures do NOT throw—they come back in `failed`/`errors` for the
83
83
  * caller to log, because retrying the whole batch to re-attempt a few rows would
84
84
  * undo the tolerance this loop exists to provide.
85
85
  */
@@ -10,7 +10,7 @@
10
10
  // the provider's own id (unique in the table) means a re-run is a no-op update
11
11
  // rather than a duplicate row.
12
12
  //
13
- // **The owned set is never in an UPDATE.** Not "usually not" — never. A sync
13
+ // **The owned set is never in an UPDATE.** Not "usually not"—never. A sync
14
14
  // that writes an owned column is a sync that silently reverts the owner's work,
15
15
  // and they find out days later when someone notices the description is back to
16
16
  // the vendor's default. So the update statement is built from the pulled set
@@ -51,7 +51,7 @@ async function allocateSlug(db, table, base, externalId) {
51
51
  /**
52
52
  * Upsert one item. Returns whether it created a row.
53
53
  *
54
- * The UPDATE branch lists pulled columns ONLY — see the note at the top of this
54
+ * The UPDATE branch lists pulled columns ONLY—see the note at the top of this
55
55
  * file. In `overlay` mode there are no pulled columns, so an existing row is
56
56
  * touched only to stamp `synced_at`.
57
57
  */
@@ -106,7 +106,7 @@ const MAX_RECORDED_ERRORS = 10;
106
106
  * Items are written one at a time and a single failure doesn't abandon the rest:
107
107
  * a partial catalog is strictly better than a stale one, and the next cron tick
108
108
  * retries whatever didn't land. Rows whose product has vanished upstream are
109
- * left alone — deciding whether a missing item is delisted or just a failed page
109
+ * left alone—deciding whether a missing item is delisted or just a failed page
110
110
  * of an API response is the project's call, not the sync's, and unpublishing
111
111
  * someone's whole catalog on a bad response is unrecoverable.
112
112
  *
@@ -118,7 +118,7 @@ const MAX_RECORDED_ERRORS = 10;
118
118
  * with nothing in `wrangler tail`. Throwing when nothing at all landed is what
119
119
  * makes the queue's retry and DLQ do their job.
120
120
  *
121
- * Partial failures do NOT throw — they come back in `failed`/`errors` for the
121
+ * Partial failures do NOT throw—they come back in `failed`/`errors` for the
122
122
  * caller to log, because retrying the whole batch to re-attempt a few rows would
123
123
  * undo the tolerance this loop exists to provide.
124
124
  */
@@ -133,7 +133,7 @@ export async function astroidCatalogSync(items, options) {
133
133
  result.updated++;
134
134
  }
135
135
  catch (cause) {
136
- // Skip this item; the next run retries it — but record it, so "nothing
136
+ // Skip this item; the next run retries it—but record it, so "nothing
137
137
  // synced" can be told apart from "nothing to sync".
138
138
  result.failed++;
139
139
  if (result.errors.length < MAX_RECORDED_ERRORS) {
@@ -31,7 +31,7 @@ export declare function alignClass(align?: string | undefined): string;
31
31
  *
32
32
  * These are closed token sets, declared as `select` (#272) so the inspector
33
33
  * renders a picker and an unknown token is rejected on write. They used to be
34
- * `text` with the valid values stuffed into `placeholder` — which meant a typo
34
+ * `text` with the valid values stuffed into `placeholder`—which meant a typo
35
35
  * wasn't a validation error at all, just a silent fallback to the default
36
36
  * inside `colorwayClass` at render time.
37
37
  */
@@ -40,8 +40,8 @@ export declare const SECTION_SETTINGS: Record<string, SectionField>;
40
40
  * What every section render component receives.
41
41
  *
42
42
  * `base` is the whole point. It is this item's path within the page's `sections`
43
- * array — `"2"` for a top-level section, `"2.blocks.0"` for a block inside it —
44
- * and every marker the component stamps is built from it. Passing it down (rather
43
+ * array—`"2"` for a top-level section, `"2.blocks.0"` for a block inside it—and
44
+ * every marker the component stamps is built from it. Passing it down (rather
45
45
  * than having each component work out its own depth) is what lets the exact same
46
46
  * component render as a section or as a block, and what keeps `data-louise-node`
47
47
  * paths correct at any nesting depth.
@@ -53,8 +53,8 @@ export interface SectionRenderProps {
53
53
  base: string;
54
54
  /** Whether to stamp edit markers. Defaults to `Astro.locals.editMode`. */
55
55
  edit?: boolean;
56
- /** Alt/caption resolved from the media registry, keyed by public URL —
57
- * looked up once for the whole page by `<Sections>`. */
56
+ /** Alt/caption resolved from the media registry, keyed by public URL—*
57
+ looked up once for the whole page by `<Sections>`. */
58
58
  mediaMeta?: MediaMeta;
59
59
  }
60
60
  /** Asset-level `alt`/`caption` from the media registry, keyed by public URL. */
@@ -78,7 +78,7 @@ export declare function itemField(row: Record<string, unknown>, key: string): st
78
78
  *
79
79
  * The precedence is the whole reason `<Sections>` does its media lookup: a
80
80
  * per-usage `alt` on the section wins, because the same photo means something
81
- * different in a hero than in a thumbnail strip — but when there isn't one, the
81
+ * different in a hero than in a thumbnail strip—but when there isn't one, the
82
82
  * alt an editor typed once in the media library is used. That's what makes
83
83
  * fixing alt text a single edit that propagates everywhere the asset appears,
84
84
  * instead of a hunt through every page that embeds it.
@@ -89,7 +89,7 @@ export declare function itemField(row: Record<string, unknown>, key: string): st
89
89
  */
90
90
  export declare function mediaAlt(mediaMeta: MediaMeta | undefined, src: string | undefined, override?: string): string;
91
91
  /** Caption for an image, same precedence as {@link mediaAlt}. Undefined when
92
- * there is none — a missing caption renders nothing, unlike a missing alt. */
92
+ * there is none—a missing caption renders nothing, unlike a missing alt. */
93
93
  export declare function mediaCaption(mediaMeta: MediaMeta | undefined, src: string | undefined, override?: string): string | undefined;
94
94
  /**
95
95
  * Every section type Astroid ships.
@@ -97,7 +97,7 @@ export declare function mediaCaption(mediaMeta: MediaMeta | undefined, src: stri
97
97
  * `satisfies` rather than a `: SectionCatalog` annotation, and it matters:
98
98
  * `SectionCatalog` is `Record<string, SectionDef>`, so annotating would widen
99
99
  * `keyof typeof` to `string` and throw away the literal keys. Those keys are
100
- * the project's whole section vocabulary — `SectionKind` is derived from them
100
+ * the project's whole section vocabulary—`SectionKind` is derived from them
101
101
  * (config.ts), `isRenderableSection` narrows to them, and `<Section>` indexes
102
102
  * its component map with them. Annotate this and all three silently degrade to
103
103
  * "any string", which is how the dispatcher lost its type safety once already.
@@ -564,7 +564,7 @@ export declare const astroidSectionCatalog: {
564
564
  settings: Record<string, SectionField>;
565
565
  };
566
566
  };
567
- /** The `_type`s with a shipped render component — derived from the catalog, so
567
+ /** The `_type`s with a shipped render component—derived from the catalog, so
568
568
  * it can't drift from what `<Section>` actually dispatches. A literal union,
569
569
  * not `string`, because the catalog is declared with `satisfies`. */
570
570
  export type RenderableSectionType = keyof typeof astroidSectionCatalog;