@drawnagency/primitives 0.1.66 → 0.1.68

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 (88) hide show
  1. package/dist/chunk-4YEOTFVU.js +14 -0
  2. package/dist/{chunk-VU3XR362.js → chunk-6UDYJQL6.js} +1 -1
  3. package/dist/{chunk-7IMQVDDJ.js → chunk-EWKCEPMW.js} +1 -1
  4. package/dist/{chunk-XNGG5AGI.js → chunk-KWBM27UR.js} +1 -1
  5. package/dist/{chunk-TEYTLQVH.js → chunk-QKOIEWZ4.js} +33 -1
  6. package/dist/chunk-TYYCKVAW.js +968 -0
  7. package/dist/{chunk-VEIDANEU.js → chunk-VVK6ZRCN.js} +128 -41
  8. package/dist/{chunk-ZYXLNJ5M.js → chunk-WNPMBFD6.js} +4 -4
  9. package/dist/{chunk-DQTKWKSK.js → chunk-WXVKX6PY.js} +12 -3
  10. package/dist/components/chat/ChatPanel.d.ts +31 -0
  11. package/dist/components/chat/ChatPanel.d.ts.map +1 -0
  12. package/dist/components/chat/ChatWidget.d.ts +11 -0
  13. package/dist/components/chat/ChatWidget.d.ts.map +1 -0
  14. package/dist/components/primitives/defineHeadingSection.d.ts +2 -0
  15. package/dist/components/primitives/defineHeadingSection.d.ts.map +1 -1
  16. package/dist/components/primitives/index.js +5 -5
  17. package/dist/components/sections/Button/index.d.ts.map +1 -1
  18. package/dist/components/sections/Colors/index.d.ts.map +1 -1
  19. package/dist/components/sections/Colors/schema.d.ts.map +1 -1
  20. package/dist/components/sections/Container/index.d.ts.map +1 -1
  21. package/dist/components/sections/DoDontMedia/index.d.ts.map +1 -1
  22. package/dist/components/sections/IconList/IconList.d.ts +2 -1
  23. package/dist/components/sections/IconList/IconList.d.ts.map +1 -1
  24. package/dist/components/sections/IconList/IconListSettings.d.ts +2 -1
  25. package/dist/components/sections/IconList/IconListSettings.d.ts.map +1 -1
  26. package/dist/components/sections/IconList/index.d.ts +1 -0
  27. package/dist/components/sections/IconList/index.d.ts.map +1 -1
  28. package/dist/components/sections/LinkHeading/index.d.ts.map +1 -1
  29. package/dist/components/sections/Media/index.d.ts.map +1 -1
  30. package/dist/components/sections/Prose/index.d.ts.map +1 -1
  31. package/dist/components/sections/Spacer/index.d.ts.map +1 -1
  32. package/dist/components/sections/SubHeading/index.d.ts.map +1 -1
  33. package/dist/components/sections/SubSubHeading/index.d.ts.map +1 -1
  34. package/dist/components/sections/all-sections.d.ts +1 -0
  35. package/dist/components/sections/all-sections.d.ts.map +1 -1
  36. package/dist/components/sections/brand-guide.d.ts +1 -0
  37. package/dist/components/sections/brand-guide.d.ts.map +1 -1
  38. package/dist/components/sections/brand-guide.js +5 -5
  39. package/dist/components/sections/register-schemas.js +13 -943
  40. package/dist/components/sections/register.js +36 -0
  41. package/dist/components/shell/ChatbotConfigModal.d.ts +13 -0
  42. package/dist/components/shell/ChatbotConfigModal.d.ts.map +1 -0
  43. package/dist/components/shell/EditorShell.d.ts +2 -1
  44. package/dist/components/shell/EditorShell.d.ts.map +1 -1
  45. package/dist/index.js +31 -24
  46. package/dist/lib/index.d.ts +1 -0
  47. package/dist/lib/index.d.ts.map +1 -1
  48. package/dist/lib/index.js +7 -4
  49. package/dist/lib/insert-menu.d.ts +19 -0
  50. package/dist/lib/insert-menu.d.ts.map +1 -0
  51. package/dist/lib/platform-broker.d.ts +7 -0
  52. package/dist/lib/platform-broker.d.ts.map +1 -1
  53. package/dist/lib/platform-broker.js +27 -1
  54. package/dist/lib/registry.d.ts +23 -0
  55. package/dist/lib/registry.d.ts.map +1 -1
  56. package/dist/media/index.js +3 -3
  57. package/dist/schemas/index.js +6 -2
  58. package/dist/schemas/site-config.d.ts +30 -0
  59. package/dist/schemas/site-config.d.ts.map +1 -1
  60. package/dist/types/database.d.ts +296 -34
  61. package/dist/types/database.d.ts.map +1 -1
  62. package/package.json +5 -1
  63. package/src/components/chat/ChatPanel.tsx +152 -0
  64. package/src/components/chat/ChatWidget.tsx +38 -0
  65. package/src/components/primitives/defineHeadingSection.tsx +18 -2
  66. package/src/components/sections/Button/index.tsx +10 -3
  67. package/src/components/sections/Colors/index.tsx +15 -7
  68. package/src/components/sections/Colors/schema.ts +5 -2
  69. package/src/components/sections/Container/index.tsx +19 -3
  70. package/src/components/sections/DoDontMedia/index.tsx +18 -7
  71. package/src/components/sections/IconList/IconList.tsx +43 -19
  72. package/src/components/sections/IconList/IconListSettings.tsx +58 -11
  73. package/src/components/sections/IconList/index.tsx +51 -7
  74. package/src/components/sections/LinkHeading/index.tsx +2 -0
  75. package/src/components/sections/Media/index.tsx +15 -6
  76. package/src/components/sections/Prose/index.tsx +9 -1
  77. package/src/components/sections/Spacer/index.tsx +2 -0
  78. package/src/components/sections/SubHeading/index.tsx +2 -0
  79. package/src/components/sections/SubSubHeading/index.tsx +2 -0
  80. package/src/components/shell/ChatbotConfigModal.tsx +152 -0
  81. package/src/components/shell/EditorShell.tsx +41 -20
  82. package/src/lib/index.ts +1 -0
  83. package/src/lib/insert-menu.ts +42 -0
  84. package/src/lib/platform-broker.ts +36 -0
  85. package/src/lib/registry.ts +24 -0
  86. package/src/schemas/site-config.ts +36 -0
  87. package/src/types/database.ts +284 -36
  88. package/dist/chunk-ZGFAYZWB.js +0 -8
@@ -0,0 +1,42 @@
1
+ import type { ReactNode } from "react";
2
+ import type { SectionDefinition } from "./registry";
3
+ import type { SectionContent } from "../schemas/sections";
4
+
5
+ /** Namespacing prefix for preset selections in the Add-section menu. */
6
+ export const PRESET_PREFIX = "__preset:";
7
+
8
+ /** One Add-section menu entry: a section `type`, or `__preset:<presetId>`. */
9
+ export interface InsertMenuOption {
10
+ type: string;
11
+ label: string;
12
+ icon?: ReactNode;
13
+ }
14
+
15
+ /** Every non-spacer section type, followed by presets contributed by registered
16
+ * sections. Presets appear only when their owning section is registered, so a
17
+ * core-only build (no brand-guide sections) shows no brand-guide presets. */
18
+ export function buildInsertMenuOptions(sections: SectionDefinition[]): InsertMenuOption[] {
19
+ const typeOptions = sections
20
+ .filter((def) => def.type !== "spacer")
21
+ .map((def) => ({ type: def.type, label: def.label, icon: def.icon }));
22
+ const presetOptions = sections
23
+ .flatMap((def) => def.presets ?? [])
24
+ .map((p) => ({ type: `${PRESET_PREFIX}${p.id}`, label: p.label, icon: p.icon }));
25
+ return [...typeOptions, ...presetOptions];
26
+ }
27
+
28
+ /** Resolve an Add-menu selection to ready-to-insert content. `newId` mints ids for
29
+ * any nested children a preset creates. Returns null for an unknown type/preset. */
30
+ export function resolveInsertedContent(
31
+ selection: string,
32
+ sections: SectionDefinition[],
33
+ newId: () => string,
34
+ ): SectionContent | null {
35
+ if (selection.startsWith(PRESET_PREFIX)) {
36
+ const id = selection.slice(PRESET_PREFIX.length);
37
+ const preset = sections.flatMap((def) => def.presets ?? []).find((p) => p.id === id);
38
+ return preset ? preset.build(newId) : null;
39
+ }
40
+ const def = sections.find((d) => d.type === selection);
41
+ return def ? (def.defaults() as SectionContent) : null;
42
+ }
@@ -70,3 +70,39 @@ export async function platformBroker<T = unknown>(
70
70
 
71
71
  throw lastError instanceof Error ? lastError : new Error("Platform broker unreachable");
72
72
  }
73
+
74
+ /**
75
+ * Streaming variant of platformBroker for SSE endpoints (the LLM broker).
76
+ * Same auth headers; retries only pre-stream connection failures — once bytes
77
+ * are flowing there is no safe retry. Non-2xx throws with the status ONLY
78
+ * (never the body: stream endpoints may proxy provider errors).
79
+ */
80
+ export async function platformBrokerStream(
81
+ path: string,
82
+ body: unknown,
83
+ ): Promise<ReadableStream<Uint8Array>> {
84
+ const apiUrl = env("PLATFORM_API_URL");
85
+ const apiKey = env("PLATFORM_API_KEY");
86
+ const siteId = env("PORTAL_SITE_ID");
87
+ const url = `${apiUrl}${path}`;
88
+
89
+ let lastError: unknown;
90
+ for (let attempt = 0; attempt < ATTEMPTS; attempt++) {
91
+ let res: Response;
92
+ try {
93
+ res = await fetch(url, {
94
+ method: "POST",
95
+ headers: { "x-api-key": apiKey, "x-site-id": siteId, "Content-Type": "application/json" },
96
+ body: JSON.stringify(body),
97
+ });
98
+ } catch (err) {
99
+ lastError = err;
100
+ if (attempt === ATTEMPTS - 1) throw err;
101
+ await sleep(RETRY_BASE_MS * 2 ** attempt);
102
+ continue;
103
+ }
104
+ if (!res.ok || !res.body) throw new Error(`Platform broker error (${res.status})`);
105
+ return res.body;
106
+ }
107
+ throw lastError instanceof Error ? lastError : new Error("Platform broker unreachable");
108
+ }
@@ -2,6 +2,7 @@ import type { ZodType, z } from "zod";
2
2
  import type { ComponentType, ReactNode } from "react";
3
3
  import type { Audience } from "../schemas/auth";
4
4
  import type { LinkValue } from "../schemas/link";
5
+ import type { SectionContent } from "../schemas/sections";
5
6
 
6
7
  // --- Settings field types ---
7
8
 
@@ -106,6 +107,19 @@ export interface WrapperProps {
106
107
 
107
108
  // --- Section definition ---
108
109
 
110
+ /**
111
+ * A ready-to-insert composite (e.g. a container of preconfigured child sections),
112
+ * surfaced in the Add-section menu. Contributed by the section definition that owns
113
+ * the composition, so it rides the section registry and disappears in a core-only
114
+ * build that never registers that section. `newId` mints unique ids for nested children.
115
+ */
116
+ export interface SectionPreset {
117
+ id: string;
118
+ label: string;
119
+ icon?: ReactNode;
120
+ build(newId: () => string): SectionContent;
121
+ }
122
+
109
123
  export interface SectionDefinition<T = unknown> {
110
124
  type: string;
111
125
  /** Grouping label. `"brand-guide"` marks opinionated sections separable from the
@@ -136,6 +150,14 @@ export interface SectionDefinition<T = unknown> {
136
150
  * into a trailing 'Other' tab.
137
151
  */
138
152
  settingsTabs?: { label: string; fields: string[] }[];
153
+ /** Composite blueprints for the Add-section menu (see SectionPreset). */
154
+ presets?: SectionPreset[];
155
+ /**
156
+ * Human/agent-facing prose describing when to use this section type and how to
157
+ * author it well. Surfaced by the get_section_schema tool as the JSON Schema
158
+ * top-level `description`. Presentation/metadata only — not validated.
159
+ */
160
+ authoringNote?: string;
139
161
  }
140
162
 
141
163
  // --- defineSection ---
@@ -162,6 +184,8 @@ type DefineSectionInput<S extends ZodType> = {
162
184
  * into a trailing 'Other' tab.
163
185
  */
164
186
  settingsTabs?: { label: string; fields: string[] }[];
187
+ presets?: SectionPreset[];
188
+ authoringNote?: string;
165
189
  };
166
190
 
167
191
  export function defineSection<S extends ZodType>(
@@ -132,6 +132,38 @@ export function normalizeSiteIndex(raw: unknown): SiteIndex {
132
132
  return IndexSchema.parse(raw);
133
133
  }
134
134
 
135
+ // Task ids share the audience-name slug rules (lowercase alnum/dash/underscore).
136
+ const ChatbotTaskIdSchema = z.string().min(1).max(32).regex(/^[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?$/,
137
+ "Task id must be lowercase letters, numbers, dashes, or underscores");
138
+
139
+ export const ChatbotTaskSchema = z.object({
140
+ id: ChatbotTaskIdSchema,
141
+ label: z.string().min(1).max(60),
142
+ prompt: z.string().max(4_000),
143
+ // Audience names allowed to see this task; [] = all — same semantics as SectionMeta.access.
144
+ access: z.array(z.string()).default([]),
145
+ });
146
+ export type ChatbotTask = z.infer<typeof ChatbotTaskSchema>;
147
+
148
+ export const ChatbotConfigSchema = z
149
+ .object({
150
+ enabled: z.boolean().default(false),
151
+ systemPrompt: z.string().max(8_000).default(""),
152
+ // Audience names the widget is shown to; [] = all audiences.
153
+ audiences: z.array(z.string()).default([]),
154
+ tasks: z.array(ChatbotTaskSchema).max(20).default([]),
155
+ })
156
+ .superRefine((cfg, ctx) => {
157
+ const seen = new Set<string>();
158
+ for (const t of cfg.tasks) {
159
+ if (seen.has(t.id)) {
160
+ ctx.addIssue({ code: z.ZodIssueCode.custom, message: `Duplicate task id "${t.id}"` });
161
+ }
162
+ seen.add(t.id);
163
+ }
164
+ });
165
+ export type ChatbotConfig = z.infer<typeof ChatbotConfigSchema>;
166
+
135
167
  export const SiteConfigSchema = z.object({
136
168
  siteName: z.string().default("Brand Portal"),
137
169
  primaryColor: HexColorSchema.default("#009ca6"),
@@ -153,6 +185,10 @@ export const SiteConfigSchema = z.object({
153
185
  .nullable()
154
186
  .default(null),
155
187
  media: MediaConfigSchema.default(MediaConfigSchema.parse({})),
188
+ // Brand chatbot config (editor-owned; the platform kill switch lives in the
189
+ // sites table, not here). Every field defaults so pre-existing
190
+ // site-config.json files keep parsing.
191
+ chatbot: ChatbotConfigSchema.default({ enabled: false, systemPrompt: "", audiences: [], tasks: [] }),
156
192
  });
157
193
 
158
194
  export type SiteConfig = z.infer<typeof SiteConfigSchema>;
@@ -68,6 +68,41 @@ export type Database = {
68
68
  },
69
69
  ]
70
70
  }
71
+ audit_log: {
72
+ Row: {
73
+ action: string
74
+ actor_platform_user_id: string | null
75
+ created_at: string
76
+ id: string
77
+ metadata: Json
78
+ target_site_id: string | null
79
+ }
80
+ Insert: {
81
+ action: string
82
+ actor_platform_user_id?: string | null
83
+ created_at?: string
84
+ id?: string
85
+ metadata?: Json
86
+ target_site_id?: string | null
87
+ }
88
+ Update: {
89
+ action?: string
90
+ actor_platform_user_id?: string | null
91
+ created_at?: string
92
+ id?: string
93
+ metadata?: Json
94
+ target_site_id?: string | null
95
+ }
96
+ Relationships: [
97
+ {
98
+ foreignKeyName: "audit_log_actor_platform_user_id_fkey"
99
+ columns: ["actor_platform_user_id"]
100
+ isOneToOne: false
101
+ referencedRelation: "platform_users"
102
+ referencedColumns: ["id"]
103
+ },
104
+ ]
105
+ }
71
106
  bug_reports: {
72
107
  Row: {
73
108
  category: string
@@ -115,6 +150,41 @@ export type Database = {
115
150
  },
116
151
  ]
117
152
  }
153
+ chat_usage: {
154
+ Row: {
155
+ day: string
156
+ input_tokens: number
157
+ output_tokens: number
158
+ requests: number
159
+ site_id: string
160
+ updated_at: string
161
+ }
162
+ Insert: {
163
+ day: string
164
+ input_tokens?: number
165
+ output_tokens?: number
166
+ requests?: number
167
+ site_id: string
168
+ updated_at?: string
169
+ }
170
+ Update: {
171
+ day?: string
172
+ input_tokens?: number
173
+ output_tokens?: number
174
+ requests?: number
175
+ site_id?: string
176
+ updated_at?: string
177
+ }
178
+ Relationships: [
179
+ {
180
+ foreignKeyName: "chat_usage_site_id_fkey"
181
+ columns: ["site_id"]
182
+ isOneToOne: false
183
+ referencedRelation: "sites"
184
+ referencedColumns: ["id"]
185
+ },
186
+ ]
187
+ }
118
188
  deploy_status: {
119
189
  Row: {
120
190
  commit_sha: string | null
@@ -227,8 +297,148 @@ export type Database = {
227
297
  },
228
298
  ]
229
299
  }
300
+ oauth_auth_codes: {
301
+ Row: {
302
+ client_id: string
303
+ code_challenge: string
304
+ code_hash: string
305
+ consumed_at: string | null
306
+ created_at: string
307
+ expires_at: string
308
+ platform_user_id: string
309
+ redirect_uri: string
310
+ resource: string | null
311
+ scopes: string[]
312
+ }
313
+ Insert: {
314
+ client_id: string
315
+ code_challenge: string
316
+ code_hash: string
317
+ consumed_at?: string | null
318
+ created_at?: string
319
+ expires_at: string
320
+ platform_user_id: string
321
+ redirect_uri: string
322
+ resource?: string | null
323
+ scopes?: string[]
324
+ }
325
+ Update: {
326
+ client_id?: string
327
+ code_challenge?: string
328
+ code_hash?: string
329
+ consumed_at?: string | null
330
+ created_at?: string
331
+ expires_at?: string
332
+ platform_user_id?: string
333
+ redirect_uri?: string
334
+ resource?: string | null
335
+ scopes?: string[]
336
+ }
337
+ Relationships: [
338
+ {
339
+ foreignKeyName: "oauth_auth_codes_platform_user_id_fkey"
340
+ columns: ["platform_user_id"]
341
+ isOneToOne: false
342
+ referencedRelation: "platform_users"
343
+ referencedColumns: ["id"]
344
+ },
345
+ ]
346
+ }
347
+ oauth_clients: {
348
+ Row: {
349
+ client_id: string
350
+ client_id_issued_at: number | null
351
+ client_metadata: Json
352
+ client_secret_hash: string | null
353
+ created_at: string
354
+ redirect_uris: string[]
355
+ }
356
+ Insert: {
357
+ client_id: string
358
+ client_id_issued_at?: number | null
359
+ client_metadata?: Json
360
+ client_secret_hash?: string | null
361
+ created_at?: string
362
+ redirect_uris: string[]
363
+ }
364
+ Update: {
365
+ client_id?: string
366
+ client_id_issued_at?: number | null
367
+ client_metadata?: Json
368
+ client_secret_hash?: string | null
369
+ created_at?: string
370
+ redirect_uris?: string[]
371
+ }
372
+ Relationships: []
373
+ }
374
+ oauth_rate_limits: {
375
+ Row: {
376
+ count: number
377
+ key: string
378
+ updated_at: string
379
+ window_start: string
380
+ }
381
+ Insert: {
382
+ count?: number
383
+ key: string
384
+ updated_at?: string
385
+ window_start?: string
386
+ }
387
+ Update: {
388
+ count?: number
389
+ key?: string
390
+ updated_at?: string
391
+ window_start?: string
392
+ }
393
+ Relationships: []
394
+ }
395
+ oauth_refresh_tokens: {
396
+ Row: {
397
+ client_id: string
398
+ created_at: string
399
+ expires_at: string
400
+ family_id: string
401
+ platform_user_id: string
402
+ prev_token_hash: string | null
403
+ revoked_at: string | null
404
+ rotated_at: string | null
405
+ token_hash: string
406
+ }
407
+ Insert: {
408
+ client_id: string
409
+ created_at?: string
410
+ expires_at: string
411
+ family_id: string
412
+ platform_user_id: string
413
+ prev_token_hash?: string | null
414
+ revoked_at?: string | null
415
+ rotated_at?: string | null
416
+ token_hash: string
417
+ }
418
+ Update: {
419
+ client_id?: string
420
+ created_at?: string
421
+ expires_at?: string
422
+ family_id?: string
423
+ platform_user_id?: string
424
+ prev_token_hash?: string | null
425
+ revoked_at?: string | null
426
+ rotated_at?: string | null
427
+ token_hash?: string
428
+ }
429
+ Relationships: [
430
+ {
431
+ foreignKeyName: "oauth_refresh_tokens_platform_user_id_fkey"
432
+ columns: ["platform_user_id"]
433
+ isOneToOne: false
434
+ referencedRelation: "platform_users"
435
+ referencedColumns: ["id"]
436
+ },
437
+ ]
438
+ }
230
439
  platform_users: {
231
440
  Row: {
441
+ can_provision: boolean
232
442
  created_at: string | null
233
443
  email: string
234
444
  github_user_id: number | null
@@ -237,6 +447,7 @@ export type Database = {
237
447
  user_id: string
238
448
  }
239
449
  Insert: {
450
+ can_provision?: boolean
240
451
  created_at?: string | null
241
452
  email: string
242
453
  github_user_id?: number | null
@@ -245,6 +456,7 @@ export type Database = {
245
456
  user_id: string
246
457
  }
247
458
  Update: {
459
+ can_provision?: boolean
248
460
  created_at?: string | null
249
461
  email?: string
250
462
  github_user_id?: number | null
@@ -254,6 +466,41 @@ export type Database = {
254
466
  }
255
467
  Relationships: []
256
468
  }
469
+ rate_limits: {
470
+ Row: {
471
+ count: number
472
+ key: string
473
+ limiter: string
474
+ site_id: string
475
+ updated_at: string
476
+ window_start: string
477
+ }
478
+ Insert: {
479
+ count?: number
480
+ key: string
481
+ limiter: string
482
+ site_id: string
483
+ updated_at?: string
484
+ window_start?: string
485
+ }
486
+ Update: {
487
+ count?: number
488
+ key?: string
489
+ limiter?: string
490
+ site_id?: string
491
+ updated_at?: string
492
+ window_start?: string
493
+ }
494
+ Relationships: [
495
+ {
496
+ foreignKeyName: "rate_limits_site_id_fkey"
497
+ columns: ["site_id"]
498
+ isOneToOne: false
499
+ referencedRelation: "sites"
500
+ referencedColumns: ["id"]
501
+ },
502
+ ]
503
+ }
257
504
  site_api_keys: {
258
505
  Row: {
259
506
  created_at: string | null
@@ -323,8 +570,10 @@ export type Database = {
323
570
  }
324
571
  sites: {
325
572
  Row: {
573
+ chatbot_enabled: boolean
326
574
  created_at: string | null
327
575
  custom_domain: string | null
576
+ failed_step: string | null
328
577
  github_owner: string
329
578
  github_repo: string
330
579
  id: string
@@ -334,10 +583,13 @@ export type Database = {
334
583
  password_enabled: boolean
335
584
  provisioned_by: string | null
336
585
  provisioning_status: string
586
+ subdomain: string | null
337
587
  }
338
588
  Insert: {
589
+ chatbot_enabled?: boolean
339
590
  created_at?: string | null
340
591
  custom_domain?: string | null
592
+ failed_step?: string | null
341
593
  github_owner: string
342
594
  github_repo: string
343
595
  id?: string
@@ -347,10 +599,13 @@ export type Database = {
347
599
  password_enabled?: boolean
348
600
  provisioned_by?: string | null
349
601
  provisioning_status?: string
602
+ subdomain?: string | null
350
603
  }
351
604
  Update: {
605
+ chatbot_enabled?: boolean
352
606
  created_at?: string | null
353
607
  custom_domain?: string | null
608
+ failed_step?: string | null
354
609
  github_owner?: string
355
610
  github_repo?: string
356
611
  id?: string
@@ -360,6 +615,7 @@ export type Database = {
360
615
  password_enabled?: boolean
361
616
  provisioned_by?: string | null
362
617
  provisioning_status?: string
618
+ subdomain?: string | null
363
619
  }
364
620
  Relationships: [
365
621
  {
@@ -419,57 +675,49 @@ export type Database = {
419
675
  },
420
676
  ]
421
677
  }
422
- rate_limits: {
423
- Row: {
424
- site_id: string
425
- limiter: string
426
- key: string
427
- window_start: string
428
- count: number
429
- updated_at: string
430
- }
431
- Insert: {
432
- site_id: string
433
- limiter: string
434
- key: string
435
- window_start?: string
436
- count?: number
437
- updated_at?: string
438
- }
439
- Update: {
440
- site_id?: string
441
- limiter?: string
442
- key?: string
443
- window_start?: string
444
- count?: number
445
- updated_at?: string
446
- }
447
- Relationships: []
448
- }
449
678
  }
450
679
  Views: {
451
680
  [_ in never]: never
452
681
  }
453
682
  Functions: {
683
+ chat_usage_hit: {
684
+ Args: {
685
+ p_day: string
686
+ p_input_tokens: number
687
+ p_output_tokens: number
688
+ p_requests: number
689
+ p_site_id: string
690
+ }
691
+ Returns: undefined
692
+ }
454
693
  get_user_id_by_email: { Args: { lookup_email: string }; Returns: string }
455
694
  is_site_member: { Args: { p_site_id: string }; Returns: boolean }
456
695
  is_site_owner: { Args: { p_site_id: string }; Returns: boolean }
457
- revoke_site_user: {
458
- Args: { p_site_id: string; p_user_id: string }
459
- Returns: undefined
696
+ oauth_cleanup: { Args: { p_max_age_ms: number }; Returns: undefined }
697
+ oauth_rate_limit_hit: {
698
+ Args: { p_key: string; p_max: number; p_window_ms: number }
699
+ Returns: {
700
+ allowed: boolean
701
+ retry_after_ms: number
702
+ }[]
460
703
  }
704
+ provision_claim: { Args: { p_site_id: string }; Returns: boolean }
705
+ rate_limit_cleanup: { Args: { p_max_age_ms: number }; Returns: undefined }
461
706
  rate_limit_hit: {
462
707
  Args: {
463
- p_site_id: string
464
- p_limiter: string
465
708
  p_key: string
466
- p_window_ms: number
709
+ p_limiter: string
467
710
  p_max: number
711
+ p_site_id: string
712
+ p_window_ms: number
468
713
  }
469
- Returns: { allowed: boolean; retry_after_ms: number }[]
714
+ Returns: {
715
+ allowed: boolean
716
+ retry_after_ms: number
717
+ }[]
470
718
  }
471
- rate_limit_cleanup: {
472
- Args: { p_max_age_ms: number }
719
+ revoke_site_user: {
720
+ Args: { p_site_id: string; p_user_id: string }
473
721
  Returns: undefined
474
722
  }
475
723
  }
@@ -1,8 +0,0 @@
1
- // src/lib/pages.ts
2
- function slugifyPageSlug(input) {
3
- return input.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
4
- }
5
-
6
- export {
7
- slugifyPageSlug
8
- };