@blinkk/root-cms 1.4.6 → 1.4.8

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.6",
10
+ version: "1.4.8",
11
11
  author: "s@blinkk.com",
12
12
  license: "MIT",
13
13
  engines: {
@@ -140,7 +140,7 @@ var package_default = {
140
140
  vitest: "0.34.6"
141
141
  },
142
142
  peerDependencies: {
143
- "@blinkk/root": "1.4.6",
143
+ "@blinkk/root": "1.4.8",
144
144
  "firebase-admin": ">=11",
145
145
  "firebase-functions": ">=4",
146
146
  preact: ">=10",
@@ -377,6 +377,8 @@ interface DataSource {
377
377
  interface DataSourceData<T = any> {
378
378
  dataSource: DataSource;
379
379
  data: T;
380
+ /** Optional list of column headers (for gsheet sources). */
381
+ headers?: string[];
380
382
  }
381
383
  type DataSourceMode = 'draft' | 'published';
382
384
  interface GetDocOptions {
@@ -486,6 +488,24 @@ declare class RootCMSClient {
486
488
  * what you are doing.
487
489
  */
488
490
  getRawDoc(collectionId: string, slug: string, options: GetDocOptions): Promise<any | null>;
491
+ /**
492
+ * Firestore path for a collection.
493
+ */
494
+ dbCollectionDocsPath(collectionId: string, options: {
495
+ mode: 'draft' | 'published';
496
+ }): string;
497
+ /**
498
+ * Firestore path for a content doc.
499
+ */
500
+ dbDocPath(collectionId: string, slug: string, options: {
501
+ mode: 'draft' | 'published';
502
+ }): string;
503
+ /**
504
+ * Firestore doc ref for a content doc.
505
+ */
506
+ dbDocRef(collectionId: string, slug: string, options: {
507
+ mode: 'draft' | 'published';
508
+ }): FirebaseFirestore.DocumentReference<FirebaseFirestore.DocumentData>;
489
509
  /**
490
510
  * Saves draft data to a doc.
491
511
  *
@@ -589,6 +609,18 @@ declare class RootCMSClient {
589
609
  * ```
590
610
  */
591
611
  loadTranslationsForLocale(locale: string, options?: LoadTranslationsOptions): Promise<LocaleTranslations>;
612
+ /**
613
+ * Firestore path for a translations file.
614
+ */
615
+ dbTranslationsPath(translationsId: string, options: {
616
+ mode: 'draft' | 'published';
617
+ }): string;
618
+ /**
619
+ * Firestore doc ref for a translations file.
620
+ */
621
+ dbTranslationsRef(translationsId: string, options: {
622
+ mode: 'draft' | 'published';
623
+ }): FirebaseFirestore.DocumentReference<FirebaseFirestore.DocumentData>;
592
624
  /**
593
625
  * Returns a data source configuration object.
594
626
  */
@@ -610,6 +642,18 @@ declare class RootCMSClient {
610
642
  getFromDataSource<T = any>(dataSourceId: string, options?: {
611
643
  mode?: 'draft' | 'published';
612
644
  }): Promise<DataSourceData<T> | null>;
645
+ /**
646
+ * Firestore path for a datasource data.
647
+ */
648
+ dbDataSourceDataPath(dataSourceId: string, options: {
649
+ mode: 'draft' | 'published';
650
+ }): string;
651
+ /**
652
+ * Firestore doc ref for a datasource data.
653
+ */
654
+ dbDataSourceDataRef(dataSourceId: string, options: {
655
+ mode: 'draft' | 'published';
656
+ }): FirebaseFirestore.DocumentReference<FirebaseFirestore.DocumentData>;
613
657
  /**
614
658
  * Gets the user's role from the project's ACL.
615
659
  */
@@ -622,6 +666,11 @@ declare class RootCMSClient {
622
666
  by?: string;
623
667
  metadata?: any;
624
668
  }): Promise<void>;
669
+ /**
670
+ * Creates a batch request that is capable of fetching one or more docs,
671
+ * corresponding translations, and dataSources.
672
+ */
673
+ createBatchRequest(options: BatchRequestOptions): BatchRequest;
625
674
  }
626
675
  /**
627
676
  * Returns true if the `data` is a rich text data object.
@@ -691,5 +740,102 @@ declare function parseDocId(docId: string): {
691
740
  collection: string;
692
741
  slug: string;
693
742
  };
743
+ interface BatchRequestOptions {
744
+ mode: 'draft' | 'published';
745
+ /**
746
+ * Whether to automatically fetch translations for the docs retrieved in the
747
+ * request.
748
+ */
749
+ translate?: boolean;
750
+ }
751
+ interface BatchRequestQuery {
752
+ queryId: string;
753
+ collectionId: string;
754
+ queryOptions?: BatchRequestQueryOptions;
755
+ }
756
+ interface BatchRequestQueryOptions {
757
+ offset?: number;
758
+ limit?: number;
759
+ orderBy?: string;
760
+ orderByDirection?: 'asc' | 'desc';
761
+ query?: (query: Query) => Query;
762
+ }
763
+ interface TranslationsDoc {
764
+ id: string;
765
+ sys: {
766
+ modifiedAt: Timestamp;
767
+ modifiedBy: string;
768
+ publishedAt?: Timestamp;
769
+ publishedBy?: string;
770
+ linkedSheet?: {
771
+ spreadsheetId: string;
772
+ gid: number;
773
+ linkedAt: Timestamp;
774
+ linkedBy: string;
775
+ };
776
+ tags?: string[];
777
+ };
778
+ strings: TranslationsMap;
779
+ }
780
+ declare class BatchRequest {
781
+ cmsClient: RootCMSClient;
782
+ private options;
783
+ private db;
784
+ private docIds;
785
+ private dataSourceIds;
786
+ private queries;
787
+ private translationsIds;
788
+ constructor(cmsClient: RootCMSClient, options: BatchRequestOptions);
789
+ /**
790
+ * Adds a doc to the batch request.
791
+ */
792
+ addDoc(docId: string): void;
793
+ /**
794
+ * Adds a data source to the batch request.
795
+ */
796
+ addDataSource(dataSourceId: string): void;
797
+ /**
798
+ * Adds a collection-based query to the batch request.
799
+ */
800
+ addQuery(queryId: string, collectionId: string, queryOptions?: BatchRequestQueryOptions): void;
801
+ /**
802
+ * Adds a translation file to the request.
803
+ */
804
+ addTranslations(translationsId: string): void;
805
+ /**
806
+ * Fetches data from the DB.
807
+ */
808
+ fetch(): Promise<BatchResponse>;
809
+ private fetchDocs;
810
+ private fetchQueries;
811
+ private fetchDataSources;
812
+ private fetchTranslations;
813
+ }
814
+ declare class BatchResponse {
815
+ docs: Record<string, Doc>;
816
+ queries: Record<string, Doc[]>;
817
+ dataSources: Record<string, DataSourceData>;
818
+ translations: Record<string, TranslationsDoc>;
819
+ /**
820
+ * Returns a map of translations for a given locale or locale fallbacks.
821
+ *
822
+ * The input is either a single locale (e.g. "de") or an array of locales
823
+ * representing the fallback tree, e.g. ["en-CA", "en-GB", "en"].
824
+ *
825
+ * TODO(stevenle): support the locale fallback tree.
826
+ *
827
+ * The returned value is a flat map of source string to translated string,
828
+ * e.g.:
829
+ * {"<source>": "<translation>"}
830
+ */
831
+ getTranslations(locale: string): LocaleTranslations;
832
+ /**
833
+ * Merges the strings from all translations files retrieved in the request.
834
+ * The returned value is a map of string to translations, e.g.:
835
+ *
836
+ * {"<hash>": {"source": "<source>", "<locale>": "<translation>"}}
837
+ */
838
+ private getTranslationsMap;
839
+ }
694
840
 
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 };
841
+ export { cmsPlugin as $, type Action as A, type BatchRequestOptions as B, BatchResponse as C, type Doc as D, type Locale as E, type SourceString as F, type GetDocOptions as G, type HttpMethod as H, type TranslatedString as I, type TranslationsDocMode as J, type TranslationsLocaleDocHashMap as K, type LoadTranslationsOptions as L, type TranslationsLocaleDocEntry as M, type MultiLocaleTranslationsMap as N, type SingleLocaleTranslationsMap as O, TranslationsManager as P, buildTranslationsDbPath as Q, type Release as R, type SetDocOptions as S, type TranslationsMap as T, type UserRole as U, buildTranslationsLocaleDocDbPath as V, type CMSUser as W, type CMSAIConfig as X, type CMSSidebarTool as Y, type CMSPluginOptions as Z, type CMSPlugin as _, 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 BatchRequestQuery as w, type BatchRequestQueryOptions as x, type TranslationsDoc as y, BatchRequest 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-c_QAurxr.js';
4
+ export { A as Action, p as ArrayObject, z as BatchRequest, B as BatchRequestOptions, w as BatchRequestQuery, x as BatchRequestQueryOptions, C as BatchResponse, 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, y as TranslationsDoc, 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-AE0BYn69.js';
package/dist/client.js CHANGED
@@ -390,6 +390,35 @@ var RootCMSClient = class {
390
390
  }
391
391
  return null;
392
392
  }
393
+ /**
394
+ * Firestore path for a collection.
395
+ */
396
+ dbCollectionDocsPath(collectionId, options) {
397
+ let modeCollection = "";
398
+ if (options.mode === "draft") {
399
+ modeCollection = "Drafts";
400
+ } else if (options.mode === "published") {
401
+ modeCollection = "Published";
402
+ } else {
403
+ throw new Error(`unknown mode: ${options.mode}`);
404
+ }
405
+ return `Projects/${this.projectId}/Collections/${collectionId}/${modeCollection}`;
406
+ }
407
+ /**
408
+ * Firestore path for a content doc.
409
+ */
410
+ dbDocPath(collectionId, slug, options) {
411
+ const collectionDocsPath = this.dbCollectionDocsPath(collectionId, options);
412
+ const normalizedSlug = slug.replaceAll("/", "--");
413
+ return `${collectionDocsPath}/${normalizedSlug}`;
414
+ }
415
+ /**
416
+ * Firestore doc ref for a content doc.
417
+ */
418
+ dbDocRef(collectionId, slug, options) {
419
+ const docPath = this.dbDocPath(collectionId, slug, options);
420
+ return this.db.doc(docPath);
421
+ }
393
422
  /**
394
423
  * Saves draft data to a doc.
395
424
  *
@@ -790,6 +819,25 @@ var RootCMSClient = class {
790
819
  const translationsMap = await this.loadTranslations(options);
791
820
  return translationsForLocale(translationsMap, locale);
792
821
  }
822
+ /**
823
+ * Firestore path for a translations file.
824
+ */
825
+ dbTranslationsPath(translationsId, options) {
826
+ const mode = options.mode;
827
+ if (!(mode === "draft" || mode === "published")) {
828
+ throw new Error(`invalid mode: ${mode}`);
829
+ }
830
+ const slug = translationsId.replaceAll("/", "--");
831
+ const dbPath = `Projects/${this.projectId}/TranslationsManager/${mode}/Translations/${slug}`;
832
+ return dbPath;
833
+ }
834
+ /**
835
+ * Firestore doc ref for a translations file.
836
+ */
837
+ dbTranslationsRef(translationsId, options) {
838
+ const dbPath = this.dbTranslationsPath(translationsId, options);
839
+ return this.db.doc(dbPath);
840
+ }
793
841
  /**
794
842
  * Returns a data source configuration object.
795
843
  */
@@ -860,7 +908,8 @@ var RootCMSClient = class {
860
908
  const batch = this.db.batch();
861
909
  batch.set(dataDocRefPublished, {
862
910
  dataSource: updatedDataSource,
863
- data: (dataRes == null ? void 0 : dataRes.data) || null
911
+ data: (dataRes == null ? void 0 : dataRes.data) || null,
912
+ ...(dataRes == null ? void 0 : dataRes.headers) ? { headers: dataRes.headers } : {}
864
913
  });
865
914
  batch.update(dataDocRefDraft, {
866
915
  dataSource: updatedDataSource
@@ -911,14 +960,34 @@ var RootCMSClient = class {
911
960
  if (!dataSourceId || dataSourceId.includes("/")) {
912
961
  throw new Error(`invalid data source id: ${dataSourceId}`);
913
962
  }
914
- const dbPath = `Projects/${this.projectId}/DataSources/${dataSourceId}/Data/${mode}`;
915
- const docRef = this.db.doc(dbPath);
963
+ const docRef = this.dbDataSourceDataRef(dataSourceId, { mode });
916
964
  const doc = await docRef.get();
917
965
  if (doc.exists) {
918
966
  return doc.data();
919
967
  }
920
968
  return null;
921
969
  }
970
+ /**
971
+ * Firestore path for a datasource data.
972
+ */
973
+ dbDataSourceDataPath(dataSourceId, options) {
974
+ if (!dataSourceId || dataSourceId.includes("/")) {
975
+ throw new Error(`invalid data source id: ${dataSourceId}`);
976
+ }
977
+ const mode = options.mode;
978
+ if (!(mode === "draft" || mode === "published")) {
979
+ throw new Error(`invalid mode: ${mode}`);
980
+ }
981
+ const dbPath = `Projects/${this.projectId}/DataSources/${dataSourceId}/Data/${mode}`;
982
+ return dbPath;
983
+ }
984
+ /**
985
+ * Firestore doc ref for a datasource data.
986
+ */
987
+ dbDataSourceDataRef(dataSourceId, options) {
988
+ const dbPath = this.dbDataSourceDataPath(dataSourceId, options);
989
+ return this.db.doc(dbPath);
990
+ }
922
991
  /**
923
992
  * Gets the user's role from the project's ACL.
924
993
  */
@@ -990,6 +1059,13 @@ var RootCMSClient = class {
990
1059
  }
991
1060
  }
992
1061
  }
1062
+ /**
1063
+ * Creates a batch request that is capable of fetching one or more docs,
1064
+ * corresponding translations, and dataSources.
1065
+ */
1066
+ createBatchRequest(options) {
1067
+ return new BatchRequest(this, options);
1068
+ }
993
1069
  };
994
1070
  function isRichTextData(data) {
995
1071
  return Boolean(
@@ -1135,7 +1211,213 @@ function parseDocId(docId) {
1135
1211
  }
1136
1212
  return { collection, slug };
1137
1213
  }
1214
+ var BatchRequest = class {
1215
+ constructor(cmsClient, options) {
1216
+ this.docIds = [];
1217
+ this.dataSourceIds = [];
1218
+ this.queries = [];
1219
+ this.translationsIds = [];
1220
+ this.cmsClient = cmsClient;
1221
+ this.db = cmsClient.db;
1222
+ this.options = options;
1223
+ }
1224
+ /**
1225
+ * Adds a doc to the batch request.
1226
+ */
1227
+ addDoc(docId) {
1228
+ this.docIds.push(docId);
1229
+ }
1230
+ /**
1231
+ * Adds a data source to the batch request.
1232
+ */
1233
+ addDataSource(dataSourceId) {
1234
+ this.dataSourceIds.push(dataSourceId);
1235
+ }
1236
+ /**
1237
+ * Adds a collection-based query to the batch request.
1238
+ */
1239
+ addQuery(queryId, collectionId, queryOptions) {
1240
+ this.queries.push({
1241
+ queryId,
1242
+ collectionId,
1243
+ queryOptions
1244
+ });
1245
+ }
1246
+ /**
1247
+ * Adds a translation file to the request.
1248
+ */
1249
+ addTranslations(translationsId) {
1250
+ this.translationsIds.push(translationsId);
1251
+ }
1252
+ /**
1253
+ * Fetches data from the DB.
1254
+ */
1255
+ async fetch() {
1256
+ const res = new BatchResponse();
1257
+ const promises = [
1258
+ this.fetchDocs(res),
1259
+ this.fetchQueries(res),
1260
+ this.fetchDataSources(res)
1261
+ ];
1262
+ if (!this.options.translate && this.translationsIds.length > 0) {
1263
+ promises.push(this.fetchTranslations(res));
1264
+ }
1265
+ await Promise.all(promises);
1266
+ if (this.translationsIds.length > 0) {
1267
+ await this.fetchTranslations(res);
1268
+ }
1269
+ return res;
1270
+ }
1271
+ async fetchDocs(res) {
1272
+ if (this.docIds.length === 0) {
1273
+ return;
1274
+ }
1275
+ const docRefs = this.docIds.map((docId) => {
1276
+ const [collectionId, slug] = docId.split("/");
1277
+ return this.cmsClient.dbDocRef(collectionId, slug, {
1278
+ mode: this.options.mode
1279
+ });
1280
+ });
1281
+ const docs = await this.db.getAll(...docRefs);
1282
+ this.docIds.forEach((docId, i) => {
1283
+ const doc = docs[i];
1284
+ if (!doc.exists) {
1285
+ console.warn(`doc "${docId}" does not exist`);
1286
+ return;
1287
+ }
1288
+ const docData = unmarshalData(doc.data());
1289
+ res.docs[docId] = docData;
1290
+ if (this.options.translate) {
1291
+ this.addTranslations(docId);
1292
+ }
1293
+ });
1294
+ }
1295
+ async fetchQueries(res) {
1296
+ if (this.queries.length === 0) {
1297
+ return;
1298
+ }
1299
+ const mode = this.options.mode;
1300
+ const handleQuery = async (queryItem) => {
1301
+ const docsPath = this.cmsClient.dbCollectionDocsPath(
1302
+ queryItem.collectionId,
1303
+ { mode }
1304
+ );
1305
+ const queryOptions = queryItem.queryOptions || {};
1306
+ let query = this.db.collection(docsPath);
1307
+ if (queryOptions.limit) {
1308
+ query = query.limit(queryOptions.limit);
1309
+ }
1310
+ if (queryOptions.offset) {
1311
+ query = query.offset(queryOptions.offset);
1312
+ }
1313
+ if (queryOptions.orderBy) {
1314
+ query = query.orderBy(
1315
+ queryOptions.orderBy,
1316
+ queryOptions.orderByDirection
1317
+ );
1318
+ }
1319
+ if (queryOptions.query) {
1320
+ query = queryOptions.query(query);
1321
+ }
1322
+ const results = await query.get();
1323
+ const docs = [];
1324
+ results.forEach((result) => {
1325
+ const doc = unmarshalData(result.data());
1326
+ docs.push(doc);
1327
+ });
1328
+ res.queries[queryItem.queryId] = docs;
1329
+ };
1330
+ await Promise.all(this.queries.map((queryItem) => handleQuery(queryItem)));
1331
+ }
1332
+ async fetchDataSources(res) {
1333
+ if (this.dataSourceIds.length === 0) {
1334
+ return;
1335
+ }
1336
+ const docRefs = this.dataSourceIds.map((dataSourceId) => {
1337
+ return this.cmsClient.dbDataSourceDataRef(dataSourceId, {
1338
+ mode: this.options.mode
1339
+ });
1340
+ });
1341
+ const docs = await this.db.getAll(...docRefs);
1342
+ this.dataSourceIds.forEach((dataSourceId, i) => {
1343
+ const doc = docs[i];
1344
+ if (!doc.exists) {
1345
+ console.warn(`"data source "${dataSourceId}" does not exist`);
1346
+ return;
1347
+ }
1348
+ res.dataSources[dataSourceId] = doc.data();
1349
+ });
1350
+ }
1351
+ async fetchTranslations(res) {
1352
+ if (this.translationsIds.length === 0) {
1353
+ return;
1354
+ }
1355
+ const docRefs = this.translationsIds.map((translationsId) => {
1356
+ return this.cmsClient.dbTranslationsRef(translationsId, {
1357
+ mode: this.options.mode
1358
+ });
1359
+ });
1360
+ const docs = await this.db.getAll(...docRefs);
1361
+ this.translationsIds.forEach((translationsId, i) => {
1362
+ const doc = docs[i];
1363
+ if (!doc.exists) {
1364
+ return;
1365
+ }
1366
+ res.translations[translationsId] = doc.data();
1367
+ });
1368
+ }
1369
+ };
1370
+ var BatchResponse = class {
1371
+ constructor() {
1372
+ this.docs = {};
1373
+ this.queries = {};
1374
+ this.dataSources = {};
1375
+ this.translations = {};
1376
+ }
1377
+ /**
1378
+ * Returns a map of translations for a given locale or locale fallbacks.
1379
+ *
1380
+ * The input is either a single locale (e.g. "de") or an array of locales
1381
+ * representing the fallback tree, e.g. ["en-CA", "en-GB", "en"].
1382
+ *
1383
+ * TODO(stevenle): support the locale fallback tree.
1384
+ *
1385
+ * The returned value is a flat map of source string to translated string,
1386
+ * e.g.:
1387
+ * {"<source>": "<translation>"}
1388
+ */
1389
+ getTranslations(locale) {
1390
+ const translationsMap = this.getTranslationsMap();
1391
+ const translations = translationsForLocale(translationsMap, locale);
1392
+ return translations;
1393
+ }
1394
+ /**
1395
+ * Merges the strings from all translations files retrieved in the request.
1396
+ * The returned value is a map of string to translations, e.g.:
1397
+ *
1398
+ * {"<hash>": {"source": "<source>", "<locale>": "<translation>"}}
1399
+ */
1400
+ getTranslationsMap() {
1401
+ const translationsDocs = Object.values(this.translations).reverse();
1402
+ const translationsMap = {};
1403
+ for (const translationsDoc of translationsDocs) {
1404
+ const strings = translationsDoc.strings || {};
1405
+ for (const hash in strings) {
1406
+ const translations = strings[hash];
1407
+ translationsMap[hash] ??= { source: translations.source };
1408
+ for (const locale in translations) {
1409
+ if (locale !== "source" && translations[locale]) {
1410
+ translationsMap[hash][locale] = translations[locale];
1411
+ }
1412
+ }
1413
+ }
1414
+ }
1415
+ return translationsMap;
1416
+ }
1417
+ };
1138
1418
  export {
1419
+ BatchRequest,
1420
+ BatchResponse,
1139
1421
  RootCMSClient,
1140
1422
  getCmsPlugin,
1141
1423
  isRichTextData,
package/dist/core.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { L as LoadTranslationsOptions, T as TranslationsMap, a as LocaleTranslations } from './client-c_QAurxr.js';
2
- 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, w as Locale, M as MultiLocaleTranslationsMap, R as Release, k as RootCMSClient, f as SaveDraftOptions, S as SetDocOptions, E as SingleLocaleTranslationsMap, x as SourceString, y as TranslatedString, i as Translation, z as TranslationsDocMode, C as TranslationsLocaleDocEntry, B as TranslationsLocaleDocHashMap, F as TranslationsManager, U as UserRole, I as buildTranslationsDbPath, J as buildTranslationsLocaleDocDbPath, 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';
1
+ import { L as LoadTranslationsOptions, T as TranslationsMap, a as LocaleTranslations } from './client-AE0BYn69.js';
2
+ export { A as Action, p as ArrayObject, z as BatchRequest, B as BatchRequestOptions, w as BatchRequestQuery, x as BatchRequestQueryOptions, C as BatchResponse, 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, E as Locale, N as MultiLocaleTranslationsMap, R as Release, k as RootCMSClient, f as SaveDraftOptions, S as SetDocOptions, O as SingleLocaleTranslationsMap, F as SourceString, I as TranslatedString, i as Translation, y as TranslationsDoc, J as TranslationsDocMode, M as TranslationsLocaleDocEntry, K as TranslationsLocaleDocHashMap, P as TranslationsManager, U as UserRole, Q as buildTranslationsDbPath, V as buildTranslationsLocaleDocDbPath, 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-AE0BYn69.js';
3
3
  import { RootConfig } from '@blinkk/root';
4
4
  import { Query } from 'firebase-admin/firestore';
5
- export { s as schema } from './schema-hlZc-G1f.js';
5
+ export { s as schema } from './schema-NuZy-PDV.js';
6
6
  import 'firebase-admin/app';
7
7
  import 'preact';
8
8