@blinkk/root-cms 3.0.1-alpha.0 → 3.0.1-alpha.1
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.
- package/dist/app.js +2 -2
- package/dist/{chunk-N4Z3O53K.js → chunk-BBOESYH7.js} +4 -3
- package/dist/{chunk-MSJGHSR6.js → chunk-R4LKO3EZ.js} +7 -9
- package/dist/{chunk-YMUZ5H5C.js → chunk-SNZ4S4IC.js} +21 -0
- package/dist/chunk-UTSL2E2P.js +921 -0
- package/dist/cli.js +1 -1
- package/dist/{client-cP6yMgT8.d.ts → client-DdB4xpM6.d.ts} +127 -18
- package/dist/client.d.ts +2 -2
- package/dist/client.js +1 -1
- package/dist/core.d.ts +3 -3
- package/dist/core.js +7 -1
- package/dist/functions.js +2 -2
- package/dist/plugin.d.ts +2 -2
- package/dist/plugin.js +88 -4
- package/dist/project.d.ts +2 -2
- package/dist/project.js +1 -1
- package/dist/{schema-D7MOj-YC.d.ts → schema-rjBOZk-j.d.ts} +61 -1
- package/dist/ui/ui.css +1 -1
- package/dist/ui/ui.js +166 -160
- package/dist/ui/ui.js.LEGAL.txt +14 -2
- package/package.json +5 -4
- package/dist/chunk-H6ZKML2S.js +0 -157
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { RootConfig, Plugin, Request } from '@blinkk/root';
|
|
2
2
|
import { App } from 'firebase-admin/app';
|
|
3
3
|
import { Firestore, WriteBatch, Timestamp, Query } from 'firebase-admin/firestore';
|
|
4
|
-
import { C as Collection } from './schema-
|
|
4
|
+
import { C as Collection } from './schema-rjBOZk-j.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Supported Root AI models. Defaults to 'gemini-3-flash-preview'.
|
|
@@ -54,6 +54,105 @@ interface CMSCheck {
|
|
|
54
54
|
run: (ctx: CheckContext) => Promise<CheckResult>;
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
+
/**
|
|
58
|
+
* Base shape for a service registered with the CMS plugin.
|
|
59
|
+
*
|
|
60
|
+
* Services are extension points that let plugins provide capabilities
|
|
61
|
+
* (e.g. email delivery, cache, translations) that root-cms can call into.
|
|
62
|
+
* Every service shares the same identifying fields — `id`, `label`, optional
|
|
63
|
+
* `icon` — and is registered via the `services` option on `cmsPlugin()`.
|
|
64
|
+
*
|
|
65
|
+
* Concrete service interfaces (e.g. `CMSEmailService`,
|
|
66
|
+
* `CMSTranslationService`) extend this base and add the handler functions
|
|
67
|
+
* specific to their capability.
|
|
68
|
+
*/
|
|
69
|
+
interface CMSService {
|
|
70
|
+
/** Unique ID for the service (e.g. `'sendgrid'`, `'crowdin'`). */
|
|
71
|
+
id: string;
|
|
72
|
+
/** Human-readable label displayed in the UI (e.g. "SendGrid"). */
|
|
73
|
+
label: string;
|
|
74
|
+
/**
|
|
75
|
+
* Optional icon URL displayed in the UI next to the label. Similar to the
|
|
76
|
+
* sidebar tools `icon` option, this should be a URL to an image.
|
|
77
|
+
*/
|
|
78
|
+
icon?: string;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Base context passed to service handler functions. Concrete services may
|
|
82
|
+
* extend this with additional fields specific to the call site (e.g. the
|
|
83
|
+
* translation context adds `docId`, `collectionId`, etc.).
|
|
84
|
+
*/
|
|
85
|
+
interface CMSServiceContext {
|
|
86
|
+
/** The Root.js config. */
|
|
87
|
+
rootConfig: RootConfig;
|
|
88
|
+
/** The Root CMS client for accessing the database. */
|
|
89
|
+
cmsClient: RootCMSClient;
|
|
90
|
+
/**
|
|
91
|
+
* Email of the user that triggered the action, if any. Some service calls
|
|
92
|
+
* are initiated by the system rather than a user, in which case this is
|
|
93
|
+
* undefined.
|
|
94
|
+
*/
|
|
95
|
+
user?: {
|
|
96
|
+
email: string;
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** Result returned by a notification service `onAction` handler. */
|
|
101
|
+
interface NotificationResult {
|
|
102
|
+
/**
|
|
103
|
+
* Delivery status.
|
|
104
|
+
* - `'success'`: the notification was delivered.
|
|
105
|
+
* - `'error'`: delivery failed; `message` should describe why.
|
|
106
|
+
* - `'info'` (default): the service handled the action but did not
|
|
107
|
+
* deliver a notification (e.g. the action was filtered out).
|
|
108
|
+
*/
|
|
109
|
+
status?: 'success' | 'info' | 'error';
|
|
110
|
+
/** Optional human-readable message describing the result. */
|
|
111
|
+
message?: string;
|
|
112
|
+
}
|
|
113
|
+
/** Context passed to notification service handler functions. */
|
|
114
|
+
interface NotificationServiceContext extends CMSServiceContext {
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Configuration for defining a CMS notification service.
|
|
118
|
+
*
|
|
119
|
+
* Notification services react to actions in the CMS (publishes, schema
|
|
120
|
+
* changes, comments, etc.) and dispatch them to an external channel.
|
|
121
|
+
* Initially this is intended for email, with Slack, webhooks, and other
|
|
122
|
+
* transports planned.
|
|
123
|
+
*
|
|
124
|
+
* Multiple notification services may be registered; each independently
|
|
125
|
+
* decides whether and how to handle a given action.
|
|
126
|
+
*
|
|
127
|
+
* Example:
|
|
128
|
+
* ```ts
|
|
129
|
+
* cmsPlugin({
|
|
130
|
+
* services: {
|
|
131
|
+
* notifications: [
|
|
132
|
+
* {
|
|
133
|
+
* id: 'sendgrid',
|
|
134
|
+
* label: 'SendGrid',
|
|
135
|
+
* onAction: async (ctx, action) => {
|
|
136
|
+
* if (action.action === 'doc.publish') {
|
|
137
|
+
* await sendgrid.send({ ... });
|
|
138
|
+
* }
|
|
139
|
+
* },
|
|
140
|
+
* },
|
|
141
|
+
* ],
|
|
142
|
+
* },
|
|
143
|
+
* });
|
|
144
|
+
* ```
|
|
145
|
+
*/
|
|
146
|
+
interface CMSNotificationService extends CMSService {
|
|
147
|
+
/**
|
|
148
|
+
* Async function called when an action occurs in the CMS. Receives the
|
|
149
|
+
* action and may dispatch a notification (e.g. send email, post to Slack)
|
|
150
|
+
* via the service's underlying transport. Can optionally return a
|
|
151
|
+
* `NotificationResult` describing delivery status.
|
|
152
|
+
*/
|
|
153
|
+
onAction?: (ctx: NotificationServiceContext, action: Action) => Promise<void | NotificationResult>;
|
|
154
|
+
}
|
|
155
|
+
|
|
57
156
|
/** A row of translation data keyed by locale. */
|
|
58
157
|
interface TranslationRow {
|
|
59
158
|
/** The source string. */
|
|
@@ -64,11 +163,7 @@ interface TranslationRow {
|
|
|
64
163
|
description?: string;
|
|
65
164
|
}
|
|
66
165
|
/** Context passed to translation service import/export functions. */
|
|
67
|
-
interface TranslationServiceContext {
|
|
68
|
-
/** The Root.js config. */
|
|
69
|
-
rootConfig: RootConfig;
|
|
70
|
-
/** The Root CMS client for accessing the database. */
|
|
71
|
-
cmsClient: RootCMSClient;
|
|
166
|
+
interface TranslationServiceContext extends CMSServiceContext {
|
|
72
167
|
/** The document ID, e.g. `Pages/index`. */
|
|
73
168
|
docId: string;
|
|
74
169
|
/** The collection ID, e.g. `Pages`. */
|
|
@@ -125,16 +220,7 @@ interface TranslationImportResult {
|
|
|
125
220
|
status?: 'success' | 'info' | 'error';
|
|
126
221
|
}
|
|
127
222
|
/** Configuration for defining a CMS translation service. */
|
|
128
|
-
interface CMSTranslationService {
|
|
129
|
-
/** Unique ID for the translation service. */
|
|
130
|
-
id: string;
|
|
131
|
-
/** Human-readable label displayed in the UI (e.g. "Crowdin"). */
|
|
132
|
-
label: string;
|
|
133
|
-
/**
|
|
134
|
-
* Optional icon URL displayed in the UI next to the label. Similar to the
|
|
135
|
-
* sidebar tools `icon` option, this should be a URL to an image.
|
|
136
|
-
*/
|
|
137
|
-
icon?: string;
|
|
223
|
+
interface CMSTranslationService extends CMSService {
|
|
138
224
|
/**
|
|
139
225
|
* Async function to import translations from the service. Should return an
|
|
140
226
|
* array of translation rows that will be merged into the CMS translations
|
|
@@ -166,7 +252,7 @@ declare function translationsCheck(options?: TranslationsCheckOptions): CMSCheck
|
|
|
166
252
|
/**
|
|
167
253
|
* Built-in sidebar tools that can be toggled on/off in the CMS UI.
|
|
168
254
|
*/
|
|
169
|
-
type CMSBuiltInSidebarTool = 'home' | 'content' | 'releases' | 'data' | 'assets' | 'translations' | 'ai' | 'settings';
|
|
255
|
+
type CMSBuiltInSidebarTool = 'home' | 'content' | 'tasks' | 'releases' | 'data' | 'assets' | 'translations' | 'ai' | 'settings';
|
|
170
256
|
interface CMSUser {
|
|
171
257
|
email: string;
|
|
172
258
|
}
|
|
@@ -367,6 +453,29 @@ type CMSPluginOptions = {
|
|
|
367
453
|
* ```
|
|
368
454
|
*/
|
|
369
455
|
translations?: CMSTranslationService[];
|
|
456
|
+
/**
|
|
457
|
+
* Notification services that react to CMS actions and dispatch them to
|
|
458
|
+
* external channels (email, Slack, webhooks, etc.). Each service defines
|
|
459
|
+
* an optional server-side `onAction` handler.
|
|
460
|
+
*
|
|
461
|
+
* Example:
|
|
462
|
+
* ```ts
|
|
463
|
+
* cmsPlugin({
|
|
464
|
+
* notifications: [
|
|
465
|
+
* {
|
|
466
|
+
* id: 'sendgrid',
|
|
467
|
+
* label: 'SendGrid',
|
|
468
|
+
* onAction: async (ctx, action) => {
|
|
469
|
+
* if (action.action === 'doc.publish') {
|
|
470
|
+
* await sendgrid.send({ ... });
|
|
471
|
+
* }
|
|
472
|
+
* },
|
|
473
|
+
* },
|
|
474
|
+
* ],
|
|
475
|
+
* });
|
|
476
|
+
* ```
|
|
477
|
+
*/
|
|
478
|
+
notifications?: CMSNotificationService[];
|
|
370
479
|
};
|
|
371
480
|
type CMSPlugin = Plugin & {
|
|
372
481
|
name: 'root-cms';
|
|
@@ -1256,4 +1365,4 @@ declare class BatchResponse {
|
|
|
1256
1365
|
private getTranslationsMap;
|
|
1257
1366
|
}
|
|
1258
1367
|
|
|
1259
|
-
export { type CMSAIConfig as $, type Action as A, type BatchRequestOptions as B, type CronUnit as C, type DocMode as D, type TranslationsDoc as E, BatchRequest as F, type GetDocOptions as G, type HttpMethod as H, BatchResponse as I, type Locale as J, type SourceString as K, type LoadTranslationsOptions as L, type TranslatedString as M, type TranslationsDocMode as N, type TranslationsLocaleDocHashMap as O, type TranslationsLocaleDocEntry as P, type MultiLocaleTranslationsMap as Q, RootCMSClient as R, type SetDocOptions as S, type TranslationsMap as T, type UserRole as U, type SingleLocaleTranslationsMap as V, TranslationsManager as W, buildTranslationsDbPath as X, buildTranslationsLocaleDocDbPath as Y, type CMSBuiltInSidebarTool as Z, type CMSUser as _, type LocaleTranslations as a, type CMSSidebarTool as a0, type CMSPluginOptions as a1, type CMSPlugin as a2, cmsPlugin as a3, type CMSCheck as a4, type CheckResult as a5, type CheckContext as a6, type CheckStatus as a7, translationsCheck as a8, type TranslationsCheckOptions as a9, type
|
|
1368
|
+
export { type CMSAIConfig as $, type Action as A, type BatchRequestOptions as B, type CronUnit as C, type DocMode as D, type TranslationsDoc as E, BatchRequest as F, type GetDocOptions as G, type HttpMethod as H, BatchResponse as I, type Locale as J, type SourceString as K, type LoadTranslationsOptions as L, type TranslatedString as M, type TranslationsDocMode as N, type TranslationsLocaleDocHashMap as O, type TranslationsLocaleDocEntry as P, type MultiLocaleTranslationsMap as Q, RootCMSClient as R, type SetDocOptions as S, type TranslationsMap as T, type UserRole as U, type SingleLocaleTranslationsMap as V, TranslationsManager as W, buildTranslationsDbPath as X, buildTranslationsLocaleDocDbPath as Y, type CMSBuiltInSidebarTool as Z, type CMSUser as _, type LocaleTranslations as a, type CMSSidebarTool as a0, type CMSPluginOptions as a1, type CMSPlugin as a2, cmsPlugin as a3, type CMSCheck as a4, type CheckResult as a5, type CheckContext as a6, type CheckStatus as a7, translationsCheck as a8, type TranslationsCheckOptions as a9, type CMSService as aa, type CMSServiceContext as ab, type CMSNotificationService as ac, type NotificationResult as ad, type NotificationServiceContext as ae, type CMSTranslationService as af, type TranslationExportResult as ag, type TranslationImportResult as ah, type TranslationRow as ai, type TranslationServiceContext as aj, type Doc as b, type DataSourceCron as c, type DataSource as d, type DataSourceData as e, type DataSourceMode as f, type SaveDraftOptions as g, type UpdateDraftOptions as h, type ListDocsOptions as i, type GetCountOptions as j, type Translation as k, type Release as l, type ListActionsOptions as m, isRichTextData as n, getCmsPlugin as o, marshalData as p, normalizeData as q, type ArrayObject as r, marshalArray as s, toArrayObject as t, unmarshalData as u, unmarshalArray as v, translationsForLocale as w, parseDocId as x, type BatchRequestQuery as y, type BatchRequestQueryOptions as z };
|
package/dist/client.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import '@blinkk/root';
|
|
2
2
|
import 'firebase-admin/app';
|
|
3
3
|
import 'firebase-admin/firestore';
|
|
4
|
-
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, D as DocMode, j as GetCountOptions, G as GetDocOptions, H as HttpMethod, m as ListActionsOptions, i as ListDocsOptions, L as LoadTranslationsOptions, a as LocaleTranslations, l as Release, R as RootCMSClient, g as SaveDraftOptions, S as SetDocOptions, k as Translation, E as TranslationsDoc, T as TranslationsMap, h as UpdateDraftOptions, U as UserRole, 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-
|
|
5
|
-
import './schema-
|
|
4
|
+
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, D as DocMode, j as GetCountOptions, G as GetDocOptions, H as HttpMethod, m as ListActionsOptions, i as ListDocsOptions, L as LoadTranslationsOptions, a as LocaleTranslations, l as Release, R as RootCMSClient, g as SaveDraftOptions, S as SetDocOptions, k as Translation, E as TranslationsDoc, T as TranslationsMap, h as UpdateDraftOptions, U as UserRole, 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-DdB4xpM6.js';
|
|
5
|
+
import './schema-rjBOZk-j.js';
|
package/dist/client.js
CHANGED
package/dist/core.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { R as RootCMSClient, D as DocMode, L as LoadTranslationsOptions, T as TranslationsMap, a as LocaleTranslations } from './client-
|
|
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-
|
|
1
|
+
import { R as RootCMSClient, D as DocMode, L as LoadTranslationsOptions, T as TranslationsMap, a as LocaleTranslations } from './client-DdB4xpM6.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-DdB4xpM6.js';
|
|
3
3
|
import { Request, RootConfig, Response, RouteParams, GetStaticProps, GetStaticPaths } from '@blinkk/root';
|
|
4
4
|
import { Query } from 'firebase-admin/firestore';
|
|
5
|
-
export { s as schema } from './schema-
|
|
5
|
+
export { s as schema } from './schema-rjBOZk-j.js';
|
|
6
6
|
import 'firebase-admin/app';
|
|
7
7
|
|
|
8
8
|
/**
|
package/dist/core.js
CHANGED
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
translationsForLocale,
|
|
17
17
|
unmarshalArray,
|
|
18
18
|
unmarshalData
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-SNZ4S4IC.js";
|
|
20
20
|
import {
|
|
21
21
|
__export
|
|
22
22
|
} from "./chunk-MLKGABMK.js";
|
|
@@ -480,6 +480,7 @@ __export(schema_exports, {
|
|
|
480
480
|
datetime: () => datetime,
|
|
481
481
|
define: () => define,
|
|
482
482
|
defineCollection: () => defineCollection,
|
|
483
|
+
definePreset: () => definePreset,
|
|
483
484
|
defineSchema: () => defineSchema,
|
|
484
485
|
file: () => file,
|
|
485
486
|
glob: () => glob,
|
|
@@ -488,6 +489,7 @@ __export(schema_exports, {
|
|
|
488
489
|
number: () => number,
|
|
489
490
|
object: () => object,
|
|
490
491
|
oneOf: () => oneOf,
|
|
492
|
+
preset: () => preset,
|
|
491
493
|
reference: () => reference,
|
|
492
494
|
references: () => references,
|
|
493
495
|
richtext: () => richtext,
|
|
@@ -560,6 +562,10 @@ function defineSchema(schema) {
|
|
|
560
562
|
return schema;
|
|
561
563
|
}
|
|
562
564
|
var define = defineSchema;
|
|
565
|
+
function definePreset(preset2) {
|
|
566
|
+
return preset2;
|
|
567
|
+
}
|
|
568
|
+
var preset = definePreset;
|
|
563
569
|
function defineCollection(collection2) {
|
|
564
570
|
return collection2;
|
|
565
571
|
}
|
package/dist/functions.js
CHANGED
package/dist/plugin.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import '@blinkk/root';
|
|
2
2
|
import 'firebase-admin/app';
|
|
3
3
|
import 'firebase-admin/firestore';
|
|
4
|
-
export { $ as CMSAIConfig, Z as CMSBuiltInSidebarTool, a4 as CMSCheck, a2 as CMSPlugin, a1 as CMSPluginOptions, a0 as CMSSidebarTool,
|
|
5
|
-
import './schema-
|
|
4
|
+
export { $ as CMSAIConfig, Z as CMSBuiltInSidebarTool, a4 as CMSCheck, ac as CMSNotificationService, a2 as CMSPlugin, a1 as CMSPluginOptions, aa as CMSService, ab as CMSServiceContext, a0 as CMSSidebarTool, af as CMSTranslationService, _ as CMSUser, a6 as CheckContext, a5 as CheckResult, a7 as CheckStatus, ad as NotificationResult, ae as NotificationServiceContext, ag as TranslationExportResult, ah as TranslationImportResult, ai as TranslationRow, aj as TranslationServiceContext, a9 as TranslationsCheckOptions, a3 as cmsPlugin, a8 as translationsCheck } from './client-DdB4xpM6.js';
|
|
5
|
+
import './schema-rjBOZk-j.js';
|
package/dist/plugin.js
CHANGED
|
@@ -4,15 +4,16 @@ import {
|
|
|
4
4
|
} from "./chunk-T5UK2H24.js";
|
|
5
5
|
import {
|
|
6
6
|
getServerVersion
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-BBOESYH7.js";
|
|
8
8
|
import {
|
|
9
|
+
SearchIndexService,
|
|
9
10
|
runCronJobs
|
|
10
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-UTSL2E2P.js";
|
|
11
12
|
import {
|
|
12
13
|
RootCMSClient,
|
|
13
14
|
parseDocId,
|
|
14
15
|
unmarshalData
|
|
15
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-SNZ4S4IC.js";
|
|
16
17
|
import "./chunk-MLKGABMK.js";
|
|
17
18
|
|
|
18
19
|
// core/plugin.ts
|
|
@@ -160,13 +161,96 @@ function api(server, options) {
|
|
|
160
161
|
});
|
|
161
162
|
server.use("/cms/api/cron.run", async (req, res) => {
|
|
162
163
|
try {
|
|
163
|
-
await runCronJobs(req.rootConfig
|
|
164
|
+
await runCronJobs(req.rootConfig, {
|
|
165
|
+
loadSchema: (collectionId) => getCollectionSchema(req, collectionId)
|
|
166
|
+
});
|
|
164
167
|
res.status(200).json({ success: true });
|
|
165
168
|
} catch (err) {
|
|
166
169
|
console.error(err);
|
|
167
170
|
res.status(500).json({ success: false });
|
|
168
171
|
}
|
|
169
172
|
});
|
|
173
|
+
const searchRebuildJobs = /* @__PURE__ */ new Map();
|
|
174
|
+
server.use("/cms/api/search.query", async (req, res) => {
|
|
175
|
+
if (req.method !== "POST" || !String(req.get("content-type")).startsWith("application/json")) {
|
|
176
|
+
res.status(400).json({ success: false, error: "BAD_REQUEST" });
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
if (!req.user?.email) {
|
|
180
|
+
res.status(401).json({ success: false, error: "UNAUTHORIZED" });
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
const body = req.body || {};
|
|
184
|
+
const q = typeof body.q === "string" ? body.q : "";
|
|
185
|
+
const limit = typeof body.limit === "number" ? body.limit : 25;
|
|
186
|
+
try {
|
|
187
|
+
const service = new SearchIndexService(req.rootConfig);
|
|
188
|
+
const result = await service.search(q, { limit });
|
|
189
|
+
res.setHeader("Cache-Control", "no-store");
|
|
190
|
+
res.status(200).json({ success: true, ...result });
|
|
191
|
+
} catch (err) {
|
|
192
|
+
console.error(err.stack || err);
|
|
193
|
+
res.status(500).json({ success: false, error: "UNKNOWN" });
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
server.use("/cms/api/search.status", async (req, res) => {
|
|
197
|
+
if (!req.user?.email) {
|
|
198
|
+
res.status(401).json({ success: false, error: "UNAUTHORIZED" });
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
try {
|
|
202
|
+
const cmsClient = new RootCMSClient(req.rootConfig);
|
|
203
|
+
const service = new SearchIndexService(req.rootConfig);
|
|
204
|
+
const status = await service.getStatus();
|
|
205
|
+
const running = searchRebuildJobs.has(cmsClient.projectId);
|
|
206
|
+
res.setHeader("Cache-Control", "no-store");
|
|
207
|
+
res.status(200).json({ success: true, status, running });
|
|
208
|
+
} catch (err) {
|
|
209
|
+
console.error(err.stack || err);
|
|
210
|
+
res.status(500).json({ success: false, error: "UNKNOWN" });
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
server.use("/cms/api/search.rebuild", async (req, res) => {
|
|
214
|
+
if (req.method !== "POST") {
|
|
215
|
+
res.status(400).json({ success: false, error: "BAD_REQUEST" });
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
if (!req.user?.email) {
|
|
219
|
+
res.status(401).json({ success: false, error: "UNAUTHORIZED" });
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
const cmsClient = new RootCMSClient(req.rootConfig);
|
|
223
|
+
try {
|
|
224
|
+
const role = await cmsClient.getUserRole(req.user.email);
|
|
225
|
+
if (role !== "ADMIN") {
|
|
226
|
+
res.status(403).json({ success: false, error: "FORBIDDEN" });
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
} catch (err) {
|
|
230
|
+
console.error(err.stack || err);
|
|
231
|
+
res.status(500).json({ success: false, error: "UNKNOWN" });
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
const body = req.body || {};
|
|
235
|
+
const force = !!body.force;
|
|
236
|
+
const projectId = cmsClient.projectId;
|
|
237
|
+
if (searchRebuildJobs.has(projectId)) {
|
|
238
|
+
res.status(202).json({ success: true, alreadyRunning: true });
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
const service = new SearchIndexService(
|
|
242
|
+
req.rootConfig,
|
|
243
|
+
(collectionId) => getCollectionSchema(req, collectionId)
|
|
244
|
+
);
|
|
245
|
+
const job = service.rebuildIndex({ force }).catch((err) => {
|
|
246
|
+
console.error("search.rebuild failed:", err.stack || err);
|
|
247
|
+
throw err;
|
|
248
|
+
}).finally(() => {
|
|
249
|
+
searchRebuildJobs.delete(projectId);
|
|
250
|
+
});
|
|
251
|
+
searchRebuildJobs.set(projectId, job);
|
|
252
|
+
res.status(202).json({ success: true, started: true, force });
|
|
253
|
+
});
|
|
170
254
|
server.use("/cms/api/csv.download", (req, res) => {
|
|
171
255
|
if (req.method !== "POST" || !String(req.get("content-type")).startsWith("application/json")) {
|
|
172
256
|
res.status(400).json({ success: false, error: "BAD_REQUEST" });
|
package/dist/project.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { S as Schema, C as Collection } from './schema-
|
|
1
|
+
import { S as Schema, C as Collection } from './schema-rjBOZk-j.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Loads various files or configurations from the project.
|
|
5
5
|
*
|
|
6
6
|
* NOTE: This file needs to be loaded through vite's ssrLoadModule so that
|
|
7
|
-
*
|
|
7
|
+
* virtual modules are resolved.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
interface SchemaModule {
|
package/dist/project.js
CHANGED
|
@@ -174,6 +174,13 @@ interface SchemaPattern {
|
|
|
174
174
|
}
|
|
175
175
|
type OneOfField = CommonFieldProps & {
|
|
176
176
|
type: 'oneof';
|
|
177
|
+
/**
|
|
178
|
+
* UI variant for the oneOf field.
|
|
179
|
+
* - `dropdown` (default): A `Select` dropdown for choosing the type.
|
|
180
|
+
* - `picker`: A `Button` that opens a modal with searchable cards. Use this
|
|
181
|
+
* variant when types declare presets or thumbnail images.
|
|
182
|
+
*/
|
|
183
|
+
variant?: 'dropdown' | 'picker';
|
|
177
184
|
/**
|
|
178
185
|
* Schema types to include in the oneOf field. Can be:
|
|
179
186
|
* - An array of Schema objects
|
|
@@ -226,6 +233,25 @@ type Field = StringField | NumberField | DateField | DateTimeField | BooleanFiel
|
|
|
226
233
|
*/
|
|
227
234
|
type FieldWithId = Field;
|
|
228
235
|
type ObjectLikeField = ImageField | FileField | ObjectField | OneOfField | ReferenceField;
|
|
236
|
+
interface SchemaPreset<T = Record<string, any>> {
|
|
237
|
+
/** Unique identifier for the preset within the schema. */
|
|
238
|
+
id: string;
|
|
239
|
+
/** Display title for the preset. Defaults to the preset id. */
|
|
240
|
+
label?: string;
|
|
241
|
+
/** Description shown below the title in the picker. */
|
|
242
|
+
description?: string;
|
|
243
|
+
/** Thumbnail image (URL or absolute /-path) for the picker. */
|
|
244
|
+
image?: string;
|
|
245
|
+
/**
|
|
246
|
+
* Field values to prefill. Deep-merged into the schema's default value
|
|
247
|
+
* (preset values override defaults). `_type` is set automatically. The
|
|
248
|
+
* preset id is NOT persisted — presets are purely a prefill mechanism.
|
|
249
|
+
*
|
|
250
|
+
* Pass a generated fields type as the generic parameter `T` to
|
|
251
|
+
* type-check the keys against the schema's fields.
|
|
252
|
+
*/
|
|
253
|
+
data?: T;
|
|
254
|
+
}
|
|
229
255
|
interface Schema {
|
|
230
256
|
/** The name of the content type. Used as the field key. */
|
|
231
257
|
name: string;
|
|
@@ -233,6 +259,19 @@ interface Schema {
|
|
|
233
259
|
label?: string;
|
|
234
260
|
/** The description of the content type. Appears in CMS menus. */
|
|
235
261
|
description?: string;
|
|
262
|
+
/**
|
|
263
|
+
* Optional thumbnail image (URL or absolute /-path) used to represent this
|
|
264
|
+
* schema in the picker UI for `oneof` fields with `variant: 'picker'`.
|
|
265
|
+
*/
|
|
266
|
+
image?: string;
|
|
267
|
+
/**
|
|
268
|
+
* Optional preset prefill configurations for use in the picker UI.
|
|
269
|
+
*
|
|
270
|
+
* Each preset appears in the picker as a separate selectable card alongside
|
|
271
|
+
* the schema's "blank" card. Selecting a preset sets `_type` to the schema's
|
|
272
|
+
* `name` and merges `data` over the schema's default field values.
|
|
273
|
+
*/
|
|
274
|
+
presets?: SchemaPreset<any>[];
|
|
236
275
|
/** Fields describe the structure of the content. */
|
|
237
276
|
fields: FieldWithId[];
|
|
238
277
|
/** Defines the preview displayed within the CMS UI. Overrides the `preview` definition for the `array` field. */
|
|
@@ -267,6 +306,24 @@ type SchemaWithTypes = Schema & {
|
|
|
267
306
|
declare function defineSchema(schema: Schema): Schema;
|
|
268
307
|
/** Defines the schema for a collection or reusable component. */
|
|
269
308
|
declare const define: typeof defineSchema;
|
|
309
|
+
/**
|
|
310
|
+
* Defines a preset for use within `schema.define({presets: [...]})`. The
|
|
311
|
+
* optional generic parameter `T` constrains the shape of the preset's `data`
|
|
312
|
+
* field. Pass an auto-generated fields type to enable type-safety:
|
|
313
|
+
*
|
|
314
|
+
* ```ts
|
|
315
|
+
* import type {HeroFields} from './generated/types.d.ts';
|
|
316
|
+
*
|
|
317
|
+
* schema.definePreset<HeroFields>({
|
|
318
|
+
* id: 'big',
|
|
319
|
+
* label: 'Big hero',
|
|
320
|
+
* data: {title: 'Welcome'},
|
|
321
|
+
* });
|
|
322
|
+
* ```
|
|
323
|
+
*/
|
|
324
|
+
declare function definePreset<T = Record<string, any>>(preset: SchemaPreset<T>): SchemaPreset<T>;
|
|
325
|
+
/** Alias for {@link definePreset}. */
|
|
326
|
+
declare const preset: typeof definePreset;
|
|
270
327
|
type Collection = SchemaWithTypes & {
|
|
271
328
|
/**
|
|
272
329
|
* The ID of the collection. This comes from the schema filename, e.g
|
|
@@ -410,6 +467,7 @@ type schema_ReferencesField = ReferencesField;
|
|
|
410
467
|
type schema_RichTextField = RichTextField;
|
|
411
468
|
type schema_Schema = Schema;
|
|
412
469
|
type schema_SchemaPattern = SchemaPattern;
|
|
470
|
+
type schema_SchemaPreset<T = Record<string, any>> = SchemaPreset<T>;
|
|
413
471
|
type schema_SchemaWithTypes = SchemaWithTypes;
|
|
414
472
|
type schema_SelectField = SelectField;
|
|
415
473
|
type schema_StringField = StringField;
|
|
@@ -420,6 +478,7 @@ declare const schema_date: typeof date;
|
|
|
420
478
|
declare const schema_datetime: typeof datetime;
|
|
421
479
|
declare const schema_define: typeof define;
|
|
422
480
|
declare const schema_defineCollection: typeof defineCollection;
|
|
481
|
+
declare const schema_definePreset: typeof definePreset;
|
|
423
482
|
declare const schema_defineSchema: typeof defineSchema;
|
|
424
483
|
declare const schema_file: typeof file;
|
|
425
484
|
declare const schema_glob: typeof glob;
|
|
@@ -428,13 +487,14 @@ declare const schema_multiselect: typeof multiselect;
|
|
|
428
487
|
declare const schema_number: typeof number;
|
|
429
488
|
declare const schema_object: typeof object;
|
|
430
489
|
declare const schema_oneOf: typeof oneOf;
|
|
490
|
+
declare const schema_preset: typeof preset;
|
|
431
491
|
declare const schema_reference: typeof reference;
|
|
432
492
|
declare const schema_references: typeof references;
|
|
433
493
|
declare const schema_richtext: typeof richtext;
|
|
434
494
|
declare const schema_select: typeof select;
|
|
435
495
|
declare const schema_string: typeof string;
|
|
436
496
|
declare namespace schema {
|
|
437
|
-
export { type schema_ArrayField as ArrayField, type schema_BooleanField as BooleanField, type schema_Collection as Collection, type schema_CommonFieldProps as CommonFieldProps, type schema_DateField as DateField, type schema_DateTimeField as DateTimeField, type schema_Field as Field, type schema_FieldWithId as FieldWithId, type schema_FileField as FileField, type schema_GlobOptions as GlobOptions, type schema_ImageField as ImageField, type schema_MultiSelectField as MultiSelectField, type schema_NumberField as NumberField, type schema_ObjectField as ObjectField, type schema_ObjectLikeField as ObjectLikeField, type schema_OneOfField as OneOfField, type schema_ReferenceField as ReferenceField, type schema_ReferencesField as ReferencesField, type schema_RichTextField as RichTextField, type schema_Schema as Schema, type schema_SchemaPattern as SchemaPattern, type schema_SchemaWithTypes as SchemaWithTypes, type schema_SelectField as SelectField, type schema_StringField as StringField, schema_array as array, schema_boolean as boolean, schema_collection as collection, schema_date as date, schema_datetime as datetime, schema_define as define, schema_defineCollection as defineCollection, schema_defineSchema as defineSchema, schema_file as file, schema_glob as glob, schema_image as image, schema_multiselect as multiselect, schema_number as number, schema_object as object, schema_oneOf as oneOf, schema_reference as reference, schema_references as references, schema_richtext as richtext, schema_select as select, schema_string as string };
|
|
497
|
+
export { type schema_ArrayField as ArrayField, type schema_BooleanField as BooleanField, type schema_Collection as Collection, type schema_CommonFieldProps as CommonFieldProps, type schema_DateField as DateField, type schema_DateTimeField as DateTimeField, type schema_Field as Field, type schema_FieldWithId as FieldWithId, type schema_FileField as FileField, type schema_GlobOptions as GlobOptions, type schema_ImageField as ImageField, type schema_MultiSelectField as MultiSelectField, type schema_NumberField as NumberField, type schema_ObjectField as ObjectField, type schema_ObjectLikeField as ObjectLikeField, type schema_OneOfField as OneOfField, type schema_ReferenceField as ReferenceField, type schema_ReferencesField as ReferencesField, type schema_RichTextField as RichTextField, type schema_Schema as Schema, type schema_SchemaPattern as SchemaPattern, type schema_SchemaPreset as SchemaPreset, type schema_SchemaWithTypes as SchemaWithTypes, type schema_SelectField as SelectField, type schema_StringField as StringField, schema_array as array, schema_boolean as boolean, schema_collection as collection, schema_date as date, schema_datetime as datetime, schema_define as define, schema_defineCollection as defineCollection, schema_definePreset as definePreset, schema_defineSchema as defineSchema, schema_file as file, schema_glob as glob, schema_image as image, schema_multiselect as multiselect, schema_number as number, schema_object as object, schema_oneOf as oneOf, schema_preset as preset, schema_reference as reference, schema_references as references, schema_richtext as richtext, schema_select as select, schema_string as string };
|
|
438
498
|
}
|
|
439
499
|
|
|
440
500
|
export { type Collection as C, type Schema as S, schema as s };
|