@blinkk/root-cms 3.0.2 → 3.0.3

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 (161) hide show
  1. package/dist/app.js +5 -5
  2. package/dist/{chunk-3HARN4U6.js → chunk-7Z5IRD2G.js} +176 -83
  3. package/dist/{chunk-2BSW7SIH.js → chunk-N4K6ICFR.js} +4 -4
  4. package/dist/{chunk-BGTUWIV6.js → chunk-PNLLZXVY.js} +4 -4
  5. package/dist/{chunk-C245C557.js → chunk-RXWDB3K4.js} +3 -3
  6. package/dist/{chunk-XLX37FRL.js → chunk-TEKMLYXS.js} +3 -4
  7. package/dist/cli/cli.d.ts +12 -0
  8. package/dist/cli/docs.d.ts +49 -0
  9. package/dist/cli/export.d.ts +11 -0
  10. package/dist/cli/generate-types.d.ts +6 -0
  11. package/dist/cli/import.d.ts +13 -0
  12. package/dist/cli/init-firebase.d.ts +7 -0
  13. package/dist/cli/utils.d.ts +27 -0
  14. package/dist/cli.js +10 -10
  15. package/dist/client.js +1 -1
  16. package/dist/core/ai-tools.d.ts +156 -0
  17. package/dist/core/ai.d.ts +330 -0
  18. package/dist/core/api.d.ts +21 -0
  19. package/dist/core/app.d.ts +16 -0
  20. package/dist/core/checks-translations.d.ts +13 -0
  21. package/dist/core/checks.d.ts +48 -0
  22. package/dist/core/client.d.ts +715 -0
  23. package/dist/core/core.d.ts +5 -0
  24. package/dist/core/cron.d.ts +19 -0
  25. package/dist/core/csv.d.ts +5 -0
  26. package/dist/core/functions.d.ts +9 -0
  27. package/dist/core/plugin.d.ts +357 -0
  28. package/dist/{project.d.ts → core/project.d.ts} +8 -12
  29. package/dist/core/richtext.d.ts +101 -0
  30. package/dist/{core.d.ts → core/route.d.ts} +13 -66
  31. package/dist/core/runtime.d.ts +46 -0
  32. package/dist/{schema-Db_xODoi.d.ts → core/schema.d.ts} +47 -100
  33. package/dist/core/search-extract.d.ts +70 -0
  34. package/dist/core/search-index.d.ts +182 -0
  35. package/dist/core/search-query.d.ts +68 -0
  36. package/dist/core/security.d.ts +6 -0
  37. package/dist/core/server-version.d.ts +5 -0
  38. package/dist/core/services-notifications.d.ts +57 -0
  39. package/dist/core/services.d.ts +44 -0
  40. package/dist/core/sse.d.ts +10 -0
  41. package/dist/core/translations-manager.d.ts +187 -0
  42. package/dist/core/translations.d.ts +83 -0
  43. package/dist/core/url-safety.d.ts +19 -0
  44. package/dist/core/validation.d.ts +30 -0
  45. package/dist/core/values.d.ts +9 -0
  46. package/dist/core/versions.d.ts +48 -0
  47. package/dist/core.js +1 -1
  48. package/dist/edit-M4PN4SGX.js +7 -0
  49. package/dist/functions.js +4 -4
  50. package/dist/{generate-types-SPV7I3A5.js → generate-types-JWIG4QVI.js} +1 -1
  51. package/dist/plugin.js +124 -129
  52. package/dist/shared/marshal.d.ts +68 -0
  53. package/dist/shared/objects.d.ts +9 -0
  54. package/dist/shared/richtext.d.ts +74 -0
  55. package/dist/shared/safe-json.d.ts +11 -0
  56. package/dist/shared/sanitize.d.ts +12 -0
  57. package/dist/shared/slug.d.ts +19 -0
  58. package/dist/shared/sse.d.ts +16 -0
  59. package/dist/shared/strings.d.ts +23 -0
  60. package/dist/ui/AIPage-2LUC2PWC.js +1 -0
  61. package/dist/ui/AssetsPage-PODV4QAB.js +1 -0
  62. package/dist/ui/CollectionPage-4DMKW5YB.js +1 -0
  63. package/dist/ui/ComparePage-JMJE5A5Y.js +1 -0
  64. package/dist/ui/DataPage-MVLZT2BU.js +1 -0
  65. package/dist/ui/DataSourcePage-4RPBXRI2.js +1 -0
  66. package/dist/ui/DocTranslationsPage-XJSPKGVX.js +1 -0
  67. package/dist/ui/DocumentPage-R2PVNG24.js +1 -0
  68. package/dist/ui/EditDataSourcePage-3SHAARNL.js +1 -0
  69. package/dist/ui/EditReleasePage-G5VW2OGW.js +1 -0
  70. package/dist/ui/ImageEditorDialog-4H665KK2.js +81 -0
  71. package/dist/ui/ImageEditorDialog-4H665KK2.js.LEGAL.txt +17 -0
  72. package/dist/ui/LogsPage-K6KYEG2P.js +1 -0
  73. package/dist/ui/NewDataSourcePage-O2VQEOJG.js +1 -0
  74. package/dist/ui/NewReleasePage-RSVS32RZ.js +1 -0
  75. package/dist/ui/NotFoundPage-ZYD5ILG6.js +1 -0
  76. package/dist/ui/ProjectPage-X3YQBWL4.js +1 -0
  77. package/dist/ui/ReleasePage-FJHHXNNB.js +1 -0
  78. package/dist/ui/ReleasesPage-VGWIBNEZ.js +1 -0
  79. package/dist/ui/SettingsPage-C4RXOQ6T.js +1 -0
  80. package/dist/ui/SidebarToolsPage-ZBOKPEMP.js +1 -0
  81. package/dist/ui/TaskPage-BQ4OX5WN.js +1 -0
  82. package/dist/ui/TasksPage-3IGQYVYS.js +1 -0
  83. package/dist/ui/TranslationsArbPage-GGHCWPQL.js +2 -0
  84. package/dist/ui/TranslationsEditPage-E2BCMKYV.js +1 -0
  85. package/dist/ui/TranslationsPage-MC4O4ZNI.js +162 -0
  86. package/dist/ui/ai-tools-5E5ELLZX.js +1 -0
  87. package/dist/ui/chunk-3IYZCUPI.js +1 -0
  88. package/dist/ui/chunk-4KE2SZKH.js +1 -0
  89. package/dist/ui/chunk-4W73RW5I.js +1 -0
  90. package/dist/ui/chunk-54DVDYU6.js +1 -0
  91. package/dist/ui/chunk-5MV6XVGA.js +1 -0
  92. package/dist/ui/chunk-62UWGWON.js +1 -0
  93. package/dist/ui/chunk-6IFGKSIE.js +1 -0
  94. package/dist/ui/chunk-767BAQ53.js +1 -0
  95. package/dist/ui/chunk-AFWBSIPL.js +1 -0
  96. package/dist/ui/chunk-AL3TN2KI.js +1 -0
  97. package/dist/ui/chunk-B6BLDN24.js +141 -0
  98. package/dist/ui/chunk-B6BLDN24.js.LEGAL.txt +106 -0
  99. package/dist/ui/chunk-BZIRGB4W.js +1 -0
  100. package/dist/ui/chunk-C5NH23G4.js +3 -0
  101. package/dist/ui/chunk-CGCKJFL4.js +1 -0
  102. package/dist/ui/chunk-DEGMKEHP.js +1 -0
  103. package/dist/ui/chunk-DTMZLUNY.js +15 -0
  104. package/dist/ui/chunk-DTMZLUNY.js.LEGAL.txt +237 -0
  105. package/dist/ui/chunk-DUJYIOLE.js +5 -0
  106. package/dist/ui/chunk-E2RCCK2T.js +1 -0
  107. package/dist/ui/chunk-EGEB6N4J.js +22 -0
  108. package/dist/ui/chunk-EGEB6N4J.js.LEGAL.txt +1059 -0
  109. package/dist/ui/chunk-GXSAEPU3.js +1 -0
  110. package/dist/ui/chunk-HHMG665Z.js +1 -0
  111. package/dist/ui/chunk-HKINZLMW.js +84 -0
  112. package/dist/ui/chunk-HLMBCVRX.js +1 -0
  113. package/dist/ui/chunk-HRGYNHZ3.js +1 -0
  114. package/dist/ui/chunk-I6ICVKEC.js +1 -0
  115. package/dist/ui/chunk-IU36W2TB.js +1 -0
  116. package/dist/ui/chunk-JDW4UORS.js +1 -0
  117. package/dist/ui/chunk-JHBAMPGB.js +1 -0
  118. package/dist/ui/chunk-JYFLU7DM.js +19 -0
  119. package/dist/ui/chunk-JZFTZ4X4.js +87 -0
  120. package/dist/ui/chunk-JZFTZ4X4.js.LEGAL.txt +9 -0
  121. package/dist/ui/chunk-KFAZBEPV.js +1 -0
  122. package/dist/ui/chunk-KKEWCXVV.js +1 -0
  123. package/dist/ui/chunk-KUCVLANF.js +1 -0
  124. package/dist/ui/chunk-KYDOSLTO.js +1 -0
  125. package/dist/ui/chunk-L4RHGQUG.js +1 -0
  126. package/dist/ui/chunk-MDUBCXU2.js +1 -0
  127. package/dist/ui/chunk-NXQVLOTK.js +1 -0
  128. package/dist/ui/chunk-NZHF733K.js +7 -0
  129. package/dist/ui/chunk-NZHF733K.js.LEGAL.txt +146 -0
  130. package/dist/ui/chunk-ONTGW2VA.js +1 -0
  131. package/dist/ui/chunk-ORXEMIQC.js +1 -0
  132. package/dist/ui/chunk-PHBMVORG.js +1 -0
  133. package/dist/ui/chunk-PJA7YP4A.js +1 -0
  134. package/dist/ui/chunk-PVAE643M.js +1 -0
  135. package/dist/ui/chunk-PWKJDYE2.js +1 -0
  136. package/dist/ui/chunk-RSVO46S3.js +1 -0
  137. package/dist/ui/chunk-SKEP5WYH.js +10 -0
  138. package/dist/ui/chunk-SKEP5WYH.js.LEGAL.txt +176 -0
  139. package/dist/ui/chunk-SQRKKWRG.js +3 -0
  140. package/dist/ui/chunk-UEON4JAT.js +1 -0
  141. package/dist/ui/chunk-V7S4IAGB.js +1 -0
  142. package/dist/ui/chunk-VMT7JFAM.js +1 -0
  143. package/dist/ui/chunk-W3BJ2EZX.js +1 -0
  144. package/dist/ui/chunk-W3HIZQ4Z.js +1 -0
  145. package/dist/ui/chunk-X2WHBGTP.js +1 -0
  146. package/dist/ui/chunk-XOQ3KDSR.js +3 -0
  147. package/dist/ui/chunk-YDO2EDVY.js +1 -0
  148. package/dist/ui/chunk-YFA6U2CV.js +1 -0
  149. package/dist/ui/gcs-L33FIRZU.js +1 -0
  150. package/dist/ui/prerender-Q4YSDCPB.js +1 -0
  151. package/dist/ui/signin.js +1 -1
  152. package/dist/ui/ui.css +1 -1
  153. package/dist/ui/ui.js +1 -630
  154. package/dist/ui/ui.js.LEGAL.txt +19 -732
  155. package/package.json +20 -20
  156. package/dist/client-1puwLgNx.d.ts +0 -1552
  157. package/dist/client.d.ts +0 -5
  158. package/dist/edit-MT4B37QK.js +0 -7
  159. package/dist/functions.d.ts +0 -13
  160. package/dist/plugin.d.ts +0 -5
  161. package/dist/richtext.d.ts +0 -104
@@ -0,0 +1,5 @@
1
+ export * from './client.js';
2
+ export * from './route.js';
3
+ export * from './runtime.js';
4
+ export * as schema from './schema.js';
5
+ export * from './translations-manager.js';
@@ -0,0 +1,19 @@
1
+ import { RootConfig } from '@blinkk/root';
2
+ import { LoadSchemaFn } from './search-index.js';
3
+ /**
4
+ * The minimum interval between incremental search-index rebuilds. The cron tick
5
+ * itself runs every 1 min; this throttle prevents a rebuild from kicking off on
6
+ * every tick.
7
+ */
8
+ export declare const SEARCH_INDEX_MIN_INTERVAL_MS: number;
9
+ export interface RunCronJobsOptions {
10
+ /**
11
+ * Optional schema loader for the search-index rebuild step. The Cloud
12
+ * Scheduler / functions path doesn't need this (prod uses the bundled
13
+ * `dist/collections/<id>.schema.json` files), but the manual
14
+ * `POST /cms/api/cron.run` trigger threads its request-aware loader through
15
+ * so dev users can rebuild without first running a full prod build.
16
+ */
17
+ loadSchema?: LoadSchemaFn;
18
+ }
19
+ export declare function runCronJobs(rootConfig: RootConfig, options?: RunCronJobsOptions): Promise<void>;
@@ -0,0 +1,5 @@
1
+ export declare function arrayToCsv(req: {
2
+ headers: string[];
3
+ rows: Array<Record<string, any>>;
4
+ }): string;
5
+ export declare function csvToArray(csvString: string): any;
@@ -0,0 +1,9 @@
1
+ import { ScheduleOptions } from 'firebase-functions/v2/scheduler';
2
+ export interface CronOptions {
3
+ rootDir?: string;
4
+ scheduleOptions?: Partial<ScheduleOptions>;
5
+ }
6
+ /**
7
+ * Runs offline CMS tasks, such as publishing of scheduled docs.
8
+ */
9
+ export declare function cron(options?: CronOptions): import("firebase-functions/scheduler").ScheduleFunction;
@@ -0,0 +1,357 @@
1
+ import { Plugin, Request } from '@blinkk/root';
2
+ import { App } from 'firebase-admin/app';
3
+ import { Firestore } from 'firebase-admin/firestore';
4
+ import { type AiConfig } from './ai.js';
5
+ import { type CMSCheck } from './checks.js';
6
+ import { Action } from './client.js';
7
+ import { type CMSNotificationService } from './services-notifications.js';
8
+ import { type CMSTranslationService } from './translations.js';
9
+ export type { AiConfig, AiModelConfig, AiProvider } from './ai.js';
10
+ export type { CMSCheck, CheckResult, CheckContext, CheckStatus, } from './checks.js';
11
+ export { translationsCheck } from './checks-translations.js';
12
+ export type { TranslationsCheckOptions } from './checks-translations.js';
13
+ export type { CMSService, CMSServiceContext } from './services.js';
14
+ export type { CMSNotificationService, NotificationResult, NotificationServiceContext, } from './services-notifications.js';
15
+ export type { CMSTranslationService, TranslationExportResult, TranslationImportResult, TranslationRow, TranslationServiceContext, } from './translations.js';
16
+ /**
17
+ * Built-in sidebar tools that can be toggled on/off in the CMS UI.
18
+ */
19
+ export type CMSBuiltInSidebarTool = 'home' | 'content' | 'releases' | 'data' | 'assets' | 'translations' | 'ai' | 'settings';
20
+ export interface CMSUser {
21
+ email: string;
22
+ }
23
+ /**
24
+ * @deprecated The `experiments.ai` flag is now used only as a sidebar toggle.
25
+ * Configure chat models on the top-level `ai` plugin option instead.
26
+ */
27
+ export interface CMSAIConfig {
28
+ /** Custom API endpoint for chat prompts. */
29
+ endpoint?: string;
30
+ /** Gen AI model to use. */
31
+ model?: string;
32
+ }
33
+ /**
34
+ * Filters applied to the spotlight / global search indexer. By default every
35
+ * collection and every doc is indexed. Use these options to scope the index to
36
+ * a subset of the project's content.
37
+ *
38
+ * Doc ids use the `<collectionId>/<slug>` format (e.g. `Pages/about`), which
39
+ * matches the format used elsewhere in the CMS.
40
+ */
41
+ export interface CMSSearchIndexConfig {
42
+ /**
43
+ * Collections to include in the search index. If specified, only these
44
+ * collections are indexed. If unset, all collections are indexed (subject to
45
+ * `excludeCollections`).
46
+ */
47
+ includeCollections?: string[];
48
+ /**
49
+ * Collections to exclude from the search index. Applied after
50
+ * `includeCollections`.
51
+ */
52
+ excludeCollections?: string[];
53
+ /**
54
+ * Doc ids to include in the search index. If specified, only these docs are
55
+ * indexed (within collections that pass the collection filter). Format:
56
+ * `<collectionId>/<slug>`.
57
+ */
58
+ includeDocIds?: string[];
59
+ /**
60
+ * Doc ids to exclude from the search index. Applied after `includeDocIds`.
61
+ * Format: `<collectionId>/<slug>`.
62
+ */
63
+ excludeDocIds?: string[];
64
+ }
65
+ export interface CMSSidebarTool {
66
+ /** URL for the sidebar icon image. */
67
+ icon?: string;
68
+ /** Label. */
69
+ label?: string;
70
+ /** Iframe URL to render for the tool. */
71
+ iframeUrl?: string;
72
+ /**
73
+ * CMS URL that should be opened when the tool is selected. The url must start
74
+ * with `/cms/`. Use this to create shortcuts to CMS pages instead of
75
+ * rendering the tool inside an iframe.
76
+ */
77
+ cmsUrl?: string;
78
+ /**
79
+ * External URL that should open in a new tab when the tool is selected.
80
+ */
81
+ externalUrl?: string;
82
+ }
83
+ export type CMSPluginOptions = {
84
+ /**
85
+ * The ID of the project. Data will be stored under the namespace
86
+ * `Projects/${id}` in firestore.
87
+ */
88
+ id?: string;
89
+ /**
90
+ * The name of the project. Used in the header of the CMS to help identify
91
+ * the project.
92
+ */
93
+ name?: string;
94
+ /**
95
+ * Firebase config object, which can be obtained in the Firebase Console by
96
+ * going to "Project Settings".
97
+ */
98
+ firebaseConfig: {
99
+ [key: string]: string | undefined;
100
+ apiKey: string;
101
+ authDomain: string;
102
+ projectId: string;
103
+ storageBucket: string;
104
+ databaseId?: string;
105
+ };
106
+ /**
107
+ * GAPI credentials. Include if using Google Drive and Google Sheets features.
108
+ * See: https://developers.google.com/sheets/api/quickstart/js
109
+ */
110
+ gapi?: {
111
+ /** https://developers.google.com/sheets/api/quickstart/js#create_an_api_key */
112
+ apiKey: string;
113
+ /** https://developers.google.com/sheets/api/quickstart/js#authorize_credentials_for_a_web_application */
114
+ clientId: string;
115
+ };
116
+ /**
117
+ * Secret value(s) used for signing the user authentication cookie.
118
+ * @deprecated This is now handled directly by root's sessionMiddleware under
119
+ * `server.sessionCookieSecret` in root.config.ts.
120
+ */
121
+ cookieSecret?: string | string[];
122
+ /** Function called to check if a user should have access to the CMS. */
123
+ isUserAuthorized?: (req: Request, user: CMSUser) => boolean | Promise<boolean>;
124
+ /**
125
+ * Function to call to check if login is required for a particular request.
126
+ */
127
+ isLoginRequired?: (req: Request) => boolean;
128
+ /**
129
+ * By default, iframing the CMS is disallowed. Setting this value will allow
130
+ * iframes from the specified origins. Example:
131
+ * ```
132
+ * allowedIframeOrigins: ['https://app.example.com']
133
+ * ```
134
+ */
135
+ allowedIframeOrigins?: string[];
136
+ /**
137
+ * URL to GCI service for transforming uploaded GCS images to a Google App
138
+ * Engine Images API serving URL.
139
+ *
140
+ * Setting this to `true` uses the default hosted service at
141
+ * https://services.rootjs.dev.
142
+ *
143
+ * To set up GCI:
144
+ *
145
+ * - Create a GCS bucket with fine-grained permissions
146
+ * - Share owner access to the bucket with the service account returned in
147
+ * https://services.rootjs.dev/_/service_account
148
+ *
149
+ * To disable GCI, leave this value empty or set to `false`, which which will
150
+ * serve images directly from GCS instead.
151
+ */
152
+ gci?: string | boolean;
153
+ /**
154
+ * Customization options for the CMS sidebar.
155
+ */
156
+ sidebar?: {
157
+ /**
158
+ * Sidebar tools, a map of the sidebar id to config options. The sidebar
159
+ * tool is url-mapped to `/cms/tools/:id` and displays the tool in an
160
+ * iframe.
161
+ */
162
+ tools?: Record<string, CMSSidebarTool>;
163
+ /**
164
+ * Hide specific built-in sidebar tools. Hiding a tool also removes its
165
+ * surfaces from the CMS home page. The underlying routes remain
166
+ * accessible via direct URL.
167
+ */
168
+ hiddenBuiltInTools?: CMSBuiltInSidebarTool[];
169
+ };
170
+ /**
171
+ * URL for a custom favicon used by the CMS UI.
172
+ */
173
+ favicon?: string;
174
+ /**
175
+ * Enables minimal branding mode in the CMS header. This hides the Root CMS
176
+ * logo and displays the project name on the top-right.
177
+ */
178
+ minimalBranding?: boolean;
179
+ /**
180
+ * Callback when an action occurs.
181
+ */
182
+ onAction?: (action: Action) => any;
183
+ /**
184
+ * Configures the Root CMS AI chat (`/cms/ai`). Provide one or more models
185
+ * — the CMS proxies user requests directly to the configured providers.
186
+ *
187
+ * The shape mirrors open source tools like Ollama and LiteLLM: each entry
188
+ * declares the provider, model id and credentials. Keys live on the server,
189
+ * never on the client.
190
+ *
191
+ * Example:
192
+ * ```ts
193
+ * cmsPlugin({
194
+ * ai: {
195
+ * models: [
196
+ * {
197
+ * id: 'gpt-5.5',
198
+ * label: 'GPT-5.5',
199
+ * provider: 'openai',
200
+ * apiKey: process.env.OPENAI_API_KEY,
201
+ * capabilities: {tools: true, reasoning: true, attachments: true},
202
+ * },
203
+ * {
204
+ * id: 'claude-opus-4-7',
205
+ * label: 'Claude Opus 4.7',
206
+ * provider: 'anthropic',
207
+ * apiKey: process.env.ANTHROPIC_API_KEY,
208
+ * capabilities: {tools: true, reasoning: true, attachments: true},
209
+ * },
210
+ * {
211
+ * id: 'gemini-3.1-pro',
212
+ * label: 'Gemini 3.1 Pro',
213
+ * provider: 'gemini',
214
+ * apiKey: process.env.GEMINI_API_KEY,
215
+ * capabilities: {tools: true, reasoning: true, attachments: true},
216
+ * },
217
+ * {
218
+ * id: 'llama3-local',
219
+ * label: 'Llama 3 (local)',
220
+ * provider: 'openai-compatible',
221
+ * baseURL: 'http://localhost:11434/v1',
222
+ * },
223
+ * ],
224
+ * defaultModel: 'gpt-4o',
225
+ * },
226
+ * });
227
+ * ```
228
+ *
229
+ * For project-specific guidance (conventions, patterns, naming rules, etc.),
230
+ * drop a `ROOT.md` file at the project root. Its contents are appended to
231
+ * the system prompt for every chat — similar to `AGENTS.md` / `CLAUDE.md`.
232
+ */
233
+ ai?: AiConfig;
234
+ /**
235
+ * Experimental config options. Note: these are subject to change at any time.
236
+ */
237
+ experiments?: {
238
+ /**
239
+ * @deprecated Use the top-level `ai` config instead. Setting this to
240
+ * `true` keeps the AI chat icon visible in the sidebar.
241
+ */
242
+ ai?: boolean | CMSAIConfig;
243
+ /**
244
+ * Enables the v2 `TranslationsManager`.
245
+ */
246
+ v2TranslationsManager?: boolean;
247
+ /**
248
+ * Enables the task manager (sidebar entry, home page card, and
249
+ * `/cms/tasks` routes).
250
+ */
251
+ taskManager?: boolean;
252
+ };
253
+ /**
254
+ * Adjust console output verbosity. Default is `'info'`.
255
+ */
256
+ logLevel?: 'info' | 'warn' | 'error' | 'silent' | 'debug';
257
+ /**
258
+ * Whether to enable/disable file watching in dev (e.g. for generating
259
+ * `root-cms.d.ts`). Defaults to `true`.
260
+ */
261
+ watch?: boolean;
262
+ /** Options associated with the preview. */
263
+ preview?: {
264
+ /**
265
+ * Whether to send messages to the preview iframe, handle messages from
266
+ * the preview iframe, enable both (`true`), or disable messages entirely
267
+ * (`false`). If unspecified, the default is `false`.
268
+ */
269
+ channel: boolean | 'to-preview' | 'from-preview';
270
+ };
271
+ /**
272
+ * Checks that can be run on-demand from the CMS UI to validate document
273
+ * content. Each check defines a server-side function that returns a
274
+ * success/warning/error result with a markdown message.
275
+ *
276
+ * Example:
277
+ * ```ts
278
+ * cmsPlugin({
279
+ * checks: [
280
+ * {
281
+ * id: 'my-check',
282
+ * label: 'My Check',
283
+ * run: async (ctx) => {
284
+ * return {status: 'success', message: 'All good!'};
285
+ * },
286
+ * },
287
+ * ],
288
+ * });
289
+ * ```
290
+ *
291
+ * NOTE: The checks feature is considered a "beta" feature, its interface
292
+ * may change from version to version as we add new features.
293
+ */
294
+ checks?: CMSCheck[];
295
+ /**
296
+ * Translation services that appear in the Localization modal's Import and
297
+ * Export menus. Each service defines server-side import/export functions
298
+ * that integrate with an external translation platform (e.g. Crowdin).
299
+ *
300
+ * Example:
301
+ * ```ts
302
+ * cmsPlugin({
303
+ * translations: [
304
+ * {
305
+ * id: 'crowdin',
306
+ * label: 'Crowdin',
307
+ * onImport: async (ctx, data) => { ... },
308
+ * onExport: async (ctx, data) => { ... },
309
+ * },
310
+ * ],
311
+ * });
312
+ * ```
313
+ */
314
+ translations?: CMSTranslationService[];
315
+ /**
316
+ * Notification services that react to CMS actions and dispatch them to
317
+ * external channels (email, Slack, webhooks, etc.). Each service defines
318
+ * an optional server-side `onAction` handler.
319
+ *
320
+ * Example:
321
+ * ```ts
322
+ * cmsPlugin({
323
+ * notifications: [
324
+ * {
325
+ * id: 'sendgrid',
326
+ * label: 'SendGrid',
327
+ * onAction: async (ctx, action) => {
328
+ * if (action.action === 'doc.publish') {
329
+ * await sendgrid.send({ ... });
330
+ * }
331
+ * },
332
+ * },
333
+ * ],
334
+ * });
335
+ * ```
336
+ */
337
+ notifications?: CMSNotificationService[];
338
+ /**
339
+ * Configuration for the spotlight / global search indexer. Use this to
340
+ * include or exclude specific collections or docs from being indexed.
341
+ */
342
+ searchIndex?: CMSSearchIndexConfig;
343
+ /**
344
+ * Default UI variant for `oneOf` fields. Individual fields can still
345
+ * override this by setting their own `variant`. Defaults to `'dropdown'`.
346
+ */
347
+ defaultOneOfVariant?: 'dropdown' | 'picker';
348
+ };
349
+ export type CMSPlugin = Plugin & {
350
+ name: 'root-cms';
351
+ getConfig: () => CMSPluginOptions;
352
+ getFirebaseApp: () => App;
353
+ getFirestore: (options?: {
354
+ databaseId?: string;
355
+ }) => Firestore;
356
+ };
357
+ export declare function cmsPlugin(options: CMSPluginOptions): CMSPlugin;
@@ -1,32 +1,30 @@
1
- import { S as Schema, C as Collection } from './schema-Db_xODoi.js';
2
-
3
1
  /**
4
2
  * Loads various files or configurations from the project.
5
3
  *
6
4
  * NOTE: This file needs to be loaded through vite's ssrLoadModule so that
7
5
  * virtual modules are resolved.
8
6
  */
9
-
10
- interface SchemaModule {
11
- default: Schema;
7
+ import * as schema from './schema.js';
8
+ export interface SchemaModule {
9
+ default: schema.Schema;
12
10
  }
13
- declare const SCHEMA_MODULES: Record<string, SchemaModule>;
11
+ export declare const SCHEMA_MODULES: Record<string, SchemaModule>;
14
12
  /**
15
13
  * Returns a map of all `schema.ts` files defined in the project as
16
14
  * fileId => schema. This is used by `generate-types.ts` to build the
17
15
  * `root-cms.d.ts` file.
18
16
  */
19
- declare function getProjectSchemas(): Record<string, Schema>;
17
+ export declare function getProjectSchemas(): Record<string, schema.Schema>;
20
18
  /**
21
19
  * Resolves SchemaPattern objects in oneOf fields to arrays of Schema objects.
22
20
  * This is needed for type generation which expects `field.types` to be an array.
23
21
  */
24
- declare function resolveOneOfPatterns(schemaObj: Schema): Schema;
22
+ export declare function resolveOneOfPatterns(schemaObj: schema.Schema): schema.Schema;
25
23
  /**
26
24
  * Returns a collection's schema definition as defined in
27
25
  * `/collections/<id>.schema.ts`.
28
26
  */
29
- declare function getCollectionSchema(collectionId: string): Collection | null;
27
+ export declare function getCollectionSchema(collectionId: string): schema.Collection | null;
30
28
  /**
31
29
  * Converts all `oneof` field type definitions into a map keyed by the type
32
30
  * name. The field definitions are replaced with an array of type names.
@@ -39,6 +37,4 @@ declare function getCollectionSchema(collectionId: string): Collection | null;
39
37
  * and skipping the clone would mutate the shared entries in `SCHEMA_MODULES`
40
38
  * and corrupt subsequent calls (e.g. when building multiple collections).
41
39
  */
42
- declare function convertOneOfTypes(collection: Collection, schemaModules?: Record<string, SchemaModule>): Collection;
43
-
44
- export { SCHEMA_MODULES, type SchemaModule, convertOneOfTypes, getCollectionSchema, getProjectSchemas, resolveOneOfPatterns };
40
+ export declare function convertOneOfTypes(collection: schema.Collection, schemaModules?: Record<string, SchemaModule>): schema.Collection;
@@ -0,0 +1,101 @@
1
+ import { FunctionalComponent } from 'preact';
2
+ export interface RichTextBlock {
3
+ type: string;
4
+ data?: any;
5
+ }
6
+ export interface RichTextData {
7
+ [key: string]: any;
8
+ blocks: RichTextBlock[];
9
+ }
10
+ export type RichTextComponent = FunctionalComponent<any>;
11
+ export type RichTextBlockComponent = RichTextComponent;
12
+ export type RichTextInlineComponent = RichTextComponent;
13
+ export type RichTextComponentMap = Record<string, RichTextComponent>;
14
+ export interface RichTextContextProps {
15
+ /**
16
+ * Rich text components override for both inline and block level components.
17
+ */
18
+ components?: RichTextComponentMap;
19
+ /**
20
+ * Translator function override.
21
+ */
22
+ t?: (msg: string, params?: Record<string, string | number>) => string;
23
+ }
24
+ export declare const RichTextContext: import("preact").Context<RichTextContextProps>;
25
+ export declare function useRichTextContext(): RichTextContextProps;
26
+ export interface RichTextProps {
27
+ data: RichTextData | undefined;
28
+ components?: Record<string, RichTextBlockComponent>;
29
+ /** @deprecated */
30
+ translate?: boolean;
31
+ }
32
+ /** Renders data from the "richtext" field. */
33
+ export declare function RichText(props: RichTextProps): import("preact").JSX.Element | null;
34
+ export declare namespace RichText {
35
+ var Block: (props: RichTextBlock) => import("preact").JSX.Element | null;
36
+ var ParagraphBlock: (props: RichTextParagraphBlockProps) => import("preact").JSX.Element | null;
37
+ var HeadingBlock: (props: RichTextHeadingBlockProps) => import("preact").JSX.Element | null;
38
+ var ListBlock: (props: RichTextListBlockProps) => import("preact").JSX.Element | null;
39
+ var ImageBlock: (props: RichTextImageBlockProps) => import("preact").JSX.Element | null;
40
+ var HtmlBlock: (props: RichTextHtmlBlockProps) => import("preact").JSX.Element | null;
41
+ var TableBlock: (props: RichTextTableBlockProps) => import("preact").JSX.Element | null;
42
+ }
43
+ export interface RichTextParagraphBlockProps {
44
+ type: 'paragraph';
45
+ data?: {
46
+ text?: string;
47
+ components?: Record<string, any>;
48
+ };
49
+ }
50
+ export interface RichTextHeadingBlockProps {
51
+ type: 'heading';
52
+ data?: {
53
+ level?: number;
54
+ text?: string;
55
+ };
56
+ }
57
+ interface ListItem {
58
+ content?: string;
59
+ items?: ListItem[];
60
+ components?: Record<string, any>;
61
+ }
62
+ export interface RichTextListBlockProps {
63
+ type: 'orderedList' | 'unorderedList';
64
+ data?: {
65
+ style?: 'ordered' | 'unordered';
66
+ items?: ListItem[];
67
+ };
68
+ }
69
+ export interface RichTextImageBlockProps {
70
+ type: 'image';
71
+ data?: {
72
+ /** The caption entered into the CMS Image field. */
73
+ caption?: string;
74
+ file?: {
75
+ url: string;
76
+ width: string | number;
77
+ height: string | number;
78
+ alt: string;
79
+ };
80
+ };
81
+ }
82
+ export interface RichTextHtmlBlockProps {
83
+ type: 'html';
84
+ data?: {
85
+ html?: string;
86
+ };
87
+ }
88
+ export interface RichTextTableBlockProps {
89
+ type: 'table';
90
+ data?: {
91
+ rows?: Array<{
92
+ cells: Array<{
93
+ blocks: RichTextBlock[];
94
+ type: 'header' | 'data';
95
+ }>;
96
+ }>;
97
+ };
98
+ }
99
+ /** Returns whether the rich text value is truthy. */
100
+ export declare function testContent(data: RichTextData): boolean;
101
+ export {};
@@ -1,10 +1,3 @@
1
- import { R as RootCMSClient, D as DocMode, L as LoadTranslationsOptions, T as TranslationsMap, a as LocaleTranslations } from './client-1puwLgNx.js';
2
- export { A as Action, r as ArrayObject, F as BatchRequest, B as BatchRequestOptions, y as BatchRequestQuery, z as BatchRequestQueryOptions, I as BatchResponse, C as CronUnit, d as DataSource, c as DataSourceCron, e as DataSourceData, f as DataSourceMode, b as Doc, j as GetCountOptions, G as GetDocOptions, H as HttpMethod, m as ListActionsOptions, i as ListDocsOptions, J as Locale, Q as MultiLocaleTranslationsMap, l as Release, g as SaveDraftOptions, S as SetDocOptions, V as SingleLocaleTranslationsMap, K as SourceString, M as TranslatedString, k as Translation, E as TranslationsDoc, N as TranslationsDocMode, P as TranslationsLocaleDocEntry, O as TranslationsLocaleDocHashMap, W as TranslationsManager, h as UpdateDraftOptions, U as UserRole, X as buildTranslationsDbPath, Y as buildTranslationsLocaleDocDbPath, o as getCmsPlugin, n as isRichTextData, s as marshalArray, p as marshalData, q as normalizeData, x as parseDocId, t as toArrayObject, w as translationsForLocale, v as unmarshalArray, u as unmarshalData } from './client-1puwLgNx.js';
3
- import { Request, RootConfig, Response, RouteParams, GetStaticProps, GetStaticPaths } from '@blinkk/root';
4
- import { Query } from 'firebase-admin/firestore';
5
- export { s as schema } from './schema-Db_xODoi.js';
6
- import 'firebase-admin/app';
7
-
8
1
  /**
9
2
  * Utility for creating Root filesystem routes that are connected to a CMS doc.
10
3
  *
@@ -30,8 +23,9 @@ import 'firebase-admin/app';
30
23
  * export const {getStaticProps, getStaticPaths} = createRoute({collection: 'BlogPosts'});
31
24
  * ```
32
25
  */
33
-
34
- interface RootCMSDoc<Fields = any> {
26
+ import { GetStaticPaths, GetStaticProps, Request, Response, RootConfig, RouteParams } from '@blinkk/root';
27
+ import { DocMode, RootCMSClient } from './client.js';
28
+ export interface RootCMSDoc<Fields = any> {
35
29
  /** The id of the doc, e.g. "Pages/foo-bar". */
36
30
  id: string;
37
31
  /** The collection id of the doc, e.g. "Pages". */
@@ -53,12 +47,12 @@ interface RootCMSDoc<Fields = any> {
53
47
  /** User-entered field values from the CMS. */
54
48
  fields?: Fields;
55
49
  }
56
- type RouteRequest = Request & {
50
+ export type RouteRequest = Request & {
57
51
  rootConfig: RootConfig;
58
52
  cmsClient: RootCMSClient;
59
53
  };
60
- type RouteResponse = Response;
61
- interface RouteContext {
54
+ export type RouteResponse = Response;
55
+ export interface RouteContext {
62
56
  /**
63
57
  * HTTP request object. Only available in SSR mode.
64
58
  */
@@ -80,7 +74,7 @@ interface RouteContext {
80
74
  */
81
75
  params: RouteParams;
82
76
  }
83
- interface Route {
77
+ export interface Route {
84
78
  /**
85
79
  * SSR handler.
86
80
  */
@@ -94,7 +88,7 @@ interface Route {
94
88
  */
95
89
  getStaticPaths?: GetStaticPaths;
96
90
  }
97
- interface CreateRouteOptions {
91
+ export interface CreateRouteOptions {
98
92
  /**
99
93
  * Collection mapped to the route.
100
94
  */
@@ -171,67 +165,20 @@ interface CreateRouteOptions {
171
165
  /**
172
166
  * Utility for creating Root filesystem routes that are connected to a CMS doc.
173
167
  */
174
- declare function createRoute(options: CreateRouteOptions): Route;
175
- declare function resolvePromisesMap(promisesMap: Record<string, Promise<any>>): Promise<Record<string, any>>;
168
+ export declare function createRoute(options: CreateRouteOptions): Route;
169
+ export declare function resolvePromisesMap(promisesMap: Record<string, Promise<any>>): Promise<Record<string, any>>;
176
170
  /**
177
171
  * Returns the first query param value in a given request.
178
172
  *
179
173
  * For example, for a URL like `/?foo=bar&foo=baz`, calling
180
174
  * `getFirstQueryParam(req, 'foo')` would return `"bar"`.
181
175
  */
182
- declare function getFirstQueryParam(req: Request, key: string): string | null;
176
+ export declare function getFirstQueryParam(req: Request, key: string): string | null;
183
177
  /**
184
178
  * Issues an HTTP redirect, preserving any query params from the original req.
185
179
  */
186
- declare function redirectWithQuery(req: Request, res: Response, redirectCode: number, redirectPath: string): void;
180
+ export declare function redirectWithQuery(req: Request, res: Response, redirectCode: number, redirectPath: string): void;
187
181
  /**
188
182
  * Returns the CMS document mode associated with the request.
189
183
  */
190
- declare function getMode(req: Request): Promise<DocMode>;
191
-
192
- /** @deprecated Use client.ts instead. */
193
-
194
- /**
195
- * Retrieves a doc from Root.js CMS.
196
- * @deprecated Use RootCMSClient.getDoc() instead.
197
- */
198
- declare function getDoc<T>(rootConfig: RootConfig, collectionId: string, slug: string, options: {
199
- mode: 'draft' | 'published';
200
- }): Promise<T | null>;
201
- /**
202
- * Lists docs from a Root.js CMS collection.
203
- * @deprecated Use RootCMSClient.listDocs() instead.
204
- */
205
- declare function listDocs<T>(rootConfig: RootConfig, collectionId: string, options: {
206
- mode: 'draft' | 'published';
207
- offset?: number;
208
- limit?: number;
209
- orderBy?: string;
210
- orderByDirection?: 'asc' | 'desc';
211
- query?: (query: Query) => Query;
212
- }): Promise<{
213
- docs: T[];
214
- }>;
215
- /**
216
- * Returns the number of docs in a Root.js CMS collection.
217
- * @deprecated Use RootCMSClient.getDocsCount() instead.
218
- */
219
- declare function numDocs(rootConfig: RootConfig, collectionId: string, options: {
220
- mode: 'draft' | 'published';
221
- query?: (query: Query) => Query;
222
- }): Promise<number>;
223
- /**
224
- * Publishes scheduled docs.
225
- * @deprecated Use RootCMSClient.publishScheduledDocs() instead.
226
- */
227
- declare function publishScheduledDocs(rootConfig: RootConfig): Promise<any[]>;
228
- /**
229
- * @deprecated Use `RootCMSClient.loadTranslations()`.
230
- */
231
- declare function loadTranslations(rootConfig: RootConfig, options?: LoadTranslationsOptions): Promise<TranslationsMap>;
232
- /**
233
- * @deprecated Use `RootCMSClient.loadTranslationsForLocale()`.
234
- */
235
- declare function loadTranslationsForLocale(rootConfig: RootConfig, locale: string, options?: LoadTranslationsOptions): Promise<LocaleTranslations>;
236
-
237
- export { type CreateRouteOptions, DocMode, LoadTranslationsOptions, LocaleTranslations, RootCMSClient, type RootCMSDoc, type Route, type RouteContext, type RouteRequest, type RouteResponse, TranslationsMap, createRoute, getDoc, getFirstQueryParam, getMode, listDocs, loadTranslations, loadTranslationsForLocale, numDocs, publishScheduledDocs, redirectWithQuery, resolvePromisesMap };
184
+ export declare function getMode(req: Request): Promise<DocMode>;