@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
@@ -15,6 +15,58 @@ export const AudienceColorSchema = HexColorSchema.nullable();
15
15
  export type AudienceName = z.infer<typeof AudienceNameSchema>;
16
16
  export type AudienceColor = z.infer<typeof AudienceColorSchema>;
17
17
 
18
+ /**
19
+ * A viewer sign-in name. Looser than an audience slug — dots are allowed, so
20
+ * `agency.jane` works — but still constrained enough to be typed correctly over
21
+ * the phone. Always lowercased before storage and lookup, so `Agency2` and
22
+ * `agency2` are the same login.
23
+ */
24
+ export const ViewerUsernameSchema = z
25
+ .string()
26
+ .min(1)
27
+ .max(64)
28
+ .regex(
29
+ /^[a-z0-9]([a-z0-9._-]*[a-z0-9])?$/,
30
+ "lowercase alphanumeric; dots, dashes and underscores allowed",
31
+ );
32
+
33
+ /** Normalize a typed username for storage and lookup. */
34
+ export function normalizeUsername(input: string): string {
35
+ return input.trim().toLowerCase();
36
+ }
37
+
38
+ /**
39
+ * Wire-facing username: lowercased and trimmed BEFORE validation, so `Agency4`
40
+ * is accepted and stored as `agency4` rather than 400-ing on a case difference.
41
+ * Everything else the base schema rejects still fails.
42
+ */
43
+ export const NormalizedUsernameSchema = z
44
+ .string()
45
+ .min(1)
46
+ .max(128)
47
+ .transform(normalizeUsername)
48
+ .pipe(ViewerUsernameSchema);
49
+
50
+ /** Minimum for a NEW credential password. Deliberately stricter than the
51
+ * audience passwords it replaces (which allowed a single character). */
52
+ export const VIEWER_PASSWORD_MIN_LENGTH = 8;
53
+
54
+ export const ViewerPasswordSchema = z.string().min(VIEWER_PASSWORD_MIN_LENGTH);
55
+
56
+ /** A credential as it travels to the editor and the Audience Details page.
57
+ * Never carries the hash or the sealed copy. */
58
+ export const ViewerCredentialSchema = z.object({
59
+ username: z.string(),
60
+ label: z.string().nullable(),
61
+ /** The audience slug this sign-in grants — its content access, verbatim. */
62
+ audienceName: z.string(),
63
+ createdAt: z.string(),
64
+ });
65
+
66
+ export type ViewerUsername = z.infer<typeof ViewerUsernameSchema>;
67
+ export type ViewerCredential = z.infer<typeof ViewerCredentialSchema>;
68
+
69
+
18
70
  /**
19
71
  * Convert a friendly display string into an audience slug.
20
72
  * Lowercases, replaces non-alphanumeric runs with single dashes,
@@ -21,8 +21,14 @@ export const AudienceSchema = z.object({
21
21
  displayName: z.string(),
22
22
  color: z.string().nullable(),
23
23
  readonly: z.boolean(),
24
+ /** Some way in exists: a credential in credential mode, an audience-level
25
+ * password in `.env` mode. Consumers that only ask "is this gated?" (admin
26
+ * dashboard, MCP) keep using this and need no knowledge of credentials. */
24
27
  hasPassword: z.boolean(),
25
28
  isDefault: z.boolean(),
29
+ /** Named sign-ins pointing at this audience. Always 0 in `.env` mode, which
30
+ * has no credentials — use `hasPassword` there. */
31
+ credentialCount: z.number().int().nonnegative().default(0),
26
32
  });
27
33
 
28
34
  export type Session = z.infer<typeof SessionSchema>;
@@ -26,7 +26,7 @@ export type SectionMeta = z.infer<typeof SectionMetaSchema>;
26
26
  // add its first segment here (the test in Step 1 guards the known set). This is
27
27
  // the single source of truth for reserved slugs; the schema, uniquePageSlug, and
28
28
  // /api/save all import it.
29
- export const RESERVED_SLUGS = ["edit", "api", "login", "set-password", "404", "present", "print"] as const;
29
+ export const RESERVED_SLUGS = ["edit", "api", "login", "set-password", "404", "present", "print", "audiences"] as const;
30
30
 
31
31
  // Subset of RESERVED_SLUGS the index schema hard-rejects at parse time. Only
32
32
  // slugs reserved since before client sites existed may hard-fail here: parse-
@@ -707,6 +707,54 @@ export type Database = {
707
707
  },
708
708
  ]
709
709
  }
710
+ viewer_credentials: {
711
+ Row: {
712
+ audience_id: string
713
+ created_at: string
714
+ id: string
715
+ label: string | null
716
+ password_cipher: string | null
717
+ password_hash: string
718
+ site_id: string
719
+ username: string
720
+ }
721
+ Insert: {
722
+ audience_id: string
723
+ created_at?: string
724
+ id?: string
725
+ label?: string | null
726
+ password_cipher?: string | null
727
+ password_hash: string
728
+ site_id: string
729
+ username: string
730
+ }
731
+ Update: {
732
+ audience_id?: string
733
+ created_at?: string
734
+ id?: string
735
+ label?: string | null
736
+ password_cipher?: string | null
737
+ password_hash?: string
738
+ site_id?: string
739
+ username?: string
740
+ }
741
+ Relationships: [
742
+ {
743
+ foreignKeyName: "viewer_credentials_audience_id_fkey"
744
+ columns: ["audience_id"]
745
+ isOneToOne: false
746
+ referencedRelation: "viewer_audiences"
747
+ referencedColumns: ["id"]
748
+ },
749
+ {
750
+ foreignKeyName: "viewer_credentials_site_id_fkey"
751
+ columns: ["site_id"]
752
+ isOneToOne: false
753
+ referencedRelation: "sites"
754
+ referencedColumns: ["id"]
755
+ },
756
+ ]
757
+ }
710
758
  }
711
759
  Views: {
712
760
  [_ in never]: never
@@ -722,6 +770,12 @@ export type Database = {
722
770
  site_id: string
723
771
  user_id: string
724
772
  }[]
773
+ SetofOptions: {
774
+ from: "*"
775
+ to: "editor_locks"
776
+ isOneToOne: false
777
+ isSetofReturn: true
778
+ }
725
779
  }
726
780
  chat_usage_hit: {
727
781
  Args: {
@@ -737,9 +791,9 @@ export type Database = {
737
791
  get_site_users_with_status: {
738
792
  Args: { p_site_id: string }
739
793
  Returns: {
740
- created_at: string | null
794
+ created_at: string
741
795
  email: string
742
- last_sign_in_at: string | null
796
+ last_sign_in_at: string
743
797
  role: string
744
798
  user_id: string
745
799
  }[]
@@ -767,10 +821,10 @@ export type Database = {
767
821
  p_token_hash: string
768
822
  }
769
823
  Returns: {
824
+ client_id: string
825
+ family_id: string
826
+ platform_user_id: string
770
827
  status: string
771
- family_id: string | null
772
- client_id: string | null
773
- platform_user_id: string | null
774
828
  }[]
775
829
  }
776
830
  provision_claim: { Args: { p_site_id: string }; Returns: boolean }
@@ -1,30 +0,0 @@
1
- import {
2
- HexColorSchema
3
- } from "./chunk-BGHWUJFV.js";
4
-
5
- // src/schemas/audience.ts
6
- import { z } from "zod";
7
- var AudienceNameSchema = z.string().min(1).max(32).regex(
8
- /^[a-z0-9]([a-z0-9_-]*[a-z0-9])?$/,
9
- "lowercase alphanumeric, dashes and underscores allowed"
10
- );
11
- var AudienceColorSchema = HexColorSchema.nullable();
12
- function slugifyAudienceName(input) {
13
- return input.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
14
- }
15
-
16
- // src/schemas/media-grid-options.ts
17
- import { z as z2 } from "zod";
18
- var MediaGridOptionsSchema = z2.object({
19
- square: z2.boolean().optional(),
20
- border: z2.boolean().optional(),
21
- crop: z2.boolean().optional(),
22
- showCaptions: z2.boolean().optional()
23
- }).default({});
24
-
25
- export {
26
- AudienceNameSchema,
27
- AudienceColorSchema,
28
- slugifyAudienceName,
29
- MediaGridOptionsSchema
30
- };