@revealui/core 0.12.2 → 0.12.4

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 (47) hide show
  1. package/dist/client/admin/components/AdminDashboard.d.ts.map +1 -1
  2. package/dist/client/admin/components/AdminDashboard.js +103 -6
  3. package/dist/client/admin/components/DocumentForm.d.ts.map +1 -1
  4. package/dist/client/admin/components/DocumentForm.js +5 -1
  5. package/dist/client/admin/page.d.ts.map +1 -1
  6. package/dist/client/admin/page.js +1 -1
  7. package/dist/client/admin/utils/apiClient.d.ts.map +1 -1
  8. package/dist/client/admin/utils/apiClient.js +27 -1
  9. package/dist/client/richtext/components/ImageUploadButton.d.ts.map +1 -1
  10. package/dist/client/richtext/components/ImageUploadButton.js +17 -4
  11. package/dist/client/richtext/components/upload.d.ts +7 -0
  12. package/dist/client/richtext/components/upload.d.ts.map +1 -1
  13. package/dist/client/richtext/components/upload.js +10 -0
  14. package/dist/client/richtext/nodes/DecoratorBlockNode.d.ts +4 -0
  15. package/dist/client/richtext/nodes/DecoratorBlockNode.d.ts.map +1 -1
  16. package/dist/client/richtext/nodes/DecoratorBlockNode.js +12 -0
  17. package/dist/features.d.ts +2 -0
  18. package/dist/features.d.ts.map +1 -1
  19. package/dist/features.js +2 -0
  20. package/dist/index.d.ts +1 -1
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +3 -1
  23. package/dist/license/mint-client.d.ts +6 -0
  24. package/dist/license/mint-client.d.ts.map +1 -1
  25. package/dist/license/mint-client.js +34 -16
  26. package/dist/license.d.ts +6 -0
  27. package/dist/license.d.ts.map +1 -1
  28. package/dist/license.js +15 -0
  29. package/dist/observability/capture.d.ts +63 -0
  30. package/dist/observability/capture.d.ts.map +1 -0
  31. package/dist/observability/capture.js +125 -0
  32. package/dist/observability/cron-failure-alert.d.ts +59 -0
  33. package/dist/observability/cron-failure-alert.d.ts.map +1 -0
  34. package/dist/observability/cron-failure-alert.js +109 -0
  35. package/dist/observability/index.d.ts +2 -0
  36. package/dist/observability/index.d.ts.map +1 -1
  37. package/dist/observability/index.js +2 -0
  38. package/dist/revforge-license-boot.d.ts +35 -0
  39. package/dist/revforge-license-boot.d.ts.map +1 -0
  40. package/dist/revforge-license-boot.js +115 -0
  41. package/dist/vite/index.d.ts +2 -0
  42. package/dist/vite/index.d.ts.map +1 -0
  43. package/dist/vite/index.js +6 -0
  44. package/dist/vite/withRevealUI.d.ts +62 -0
  45. package/dist/vite/withRevealUI.d.ts.map +1 -0
  46. package/dist/vite/withRevealUI.js +94 -0
  47. package/package.json +30 -3
@@ -1 +1 @@
1
- {"version":3,"file":"AdminDashboard.d.ts","sourceRoot":"","sources":["../../../../src/client/admin/components/AdminDashboard.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAEV,YAAY,EAGb,MAAM,yBAAyB,CAAC;AAUjC,UAAU,mBAAmB;IAC3B,MAAM,EAAE,YAAY,CAAC;IACrB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AA2YD,wBAAgB,cAAc,CAAC,EAAE,MAAM,EAAE,QAAqB,EAAE,EAAE,mBAAmB,+BAmVpF"}
1
+ {"version":3,"file":"AdminDashboard.d.ts","sourceRoot":"","sources":["../../../../src/client/admin/components/AdminDashboard.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAEV,YAAY,EAGb,MAAM,yBAAyB,CAAC;AAUjC,UAAU,mBAAmB;IAC3B,MAAM,EAAE,YAAY,CAAC;IACrB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AA2iBD,wBAAgB,cAAc,CAAC,EAAE,MAAM,EAAE,QAAqB,EAAE,EAAE,mBAAmB,+BAoVpF"}
@@ -75,11 +75,108 @@ function SignOutButton() {
75
75
  }, []);
76
76
  return (_jsx("button", { type: "button", onClick: () => void handleSignOut(), disabled: loading, className: "text-sm text-muted-foreground hover:text-foreground px-3 py-1.5 rounded-md hover:bg-muted transition-colors", children: loading ? 'Signing out...' : 'Sign Out' }));
77
77
  }
78
- // =============================================================================
79
- // Dashboard home view
80
- // =============================================================================
81
- function DashboardHome({ siteName, collections, globals, onCollectionClick, onGlobalClick, }) {
82
- return (_jsxs("div", { className: "min-h-screen bg-background", children: [_jsx("header", { className: "bg-card shadow-sm border-b", children: _jsx("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: _jsxs("div", { className: "flex justify-between items-center py-4", children: [_jsx("div", { className: "flex items-center", children: _jsx("h1", { className: "text-2xl font-bold text-foreground", children: `${siteName} Admin` }) }), _jsxs("div", { className: "flex items-center space-x-4", children: [_jsx("span", { className: "text-sm text-muted-foreground", children: "v0.1.0" }), _jsx(SignOutButton, {})] })] }) }) }), _jsx("main", { className: "max-w-7xl mx-auto py-6 sm:px-6 lg:px-8", children: _jsx("div", { className: "px-4 py-6 sm:px-0", children: _jsxs("div", { className: "grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3", children: [_jsxs("div", { className: "bg-card overflow-hidden shadow rounded-lg", children: [_jsx("div", { className: "p-5", children: _jsxs("div", { className: "flex items-center", children: [_jsx("div", { className: "flex-shrink-0", children: _jsxs("svg", { className: "h-8 w-8 text-muted-foreground", "aria-label": "Collections", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", role: "img", children: [_jsx("title", { children: "Collections" }), _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" })] }) }), _jsx("div", { className: "ml-5 w-0 flex-1", children: _jsxs("dl", { children: [_jsx("dt", { className: "text-sm font-medium text-muted-foreground truncate", children: "Collections" }), _jsx("dd", { className: "text-lg font-medium text-foreground", children: collections.length })] }) })] }) }), _jsx("div", { className: "bg-muted px-5 py-3", children: _jsx("div", { className: "text-sm", children: collections.length > 0 ? (_jsx("ul", { className: "space-y-1 max-h-48 overflow-y-auto", children: collections.map((collection) => (_jsx("li", { className: "text-muted-foreground hover:text-foreground", children: _jsx("button", { type: "button", onClick: () => onCollectionClick(collection), className: "hover:underline cursor-pointer", children: String(collection.slug) }) }, String(collection.slug)))) })) : (_jsx("p", { className: "text-muted-foreground", children: "No collections configured" })) }) })] }), _jsxs("div", { className: "bg-card overflow-hidden shadow rounded-lg", children: [_jsx("div", { className: "p-5", children: _jsxs("div", { className: "flex items-center", children: [_jsx("div", { className: "flex-shrink-0", children: _jsxs("svg", { className: "h-8 w-8 text-muted-foreground", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-labelledby": "globals-icon-title", role: "img", children: [_jsx("title", { id: "globals-icon-title", children: "Globals" }), _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 100 4m0-4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 100 4m0-4v2m0-6V4" })] }) }), _jsx("div", { className: "ml-5 w-0 flex-1", children: _jsxs("dl", { children: [_jsx("dt", { className: "text-sm font-medium text-muted-foreground truncate", children: "Globals" }), _jsx("dd", { className: "text-lg font-medium text-foreground", children: globals.length })] }) })] }) }), _jsx("div", { className: "bg-muted px-5 py-3", children: _jsx("div", { className: "text-sm", children: globals.length > 0 ? (_jsx("ul", { className: "space-y-1 max-h-32 overflow-y-auto", children: globals.map((global) => (_jsx("li", { className: "text-muted-foreground hover:text-foreground", children: _jsx("button", { type: "button", onClick: () => onGlobalClick(global), className: "hover:underline cursor-pointer", children: global.label || String(global.slug) }) }, String(global.slug)))) })) : (_jsx("p", { className: "text-muted-foreground", children: "No globals configured" })) }) })] }), _jsxs("div", { className: "bg-card overflow-hidden shadow rounded-lg", children: [_jsx("div", { className: "p-5", children: _jsxs("div", { className: "flex items-center", children: [_jsx("div", { className: "flex-shrink-0", children: _jsx("div", { className: "h-8 w-8 bg-success/15 rounded-full flex items-center justify-center", children: _jsxs("svg", { className: "h-5 w-5 text-success", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-labelledby": "system-status-icon-title", role: "img", children: [_jsx("title", { id: "system-status-icon-title", children: "System Status: Healthy" }), _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" })] }) }) }), _jsx("div", { className: "ml-5 w-0 flex-1", children: _jsxs("dl", { children: [_jsx("dt", { className: "text-sm font-medium text-muted-foreground truncate", children: "System Status" }), _jsx("dd", { className: "text-lg font-medium text-foreground", children: "Healthy" })] }) })] }) }), _jsx("div", { className: "bg-muted px-5 py-3", children: _jsxs("div", { className: "text-sm text-muted-foreground", children: [siteName, " admin is running successfully"] }) })] })] }) }) })] }));
78
+ const TAXONOMY_GROUPS = ['Operate', 'Build', 'Configure'];
79
+ function isTaxonomyGroup(value) {
80
+ return value === 'Operate' || value === 'Build' || value === 'Configure';
81
+ }
82
+ /**
83
+ * Buckets a collection into Operate / Build / Configure. A collection's own
84
+ * `admin.group` wins when it already names one of the three groups (a
85
+ * project can opt in explicitly). Otherwise the bucket falls out of
86
+ * structural traits every RevealCollectionConfig already carries: auth
87
+ * collections gate who can act (Configure), versioned collections are the
88
+ * ones worked day to day with drafts and publishing (Operate), and
89
+ * everything else is catalog or content structure (Build).
90
+ */
91
+ function classifyCollectionGroup(collection) {
92
+ if (isTaxonomyGroup(collection.admin?.group)) {
93
+ return collection.admin.group;
94
+ }
95
+ if (collection.auth)
96
+ return 'Configure';
97
+ if (collection.versions)
98
+ return 'Operate';
99
+ return 'Build';
100
+ }
101
+ function groupCollectionsByTaxonomy(collections) {
102
+ const grouped = {
103
+ Operate: [],
104
+ Build: [],
105
+ Configure: [],
106
+ };
107
+ for (const collection of collections) {
108
+ grouped[classifyCollectionGroup(collection)].push(collection);
109
+ }
110
+ return grouped;
111
+ }
112
+ /**
113
+ * Per-collection link overrides. A slug listed here has a dedicated page
114
+ * that supersedes the generic collection editor, so the dashboard links
115
+ * straight to it instead of opening the generic editor.
116
+ *
117
+ * GAP-452: the generic editor's create path posts JSON to a multipart-only
118
+ * endpoint and 400s for upload collections, so `media` must route to the
119
+ * media library instead.
120
+ */
121
+ const COLLECTION_LINK_OVERRIDES = {
122
+ media: '/media',
123
+ };
124
+ // Static icons: hoisted so the same element is reused across renders instead
125
+ // of re-created (they take no props and never change).
126
+ const collectionsIcon = (_jsx("svg", { className: "h-5 w-5 text-muted-foreground", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" }) }));
127
+ const globalsIcon = (_jsx("svg", { className: "h-5 w-5 text-muted-foreground", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 100 4m0-4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 100 4m0-4v2m0-6V4" }) }));
128
+ /**
129
+ * Small local equivalents of `@revealui/presentation`'s `Badge` / `Stat` /
130
+ * `StatusDot`, built from the same `--rvui-*` token bridge classes (`bg-muted`,
131
+ * `bg-success`, `bg-warning`, ...) this file already uses elsewhere.
132
+ *
133
+ * `@revealui/core` is imported by the Hono API server (`apps/server`), which
134
+ * never renders React. `@revealui/presentation` is a browser UI package built
135
+ * with Vite, a devDependency the server Docker image's install layer does not
136
+ * carry. Depending on it here pulled a client-only build tool into a headless
137
+ * server's dependency closure and broke the `migrate`/`server` Docker builds
138
+ * (turbo builds the whole workspace closure, `vite: ENOENT`). Reproducing the
139
+ * handful of classes these components render keeps the same visual result
140
+ * without adding that edge. See PR discussion for the audited alternative
141
+ * (moving the view into `apps/admin`, which already depends on presentation)
142
+ * — rejected because it duplicates the grouping/status logic across packages
143
+ * for no benefit over inlining a few CSS classes.
144
+ */
145
+ function CountBadge({ count }) {
146
+ return (_jsx("span", { className: "inline-flex items-center rounded-full bg-muted px-2 py-0.5 text-xs font-medium text-muted-foreground", children: count }));
147
+ }
148
+ function StatTile({ label, value, icon }) {
149
+ return (_jsxs("div", { className: "rounded-lg bg-card p-5 shadow", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("p", { className: "text-sm font-medium text-muted-foreground", children: label }), _jsx("div", { className: "rounded-md bg-muted p-1.5", children: icon })] }), _jsx("p", { className: "mt-2 text-2xl font-semibold tracking-tight text-foreground", children: value })] }));
150
+ }
151
+ function StatusIndicator({ degraded, label, pulse = false, }) {
152
+ const fill = degraded ? 'bg-warning' : 'bg-success';
153
+ return (_jsxs("span", { role: "img", "aria-label": label, className: "relative inline-flex size-2.5 shrink-0", children: [pulse && (_jsx("span", { "aria-hidden": "true", className: `absolute inline-flex size-full motion-safe:animate-ping rounded-full opacity-75 ${fill}` })), _jsx("span", { "aria-hidden": "true", className: `relative inline-flex size-2.5 rounded-full ${fill}` })] }));
154
+ }
155
+ function CollectionGroupCard({ group, collections, onCollectionClick, }) {
156
+ if (collections.length === 0)
157
+ return null;
158
+ const headingId = `dashboard-group-${group.toLowerCase()}`;
159
+ return (_jsxs("section", { "aria-labelledby": headingId, className: "overflow-hidden rounded-lg bg-card shadow", children: [_jsxs("div", { className: "flex items-center justify-between border-b px-5 py-3", children: [_jsx("h3", { id: headingId, className: "text-sm font-semibold text-foreground", children: group }), _jsx(CountBadge, { count: collections.length })] }), _jsx("ul", { className: "divide-y divide-border", children: collections.map((collection) => {
160
+ const slug = String(collection.slug);
161
+ const overrideHref = COLLECTION_LINK_OVERRIDES[slug];
162
+ const rowClassName = 'flex w-full items-center px-5 py-2.5 text-left text-sm font-medium text-muted-foreground transition-colors hover:bg-muted hover:text-foreground cursor-pointer';
163
+ return (_jsx("li", { children: overrideHref ? (_jsx("a", { href: overrideHref, className: rowClassName, children: slug })) : (_jsx("button", { type: "button", onClick: () => onCollectionClick(collection), className: rowClassName, children: slug })) }, slug));
164
+ }) })] }));
165
+ }
166
+ function GlobalsCard({ globals, onGlobalClick, }) {
167
+ return (_jsxs("section", { "aria-labelledby": "dashboard-globals", className: "overflow-hidden rounded-lg bg-card shadow", children: [_jsxs("div", { className: "flex items-center justify-between border-b px-5 py-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [globalsIcon, _jsx("h3", { id: "dashboard-globals", className: "text-sm font-semibold text-foreground", children: "Globals" })] }), _jsx(CountBadge, { count: globals.length })] }), globals.length > 0 ? (_jsx("ul", { className: "divide-y divide-border", children: globals.map((global) => (_jsx("li", { children: _jsx("button", { type: "button", onClick: () => onGlobalClick(global), className: "flex w-full items-center px-5 py-2.5 text-left text-sm font-medium text-muted-foreground transition-colors hover:bg-muted hover:text-foreground cursor-pointer", children: global.label || String(global.slug) }) }, String(global.slug)))) })) : (_jsx("p", { className: "px-5 py-4 text-sm text-muted-foreground", children: "No globals configured" }))] }));
168
+ }
169
+ /** System status card: a status-dot-led card, never a bare prose sentence. */
170
+ function SystemStatusCard({ degraded }) {
171
+ const word = degraded ? 'Degraded' : 'Healthy';
172
+ const description = degraded
173
+ ? 'The last admin action failed. Retry it or check the server logs.'
174
+ : 'The admin console is responding normally.';
175
+ return (_jsxs("section", { "aria-labelledby": "dashboard-system-status", className: "overflow-hidden rounded-lg bg-card shadow", children: [_jsxs("div", { className: "flex items-center justify-between border-b px-5 py-3", children: [_jsx("h3", { id: "dashboard-system-status", className: "text-sm font-semibold text-foreground", children: "System status" }), _jsxs("span", { className: "inline-flex items-center gap-2 text-sm font-medium text-foreground", children: [_jsx(StatusIndicator, { degraded: degraded, label: `System status: ${word}`, pulse: !degraded }), word] })] }), _jsx("p", { className: "px-5 py-4 text-sm text-muted-foreground", children: description })] }));
176
+ }
177
+ function DashboardHome({ siteName, collections, globals, degraded, onCollectionClick, onGlobalClick, }) {
178
+ const grouped = groupCollectionsByTaxonomy(collections);
179
+ return (_jsxs("div", { className: "min-h-screen bg-background", children: [_jsx("header", { className: "bg-card shadow-sm border-b", children: _jsx("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: _jsxs("div", { className: "flex justify-between items-center py-4", children: [_jsx("div", { className: "flex items-center", children: _jsx("h1", { className: "text-2xl font-bold text-foreground", children: `${siteName} Admin` }) }), _jsxs("div", { className: "flex shrink-0 items-center gap-3", children: [_jsxs("span", { className: "shrink-0 text-sm tabular-nums text-muted-foreground", title: "Application version", children: ["v", process.env.NEXT_PUBLIC_APP_VERSION ?? process.env.APP_VERSION ?? '0.0.0'] }), _jsx(SignOutButton, {})] })] }) }) }), _jsxs("main", { className: "max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8", children: [_jsxs("div", { className: "mb-6", children: [_jsx("h2", { className: "text-2xl font-bold tracking-tight text-foreground", children: "Overview" }), _jsxs("p", { className: "mt-1 text-sm text-muted-foreground", children: ["Collections, globals, and system status for ", siteName, "."] })] }), _jsxs("div", { className: "mb-8 grid grid-cols-1 gap-4 sm:grid-cols-3", children: [_jsx(StatTile, { label: "Collections", value: collections.length, icon: collectionsIcon }), _jsx(StatTile, { label: "Globals", value: globals.length, icon: globalsIcon }), _jsx(StatTile, { label: "Status", value: degraded ? 'Degraded' : 'Healthy', icon: _jsx(StatusIndicator, { degraded: degraded, label: degraded ? 'Degraded' : 'Healthy' }) })] }), _jsxs("div", { className: "grid grid-cols-1 gap-6 lg:grid-cols-3", children: [_jsx("div", { className: "lg:col-span-2 flex flex-col gap-6", children: collections.length > 0 ? (TAXONOMY_GROUPS.map((group) => (_jsx(CollectionGroupCard, { group: group, collections: grouped[group], onCollectionClick: onCollectionClick }, group)))) : (_jsx("div", { className: "rounded-lg bg-card p-5 shadow", children: _jsx("p", { className: "text-sm text-muted-foreground", children: "No collections configured" }) })) }), _jsxs("div", { className: "flex flex-col gap-6", children: [_jsx(GlobalsCard, { globals: globals, onGlobalClick: onGlobalClick }), _jsx(SystemStatusCard, { degraded: degraded })] })] })] })] }));
83
180
  }
84
181
  // =============================================================================
85
182
  // Error handling helpers
@@ -344,5 +441,5 @@ export function AdminDashboard({ config, siteName = 'RevealUI' }) {
344
441
  return (_jsxs("div", { className: "min-h-screen bg-background", children: [_jsx(AdminHeader, { title: state.view.global.label || String(state.view.global.slug), onBack: goToDashboard }), _jsx("main", { className: "max-w-7xl mx-auto py-6 sm:px-6 lg:px-8", children: _jsxs("div", { className: "max-w-3xl", children: [_jsx(StatusBanners, { error: state.error, successMessage: state.successMessage }), state.globalLoading && _jsx(LoadingSpinner, {}), !state.globalLoading && state.globalDocument && (_jsx(GlobalForm, { global: state.view.global, document: state.globalDocument, onSave: (data) => void handleSaveGlobal(data), onCancel: goToDashboard, isLoading: state.saving }))] }) })] }));
345
442
  }
346
443
  // ── Dashboard home ────────────────────────────────────────────────────
347
- return (_jsx(DashboardHome, { siteName: siteName, collections: collections, globals: globals, onCollectionClick: (c) => void handleCollectionClick(c), onGlobalClick: (g) => void handleGlobalClick(g) }));
444
+ return (_jsx(DashboardHome, { siteName: siteName, collections: collections, globals: globals, degraded: Boolean(state.error), onCollectionClick: (c) => void handleCollectionClick(c), onGlobalClick: (g) => void handleGlobalClick(g) }));
348
445
  }
@@ -1 +1 @@
1
- {"version":3,"file":"DocumentForm.d.ts","sourceRoot":"","sources":["../../../../src/client/admin/components/DocumentForm.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,KAAK,EACV,sBAAsB,EACtB,cAAc,EAEf,MAAM,yBAAyB,CAAC;AAiEjC,UAAU,iBAAiB;IACzB,UAAU,EAAE,sBAAsB,CAAC;IACnC,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IAChD,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,wBAAgB,YAAY,CAAC,EAC3B,UAAU,EACV,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,SAAiB,GAClB,EAAE,iBAAiB,qBA0DnB"}
1
+ {"version":3,"file":"DocumentForm.d.ts","sourceRoot":"","sources":["../../../../src/client/admin/components/DocumentForm.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,KAAK,EACV,sBAAsB,EACtB,cAAc,EAEf,MAAM,yBAAyB,CAAC;AAiEjC,UAAU,iBAAiB;IACzB,UAAU,EAAE,sBAAsB,CAAC;IACnC,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IAChD,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,wBAAgB,YAAY,CAAC,EAC3B,UAAU,EACV,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,SAAiB,GAClB,EAAE,iBAAiB,qBA8EnB"}
@@ -70,7 +70,11 @@ export function DocumentForm({ collection, document, onSave, onCancel, isLoading
70
70
  const handleFieldChange = (fieldName, value) => {
71
71
  setFormData((prev) => ({ ...prev, [fieldName]: value }));
72
72
  };
73
- return (_jsx("div", { className: "bg-card shadow overflow-hidden sm:rounded-lg", children: _jsxs("div", { className: "px-4 py-5 sm:p-6", children: [_jsxs("h3", { className: "text-lg leading-6 font-medium text-foreground mb-4", children: [document ? 'Edit' : 'Create', " ", collection.slug.slice(0, -1)] }), _jsxs("form", { onSubmit: handleSubmit, className: "space-y-6", children: [visibleFields.map((field) => (_jsxs("div", { children: [_jsxs("label", { htmlFor: field.name, className: "block text-sm font-medium text-foreground", children: [getFieldLabel(field), field.required && _jsx("span", { className: "text-red-500 ml-1", children: "*" })] }), _jsx("div", { className: "mt-1", children: _jsx(FieldInput, { field: field, value: field.name ? formData[field.name] : undefined, onChange: (value) => field.name && handleFieldChange(field.name, value) }) })] }, field.name || 'layout'))), _jsxs("div", { className: "flex justify-end space-x-3 pt-6", children: [_jsx("button", { type: "button", onClick: onCancel, className: "bg-card py-2 px-4 border border-input rounded-md shadow-sm text-sm font-medium text-foreground hover:bg-muted focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-background focus:ring-ring", children: "Cancel" }), _jsx("button", { type: "submit", disabled: isLoading, className: "inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-primary-foreground bg-primary hover:bg-primary/90 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-background focus:ring-ring disabled:opacity-50 disabled:cursor-not-allowed", children: isLoading ? 'Saving...' : 'Save' })] })] })] }) }));
73
+ return (_jsx("div", { className: "bg-card shadow overflow-hidden sm:rounded-lg", children: _jsxs("div", { className: "px-4 py-5 sm:p-6", children: [_jsxs("h3", { className: "text-lg leading-6 font-medium text-foreground mb-4", children: [document ? 'Edit' : 'Create', " ", collection.slug.slice(0, -1)] }), _jsxs("form", { onSubmit: handleSubmit, className: "space-y-6", children: [collection.upload && !document ? (_jsxs("div", { children: [_jsxs("label", { htmlFor: "__file", className: "block text-sm font-medium text-foreground", children: ["File", _jsx("span", { className: "text-red-500 ml-1", children: "*" })] }), _jsx("div", { className: "mt-1", children: _jsx("input", { type: "file", id: "__file", required: true, onChange: (e) => {
74
+ const file = e.target.files?.[0];
75
+ if (file)
76
+ handleFieldChange('file', file);
77
+ }, className: "block w-full text-sm text-muted-foreground file:mr-4 file:py-2 file:px-4 file:rounded-md file:border-0 file:text-sm file:font-medium file:bg-primary/10 file:text-primary hover:file:bg-primary/20" }) })] })) : null, visibleFields.map((field) => (_jsxs("div", { children: [_jsxs("label", { htmlFor: field.name, className: "block text-sm font-medium text-foreground", children: [getFieldLabel(field), field.required && _jsx("span", { className: "text-red-500 ml-1", children: "*" })] }), _jsx("div", { className: "mt-1", children: _jsx(FieldInput, { field: field, value: field.name ? formData[field.name] : undefined, onChange: (value) => field.name && handleFieldChange(field.name, value) }) })] }, field.name || 'layout'))), _jsxs("div", { className: "flex justify-end space-x-3 pt-6", children: [_jsx("button", { type: "button", onClick: onCancel, className: "bg-card py-2 px-4 border border-input rounded-md shadow-sm text-sm font-medium text-foreground hover:bg-muted focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-background focus:ring-ring", children: "Cancel" }), _jsx("button", { type: "submit", disabled: isLoading, className: "inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-primary-foreground bg-primary hover:bg-primary/90 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-background focus:ring-ring disabled:opacity-50 disabled:cursor-not-allowed", children: isLoading ? 'Saving...' : 'Save' })] })] })] }) }));
74
78
  }
75
79
  // ---------------------------------------------------------------------------
76
80
  // Array field: repeatable list of sub-fields
@@ -1 +1 @@
1
- {"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../../src/client/admin/page.tsx"],"names":[],"mappings":"AACA,UAAU,QAAQ;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE;QACN,WAAW,CAAC,EAAE,OAAO,EAAE,CAAC;QACxB,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;QACpB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;IACF,MAAM,EAAE,OAAO,CAAC;QAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IACzC,YAAY,EAAE,OAAO,CAAC;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE;QACN,WAAW,CAAC,EAAE,OAAO,EAAE,CAAC;QACxB,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;QACpB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;IACF,MAAM,EAAE,OAAO,CAAC;QAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IACzC,YAAY,EAAE,OAAO,CAAC;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,wBAAgB,QAAQ,CAAC,EAAE,MAAM,EAAE,EAAE,aAAa,+BA+KjD;AAED,wBAAgB,YAAY,gCAO3B;AAED,wBAAgB,oBAAoB,IAAI,QAAQ,CAS/C"}
1
+ {"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../../src/client/admin/page.tsx"],"names":[],"mappings":"AACA,UAAU,QAAQ;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE;QACN,WAAW,CAAC,EAAE,OAAO,EAAE,CAAC;QACxB,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;QACpB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;IACF,MAAM,EAAE,OAAO,CAAC;QAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IACzC,YAAY,EAAE,OAAO,CAAC;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE;QACN,WAAW,CAAC,EAAE,OAAO,EAAE,CAAC;QACxB,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;QACpB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;IACF,MAAM,EAAE,OAAO,CAAC;QAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IACzC,YAAY,EAAE,OAAO,CAAC;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,wBAAgB,QAAQ,CAAC,EAAE,MAAM,EAAE,EAAE,aAAa,+BAoLjD;AAED,wBAAgB,YAAY,gCAO3B;AAED,wBAAgB,oBAAoB,IAAI,QAAQ,CAS/C"}
@@ -6,7 +6,7 @@ export function RootPage({ config }) {
6
6
  // REVEALUI_TENANT_NAME. `||` not `??`: Compose `${VAR:-}` interpolation
7
7
  // delivers unset vars as empty strings.
8
8
  const siteName = process.env.REVEALUI_BRAND_NAME || process.env.REVEALUI_TENANT_NAME || 'RevealUI';
9
- return (_jsxs("div", { className: "min-h-screen bg-background", children: [_jsx("header", { className: "bg-card shadow-sm border-b", children: _jsx("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: _jsxs("div", { className: "flex justify-between items-center py-4", children: [_jsx("div", { className: "flex items-center", children: _jsx("h1", { className: "text-2xl font-bold text-foreground", children: `${siteName} Admin` }) }), _jsx("div", { className: "flex items-center space-x-4", children: _jsx("span", { className: "text-sm text-muted-foreground", children: "v0.1.0" }) })] }) }) }), _jsx("main", { className: "max-w-7xl mx-auto py-6 sm:px-6 lg:px-8", children: _jsx("div", { className: "px-4 py-6 sm:px-0", children: _jsxs("div", { className: "grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3", children: [_jsxs("div", { className: "bg-card overflow-hidden shadow rounded-lg", children: [_jsx("div", { className: "p-5", children: _jsxs("div", { className: "flex items-center", children: [_jsx("div", { className: "flex-shrink-0", children: _jsxs("svg", { className: "h-8 w-8 text-muted-foreground", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: [_jsx("title", { children: "Collections icon" }), _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" })] }) }), _jsx("div", { className: "ml-5 w-0 flex-1", children: _jsxs("dl", { children: [_jsx("dt", { className: "text-sm font-medium text-muted-foreground truncate", children: "Collections" }), _jsx("dd", { className: "text-lg font-medium text-foreground", children: collections.length })] }) })] }) }), _jsx("div", { className: "bg-muted px-5 py-3", children: _jsx("div", { className: "text-sm", children: collections.length > 0 ? (_jsx("ul", { className: "space-y-1", children: collections.map((collection) => (_jsxs("li", { className: "text-muted-foreground", children: [_jsx("span", { className: "font-medium", children: collection.slug }), _jsxs("span", { className: "ml-2 text-xs text-muted-foreground", children: ["(", collection.fields?.length || 0, " fields)"] })] }, collection.slug))) })) : (_jsx("p", { className: "text-muted-foreground", children: "No collections configured" })) }) })] }), _jsxs("div", { className: "bg-card overflow-hidden shadow rounded-lg", children: [_jsx("div", { className: "p-5", children: _jsxs("div", { className: "flex items-center", children: [_jsx("div", { className: "flex-shrink-0", children: _jsxs("svg", { className: "h-8 w-8 text-muted-foreground", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: [_jsx("title", { children: "Globals icon" }), _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 100 4m0-4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 100 4m0-4v2m0-6V4" })] }) }), _jsx("div", { className: "ml-5 w-0 flex-1", children: _jsxs("dl", { children: [_jsx("dt", { className: "text-sm font-medium text-muted-foreground truncate", children: "Globals" }), _jsx("dd", { className: "text-lg font-medium text-foreground", children: globals.length })] }) })] }) }), _jsx("div", { className: "bg-muted px-5 py-3", children: _jsx("div", { className: "text-sm", children: globals.length > 0 ? (_jsx("ul", { className: "space-y-1", children: globals.map((global) => (_jsxs("li", { className: "text-muted-foreground", children: [_jsx("span", { className: "font-medium", children: global.slug }), _jsxs("span", { className: "ml-2 text-xs text-muted-foreground", children: ["(", global.fields?.length || 0, " fields)"] })] }, global.slug))) })) : (_jsx("p", { className: "text-muted-foreground", children: "No globals configured" })) }) })] }), _jsxs("div", { className: "bg-card overflow-hidden shadow rounded-lg", children: [_jsx("div", { className: "p-5", children: _jsxs("div", { className: "flex items-center", children: [_jsx("div", { className: "flex-shrink-0", children: _jsx("div", { className: "h-8 w-8 bg-success/15 rounded-full flex items-center justify-center", children: _jsxs("svg", { className: "h-5 w-5 text-success", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: [_jsx("title", { children: "System operational" }), _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" })] }) }) }), _jsx("div", { className: "ml-5 w-0 flex-1", children: _jsxs("dl", { children: [_jsx("dt", { className: "text-sm font-medium text-muted-foreground truncate", children: "System Status" }), _jsx("dd", { className: "text-lg font-medium text-foreground", children: "Operational" })] }) })] }) }), _jsx("div", { className: "bg-muted px-5 py-3", children: _jsxs("div", { className: "text-sm text-muted-foreground", children: [siteName, " admin is running successfully with ", collections.length, " collections and", ' ', globals.length, " globals configured."] }) })] })] }) }) })] }));
9
+ return (_jsxs("div", { className: "min-h-screen bg-background", children: [_jsx("header", { className: "bg-card shadow-sm border-b", children: _jsx("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: _jsxs("div", { className: "flex justify-between items-center py-4", children: [_jsx("div", { className: "flex items-center", children: _jsx("h1", { className: "text-2xl font-bold text-foreground", children: `${siteName} Admin` }) }), _jsx("div", { className: "flex shrink-0 items-center gap-3", children: _jsxs("span", { className: "shrink-0 text-sm tabular-nums text-muted-foreground", title: "Application version", children: ["v", process.env.NEXT_PUBLIC_APP_VERSION ?? process.env.APP_VERSION ?? '0.0.0'] }) })] }) }) }), _jsx("main", { className: "max-w-7xl mx-auto py-6 sm:px-6 lg:px-8", children: _jsx("div", { className: "px-4 py-6 sm:px-0", children: _jsxs("div", { className: "grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3", children: [_jsxs("div", { className: "bg-card overflow-hidden shadow rounded-lg", children: [_jsx("div", { className: "p-5", children: _jsxs("div", { className: "flex items-center", children: [_jsx("div", { className: "flex-shrink-0", children: _jsxs("svg", { className: "h-8 w-8 text-muted-foreground", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: [_jsx("title", { children: "Collections icon" }), _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" })] }) }), _jsx("div", { className: "ml-5 w-0 flex-1", children: _jsxs("dl", { children: [_jsx("dt", { className: "text-sm font-medium text-muted-foreground truncate", children: "Collections" }), _jsx("dd", { className: "text-lg font-medium text-foreground", children: collections.length })] }) })] }) }), _jsx("div", { className: "bg-muted px-5 py-3", children: _jsx("div", { className: "text-sm", children: collections.length > 0 ? (_jsx("ul", { className: "space-y-1", children: collections.map((collection) => (_jsxs("li", { className: "text-muted-foreground", children: [_jsx("span", { className: "font-medium", children: collection.slug }), _jsxs("span", { className: "ml-2 text-xs text-muted-foreground", children: ["(", collection.fields?.length || 0, " fields)"] })] }, collection.slug))) })) : (_jsx("p", { className: "text-muted-foreground", children: "No collections configured" })) }) })] }), _jsxs("div", { className: "bg-card overflow-hidden shadow rounded-lg", children: [_jsx("div", { className: "p-5", children: _jsxs("div", { className: "flex items-center", children: [_jsx("div", { className: "flex-shrink-0", children: _jsxs("svg", { className: "h-8 w-8 text-muted-foreground", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: [_jsx("title", { children: "Globals icon" }), _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 100 4m0-4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 100 4m0-4v2m0-6V4" })] }) }), _jsx("div", { className: "ml-5 w-0 flex-1", children: _jsxs("dl", { children: [_jsx("dt", { className: "text-sm font-medium text-muted-foreground truncate", children: "Globals" }), _jsx("dd", { className: "text-lg font-medium text-foreground", children: globals.length })] }) })] }) }), _jsx("div", { className: "bg-muted px-5 py-3", children: _jsx("div", { className: "text-sm", children: globals.length > 0 ? (_jsx("ul", { className: "space-y-1", children: globals.map((global) => (_jsxs("li", { className: "text-muted-foreground", children: [_jsx("span", { className: "font-medium", children: global.slug }), _jsxs("span", { className: "ml-2 text-xs text-muted-foreground", children: ["(", global.fields?.length || 0, " fields)"] })] }, global.slug))) })) : (_jsx("p", { className: "text-muted-foreground", children: "No globals configured" })) }) })] }), _jsxs("div", { className: "bg-card overflow-hidden shadow rounded-lg", children: [_jsx("div", { className: "p-5", children: _jsxs("div", { className: "flex items-center", children: [_jsx("div", { className: "flex-shrink-0", children: _jsx("div", { className: "h-8 w-8 bg-success/15 rounded-full flex items-center justify-center", children: _jsxs("svg", { className: "h-5 w-5 text-success", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: [_jsx("title", { children: "System operational" }), _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" })] }) }) }), _jsx("div", { className: "ml-5 w-0 flex-1", children: _jsxs("dl", { children: [_jsx("dt", { className: "text-sm font-medium text-muted-foreground truncate", children: "System Status" }), _jsx("dd", { className: "text-lg font-medium text-foreground", children: "Operational" })] }) })] }) }), _jsx("div", { className: "bg-muted px-5 py-3", children: _jsxs("div", { className: "text-sm text-muted-foreground", children: [siteName, " admin is running successfully with ", collections.length, " collections and", ' ', globals.length, " globals configured."] }) })] })] }) }) })] }));
10
10
  }
11
11
  export function NotFoundPage() {
12
12
  return (_jsxs("div", { children: [_jsx("h1", { children: "404 - Page Not Found" }), _jsx("p", { children: "The requested admin page could not be found." })] }));
@@ -1 +1 @@
1
- {"version":3,"file":"apiClient.d.ts","sourceRoot":"","sources":["../../../../src/client/admin/utils/apiClient.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"apiClient.d.ts","sourceRoot":"","sources":["../../../../src/client/admin/utils/apiClient.ts"],"names":[],"mappings":"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"}
@@ -67,8 +67,10 @@ export class APIClient {
67
67
  const Unsafe = new Set(['POST', 'PUT', 'PATCH', 'DELETE']);
68
68
  const method = (options.method ?? 'GET').toUpperCase();
69
69
  const csrfToken = Unsafe.has(method) ? readCsrfToken() : undefined;
70
+ // FormData must set its own multipart boundary; never force JSON Content-Type.
71
+ const isFormData = typeof FormData !== 'undefined' && options.body instanceof FormData;
70
72
  const headers = {
71
- 'Content-Type': 'application/json',
73
+ ...(isFormData ? {} : { 'Content-Type': 'application/json' }),
72
74
  ...(csrfToken ? { 'X-CSRF-Token': csrfToken } : {}),
73
75
  ...options.headers,
74
76
  };
@@ -159,6 +161,30 @@ export class APIClient {
159
161
  async create(options) {
160
162
  const { collection, data } = options;
161
163
  const endpoint = `/api/collections/${collection}`;
164
+ // GAP-452: upload collections send File + fields as multipart so the api
165
+ // media endpoint (multipart-only) accepts the create.
166
+ const fileEntry = Object.entries(data).find(([, v]) => typeof File !== 'undefined' && v instanceof File);
167
+ if (fileEntry) {
168
+ const formData = new FormData();
169
+ const [fileKey, fileValue] = fileEntry;
170
+ // Api media upload expects the binary field name `file`.
171
+ formData.append('file', fileValue);
172
+ for (const [key, value] of Object.entries(data)) {
173
+ if (key === fileKey)
174
+ continue;
175
+ if (value === null || value === undefined)
176
+ continue;
177
+ // Skip nested objects (richtext caption) on create; follow-up PATCH owns them.
178
+ if (typeof value === 'object')
179
+ continue;
180
+ formData.append(key, String(value));
181
+ }
182
+ const response = await this.request(endpoint, {
183
+ method: 'POST',
184
+ body: formData,
185
+ });
186
+ return response.doc;
187
+ }
162
188
  const response = await this.request(endpoint, {
163
189
  method: 'POST',
164
190
  body: JSON.stringify(data),
@@ -1 +1 @@
1
- {"version":3,"file":"ImageUploadButton.d.ts","sourceRoot":"","sources":["../../../../src/client/richtext/components/ImageUploadButton.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAQ/B,UAAU,sBAAsB;IAC9B,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACvC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,0DAA0D;IAC1D,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAqBD,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAsI9D,CAAC"}
1
+ {"version":3,"file":"ImageUploadButton.d.ts","sourceRoot":"","sources":["../../../../src/client/richtext/components/ImageUploadButton.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAQ/B,UAAU,sBAAsB;IAC9B,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACvC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,0DAA0D;IAC1D,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAqBD,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAkJ9D,CAAC"}
@@ -9,7 +9,7 @@ import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext
9
9
  import { logger } from '@revealui/core/utils/logger';
10
10
  import { useCallback, useRef, useState } from 'react';
11
11
  import { INSERT_IMAGE_COMMAND } from '../nodes/ImageNode.js';
12
- import { postMediaUpload } from './upload.js';
12
+ import { deriveAltTextFromFilename, postMediaUpload } from './upload.js';
13
13
  /** Default maximum file size: 10 MB */
14
14
  const DEFAULT_MAX_FILE_SIZE_BYTES = 10 * 1024 * 1024;
15
15
  const getUploadUrl = (payload) => {
@@ -56,9 +56,12 @@ export const ImageUploadButton = ({ onUploadStart, onUploadComplete, onUploadErr
56
56
  img.onerror = reject;
57
57
  img.src = URL.createObjectURL(file);
58
58
  });
59
- // Upload file
59
+ // Upload file. The admin Media collection requires `alt`, so it is
60
+ // derived from the filename and sent alongside the file.
61
+ const altText = deriveAltTextFromFilename(file.name);
60
62
  const formData = new FormData();
61
63
  formData.append('file', file);
64
+ formData.append('alt', altText);
62
65
  // Scale timeout with file size: 30s base + 10s per MB
63
66
  const timeoutMs = 30_000 + Math.ceil(file.size / (1024 * 1024)) * 10_000;
64
67
  const controller = new AbortController();
@@ -71,7 +74,17 @@ export const ImageUploadButton = ({ onUploadStart, onUploadComplete, onUploadErr
71
74
  clearTimeout(timeoutId);
72
75
  }
73
76
  if (!response.ok) {
74
- throw new Error(`Upload failed: ${response.statusText}`);
77
+ let message = `Upload failed: ${response.statusText}`;
78
+ try {
79
+ const body = (await response.json());
80
+ if (typeof body.message === 'string' && body.message.length > 0) {
81
+ message = body.message;
82
+ }
83
+ }
84
+ catch {
85
+ // Body wasn't JSON - keep the generic message.
86
+ }
87
+ throw new Error(message);
75
88
  }
76
89
  const result = (await response.json());
77
90
  // Extract URL from response (adapt based on your API response structure)
@@ -82,7 +95,7 @@ export const ImageUploadButton = ({ onUploadStart, onUploadComplete, onUploadErr
82
95
  // Insert image into editor
83
96
  editor.dispatchCommand(INSERT_IMAGE_COMMAND, {
84
97
  src: imageUrl,
85
- alt: file.name.replace(/\.[^/.]+$/, ''), // Remove extension for alt text
98
+ alt: altText,
86
99
  width: imageDimensions.width,
87
100
  height: imageDimensions.height,
88
101
  });
@@ -10,6 +10,13 @@
10
10
  * re-issues the cookie whenever it no longer validates against the current
11
11
  * session (e.g. after re-login or session rotation).
12
12
  */
13
+ /**
14
+ * Derive alt text from a filename by stripping its extension. Falls back to
15
+ * the whole name when there is no extension (`lastIndexOf` returns -1) or
16
+ * the only dot is a leading dotfile marker (e.g. `.env`), where `dot > 0` is
17
+ * false.
18
+ */
19
+ export declare function deriveAltTextFromFilename(fileName: string): string;
13
20
  /**
14
21
  * POST `body` to `uploadEndpoint`, echoing the CSRF cookie as `X-CSRF-Token`
15
22
  * when one is readable. `Content-Type` is never set here - `fetch` derives
@@ -1 +1 @@
1
- {"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../../../src/client/richtext/components/upload.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,cAAc,EAAE,MAAM,EACtB,IAAI,EAAE,QAAQ,EACd,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,QAAQ,CAAC,CAQnB"}
1
+ {"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../../../src/client/richtext/components/upload.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGlE;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,cAAc,EAAE,MAAM,EACtB,IAAI,EAAE,QAAQ,EACd,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,QAAQ,CAAC,CAQnB"}
@@ -11,6 +11,16 @@
11
11
  * session (e.g. after re-login or session rotation).
12
12
  */
13
13
  import { readCsrfToken } from '../../admin/utils/csrf.js';
14
+ /**
15
+ * Derive alt text from a filename by stripping its extension. Falls back to
16
+ * the whole name when there is no extension (`lastIndexOf` returns -1) or
17
+ * the only dot is a leading dotfile marker (e.g. `.env`), where `dot > 0` is
18
+ * false.
19
+ */
20
+ export function deriveAltTextFromFilename(fileName) {
21
+ const dot = fileName.lastIndexOf('.');
22
+ return dot > 0 ? fileName.slice(0, dot) : fileName;
23
+ }
14
24
  /**
15
25
  * POST `body` to `uploadEndpoint`, echoing the CSRF cookie as `X-CSRF-Token`
16
26
  * when one is readable. `Content-Type` is never set here - `fetch` derives
@@ -15,6 +15,10 @@ export declare abstract class DecoratorBlockNode<T extends Record<string, unknow
15
15
  constructor(format?: ElementFormatType, key?: NodeKey);
16
16
  getFormat(): ElementFormatType;
17
17
  setFormat(format: ElementFormatType): void;
18
+ createDOM(): HTMLElement;
19
+ updateDOM(): false;
20
+ isInline(): false;
21
+ canIndent(): false;
18
22
  exportJSON(): SerializedDecoratorBlockNode<T>;
19
23
  }
20
24
  //# sourceMappingURL=DecoratorBlockNode.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DecoratorBlockNode.d.ts","sourceRoot":"","sources":["../../../../src/client/richtext/nodes/DecoratorBlockNode.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AAEH,OAAO,EACL,aAAa,EACb,KAAK,iBAAiB,EACtB,KAAK,OAAO,EACZ,KAAK,qBAAqB,EAC1B,KAAK,MAAM,EACZ,MAAM,SAAS,CAAC;AACjB,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAEjC,MAAM,MAAM,4BAA4B,CACtC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IACzD,MAAM,CACR;IACE,MAAM,EAAE,iBAAiB,CAAC;IAC1B,MAAM,EAAE,CAAC,CAAC;CACX,EACD,qBAAqB,CACtB,CAAC;AAEF,8BAAsB,kBAAkB,CACtC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAC3D,SAAQ,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC;IAClC,QAAQ,EAAE,iBAAiB,CAAC;gBAEhB,MAAM,CAAC,EAAE,iBAAiB,EAAE,GAAG,CAAC,EAAE,OAAO;IAKrD,SAAS,IAAI,iBAAiB;IAI9B,SAAS,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI;IAK1C,UAAU,IAAI,4BAA4B,CAAC,CAAC,CAAC;CAO9C"}
1
+ {"version":3,"file":"DecoratorBlockNode.d.ts","sourceRoot":"","sources":["../../../../src/client/richtext/nodes/DecoratorBlockNode.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AAEH,OAAO,EACL,aAAa,EACb,KAAK,iBAAiB,EACtB,KAAK,OAAO,EACZ,KAAK,qBAAqB,EAC1B,KAAK,MAAM,EACZ,MAAM,SAAS,CAAC;AACjB,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAEjC,MAAM,MAAM,4BAA4B,CACtC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IACzD,MAAM,CACR;IACE,MAAM,EAAE,iBAAiB,CAAC;IAC1B,MAAM,EAAE,CAAC,CAAC;CACX,EACD,qBAAqB,CACtB,CAAC;AAEF,8BAAsB,kBAAkB,CACtC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAC3D,SAAQ,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC;IAClC,QAAQ,EAAE,iBAAiB,CAAC;gBAEhB,MAAM,CAAC,EAAE,iBAAiB,EAAE,GAAG,CAAC,EAAE,OAAO;IAKrD,SAAS,IAAI,iBAAiB;IAI9B,SAAS,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI;IAK1C,SAAS,IAAI,WAAW;IAIxB,SAAS,IAAI,KAAK;IAIlB,QAAQ,IAAI,KAAK;IAIjB,SAAS,IAAI,KAAK;IAIlB,UAAU,IAAI,4BAA4B,CAAC,CAAC,CAAC;CAO9C"}
@@ -19,6 +19,18 @@ export class DecoratorBlockNode extends DecoratorNode {
19
19
  const writable = this.getWritable();
20
20
  writable.__format = format;
21
21
  }
22
+ createDOM() {
23
+ return document.createElement('div');
24
+ }
25
+ updateDOM() {
26
+ return false;
27
+ }
28
+ isInline() {
29
+ return false;
30
+ }
31
+ canIndent() {
32
+ return false;
33
+ }
22
34
  exportJSON() {
23
35
  return {
24
36
  ...super.exportJSON(),
@@ -43,6 +43,8 @@ export interface FeatureFlags {
43
43
  vaultRotation: boolean;
44
44
  /** RevKit environment provisioning - tiered dev profiles (Max+) */
45
45
  devkitProfiles: boolean;
46
+ /** Enterprise SSO (OIDC/SAML) - account IdP federation (Enterprise) */
47
+ sso: boolean;
46
48
  }
47
49
  /**
48
50
  * Returns the current feature flags based on the active license tier.
@@ -1 +1 @@
1
- {"version":3,"file":"features.d.ts","sourceRoot":"","sources":["../src/features.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAc,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAE5D,qCAAqC;AACrC,MAAM,WAAW,YAAY;IAC3B,sGAAsG;IACtG,OAAO,EAAE,OAAO,CAAC;IACjB,oEAAoE;IACpE,EAAE,EAAE,OAAO,CAAC;IACZ,sFAAsF;IACtF,QAAQ,EAAE,OAAO,CAAC;IAClB,6BAA6B;IAC7B,GAAG,EAAE,OAAO,CAAC;IACb,yCAAyC;IACzC,QAAQ,EAAE,OAAO,CAAC;IAClB,mCAAmC;IACnC,WAAW,EAAE,OAAO,CAAC;IACrB,oEAAoE;IACpE,UAAU,EAAE,OAAO,CAAC;IACpB,2EAA2E;IAC3E,WAAW,EAAE,OAAO,CAAC;IACrB,yCAAyC;IACzC,QAAQ,EAAE,OAAO,CAAC;IAClB,mDAAmD;IACnD,YAAY,EAAE,OAAO,CAAC;IACtB,2BAA2B;IAC3B,SAAS,EAAE,OAAO,CAAC;IACnB,4BAA4B;IAC5B,YAAY,EAAE,OAAO,CAAC;IACtB,wCAAwC;IACxC,SAAS,EAAE,OAAO,CAAC;IACnB,iGAAiG;IACjG,YAAY,EAAE,OAAO,CAAC;IACtB,yEAAyE;IACzE,aAAa,EAAE,OAAO,CAAC;IACvB,qEAAqE;IACrE,cAAc,EAAE,OAAO,CAAC;CACzB;AAyBD;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,IAAI,YAAY,CAW1C;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,YAAY,GAAG,OAAO,CAMrE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,WAAW,GAAG,YAAY,CAkBlE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,YAAY,GAAG,WAAW,CAExE;AAED;;GAEG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"features.d.ts","sourceRoot":"","sources":["../src/features.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAc,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAE5D,qCAAqC;AACrC,MAAM,WAAW,YAAY;IAC3B,sGAAsG;IACtG,OAAO,EAAE,OAAO,CAAC;IACjB,oEAAoE;IACpE,EAAE,EAAE,OAAO,CAAC;IACZ,sFAAsF;IACtF,QAAQ,EAAE,OAAO,CAAC;IAClB,6BAA6B;IAC7B,GAAG,EAAE,OAAO,CAAC;IACb,yCAAyC;IACzC,QAAQ,EAAE,OAAO,CAAC;IAClB,mCAAmC;IACnC,WAAW,EAAE,OAAO,CAAC;IACrB,oEAAoE;IACpE,UAAU,EAAE,OAAO,CAAC;IACpB,2EAA2E;IAC3E,WAAW,EAAE,OAAO,CAAC;IACrB,yCAAyC;IACzC,QAAQ,EAAE,OAAO,CAAC;IAClB,mDAAmD;IACnD,YAAY,EAAE,OAAO,CAAC;IACtB,2BAA2B;IAC3B,SAAS,EAAE,OAAO,CAAC;IACnB,4BAA4B;IAC5B,YAAY,EAAE,OAAO,CAAC;IACtB,wCAAwC;IACxC,SAAS,EAAE,OAAO,CAAC;IACnB,iGAAiG;IACjG,YAAY,EAAE,OAAO,CAAC;IACtB,yEAAyE;IACzE,aAAa,EAAE,OAAO,CAAC;IACvB,qEAAqE;IACrE,cAAc,EAAE,OAAO,CAAC;IACxB,yEAAyE;IACzE,GAAG,EAAE,OAAO,CAAC;CACd;AA2BD;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,IAAI,YAAY,CAW1C;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,YAAY,GAAG,OAAO,CAMrE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,WAAW,GAAG,YAAY,CAkBlE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,YAAY,GAAG,WAAW,CAExE;AAED;;GAEG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC"}
package/dist/features.js CHANGED
@@ -27,6 +27,8 @@ const featureTierMap = {
27
27
  // Forced to false below in getFeatures/getFeaturesForTier/isFeatureEnabled
28
28
  // to avoid advertising features that don't exist. Re-enable when implemented.
29
29
  whiteLabel: 'enterprise',
30
+ /** GAP-464 OIDC routes + JIT; SAML + admin UI residual */
31
+ sso: 'enterprise',
30
32
  vaultDesktop: 'pro',
31
33
  vaultRotation: 'pro',
32
34
  devkitProfiles: 'max',
package/dist/index.d.ts CHANGED
@@ -20,7 +20,7 @@ export type { UniversalPostgresAdapterConfig } from './database/universal-postgr
20
20
  export { universalPostgresAdapter } from './database/universal-postgres.js';
21
21
  export { createRevealUI, createRevealUIAccessRule, createRevealUIBlock, createRevealUICollection, createRevealUIField, } from './factories/index.js';
22
22
  export { type FeatureFlags, getFeatures, getFeaturesForTier, getRequiredTier, isFeatureEnabled, } from './features.js';
23
- export { computeKeyId, configureGracePeriods, configureLicenseCache, type GracePeriodConfig, generateLicenseKey, getCurrentTier, getGraceConfig, getLicensePayload, getLicenseStatus, getMaxSites, getMaxUsers, initializeLicense, isLicensed, type LicenseCacheConfig, type LicenseCheckResult, type LicenseMode, type LicensePayload, type LicenseTier, resetLicenseState, validateLicenseKey, } from './license.js';
23
+ export { computeKeyId, configureGracePeriods, configureLicenseCache, type GracePeriodConfig, generateLicenseKey, getCurrentTier, getGraceConfig, getLicensePayload, getLicenseStatus, getMaxSites, getMaxUsers, initializeLicense, isLicensed, type LicenseCacheConfig, type LicenseCheckResult, type LicenseMode, type LicensePayload, type LicenseTier, readLicenseExp, readLicenseJti, resetLicenseState, validateLicenseKey, } from './license.js';
24
24
  export { getRevealUI as getRevealUINext } from './nextjs/index.js';
25
25
  export { formBuilderPlugin } from './plugins/form-builder.js';
26
26
  export { nestedDocsPlugin } from './plugins/nested-docs.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEtE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACzD,YAAY,EACV,0BAA0B,EAC1B,aAAa,EACb,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACL,gBAAgB,EAChB,YAAY,EAEZ,cAAc,EACd,QAAQ,EACR,YAAY,EAEZ,SAAS,EACT,cAAc,EACd,YAAY,EACZ,qBAAqB,EACrB,oBAAoB,EACpB,SAAS,EACT,kBAAkB,EAClB,WAAW,EACX,iBAAiB,EACjB,oBAAoB,EACpB,YAAY,EACZ,yBAAyB,EACzB,UAAU,EACV,QAAQ,EAER,oBAAoB,EACpB,eAAe,EAEf,aAAa,EAEb,WAAW,EACX,kBAAkB,GACnB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAE9C,YAAY,EAAE,8BAA8B,EAAE,MAAM,kCAAkC,CAAC;AACvF,OAAO,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAE5E,OAAO,EACL,cAAc,EACd,wBAAwB,EACxB,mBAAmB,EACnB,wBAAwB,EACxB,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,KAAK,YAAY,EACjB,WAAW,EACX,kBAAkB,EAClB,eAAe,EACf,gBAAgB,GACjB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,YAAY,EACZ,qBAAqB,EACrB,qBAAqB,EACrB,KAAK,iBAAiB,EACtB,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,WAAW,EACX,WAAW,EACX,iBAAiB,EACjB,UAAU,EACV,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,cAAc,CAAC;AAMtB,OAAO,EAAE,WAAW,IAAI,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAInE,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,OAAO,EAEL,yBAAyB,EACzB,uBAAuB,EACvB,0BAA0B,EAC1B,4BAA4B,EAE5B,gBAAgB,EAEhB,iBAAiB,EAEjB,sBAAsB,EACtB,aAAa,EACb,kBAAkB,EAClB,aAAa,EAEb,qBAAqB,EAErB,MAAM,EAEN,kBAAkB,EAClB,cAAc,EACd,KAAK,cAAc,EAEnB,KAAK,eAAe,EACpB,6BAA6B,EAC7B,4BAA4B,EAC5B,0BAA0B,GAC3B,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,WAAW,EACX,mBAAmB,EACnB,cAAc,EACd,aAAa,EACb,WAAW,EACX,aAAa,EACb,eAAe,EACf,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAI5D,OAAO,EAAE,QAAQ,EAAE,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAElE,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD,OAAO,EACL,kCAAkC,EAClC,uBAAuB,EACvB,yBAAyB,EACzB,iCAAiC,EACjC,KAAK,iBAAiB,GACvB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,EAClB,aAAa,EACb,aAAa,EACb,cAAc,EACd,mBAAmB,EACnB,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,eAAe,GAChB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,YAAY,EACZ,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,MAAM,GACP,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAQlF,OAAO,EACL,KAAK,UAAU,EAEf,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,qBAAqB,EACrB,eAAe,EACf,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAE3B,KAAK,yBAAyB,EAC9B,KAAK,uBAAuB,EAC5B,KAAK,0BAA0B,EAC/B,KAAK,4BAA4B,EACjC,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,MAAM,EAEX,qBAAqB,EAErB,gBAAgB,EAChB,WAAW,EACX,YAAY,EAEZ,KAAK,KAAK,EACV,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EAGtB,yBAAyB,EACzB,qBAAqB,EACrB,KAAK,kBAAkB,EACvB,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,kBAAkB,EAClB,qBAAqB,EAErB,qBAAqB,EACrB,gBAAgB,EAChB,WAAW,EACX,sBAAsB,EACtB,WAAW,EAEX,uBAAuB,EACvB,uBAAuB,EACvB,KAAK,yBAAyB,EAC9B,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,YAAY,EAEZ,uBAAuB,EACvB,mBAAmB,EACnB,MAAM,EACN,kBAAkB,EAClB,KAAK,KAAK,GACX,MAAM,2BAA2B,CAAC;AAOnC,YAAY,EACV,kBAAkB,EAClB,kBAAkB,EAClB,WAAW,EACX,kBAAkB,EAElB,KAAK,EACL,WAAW,EACX,aAAa,EACb,eAAe,EAEf,cAAc,EACd,QAAQ,EACR,UAAU,EACV,gBAAgB,EAChB,aAAa,EACb,UAAU,EAEV,MAAM,EACN,aAAa,EACb,YAAY,EACZ,cAAc,EAEd,qBAAqB,EACrB,mBAAmB,EACnB,sBAAsB,EACtB,gBAAgB,EAEhB,sBAAsB,EACtB,qBAAqB,EACrB,YAAY,EACZ,mBAAmB,EACnB,gBAAgB,EAChB,mBAAmB,EAEnB,cAAc,EACd,sBAAsB,EACtB,iBAAiB,EACjB,YAAY,EACZ,kBAAkB,EAClB,iBAAiB,EAEjB,cAAc,EACd,qBAAqB,EAErB,aAAa,EACb,YAAY,EACZ,UAAU,EACV,QAAQ,EACR,qBAAqB,EACrB,oBAAoB,EACpB,kBAAkB,EAClB,wBAAwB,EAExB,eAAe,EACf,qBAAqB,EACrB,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,sBAAsB,EACtB,oBAAoB,EACpB,wBAAwB,EAExB,mBAAmB,EAEnB,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,YAAY,EACZ,sBAAsB,EACtB,mBAAmB,EAEnB,UAAU,EACV,WAAW,EACX,WAAW,EACX,cAAc,EAEd,eAAe,EACf,UAAU,EACV,cAAc,EACd,UAAU,EACV,WAAW,GACZ,MAAM,kBAAkB,CAAC;AAM1B,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,YAAY,EAEV,MAAM,EAEN,UAAU,EACV,UAAU,EACV,sBAAsB,EAEtB,YAAY,EACZ,gBAAgB,EAChB,qBAAqB,EACrB,gBAAgB,EAEhB,eAAe,EAEf,qBAAqB,EACrB,QAAQ,EACR,eAAe,EACf,mBAAmB,EACnB,WAAW,EACX,eAAe,EACf,iBAAiB,IAAI,uBAAuB,EAC5C,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,EAEX,SAAS,EACT,YAAY,EACZ,iBAAiB,EACjB,YAAY,EACZ,oBAAoB,EACpB,UAAU,EACV,oBAAoB,EAEpB,aAAa,EACb,kBAAkB,EAElB,aAAa,EACb,iBAAiB,EACjB,2BAA2B,EAC3B,kBAAkB,EAClB,uBAAuB,EACvB,kBAAkB,EAClB,0BAA0B,EAC1B,4BAA4B,EAC5B,UAAU,EACV,aAAa,EACb,SAAS,EAET,mBAAmB,EACnB,YAAY,EAEZ,gBAAgB,EAChB,aAAa,GACd,MAAM,kBAAkB,CAAC;AAK1B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG"}
package/dist/index.js CHANGED
@@ -36,13 +36,15 @@ export { universalPostgresAdapter } from './database/universal-postgres.js';
36
36
  export { createRevealUI, createRevealUIAccessRule, createRevealUIBlock, createRevealUICollection, createRevealUIField, } from './factories/index.js';
37
37
  export { getFeatures, getFeaturesForTier, getRequiredTier, isFeatureEnabled, } from './features.js';
38
38
  // License and feature flags
39
- export { computeKeyId, configureGracePeriods, configureLicenseCache, generateLicenseKey, getCurrentTier, getGraceConfig, getLicensePayload, getLicenseStatus, getMaxSites, getMaxUsers, initializeLicense, isLicensed, resetLicenseState, validateLicenseKey, } from './license.js';
39
+ export { computeKeyId, configureGracePeriods, configureLicenseCache, generateLicenseKey, getCurrentTier, getGraceConfig, getLicensePayload, getLicenseStatus, getMaxSites, getMaxUsers, initializeLicense, isLicensed, readLicenseExp, readLicenseJti, resetLicenseState, validateLicenseKey, } from './license.js';
40
40
  // Next.js integration
41
41
  // Note: `withRevealUI` is intentionally NOT re-exported here — it pulls in
42
42
  // `node:fs` at module load, which causes Next's NFT tracer to pull the whole
43
43
  // project into every route that transitively imports from '@revealui/core'.
44
44
  // Import it directly from '@revealui/core/nextjs/withRevealUI' in next.config.mjs.
45
45
  export { getRevealUI as getRevealUINext } from './nextjs/index.js';
46
+ // Vite integration: same rule — import `@revealui/core/vite/withRevealUI` from
47
+ // vite.config.ts only (GAP-194 Phase 3 Tier 0 step 3.0).
46
48
  // Plugins
47
49
  export { formBuilderPlugin } from './plugins/form-builder.js';
48
50
  export { nestedDocsPlugin } from './plugins/nested-docs.js';
@@ -60,6 +60,12 @@ export declare function canMintLicense(env?: MintEnv): boolean;
60
60
  /** Human-readable reason mint is unavailable (for CRITICAL logs). */
61
61
  export declare function mintConfigMissingMessage(env?: MintEnv): string;
62
62
  export declare function signMintRequest(secret: string, method: string, path: string, body: string, timestampSeconds: number): string;
63
+ /**
64
+ * GAP-448: perpetual Agency (tier max) must bake maxSites 10 on the JWT.
65
+ * Callers may still pass maxSites explicitly (wins). Subscription mints leave
66
+ * maxSites unset so runtime TIER_LIMITS apply.
67
+ */
68
+ export declare function withPerpetualSiteCaps(input: MintLicensePayload): MintLicensePayload;
63
69
  export type MintLicenseKeyOptions = {
64
70
  env?: MintEnv;
65
71
  /** Inject for tests; defaults to global fetch. */
@@ -1 +1 @@
1
- {"version":3,"file":"mint-client.d.ts","sourceRoot":"","sources":["../../src/license/mint-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAKH,eAAO,MAAM,uBAAuB,gCAAgC,CAAC;AACrE,eAAO,MAAM,uBAAuB,gCAAgC,CAAC;AACrE,eAAO,MAAM,gBAAgB,mBAAmB,CAAC;AAEjD,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAEzD,8EAA8E;AAC9E,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,KAAK,GAAG,KAAK,GAAG,YAAY,CAAC;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC,CAAC;AAEF,qBAAa,sBAAuB,SAAQ,KAAK;IAC/C,QAAQ,CAAC,IAAI,EAAG,qBAAqB,CAAU;gBACnC,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,sBAAuB,SAAQ,KAAK;IAC/C,QAAQ,CAAC,IAAI,EAAG,qBAAqB,CAAU;IAC/C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBACZ,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAK5C;AAED,+DAA+D;AAC/D,wBAAgB,eAAe,CAAC,GAAG,GAAE,OAAqB,GAAG,OAAO,CAGnE;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,GAAE,OAAqB,GAAG,OAAO,CAOlE;AAED,qEAAqE;AACrE,wBAAgB,wBAAwB,CAAC,GAAG,GAAE,OAAqB,GAAG,MAAM,CAQ3E;AAED,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,gBAAgB,EAAE,MAAM,GACvB,MAAM,CAGR;AAyGD,MAAM,MAAM,qBAAqB,GAAG;IAClC,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,kDAAkD;IAClD,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;CACtB,CAAC;AAEF;;GAEG;AACH,wBAAsB,cAAc,CAClC,KAAK,EAAE,kBAAkB,EACzB,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,MAAM,CAAC,CAQjB"}
1
+ {"version":3,"file":"mint-client.d.ts","sourceRoot":"","sources":["../../src/license/mint-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAMH,eAAO,MAAM,uBAAuB,gCAAgC,CAAC;AACrE,eAAO,MAAM,uBAAuB,gCAAgC,CAAC;AACrE,eAAO,MAAM,gBAAgB,mBAAmB,CAAC;AAEjD,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAEzD,8EAA8E;AAC9E,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,KAAK,GAAG,KAAK,GAAG,YAAY,CAAC;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC,CAAC;AAEF,qBAAa,sBAAuB,SAAQ,KAAK;IAC/C,QAAQ,CAAC,IAAI,EAAG,qBAAqB,CAAU;gBACnC,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,sBAAuB,SAAQ,KAAK;IAC/C,QAAQ,CAAC,IAAI,EAAG,qBAAqB,CAAU;IAC/C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBACZ,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAK5C;AAED,+DAA+D;AAC/D,wBAAgB,eAAe,CAAC,GAAG,GAAE,OAAqB,GAAG,OAAO,CAGnE;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,GAAE,OAAqB,GAAG,OAAO,CAOlE;AAED,qEAAqE;AACrE,wBAAgB,wBAAwB,CAAC,GAAG,GAAE,OAAqB,GAAG,MAAM,CAQ3E;AAED,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,gBAAgB,EAAE,MAAM,GACvB,MAAM,CAGR;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,kBAAkB,GAAG,kBAAkB,CASnF;AA0GD,MAAM,MAAM,qBAAqB,GAAG;IAClC,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,kDAAkD;IAClD,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;CACtB,CAAC;AAEF;;GAEG;AACH,wBAAsB,cAAc,CAClC,KAAK,EAAE,kBAAkB,EACzB,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,MAAM,CAAC,CASjB"}
@@ -20,6 +20,7 @@
20
20
  * REVEALUI_LICENSE_PUBLIC_KEY optional; enables kid on JWT header
21
21
  */
22
22
  import { createHmac } from 'node:crypto';
23
+ import { perpetualMaxSitesForTier } from '@revealui/contracts';
23
24
  import { generateLicenseKey, readPemEnv } from '../license.js';
24
25
  export const SIGNER_TIMESTAMP_HEADER = 'x-revealui-signer-timestamp';
25
26
  export const SIGNER_SIGNATURE_HEADER = 'x-revealui-signer-signature';
@@ -70,23 +71,39 @@ export function signMintRequest(secret, method, path, body, timestampSeconds) {
70
71
  const payload = `${timestampSeconds}.${method.toUpperCase()}.${path}.${body}`;
71
72
  return createHmac('sha256', secret).update(payload, 'utf8').digest('hex');
72
73
  }
74
+ /**
75
+ * GAP-448: perpetual Agency (tier max) must bake maxSites 10 on the JWT.
76
+ * Callers may still pass maxSites explicitly (wins). Subscription mints leave
77
+ * maxSites unset so runtime TIER_LIMITS apply.
78
+ */
79
+ export function withPerpetualSiteCaps(input) {
80
+ if (!input.perpetual || input.maxSites !== undefined) {
81
+ return input;
82
+ }
83
+ const maxSites = perpetualMaxSitesForTier(input.tier);
84
+ if (maxSites === null) {
85
+ return input;
86
+ }
87
+ return { ...input, maxSites };
88
+ }
73
89
  function buildMintBody(input) {
90
+ const normalized = withPerpetualSiteCaps(input);
74
91
  const body = {
75
- tier: input.tier,
76
- customerId: input.customerId,
92
+ tier: normalized.tier,
93
+ customerId: normalized.customerId,
77
94
  };
78
- if (input.domains !== undefined)
79
- body.domains = input.domains;
80
- if (input.maxSites !== undefined)
81
- body.maxSites = input.maxSites;
82
- if (input.maxUsers !== undefined)
83
- body.maxUsers = input.maxUsers;
84
- if (input.perpetual !== undefined)
85
- body.perpetual = input.perpetual;
86
- if (input.jti !== undefined)
87
- body.jti = input.jti;
88
- if (input.expiresInSeconds !== undefined) {
89
- body.expiresInSeconds = input.expiresInSeconds;
95
+ if (normalized.domains !== undefined)
96
+ body.domains = normalized.domains;
97
+ if (normalized.maxSites !== undefined)
98
+ body.maxSites = normalized.maxSites;
99
+ if (normalized.maxUsers !== undefined)
100
+ body.maxUsers = normalized.maxUsers;
101
+ if (normalized.perpetual !== undefined)
102
+ body.perpetual = normalized.perpetual;
103
+ if (normalized.jti !== undefined)
104
+ body.jti = normalized.jti;
105
+ if (normalized.expiresInSeconds !== undefined) {
106
+ body.expiresInSeconds = normalized.expiresInSeconds;
90
107
  }
91
108
  return body;
92
109
  }
@@ -168,8 +185,9 @@ async function mintLocal(input, env) {
168
185
  export async function mintLicenseKey(input, options = {}) {
169
186
  const env = options.env ?? process.env;
170
187
  const fetchImpl = options.fetch ?? globalThis.fetch.bind(globalThis);
188
+ const normalized = withPerpetualSiteCaps(input);
171
189
  if (isSignViaSigner(env)) {
172
- return mintViaSigner(input, env, fetchImpl);
190
+ return mintViaSigner(normalized, env, fetchImpl);
173
191
  }
174
- return mintLocal(input, env);
192
+ return mintLocal(normalized, env);
175
193
  }