@drawnagency/primitives 0.1.104 → 0.1.106

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 (104) hide show
  1. package/dist/auth/cookies.d.ts +21 -1
  2. package/dist/auth/cookies.d.ts.map +1 -1
  3. package/dist/auth/index.d.ts +2 -1
  4. package/dist/auth/index.d.ts.map +1 -1
  5. package/dist/auth/index.js +3 -1
  6. package/dist/auth/types.d.ts +28 -0
  7. package/dist/auth/types.d.ts.map +1 -1
  8. package/dist/{chunk-PTOLUMGV.js → chunk-4RNF2DRG.js} +1 -0
  9. package/dist/{chunk-MUTHF2GT.js → chunk-5IZ2KTMU.js} +2 -2
  10. package/dist/{chunk-LZKVV4K2.js → chunk-6P4CJCXB.js} +7 -1
  11. package/dist/{chunk-CZLYECHC.js → chunk-AB3XVXI3.js} +4 -4
  12. package/dist/chunk-B7VBSE5X.js +12 -0
  13. package/dist/{chunk-BGHWUJFV.js → chunk-BOZUEKWL.js} +107 -171
  14. package/dist/{chunk-TGNS7D4F.js → chunk-CPTFFLK2.js} +1 -1
  15. package/dist/{chunk-26ALJO4K.js → chunk-D6TLUVOP.js} +1 -1
  16. package/dist/{chunk-EM5DFHDZ.js → chunk-GEENI3OC.js} +13 -4
  17. package/dist/chunk-GGXZZ77Z.js +70 -0
  18. package/dist/{chunk-EWNDBKYK.js → chunk-LUAI5DWR.js} +1 -1
  19. package/dist/chunk-NLQ5F3RQ.js +43 -0
  20. package/dist/{chunk-X4PRBGB3.js → chunk-QLBHERK6.js} +9 -9
  21. package/dist/{chunk-3COSXTOY.js → chunk-XBYJQ5RS.js} +1 -1
  22. package/dist/{chunk-CXQWLG6X.js → chunk-Z7VXESB6.js} +18 -18
  23. package/dist/{chunk-WA6QPDJI.js → chunk-ZHHJVKU7.js} +6 -6
  24. package/dist/collab/rebase.js +2 -1
  25. package/dist/components/chat/ChatPanel.d.ts.map +1 -1
  26. package/dist/components/chat/ChatWidget.d.ts.map +1 -1
  27. package/dist/components/docfile/DocFileOverlay.d.ts.map +1 -1
  28. package/dist/components/docfile/DocFilePane.d.ts +4 -3
  29. package/dist/components/docfile/DocFilePane.d.ts.map +1 -1
  30. package/dist/components/editor/SectionOrderingModal.d.ts.map +1 -1
  31. package/dist/components/editor/index.js +8 -7
  32. package/dist/components/primitives/index.js +7 -6
  33. package/dist/components/sections/brand-guide.js +8 -7
  34. package/dist/components/sections/register-schemas.js +13 -12
  35. package/dist/components/sections/register.js +13 -12
  36. package/dist/components/shared/Navigation.d.ts +16 -1
  37. package/dist/components/shared/Navigation.d.ts.map +1 -1
  38. package/dist/components/shared/SectionSummaryRow.d.ts +24 -0
  39. package/dist/components/shared/SectionSummaryRow.d.ts.map +1 -0
  40. package/dist/components/shell/AudienceAddForm.d.ts +4 -1
  41. package/dist/components/shell/AudienceAddForm.d.ts.map +1 -1
  42. package/dist/components/shell/AudienceDetailsPanel.d.ts +28 -0
  43. package/dist/components/shell/AudienceDetailsPanel.d.ts.map +1 -0
  44. package/dist/components/shell/AudienceRow.d.ts +15 -1
  45. package/dist/components/shell/AudienceRow.d.ts.map +1 -1
  46. package/dist/components/shell/CredentialList.d.ts +18 -0
  47. package/dist/components/shell/CredentialList.d.ts.map +1 -0
  48. package/dist/components/shell/EditorShell.d.ts.map +1 -1
  49. package/dist/components/shell/SiteSettingsViewerAccess.d.ts.map +1 -1
  50. package/dist/components/shell/ViewerLoginForm.d.ts +5 -1
  51. package/dist/components/shell/ViewerLoginForm.d.ts.map +1 -1
  52. package/dist/index.js +47 -29
  53. package/dist/lib/audience-overview.d.ts +53 -0
  54. package/dist/lib/audience-overview.d.ts.map +1 -0
  55. package/dist/lib/audience-secret.d.ts +11 -0
  56. package/dist/lib/audience-secret.d.ts.map +1 -0
  57. package/dist/lib/audience-secret.js +70 -0
  58. package/dist/lib/events.d.ts +3 -0
  59. package/dist/lib/events.d.ts.map +1 -1
  60. package/dist/lib/index-ops.js +3 -2
  61. package/dist/lib/index.js +13 -12
  62. package/dist/lib/nav.d.ts.map +1 -1
  63. package/dist/lib/thumb-views.d.ts +17 -0
  64. package/dist/lib/thumb-views.d.ts.map +1 -0
  65. package/dist/media/index.js +4 -3
  66. package/dist/schemas/audience.d.ts +29 -0
  67. package/dist/schemas/audience.d.ts.map +1 -1
  68. package/dist/schemas/audience.js +24 -0
  69. package/dist/schemas/auth.d.ts +1 -0
  70. package/dist/schemas/auth.d.ts.map +1 -1
  71. package/dist/schemas/auth.js +1 -1
  72. package/dist/schemas/index.js +28 -12
  73. package/dist/schemas/site-config.d.ts +1 -1
  74. package/dist/schemas/site-config.d.ts.map +1 -1
  75. package/dist/types/database.d.ts +59 -5
  76. package/dist/types/database.d.ts.map +1 -1
  77. package/package.json +9 -1
  78. package/src/auth/cookies.ts +37 -4
  79. package/src/auth/index.ts +2 -1
  80. package/src/auth/types.ts +32 -0
  81. package/src/components/chat/ChatPanel.tsx +4 -2
  82. package/src/components/chat/ChatWidget.tsx +4 -1
  83. package/src/components/docfile/DocFileOverlay.tsx +28 -2
  84. package/src/components/docfile/DocFilePane.tsx +4 -3
  85. package/src/components/editor/SectionOrderingModal.tsx +8 -73
  86. package/src/components/shared/Navigation.tsx +113 -7
  87. package/src/components/shared/SectionSummaryRow.tsx +73 -0
  88. package/src/components/shell/AudienceAddForm.tsx +18 -9
  89. package/src/components/shell/AudienceDetailsPanel.tsx +263 -0
  90. package/src/components/shell/AudienceRow.tsx +55 -13
  91. package/src/components/shell/CredentialList.tsx +285 -0
  92. package/src/components/shell/EditorShell.tsx +94 -4
  93. package/src/components/shell/SiteSettingsViewerAccess.tsx +57 -6
  94. package/src/components/shell/ViewerLoginForm.tsx +35 -15
  95. package/src/lib/audience-overview.ts +110 -0
  96. package/src/lib/audience-secret.ts +99 -0
  97. package/src/lib/events.ts +3 -0
  98. package/src/lib/nav.ts +6 -2
  99. package/src/lib/thumb-views.ts +28 -0
  100. package/src/schemas/audience.ts +52 -0
  101. package/src/schemas/auth.ts +6 -0
  102. package/src/schemas/site-config.ts +1 -1
  103. package/src/types/database.ts +59 -5
  104. package/dist/chunk-ZDQ3TT47.js +0 -30
@@ -5,7 +5,27 @@ export declare const SESSION_MAX_AGE_SECONDS: number;
5
5
  export declare const AUDIENCE_MAX_AGE_SECONDS: number;
6
6
  export declare function signSessionToken(session: Session): Promise<string>;
7
7
  export declare function verifySessionToken(token: string): Promise<Session | null>;
8
- export declare function signAudienceToken(audience: string): Promise<string>;
8
+ export declare function signAudienceToken(audience: string, isDefault?: boolean, username?: string | null): Promise<string>;
9
+ export interface AudienceClaims {
10
+ audience: string;
11
+ /** Is this the site's default audience? Gates the Audience Details page. */
12
+ isDefault: boolean;
13
+ /**
14
+ * The named sign-in used, in credential mode. Null in `.env`/audience mode,
15
+ * and on any cookie issued before credentials shipped. Drives the sidebar's
16
+ * "Logged in as" label and the reveal audit log — NOT any access decision,
17
+ * which stays keyed on the audience.
18
+ */
19
+ username: string | null;
20
+ }
21
+ /**
22
+ * Full audience claims. The `isDefault` claim exists so a viewer page can gate
23
+ * the Audience Details link without a per-render lookup of the audience list.
24
+ * A cookie issued before the claim shipped reads as `false` — the viewer sees
25
+ * the link after their next login, which is at most AUDIENCE_MAX_AGE_SECONDS
26
+ * away, so no compatibility path is needed.
27
+ */
28
+ export declare function verifyAudienceClaims(token: string): Promise<AudienceClaims | null>;
9
29
  export declare function verifyAudienceToken(token: string): Promise<string | null>;
10
30
  export declare function setSessionCookie(cookies: CookieLike, token: string, isProduction: boolean): void;
11
31
  //# sourceMappingURL=cookies.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cookies.d.ts","sourceRoot":"","sources":["../../src/auth/cookies.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAGnD,eAAO,MAAM,cAAc,eAAe,CAAC;AAC3C,eAAO,MAAM,eAAe,gBAAgB,CAAC;AAC7C,eAAO,MAAM,uBAAuB,QAAe,CAAC;AAMpD,eAAO,MAAM,wBAAwB,QAAe,CAAC;AAErD,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAWxE;AAED,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAe/E;AAMD,wBAAsB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAMzE;AAED,wBAAsB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAS/E;AAED,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,UAAU,EACnB,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,OAAO,GACpB,IAAI,CAQN"}
1
+ {"version":3,"file":"cookies.d.ts","sourceRoot":"","sources":["../../src/auth/cookies.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAGnD,eAAO,MAAM,cAAc,eAAe,CAAC;AAC3C,eAAO,MAAM,eAAe,gBAAgB,CAAC;AAC7C,eAAO,MAAM,uBAAuB,QAAe,CAAC;AAMpD,eAAO,MAAM,wBAAwB,QAAe,CAAC;AAErD,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAWxE;AAED,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAe/E;AAMD,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,MAAM,EAChB,SAAS,UAAQ,EACjB,QAAQ,GAAE,MAAM,GAAG,IAAW,GAC7B,OAAO,CAAC,MAAM,CAAC,CAMjB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,4EAA4E;IAC5E,SAAS,EAAE,OAAO,CAAC;IACnB;;;;;OAKG;IACH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAcxF;AAED,wBAAsB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAE/E;AAED,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,UAAU,EACnB,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,OAAO,GACpB,IAAI,CAQN"}
@@ -2,6 +2,7 @@ export type { Role, Session, SiteUser, Audience, SignInMethod, SignInResult, Tok
2
2
  export type { UiCapabilities } from "./capabilities";
3
3
  export { deriveUiCapabilities } from "./capabilities";
4
4
  export { requireSessionSecret, isSameOriginRequest, safeNextPath } from "./security";
5
- export { signSessionToken, verifySessionToken, signAudienceToken, verifyAudienceToken, setSessionCookie, SESSION_COOKIE, AUDIENCE_COOKIE, SESSION_MAX_AGE_SECONDS, AUDIENCE_MAX_AGE_SECONDS } from "./cookies";
5
+ export { signSessionToken, verifySessionToken, signAudienceToken, verifyAudienceToken, verifyAudienceClaims, setSessionCookie, SESSION_COOKIE, AUDIENCE_COOKIE, SESSION_MAX_AGE_SECONDS, AUDIENCE_MAX_AGE_SECONDS } from "./cookies";
6
+ export type { AudienceClaims } from "./cookies";
6
7
  export { LastOwnerError, SessionExpiredError } from "./errors";
7
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,EACnB,YAAY,EACZ,UAAU,EACV,WAAW,GACZ,MAAM,SAAS,CAAC;AAEjB,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAEtD,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AACrF,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,cAAc,EAAE,eAAe,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AAC/M,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,EACnB,YAAY,EACZ,UAAU,EACV,WAAW,GACZ,MAAM,SAAS,CAAC;AAEjB,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAEtD,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AACrF,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,cAAc,EAAE,eAAe,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AACrO,YAAY,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC"}
@@ -9,9 +9,10 @@ import {
9
9
  setSessionCookie,
10
10
  signAudienceToken,
11
11
  signSessionToken,
12
+ verifyAudienceClaims,
12
13
  verifyAudienceToken,
13
14
  verifySessionToken
14
- } from "../chunk-EM5DFHDZ.js";
15
+ } from "../chunk-GEENI3OC.js";
15
16
  import {
16
17
  isSameOriginRequest,
17
18
  requireSessionSecret,
@@ -33,6 +34,7 @@ export {
33
34
  setSessionCookie,
34
35
  signAudienceToken,
35
36
  signSessionToken,
37
+ verifyAudienceClaims,
36
38
  verifyAudienceToken,
37
39
  verifySessionToken
38
40
  };
@@ -1,5 +1,7 @@
1
1
  export type { Role, Session, SiteUser, Audience } from "../schemas/auth";
2
2
  import type { Role, Session, SiteUser, Audience } from "../schemas/auth";
3
+ export type { ViewerCredential } from "../schemas/audience";
4
+ import type { ViewerCredential } from "../schemas/audience";
3
5
  export type SignInMethod = {
4
6
  type: "oauth";
5
7
  provider: "google" | "github";
@@ -44,6 +46,32 @@ export interface AuthProvider {
44
46
  list(): Promise<Audience[]>;
45
47
  verify(name: string, password: string): Promise<boolean>;
46
48
  get?(name: string): Promise<Audience | null>;
49
+ credentials?: {
50
+ /** Every credential on the site, each carrying the audience it grants. */
51
+ list(): Promise<ViewerCredential[]>;
52
+ /**
53
+ * Authenticate a viewer login. Returns the audience to put in the cookie,
54
+ * or ONE uniform null for both an unknown username and a wrong password —
55
+ * the login page must not become a username oracle.
56
+ */
57
+ verify(username: string, password: string): Promise<{
58
+ audienceName: string;
59
+ isDefault: boolean;
60
+ } | null>;
61
+ /**
62
+ * Show an existing password. Returns null for "not revealable": no sealed
63
+ * copy (predates the feature, or a writer skipped it), an unopenable seal
64
+ * (rotated SESSION_SECRET), or a seal that no longer matches
65
+ * `password_hash`. That last check is what stops a stale seal being shown
66
+ * as the live password — any implementation MUST verify against the hash
67
+ * before returning.
68
+ */
69
+ reveal(username: string): Promise<string | null>;
70
+ create(audienceName: string, username: string, label: string | null, password: string): Promise<void>;
71
+ setPassword(username: string, password: string): Promise<void>;
72
+ setLabel(username: string, label: string | null): Promise<void>;
73
+ delete(username: string): Promise<void>;
74
+ };
47
75
  manage?: {
48
76
  create(displayName: string, color: string | null, password: string): Promise<void>;
49
77
  setPassword(name: string, password: string): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/auth/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/auth/types.ts"],"names":[],"mappings":"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"}
@@ -21,6 +21,7 @@ var historyRestoreFailedEvent = createEvent("history-restore-failed");
21
21
  var editorDirtyEvent = createEvent("editor-dirty");
22
22
  var siteNavChangeEvent = createEvent("sitenavchange-v2");
23
23
  var pageSelectEvent = createEvent("pageselect");
24
+ var audienceDetailsEvent = createEvent("audiencedetailsopen");
24
25
 
25
26
  export {
26
27
  createEvent,
@@ -6,10 +6,10 @@ import {
6
6
  SettingsIcon,
7
7
  useMediaLibrary,
8
8
  useResolvedMedia
9
- } from "./chunk-26ALJO4K.js";
9
+ } from "./chunk-D6TLUVOP.js";
10
10
  import {
11
11
  rebindImageRef
12
- } from "./chunk-3COSXTOY.js";
12
+ } from "./chunk-XBYJQ5RS.js";
13
13
  import {
14
14
  cn
15
15
  } from "./chunk-7EOSDFS3.js";
@@ -18,8 +18,14 @@ var AudienceSchema = z.object({
18
18
  displayName: z.string(),
19
19
  color: z.string().nullable(),
20
20
  readonly: z.boolean(),
21
+ /** Some way in exists: a credential in credential mode, an audience-level
22
+ * password in `.env` mode. Consumers that only ask "is this gated?" (admin
23
+ * dashboard, MCP) keep using this and need no knowledge of credentials. */
21
24
  hasPassword: z.boolean(),
22
- isDefault: z.boolean()
25
+ isDefault: z.boolean(),
26
+ /** Named sign-ins pointing at this audience. Always 0 in `.env` mode, which
27
+ * has no credentials — use `hasPassword` there. */
28
+ credentialCount: z.number().int().nonnegative().default(0)
23
29
  });
24
30
 
25
31
  export {
@@ -1,9 +1,9 @@
1
- import {
2
- safeNextPath
3
- } from "./chunk-S2L3BPLS.js";
4
1
  import {
5
2
  upgradeLegacySection
6
3
  } from "./chunk-5BM2Y3NJ.js";
4
+ import {
5
+ safeNextPath
6
+ } from "./chunk-S2L3BPLS.js";
7
7
  import {
8
8
  NavEntrySchema
9
9
  } from "./chunk-REDDTTGJ.js";
@@ -15,7 +15,7 @@ import {
15
15
  } from "./chunk-VKAGMEKE.js";
16
16
  import {
17
17
  IndexSchema
18
- } from "./chunk-BGHWUJFV.js";
18
+ } from "./chunk-BOZUEKWL.js";
19
19
  import {
20
20
  MAX_BLOCK_DEPTH,
21
21
  blockDepth
@@ -0,0 +1,12 @@
1
+ // src/schemas/media-grid-options.ts
2
+ import { z } from "zod";
3
+ var MediaGridOptionsSchema = z.object({
4
+ square: z.boolean().optional(),
5
+ border: z.boolean().optional(),
6
+ crop: z.boolean().optional(),
7
+ showCaptions: z.boolean().optional()
8
+ }).default({});
9
+
10
+ export {
11
+ MediaGridOptionsSchema
12
+ };
@@ -1,159 +1,100 @@
1
1
  import {
2
2
  documentOptionsSchema
3
3
  } from "./chunk-FM4M4Q2W.js";
4
-
5
- // src/schemas/shared.ts
6
- import { z } from "zod";
7
- var TextHeadingLine = z.object({
8
- type: z.literal("heading"),
9
- text: z.string()
10
- });
11
- var TextParagraphLine = z.object({
12
- type: z.enum(["paragraph", "paragraph_large"]),
13
- text: z.string()
14
- });
15
- var TextLabelValueLine = z.object({
16
- type: z.literal("label_value"),
17
- label: z.string(),
18
- text: z.string()
19
- });
20
- var TextListItemLine = z.object({
21
- type: z.enum(["list_item_unordered", "list_item_ordered"]),
22
- text: z.string()
23
- });
24
- var TextLineSchema = z.discriminatedUnion("type", [
25
- TextHeadingLine,
26
- TextParagraphLine,
27
- TextLabelValueLine,
28
- TextListItemLine
29
- ]);
30
- var BaseMediaRef = z.object({
31
- imageId: z.string().default("").describe("Media-library id of the image/video asset."),
32
- caption: z.union([z.string(), z.array(z.string())]).optional().describe("Optional caption: a single string, or multiple lines as an array of strings."),
33
- background: z.string().optional().describe("Optional CSS background color/value shown behind a transparent image."),
34
- invertFrom: z.string().optional().describe("Optional CSS color; the image inverts when the page background matches it (e.g. for dark-mode logo swaps)."),
35
- border: z.boolean().optional().describe("When true, draw a border around the media."),
36
- objectFit: z.enum(["cover", "contain"]).optional().describe("How the image fills its box: 'contain' (fit whole image) or 'cover' (fill and crop).")
37
- });
38
- var ImageRef = BaseMediaRef.extend({
39
- type: z.literal("image")
40
- });
41
- var VideoRef = BaseMediaRef.extend({
42
- type: z.literal("video"),
43
- poster: z.string().optional().describe("Optional poster-image URL shown before playback starts."),
44
- autoplay: z.boolean().optional().describe("When true, the video starts playing automatically."),
45
- loop: z.boolean().optional().describe("When true, the video repeats when it finishes."),
46
- muted: z.boolean().optional().describe("When true, the video plays without sound.")
47
- });
48
- var DoDontImageRef = BaseMediaRef.extend({
49
- type: z.literal("doDontImage"),
50
- doDont: z.enum(["do", "dont"]).describe("Whether this is a 'do' (correct) or 'dont' (incorrect) example.")
51
- });
52
- var LinkedImageRef = BaseMediaRef.extend({
53
- type: z.literal("linkedImage"),
54
- href: z.string().describe("URL the image links to."),
55
- target: z.string().optional().describe("Link target, e.g. '_self' or '_blank'."),
56
- linkText: z.string().optional().describe("Optional accessible link text/label.")
57
- });
58
- var MediaReferenceSchema = z.discriminatedUnion("type", [
59
- ImageRef,
60
- VideoRef,
61
- DoDontImageRef,
62
- LinkedImageRef
63
- ]);
64
- var SingleMediaReferenceSchema = z.discriminatedUnion("type", [ImageRef, VideoRef]);
65
- var HexColorSchema = z.string().regex(/^#[0-9a-fA-F]{6}$/, "must be a 6-digit hex color");
66
- var FontNameSchema = z.string().max(120).regex(/^[a-zA-Z0-9 ,'"-]+$/, "contains invalid font-name characters");
4
+ import {
5
+ FontNameSchema,
6
+ HexColorSchema
7
+ } from "./chunk-GGXZZ77Z.js";
67
8
 
68
9
  // src/schemas/media.ts
69
- import { z as z2 } from "zod";
70
- var VariantSchema = z2.object({
71
- width: z2.number().int().positive(),
72
- height: z2.number().int().positive(),
73
- size: z2.number().int().nonnegative()
10
+ import { z } from "zod";
11
+ var VariantSchema = z.object({
12
+ width: z.number().int().positive(),
13
+ height: z.number().int().positive(),
14
+ size: z.number().int().nonnegative()
74
15
  });
75
- var MediaFolderSchema = z2.object({
76
- name: z2.string().min(1),
77
- parentId: z2.string().nullable()
16
+ var MediaFolderSchema = z.object({
17
+ name: z.string().min(1),
18
+ parentId: z.string().nullable()
78
19
  // null = root
79
20
  });
80
- var MediaItemSchema = z2.object({
81
- id: z2.string(),
82
- hash: z2.string(),
83
- kind: z2.enum(["image", "animated", "video"]),
84
- originalName: z2.string(),
85
- width: z2.number().int().positive(),
86
- height: z2.number().int().positive(),
87
- mimeType: z2.string(),
88
- size: z2.number().int().nonnegative(),
89
- folder: z2.string(),
90
- variants: z2.array(VariantSchema),
91
- alt: z2.string().default(""),
21
+ var MediaItemSchema = z.object({
22
+ id: z.string(),
23
+ hash: z.string(),
24
+ kind: z.enum(["image", "animated", "video"]),
25
+ originalName: z.string(),
26
+ width: z.number().int().positive(),
27
+ height: z.number().int().positive(),
28
+ mimeType: z.string(),
29
+ size: z.number().int().nonnegative(),
30
+ folder: z.string(),
31
+ variants: z.array(VariantSchema),
32
+ alt: z.string().default(""),
92
33
  // Where the original bytes live. "github" = committed to the repo (images,
93
34
  // small loops); "assets" = large original in the AssetStore bucket. Legacy
94
35
  // manifests have no field — default keeps them on the git path.
95
- storage: z2.enum(["github", "assets"]).default("github"),
36
+ storage: z.enum(["github", "assets"]).default("github"),
96
37
  // Public CDN URL for assets-backed originals, baked at upload time so
97
38
  // resolution needs no env access in the browser or at SSR.
98
- url: z2.string().optional(),
39
+ url: z.string().optional(),
99
40
  // Seconds; videos only. Informational (library UI).
100
- duration: z2.number().positive().optional(),
41
+ duration: z.number().positive().optional(),
101
42
  // Display folder (MediaFolderSchema key). Absent = root/unfiled. NOT the
102
43
  // git storage dir — that's `folder` above, which never changes.
103
- folderId: z2.string().optional(),
44
+ folderId: z.string().optional(),
104
45
  // System-generated assets (e.g. the Phase 3 social-preview raster) set this
105
46
  // so the media-library UI can exclude them. Absent on all user uploads.
106
- hidden: z2.boolean().optional()
47
+ hidden: z.boolean().optional()
107
48
  });
108
- var ImageManifestSchema = z2.object({
109
- images: z2.record(z2.string(), MediaItemSchema),
110
- folders: z2.record(z2.string(), MediaFolderSchema).default({})
49
+ var ImageManifestSchema = z.object({
50
+ images: z.record(z.string(), MediaItemSchema),
51
+ folders: z.record(z.string(), MediaFolderSchema).default({})
111
52
  });
112
- var MediaConfigSchema = z2.object({
113
- sizes: z2.array(z2.number()).default([640, 1080, 1920]),
114
- maxFileSize: z2.number().default(5242880),
115
- quality: z2.number().min(1).max(100).default(85),
53
+ var MediaConfigSchema = z.object({
54
+ sizes: z.array(z.number()).default([640, 1080, 1920]),
55
+ maxFileSize: z.number().default(5242880),
56
+ quality: z.number().min(1).max(100).default(85),
116
57
  // Per-file cap for bucket-backed video uploads (bytes). The git-path cap is
117
58
  // maxFileSize; anything between the two routes to the AssetStore.
118
- maxAssetSize: z2.number().default(209715200)
59
+ maxAssetSize: z.number().default(209715200)
119
60
  });
120
61
 
121
62
  // src/schemas/site-config.ts
122
- import { z as z3 } from "zod";
63
+ import { z as z2 } from "zod";
123
64
 
124
65
  // src/lib/corner-radius.ts
125
66
  var CORNER_RADIUS_OPTIONS = ["none", "small", "medium", "large"];
126
67
 
127
68
  // src/schemas/site-config.ts
128
- var StatusSchema = z3.enum(["draft", "live", "archived", "published"]).transform(
69
+ var StatusSchema = z2.enum(["draft", "live", "archived", "published"]).transform(
129
70
  (val) => val === "published" ? "live" : val
130
71
  );
131
- var SectionMetaSchema = z3.object({
132
- type: z3.string(),
72
+ var SectionMetaSchema = z2.object({
73
+ type: z2.string(),
133
74
  status: StatusSchema,
134
- access: z3.array(z3.string())
75
+ access: z2.array(z2.string())
135
76
  });
136
- var RESERVED_SLUGS = ["edit", "api", "login", "set-password", "404", "present", "print"];
77
+ var RESERVED_SLUGS = ["edit", "api", "login", "set-password", "404", "present", "print", "audiences"];
137
78
  var PARSE_REJECTED_SLUGS = ["edit", "api", "login", "set-password", "404"];
138
- var PageStatusSchema = z3.enum(["live", "archived"]);
139
- var PageSchema = z3.object({
140
- id: z3.string().min(1),
141
- title: z3.string(),
142
- slug: z3.string(),
143
- isHome: z3.boolean(),
144
- showInNav: z3.boolean(),
79
+ var PageStatusSchema = z2.enum(["live", "archived"]);
80
+ var PageSchema = z2.object({
81
+ id: z2.string().min(1),
82
+ title: z2.string(),
83
+ slug: z2.string(),
84
+ isHome: z2.boolean(),
85
+ showInNav: z2.boolean(),
145
86
  status: PageStatusSchema,
146
- access: z3.array(z3.string()),
147
- order: z3.array(z3.string()),
87
+ access: z2.array(z2.string()),
88
+ order: z2.array(z2.string()),
148
89
  document: documentOptionsSchema.optional()
149
90
  });
150
91
  var SLUG_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
151
- var RawIndexSchema = z3.object({
152
- siteId: z3.string(),
153
- order: z3.array(z3.string()).optional(),
154
- pages: z3.array(PageSchema).optional(),
155
- sections: z3.record(z3.string(), SectionMetaSchema),
156
- lastModified: z3.string().nullable().optional()
92
+ var RawIndexSchema = z2.object({
93
+ siteId: z2.string(),
94
+ order: z2.array(z2.string()).optional(),
95
+ pages: z2.array(PageSchema).optional(),
96
+ sections: z2.record(z2.string(), SectionMetaSchema),
97
+ lastModified: z2.string().nullable().optional()
157
98
  });
158
99
  function normalizeRawIndex(data) {
159
100
  if (data.pages && data.pages.length > 0) {
@@ -183,34 +124,34 @@ function normalizeRawIndex(data) {
183
124
  lastModified: data.lastModified ?? null
184
125
  };
185
126
  }
186
- var CanonicalIndexSchema = z3.object({
187
- siteId: z3.string(),
188
- pages: z3.array(PageSchema),
189
- sections: z3.record(z3.string(), SectionMetaSchema),
190
- lastModified: z3.string().nullable().optional()
127
+ var CanonicalIndexSchema = z2.object({
128
+ siteId: z2.string(),
129
+ pages: z2.array(PageSchema),
130
+ sections: z2.record(z2.string(), SectionMetaSchema),
131
+ lastModified: z2.string().nullable().optional()
191
132
  }).superRefine((data, ctx) => {
192
133
  const homes = data.pages.filter((p) => p.isHome);
193
134
  if (homes.length !== 1) {
194
- ctx.addIssue({ code: z3.ZodIssueCode.custom, message: "Exactly one page must be the home page" });
135
+ ctx.addIssue({ code: z2.ZodIssueCode.custom, message: "Exactly one page must be the home page" });
195
136
  }
196
137
  if (homes[0]?.status === "archived") {
197
- ctx.addIssue({ code: z3.ZodIssueCode.custom, message: "The home page cannot be archived" });
138
+ ctx.addIssue({ code: z2.ZodIssueCode.custom, message: "The home page cannot be archived" });
198
139
  }
199
140
  if (homes[0] && homes[0].slug !== "") {
200
- ctx.addIssue({ code: z3.ZodIssueCode.custom, message: "The home page slug must be empty" });
141
+ ctx.addIssue({ code: z2.ZodIssueCode.custom, message: "The home page slug must be empty" });
201
142
  }
202
143
  const seenSlugs = /* @__PURE__ */ new Set();
203
144
  for (const p of data.pages) {
204
145
  if (!p.isHome) {
205
146
  if (!SLUG_RE.test(p.slug)) {
206
- ctx.addIssue({ code: z3.ZodIssueCode.custom, message: `Invalid slug "${p.slug}"` });
147
+ ctx.addIssue({ code: z2.ZodIssueCode.custom, message: `Invalid slug "${p.slug}"` });
207
148
  }
208
149
  if (PARSE_REJECTED_SLUGS.includes(p.slug)) {
209
- ctx.addIssue({ code: z3.ZodIssueCode.custom, message: `Slug "${p.slug}" is reserved` });
150
+ ctx.addIssue({ code: z2.ZodIssueCode.custom, message: `Slug "${p.slug}" is reserved` });
210
151
  }
211
152
  }
212
153
  if (seenSlugs.has(p.slug)) {
213
- ctx.addIssue({ code: z3.ZodIssueCode.custom, message: `Duplicate slug "${p.slug}"` });
154
+ ctx.addIssue({ code: z2.ZodIssueCode.custom, message: `Duplicate slug "${p.slug}"` });
214
155
  }
215
156
  seenSlugs.add(p.slug);
216
157
  }
@@ -225,21 +166,21 @@ var CanonicalIndexSchema = z3.object({
225
166
  const duplicated = [...counts].filter(([, n]) => n > 1).map(([id]) => id);
226
167
  if (duplicated.length > 0) {
227
168
  ctx.addIssue({
228
- code: z3.ZodIssueCode.custom,
169
+ code: z2.ZodIssueCode.custom,
229
170
  message: `Section id(s) appear in more than one page order: ${fmtIds(duplicated)}`
230
171
  });
231
172
  }
232
173
  const orderedNotInSections = [...fromPagesSet].filter((id) => !sectionSet.has(id));
233
174
  if (orderedNotInSections.length > 0) {
234
175
  ctx.addIssue({
235
- code: z3.ZodIssueCode.custom,
176
+ code: z2.ZodIssueCode.custom,
236
177
  message: `Section id(s) in a page order but missing from sections{}: ${fmtIds(orderedNotInSections)}`
237
178
  });
238
179
  }
239
180
  const sectionsNotOrdered = sectionKeys.filter((id) => !fromPagesSet.has(id));
240
181
  if (sectionsNotOrdered.length > 0) {
241
182
  ctx.addIssue({
242
- code: z3.ZodIssueCode.custom,
183
+ code: z2.ZodIssueCode.custom,
243
184
  message: `Section id(s) in sections{} but not in any page order: ${fmtIds(sectionsNotOrdered)}`
244
185
  });
245
186
  }
@@ -248,51 +189,51 @@ var IndexSchema = RawIndexSchema.transform(normalizeRawIndex).pipe(CanonicalInde
248
189
  function normalizeSiteIndex(raw) {
249
190
  return IndexSchema.parse(raw);
250
191
  }
251
- var ChatbotTaskIdSchema = z3.string().min(1).max(32).regex(
192
+ var ChatbotTaskIdSchema = z2.string().min(1).max(32).regex(
252
193
  /^[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?$/,
253
194
  "Task id must be lowercase letters, numbers, dashes, or underscores"
254
195
  );
255
- var ChatbotTaskSchema = z3.object({
196
+ var ChatbotTaskSchema = z2.object({
256
197
  id: ChatbotTaskIdSchema,
257
- label: z3.string().min(1).max(60),
258
- prompt: z3.string().max(4e3),
198
+ label: z2.string().min(1).max(60),
199
+ prompt: z2.string().max(4e3),
259
200
  // Audience names allowed to see this task; [] = all — same semantics as SectionMeta.access.
260
- access: z3.array(z3.string()).default([])
201
+ access: z2.array(z2.string()).default([])
261
202
  });
262
- var ChatbotConfigSchema = z3.object({
263
- enabled: z3.boolean().default(false),
203
+ var ChatbotConfigSchema = z2.object({
204
+ enabled: z2.boolean().default(false),
264
205
  // Assistant display name shown in the widget header and used in the system
265
206
  // prompt. Blank falls back to "Portal Assistant" (resolveChatbotName).
266
- name: z3.string().max(60).default("Portal Assistant"),
207
+ name: z2.string().max(60).default("Portal Assistant"),
267
208
  // Per-audience name overrides, keyed by audience name — same inert-when-
268
209
  // deselected semantics as audiencePrompts.
269
- audienceNames: z3.record(z3.string(), z3.string().max(60)).default({}),
210
+ audienceNames: z2.record(z2.string(), z2.string().max(60)).default({}),
270
211
  // Brand-flavored waiting phrases, shown (with "…" appended) while the
271
212
  // assistant streams no text yet. Empty = the widget's "Thinking…" default.
272
- thinkingPhrases: z3.array(z3.string().max(80)).max(30).default([]),
273
- systemPrompt: z3.string().max(8e3).default(""),
213
+ thinkingPhrases: z2.array(z2.string().max(80)).max(30).default([]),
214
+ systemPrompt: z2.string().max(8e3).default(""),
274
215
  // Audience names the widget is shown to — strict opt-in: [] = no viewer
275
216
  // sees it (editors always can via /edit). Gates: [...slug].astro + /api/chat.
276
- audiences: z3.array(z3.string()).default([]),
217
+ audiences: z2.array(z2.string()).default([]),
277
218
  // Per-audience prompt overlays, keyed by audience name. Appended AFTER the
278
219
  // base systemPrompt, and ONLY for requests whose session audience matches
279
220
  // (or an editor's explicit test-panel simulation) — enforced in
280
221
  // assembleBrandChat. Keys are not validated against the audience list:
281
222
  // entries for deselected/renamed audiences are inert (strict opt-in means
282
223
  // those audiences cannot chat at all).
283
- audiencePrompts: z3.record(z3.string(), z3.string().max(8e3)).default({}),
284
- tasks: z3.array(ChatbotTaskSchema).max(20).default([])
224
+ audiencePrompts: z2.record(z2.string(), z2.string().max(8e3)).default({}),
225
+ tasks: z2.array(ChatbotTaskSchema).max(20).default([])
285
226
  }).superRefine((cfg, ctx) => {
286
227
  const seen = /* @__PURE__ */ new Set();
287
228
  for (const t of cfg.tasks) {
288
229
  if (seen.has(t.id)) {
289
- ctx.addIssue({ code: z3.ZodIssueCode.custom, message: `Duplicate task id "${t.id}"` });
230
+ ctx.addIssue({ code: z2.ZodIssueCode.custom, message: `Duplicate task id "${t.id}"` });
290
231
  }
291
232
  seen.add(t.id);
292
233
  }
293
234
  });
294
- var SiteConfigSchema = z3.object({
295
- siteName: z3.string().default("Brand Portal"),
235
+ var SiteConfigSchema = z2.object({
236
+ siteName: z2.string().default("Brand Portal"),
296
237
  primaryColor: HexColorSchema.default("#009ca6"),
297
238
  primaryContrast: HexColorSchema.default("#f0f0f0"),
298
239
  // Dark-mode overrides for the brand primary / accent. Only applied when
@@ -301,28 +242,28 @@ var SiteConfigSchema = z3.object({
301
242
  // CSS light-dark() function (see lib/theme-vars.ts).
302
243
  primaryColorDark: HexColorSchema.nullable().default(null),
303
244
  primaryContrastDark: HexColorSchema.nullable().default(null),
304
- darkMode: z3.enum(["light", "dark", "optional"]).default("light"),
245
+ darkMode: z2.enum(["light", "dark", "optional"]).default("light"),
305
246
  // Maps to the --radius-outer design token (see lib/corner-radius.ts);
306
247
  // defaults so pre-existing site-config.json files keep parsing.
307
- cornerRadius: z3.enum(CORNER_RADIUS_OPTIONS).default("medium"),
248
+ cornerRadius: z2.enum(CORNER_RADIUS_OPTIONS).default("medium"),
308
249
  headingFont: FontNameSchema.default("system-ui"),
309
250
  bodyFont: FontNameSchema.default("system-ui"),
310
- uppercaseHeadings: z3.boolean().default(true),
311
- uppercaseSubheadings: z3.boolean().default(true),
312
- uppercaseNavHeadings: z3.boolean().default(true),
313
- googleFontsUrl: z3.string().refine((url) => url.startsWith("https://fonts.googleapis.com/"), "Must be a Google Fonts URL").nullable().default(null),
251
+ uppercaseHeadings: z2.boolean().default(true),
252
+ uppercaseSubheadings: z2.boolean().default(true),
253
+ uppercaseNavHeadings: z2.boolean().default(true),
254
+ googleFontsUrl: z2.string().refine((url) => url.startsWith("https://fonts.googleapis.com/"), "Must be a Google Fonts URL").nullable().default(null),
314
255
  // Favicon stored as a data URL (SVG/PNG, small) so it travels with
315
256
  // site-config.json — no media manifest or CDN round-trip needed.
316
- favicon: z3.string().refine((v) => v.startsWith("data:image/"), "Favicon must be an image data URL").nullable().default(null),
257
+ favicon: z2.string().refine((v) => v.startsWith("data:image/"), "Favicon must be an image data URL").nullable().default(null),
317
258
  // Optional site logo, stored as media-library references (so it participates
318
259
  // in usage tracking + GC protection, and its resolved URL is reusable for the
319
260
  // Phase 3 social-preview image). Every field defaults so pre-existing
320
261
  // site-config.json files keep parsing.
321
- logo: z3.object({
322
- light: z3.object({ imageId: z3.string() }),
323
- dark: z3.object({ imageId: z3.string() }).nullable().default(null),
324
- invertInDark: z3.boolean().default(false),
325
- showInNav: z3.boolean().default(true)
262
+ logo: z2.object({
263
+ light: z2.object({ imageId: z2.string() }),
264
+ dark: z2.object({ imageId: z2.string() }).nullable().default(null),
265
+ invertInDark: z2.boolean().default(false),
266
+ showInNav: z2.boolean().default(true)
326
267
  }).nullable().default(null),
327
268
  media: MediaConfigSchema.default(MediaConfigSchema.parse({})),
328
269
  // Composed social-preview raster, stored as a media-library reference so it
@@ -331,17 +272,17 @@ var SiteConfigSchema = z3.object({
331
272
  // (the /api/media route only serves exact generated-variant widths), so the
332
273
  // og:image URL + dimensions are correct. Defaults null so pre-existing
333
274
  // configs keep parsing and sites without a preview emit no og:image tags.
334
- previewImage: z3.object({
335
- imageId: z3.string(),
336
- width: z3.number().int().positive(),
337
- height: z3.number().int().positive(),
275
+ previewImage: z2.object({
276
+ imageId: z2.string(),
277
+ width: z2.number().int().positive(),
278
+ height: z2.number().int().positive(),
338
279
  // Compose-logic version that produced this raster. Pre-existing rasters
339
280
  // (and manifests written before this field) default to 0, which is below
340
281
  // any current PREVIEW_COMPOSE_VERSION, so the editor regenerates them.
341
- version: z3.number().int().nonnegative().default(0)
282
+ version: z2.number().int().nonnegative().default(0)
342
283
  }).nullable().default(null),
343
284
  // Optional site description → og:description + <meta name="description">.
344
- description: z3.string().max(300).nullable().default(null),
285
+ description: z2.string().max(300).nullable().default(null),
345
286
  // Brand chatbot config (editor-owned; the platform kill switch lives in the
346
287
  // sites table, not here). Every field defaults so pre-existing
347
288
  // site-config.json files keep parsing.
@@ -349,11 +290,6 @@ var SiteConfigSchema = z3.object({
349
290
  });
350
291
 
351
292
  export {
352
- TextLineSchema,
353
- MediaReferenceSchema,
354
- SingleMediaReferenceSchema,
355
- HexColorSchema,
356
- FontNameSchema,
357
293
  VariantSchema,
358
294
  MediaFolderSchema,
359
295
  MediaItemSchema,