@blinkk/root-cms 1.4.3 → 1.4.5

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 CHANGED
@@ -7,7 +7,7 @@ import { render as renderToString } from "preact-render-to-string";
7
7
  // package.json
8
8
  var package_default = {
9
9
  name: "@blinkk/root-cms",
10
- version: "1.4.3",
10
+ version: "1.4.5",
11
11
  author: "s@blinkk.com",
12
12
  license: "MIT",
13
13
  engines: {
@@ -79,6 +79,7 @@ var package_default = {
79
79
  "csv-parse": "5.5.2",
80
80
  "csv-stringify": "6.4.4",
81
81
  "dts-dom": "3.7.0",
82
+ "fnv-plus": "1.3.1",
82
83
  jsonwebtoken: "9.0.2",
83
84
  kleur: "4.1.5",
84
85
  sirv: "2.0.3",
@@ -108,6 +109,7 @@ var package_default = {
108
109
  "@preact/compat": "17.1.2",
109
110
  "@tabler/icons-preact": "2.47.0",
110
111
  "@types/body-parser": "1.19.3",
112
+ "@types/fnv-plus": "1.3.2",
111
113
  "@types/gapi": "0.0.47",
112
114
  "@types/gapi.client.drive-v3": "0.0.4",
113
115
  "@types/gapi.client.sheets-v4": "0.0.4",
@@ -138,7 +140,7 @@ var package_default = {
138
140
  vitest: "0.34.6"
139
141
  },
140
142
  peerDependencies: {
141
- "@blinkk/root": "1.4.3",
143
+ "@blinkk/root": "1.4.5",
142
144
  "firebase-admin": ">=11",
143
145
  "firebase-functions": ">=4",
144
146
  preact: ">=10",
@@ -300,7 +302,10 @@ function serializeCollection(collection) {
300
302
  domain: collection.domain,
301
303
  url: collection.url,
302
304
  previewUrl: collection.previewUrl,
303
- preview: collection.preview
305
+ preview: collection.preview,
306
+ slugRegex: collection.slugRegex,
307
+ autolock: collection.autolock,
308
+ autolockReason: collection.autolockReason
304
309
  };
305
310
  }
306
311
  function SignIn(props) {
package/dist/cli.js CHANGED
@@ -294,10 +294,25 @@ import { loadRootConfig as loadRootConfig2 } from "@blinkk/root/node";
294
294
 
295
295
  // core/client.ts
296
296
  import crypto from "node:crypto";
297
+ import {
298
+ FieldValue as FieldValue2,
299
+ Timestamp as Timestamp2
300
+ } from "firebase-admin/firestore";
301
+
302
+ // core/translations-manager.ts
297
303
  import {
298
304
  FieldValue,
299
305
  Timestamp
300
306
  } from "firebase-admin/firestore";
307
+
308
+ // shared/strings.ts
309
+ import fnv from "fnv-plus";
310
+
311
+ // core/translations-manager.ts
312
+ var TRANSLATIONS_DB_PATH_FORMAT = "/Projects/{project}/TranslationsManager/{mode}/Translations";
313
+ var TRANSLATIONS_LOCALE_DOC_DB_PATH_FORMAT = `${TRANSLATIONS_DB_PATH_FORMAT}/{id}:{locale}`;
314
+
315
+ // core/client.ts
301
316
  function getCmsPlugin(rootConfig) {
302
317
  const plugins = rootConfig.plugins || [];
303
318
  const plugin = plugins.find((plugin2) => plugin2.name === "root-cms");
@@ -1,6 +1,6 @@
1
1
  import { Request, Plugin, RootConfig } from '@blinkk/root';
2
2
  import { App } from 'firebase-admin/app';
3
- import { Firestore, Timestamp, Query, WriteBatch } from 'firebase-admin/firestore';
3
+ import { Firestore, WriteBatch, Timestamp, Query } from 'firebase-admin/firestore';
4
4
 
5
5
  interface CMSUser {
6
6
  email: string;
@@ -108,7 +108,14 @@ type CMSPluginOptions = {
108
108
  * Experimental config options. Note: these are subject to change at any time.
109
109
  */
110
110
  experiments?: {
111
+ /**
112
+ * Enables the Root CMS AI page.
113
+ */
111
114
  ai?: boolean | CMSAIConfig;
115
+ /**
116
+ * Enables the v2 `TranslationsManager`.
117
+ */
118
+ v2TranslationsManager?: boolean;
112
119
  };
113
120
  /**
114
121
  * Adjust console output verbosity. Default is `'info'`.
@@ -128,6 +135,191 @@ type CMSPlugin = Plugin & {
128
135
  };
129
136
  declare function cmsPlugin(options: CMSPluginOptions): CMSPlugin;
130
137
 
138
+ type Locale = string;
139
+ type SourceString = string;
140
+ type TranslatedString = string;
141
+ type TranslationsDocMode = 'draft' | 'published';
142
+ interface TranslationsLocaleDocHashMap {
143
+ /**
144
+ * A hash map of a source string's hash fingerprint to the source string and
145
+ * translated string.
146
+ */
147
+ [hash: string]: TranslationsLocaleDocEntry;
148
+ }
149
+ interface TranslationsLocaleDocEntry {
150
+ source: SourceString;
151
+ translation: TranslatedString;
152
+ }
153
+ interface TranslationsDbPathOptions {
154
+ project: string;
155
+ mode: TranslationsDocMode;
156
+ }
157
+ type TranslationsLocaleDocDbPathOptions = TranslationsDbPathOptions & {
158
+ id: string;
159
+ locale: string;
160
+ };
161
+ /**
162
+ * A translations map containing translations for multiple locales.
163
+ *
164
+ * Example:
165
+ * ```
166
+ * {
167
+ * "one": {"es": "uno", "fr": "un"},
168
+ * "two": {"es": "dos", "fr": "deux"}
169
+ * }
170
+ * ```
171
+ */
172
+ interface MultiLocaleTranslationsMap {
173
+ [source: SourceString]: {
174
+ [locale: Locale]: TranslatedString;
175
+ };
176
+ }
177
+ /**
178
+ * A translations map containing translations for a single locale.
179
+ *
180
+ * Example:
181
+ * ```
182
+ * {
183
+ * "one": "uno",
184
+ * "two": "dos"
185
+ * }
186
+ * ```
187
+ */
188
+ interface SingleLocaleTranslationsMap {
189
+ [source: SourceString]: TranslatedString;
190
+ }
191
+ declare class TranslationsManager {
192
+ cmsClient: RootCMSClient;
193
+ constructor(cmsClient: RootCMSClient);
194
+ /**
195
+ * Saves draft translations for a translations doc id.
196
+ *
197
+ * Example:
198
+ * ```
199
+ * const strings = {
200
+ * 'one': {es: 'uno', fr: 'un'},
201
+ * 'two': {es: 'dos', fr: 'deux'},
202
+ * };
203
+ * await tm.saveTranslations('Pages/index', strings);
204
+ * ```
205
+ */
206
+ saveTranslations(id: string, strings: MultiLocaleTranslationsMap, options?: {
207
+ tags?: string[];
208
+ modifiedBy?: string;
209
+ }): Promise<void>;
210
+ /**
211
+ * Publishes a translations doc.
212
+ */
213
+ publishTranslations(id: string, options?: {
214
+ batch?: WriteBatch;
215
+ publishedBy?: string;
216
+ }): Promise<void>;
217
+ /**
218
+ * Fetches translations from one or more translations docs in the translations
219
+ * manager.
220
+ *
221
+ * Example:
222
+ * ```
223
+ * await tm.loadTranslations();
224
+ * // =>
225
+ * // {
226
+ * // "one": {"es": "uno", "fr": "un"},
227
+ * // "two": {"es": "dos", "fr": "deux"}
228
+ * // }
229
+ * ```
230
+ *
231
+ * To load a specific set of translations docs by id:
232
+ * ```
233
+ * const translationsToLoad = ['Global/strings', 'Global/header', 'Global/footer', 'Pages/index'];
234
+ * await tm.loadTranslations({ids: translationsToLoad});
235
+ * // =>
236
+ * // {
237
+ * // "one": {"es": "uno", "fr": "un"},
238
+ * // "two": {"es": "dos", "fr": "deux"}
239
+ * // }
240
+ * ```
241
+ *
242
+ * To load a subset of locales (more performant):
243
+ * ```
244
+ * await tm.loadTranslations({locales: ['es']});
245
+ * // =>
246
+ * // {
247
+ * // "one": {"es": "uno"},
248
+ * // "two": {"es": "dos"}
249
+ * // }
250
+ * ```
251
+ */
252
+ loadTranslations(options?: {
253
+ ids?: string[];
254
+ tags?: string[];
255
+ locales?: Locale[];
256
+ mode?: TranslationsDocMode;
257
+ }): Promise<MultiLocaleTranslationsMap>;
258
+ /**
259
+ * Fetches translations for a given locale, with optional fallbacks.
260
+ * The return value is a map of source string to translated string.
261
+ *
262
+ * Example:
263
+ * ```
264
+ * await translationsDoc.loadTranslationsForLocale('es');
265
+ * // =>
266
+ * // {
267
+ * // "one": "uno",
268
+ * // "two": "dos",
269
+ * // }
270
+ * ```
271
+ */
272
+ loadTranslationsForLocale(locale: Locale, options?: {
273
+ mode?: TranslationsDocMode;
274
+ fallbackLocales?: Locale[];
275
+ }): Promise<SingleLocaleTranslationsMap>;
276
+ /**
277
+ * Converts a multi-locale translations map to a flat single-locale map,
278
+ * with optional support for fallback locales.
279
+ *
280
+ * ```
281
+ * const multiLocaleStrings = {
282
+ * 'one': {es: 'uno', fr: 'un'},
283
+ * 'two': {es: 'dos', fr: 'deux'}
284
+ * };
285
+ * translationsDoc.toSingleLocaleMap(multiLocaleStrings, ['es']);
286
+ * // =>
287
+ * // {
288
+ * // "one": "uno",
289
+ * // "two": "dos",
290
+ * // }
291
+ * ```
292
+ */
293
+ private toSingleLocaleMap;
294
+ /**
295
+ * Converts a multi-locale translations map to a single-locale hashed version,
296
+ * used for storage in in the DB.
297
+ *
298
+ * ```
299
+ * const multiLocaleStrings = {
300
+ * 'one': {es: 'uno', fr: 'un'},
301
+ * 'two': {es: 'dos', fr: 'deux'}
302
+ * };
303
+ * translationsDoc.toLocaleDocHashMap(multiLocaleStrings, 'es');
304
+ * // =>
305
+ * // {
306
+ * // "<hash1>": {"source": "one", "translation": "uno"},
307
+ * // "<hash2>": {"source": "two", "translation": "dos"},
308
+ * // }
309
+ * ```
310
+ *
311
+ * One reason for using hashes is because the DB has limits on the number of
312
+ * chars that can be used as the "key" in a object map.
313
+ */
314
+ private toLocaleDocHashMap;
315
+ /**
316
+ * Import translations from the v1 system to the TranslationsManager.
317
+ */
318
+ importTranslationsFromV1(): Promise<void>;
319
+ }
320
+ declare function buildTranslationsDbPath(options: TranslationsDbPathOptions): string;
321
+ declare function buildTranslationsLocaleDocDbPath(options: TranslationsLocaleDocDbPathOptions): string;
322
+
131
323
  interface Doc<Fields = any> {
132
324
  /** The id of the doc, e.g. "Pages/foo-bar". */
133
325
  id: string;
@@ -335,6 +527,21 @@ declare class RootCMSClient {
335
527
  * Checks if a doc is currently "locked" for publishing.
336
528
  */
337
529
  testPublishingLocked(doc: Doc): boolean;
530
+ /**
531
+ * Returns a `TranslationsManager` object for managing translations.
532
+ *
533
+ * To get translations:
534
+ * ```
535
+ * await tm.loadTranslations({
536
+ * ids: ['Global/strings', 'Pages/index'],
537
+ * locales: ['es'],
538
+ * });
539
+ * ```
540
+ *
541
+ * NOTE: The `TranslationsManager` is a v2 feature that will eventually
542
+ * replace the v1 translations system.
543
+ */
544
+ getTranslationsManager(): TranslationsManager;
338
545
  /**
339
546
  * Loads translations saved in the translations collection, optionally
340
547
  * filtered by tag.
@@ -485,4 +692,4 @@ declare function parseDocId(docId: string): {
485
692
  slug: string;
486
693
  };
487
694
 
488
- export { type Action as A, cmsPlugin as B, type CMSUser as C, type Doc as D, type GetDocOptions as G, type HttpMethod as H, type LoadTranslationsOptions as L, type Release as R, type SetDocOptions as S, type TranslationsMap as T, type UserRole as U, type LocaleTranslations as a, type DocMode as b, type DataSource as c, type DataSourceData as d, type DataSourceMode as e, type SaveDraftOptions as f, type ListDocsOptions as g, type GetCountOptions as h, type Translation as i, type ListActionsOptions as j, RootCMSClient as k, isRichTextData as l, getCmsPlugin as m, marshalData as n, normalizeData as o, type ArrayObject as p, marshalArray as q, unmarshalArray as r, translationsForLocale as s, toArrayObject as t, unmarshalData as u, parseDocId as v, type CMSAIConfig as w, type CMSSidebarTool as x, type CMSPluginOptions as y, type CMSPlugin as z };
695
+ export { type Action as A, type TranslationsLocaleDocHashMap as B, type TranslationsLocaleDocEntry as C, type Doc as D, type SingleLocaleTranslationsMap as E, TranslationsManager as F, type GetDocOptions as G, type HttpMethod as H, buildTranslationsDbPath as I, buildTranslationsLocaleDocDbPath as J, type CMSUser as K, type LoadTranslationsOptions as L, type MultiLocaleTranslationsMap as M, type CMSAIConfig as N, type CMSSidebarTool as O, type CMSPluginOptions as P, type CMSPlugin as Q, type Release as R, type SetDocOptions as S, type TranslationsMap as T, type UserRole as U, cmsPlugin as V, type LocaleTranslations as a, type DocMode as b, type DataSource as c, type DataSourceData as d, type DataSourceMode as e, type SaveDraftOptions as f, type ListDocsOptions as g, type GetCountOptions as h, type Translation as i, type ListActionsOptions as j, RootCMSClient as k, isRichTextData as l, getCmsPlugin as m, marshalData as n, normalizeData as o, type ArrayObject as p, marshalArray as q, unmarshalArray as r, translationsForLocale as s, toArrayObject as t, unmarshalData as u, parseDocId as v, type Locale as w, type SourceString as x, type TranslatedString as y, type TranslationsDocMode as z };
package/dist/client.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  import '@blinkk/root';
2
2
  import 'firebase-admin/app';
3
3
  import 'firebase-admin/firestore';
4
- export { A as Action, p as ArrayObject, c as DataSource, d as DataSourceData, e as DataSourceMode, D as Doc, b as DocMode, h as GetCountOptions, G as GetDocOptions, H as HttpMethod, j as ListActionsOptions, g as ListDocsOptions, L as LoadTranslationsOptions, a as LocaleTranslations, R as Release, k as RootCMSClient, f as SaveDraftOptions, S as SetDocOptions, i as Translation, T as TranslationsMap, U as UserRole, m as getCmsPlugin, l as isRichTextData, q as marshalArray, n as marshalData, o as normalizeData, v as parseDocId, t as toArrayObject, s as translationsForLocale, r as unmarshalArray, u as unmarshalData } from './client-98Le1XxF.js';
4
+ export { A as Action, p as ArrayObject, c as DataSource, d as DataSourceData, e as DataSourceMode, D as Doc, b as DocMode, h as GetCountOptions, G as GetDocOptions, H as HttpMethod, j as ListActionsOptions, g as ListDocsOptions, L as LoadTranslationsOptions, a as LocaleTranslations, R as Release, k as RootCMSClient, f as SaveDraftOptions, S as SetDocOptions, i as Translation, T as TranslationsMap, U as UserRole, m as getCmsPlugin, l as isRichTextData, q as marshalArray, n as marshalData, o as normalizeData, v as parseDocId, t as toArrayObject, s as translationsForLocale, r as unmarshalArray, u as unmarshalData } from './client-c_QAurxr.js';