@blinkk/root-cms 2.0.1 → 2.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.
- package/dist/app.js +15 -5
- package/dist/client.js +38 -43
- package/dist/core.js +40 -46
- package/dist/functions.js +40 -46
- package/dist/plugin.js +163 -85
- package/dist/richtext.js +12 -19
- package/dist/ui/ui.css +1 -1
- package/dist/ui/ui.js +142 -95
- package/package.json +14 -3
package/dist/functions.js
CHANGED
|
@@ -69,11 +69,11 @@ var TranslationsManager = class {
|
|
|
69
69
|
locale,
|
|
70
70
|
sys: {
|
|
71
71
|
modifiedAt: Timestamp.now(),
|
|
72
|
-
modifiedBy:
|
|
72
|
+
modifiedBy: options?.modifiedBy || "root-cms-client"
|
|
73
73
|
},
|
|
74
74
|
strings: {}
|
|
75
75
|
};
|
|
76
|
-
if (
|
|
76
|
+
if (options?.tags && options.tags.length > 0) {
|
|
77
77
|
updates.tags = FieldValue.arrayUnion(...options.tags);
|
|
78
78
|
}
|
|
79
79
|
let numUpdates = 0;
|
|
@@ -113,13 +113,13 @@ var TranslationsManager = class {
|
|
|
113
113
|
console.warn(`no translations to publish for ${id}`);
|
|
114
114
|
return;
|
|
115
115
|
}
|
|
116
|
-
const batch =
|
|
116
|
+
const batch = options?.batch || db.batch();
|
|
117
117
|
res.docs.forEach((doc) => {
|
|
118
118
|
const translationsLocaleDoc = doc.data();
|
|
119
119
|
const sys = {
|
|
120
120
|
...translationsLocaleDoc.sys,
|
|
121
121
|
publishedAt: Timestamp.now(),
|
|
122
|
-
publishedBy:
|
|
122
|
+
publishedBy: options?.publishedBy || "root-cms-client"
|
|
123
123
|
};
|
|
124
124
|
batch.update(doc.ref, { sys });
|
|
125
125
|
const publishedDocPath = buildTranslationsLocaleDocDbPath({
|
|
@@ -131,7 +131,7 @@ var TranslationsManager = class {
|
|
|
131
131
|
const publishedDocRef = db.doc(publishedDocPath);
|
|
132
132
|
batch.set(publishedDocRef, { ...translationsLocaleDoc, sys });
|
|
133
133
|
});
|
|
134
|
-
const shouldCommitBatch = !
|
|
134
|
+
const shouldCommitBatch = !options?.batch;
|
|
135
135
|
if (shouldCommitBatch) {
|
|
136
136
|
await batch.commit();
|
|
137
137
|
}
|
|
@@ -172,19 +172,19 @@ var TranslationsManager = class {
|
|
|
172
172
|
* ```
|
|
173
173
|
*/
|
|
174
174
|
async loadTranslations(options) {
|
|
175
|
-
const mode =
|
|
175
|
+
const mode = options?.mode || "published";
|
|
176
176
|
const dbPath = buildTranslationsDbPath({
|
|
177
177
|
project: this.cmsClient.projectId,
|
|
178
178
|
mode
|
|
179
179
|
});
|
|
180
180
|
let query = this.cmsClient.db.collection(dbPath);
|
|
181
|
-
if (
|
|
181
|
+
if (options?.ids && options.ids.length > 0) {
|
|
182
182
|
query = query.where("id", "in", options.ids);
|
|
183
183
|
}
|
|
184
|
-
if (
|
|
184
|
+
if (options?.tags && options.tags.length > 0) {
|
|
185
185
|
query = query.where("tags", "array-contains", options.tags);
|
|
186
186
|
}
|
|
187
|
-
if (
|
|
187
|
+
if (options?.locales && options.locales.length > 0) {
|
|
188
188
|
query = query.where("locale", "in", options.locales);
|
|
189
189
|
}
|
|
190
190
|
const results = await query.get();
|
|
@@ -215,11 +215,11 @@ var TranslationsManager = class {
|
|
|
215
215
|
async loadTranslationsForLocale(locale, options) {
|
|
216
216
|
const localeSet = /* @__PURE__ */ new Set([
|
|
217
217
|
locale,
|
|
218
|
-
...
|
|
218
|
+
...options?.fallbackLocales || []
|
|
219
219
|
]);
|
|
220
220
|
const fallbackLocales = Array.from(localeSet);
|
|
221
221
|
const multiLocaleStrings = await this.loadTranslations({
|
|
222
|
-
mode: options
|
|
222
|
+
mode: options?.mode,
|
|
223
223
|
locales: fallbackLocales
|
|
224
224
|
});
|
|
225
225
|
return this.toSingleLocaleMap(multiLocaleStrings, fallbackLocales);
|
|
@@ -290,7 +290,6 @@ var TranslationsManager = class {
|
|
|
290
290
|
* Import translations from the v1 system to the TranslationsManager.
|
|
291
291
|
*/
|
|
292
292
|
async importTranslationsFromV1() {
|
|
293
|
-
var _a;
|
|
294
293
|
const projectId = this.cmsClient.projectId;
|
|
295
294
|
const db = this.cmsClient.db;
|
|
296
295
|
const dbPath = `Projects/${projectId}/Translations`;
|
|
@@ -331,7 +330,7 @@ var TranslationsManager = class {
|
|
|
331
330
|
const doc = await this.cmsClient.getDoc(collection, slug, {
|
|
332
331
|
mode: "draft"
|
|
333
332
|
});
|
|
334
|
-
const linkedSheet =
|
|
333
|
+
const linkedSheet = doc?.sys?.l10nSheet;
|
|
335
334
|
if (linkedSheet) {
|
|
336
335
|
translationsDocs[docId].sys.linkedSheet = linkedSheet;
|
|
337
336
|
}
|
|
@@ -434,7 +433,7 @@ var RootCMSClient = class {
|
|
|
434
433
|
const { collection, slug } = parseDocId(docId);
|
|
435
434
|
const draftDoc = await this.getRawDoc(collection, slug, { mode: "draft" }) || {};
|
|
436
435
|
const draftSys = draftDoc.sys || {};
|
|
437
|
-
const modifiedBy =
|
|
436
|
+
const modifiedBy = options?.modifiedBy || "root-cms-client";
|
|
438
437
|
const fields = marshalData(fieldsData || {});
|
|
439
438
|
const data = {
|
|
440
439
|
id: docId,
|
|
@@ -446,7 +445,7 @@ var RootCMSClient = class {
|
|
|
446
445
|
createdBy: draftSys.createdBy ?? modifiedBy,
|
|
447
446
|
modifiedAt: Timestamp2.now(),
|
|
448
447
|
modifiedBy,
|
|
449
|
-
locales:
|
|
448
|
+
locales: options?.locales ?? draftSys.locales ?? ["en"]
|
|
450
449
|
},
|
|
451
450
|
fields
|
|
452
451
|
};
|
|
@@ -516,7 +515,7 @@ var RootCMSClient = class {
|
|
|
516
515
|
*/
|
|
517
516
|
async publishDocs(docIds, options) {
|
|
518
517
|
const projectCollectionsPath = `Projects/${this.projectId}/Collections`;
|
|
519
|
-
const publishedBy =
|
|
518
|
+
const publishedBy = options?.publishedBy || "root-cms-client";
|
|
520
519
|
const docRefs = docIds.map((docId) => {
|
|
521
520
|
const [collection, slug] = docId.split("/");
|
|
522
521
|
if (!collection || !slug) {
|
|
@@ -539,9 +538,9 @@ var RootCMSClient = class {
|
|
|
539
538
|
}
|
|
540
539
|
}
|
|
541
540
|
let batchCount = 0;
|
|
542
|
-
const batch =
|
|
541
|
+
const batch = options?.batch || this.db.batch();
|
|
543
542
|
const versionTags = ["published"];
|
|
544
|
-
if (options
|
|
543
|
+
if (options?.releaseId) {
|
|
545
544
|
versionTags.push(`release:${options.releaseId}`);
|
|
546
545
|
}
|
|
547
546
|
const publishedDocs = [];
|
|
@@ -624,12 +623,11 @@ var RootCMSClient = class {
|
|
|
624
623
|
const now = Math.ceil((/* @__PURE__ */ new Date()).getTime());
|
|
625
624
|
const snapshot = await this.db.collectionGroup("Scheduled").get();
|
|
626
625
|
const docs = snapshot.docs.filter((d) => {
|
|
627
|
-
var _a;
|
|
628
626
|
if (!d.ref.path.startsWith(projectCollectionsPath)) {
|
|
629
627
|
return false;
|
|
630
628
|
}
|
|
631
629
|
const data = d.data() || {};
|
|
632
|
-
const scheduledAt =
|
|
630
|
+
const scheduledAt = data.sys?.scheduledAt;
|
|
633
631
|
return scheduledAt && scheduledAt.toMillis && scheduledAt.toMillis() <= now;
|
|
634
632
|
}).map((d) => {
|
|
635
633
|
const dbPath = d.ref.path;
|
|
@@ -760,8 +758,7 @@ var RootCMSClient = class {
|
|
|
760
758
|
* Checks if a doc is currently "locked" for publishing.
|
|
761
759
|
*/
|
|
762
760
|
testPublishingLocked(doc) {
|
|
763
|
-
|
|
764
|
-
if ((_a = doc.sys) == null ? void 0 : _a.publishingLocked) {
|
|
761
|
+
if (doc.sys?.publishingLocked) {
|
|
765
762
|
if (doc.sys.publishingLocked.until) {
|
|
766
763
|
const now = Timestamp2.now().toMillis();
|
|
767
764
|
const until = doc.sys.publishingLocked.until.toMillis();
|
|
@@ -786,9 +783,8 @@ var RootCMSClient = class {
|
|
|
786
783
|
* replace the v1 translations system.
|
|
787
784
|
*/
|
|
788
785
|
getTranslationsManager() {
|
|
789
|
-
var _a;
|
|
790
786
|
const cmsPluginOptions = this.cmsPlugin.getConfig();
|
|
791
|
-
if (
|
|
787
|
+
if (cmsPluginOptions.experiments?.v2TranslationsManager) {
|
|
792
788
|
throw new Error(
|
|
793
789
|
"`v2TranslationsManager` is not enabled. update root.config.ts and add: `{experiments: {v2TranslationsManager: true}}`"
|
|
794
790
|
);
|
|
@@ -809,7 +805,7 @@ var RootCMSClient = class {
|
|
|
809
805
|
async loadTranslations(options) {
|
|
810
806
|
const dbPath = `Projects/${this.projectId}/Translations`;
|
|
811
807
|
let query = this.db.collection(dbPath);
|
|
812
|
-
if (options
|
|
808
|
+
if (options?.tags) {
|
|
813
809
|
query = query.where("tags", "array-contains-any", options.tags);
|
|
814
810
|
}
|
|
815
811
|
const querySnapshot = await query.get();
|
|
@@ -927,7 +923,7 @@ var RootCMSClient = class {
|
|
|
927
923
|
const dataDocRef = this.db.doc(
|
|
928
924
|
`Projects/${this.projectId}/DataSources/${dataSourceId}/Data/draft`
|
|
929
925
|
);
|
|
930
|
-
const syncedBy =
|
|
926
|
+
const syncedBy = options?.syncedBy || "root-cms-client";
|
|
931
927
|
const updatedDataSource = {
|
|
932
928
|
...dataSource,
|
|
933
929
|
syncedAt: Timestamp2.now(),
|
|
@@ -961,7 +957,7 @@ var RootCMSClient = class {
|
|
|
961
957
|
`Projects/${this.projectId}/DataSources/${dataSourceId}/published`
|
|
962
958
|
);
|
|
963
959
|
const dataRes = await this.getFromDataSource(dataSourceId, { mode: "draft" });
|
|
964
|
-
const publishedBy =
|
|
960
|
+
const publishedBy = options?.publishedBy || "root-cms-client";
|
|
965
961
|
const updatedDataSource = {
|
|
966
962
|
...dataSource,
|
|
967
963
|
publishedAt: Timestamp2.now(),
|
|
@@ -970,8 +966,8 @@ var RootCMSClient = class {
|
|
|
970
966
|
const batch = this.db.batch();
|
|
971
967
|
batch.set(dataDocRefPublished, {
|
|
972
968
|
dataSource: updatedDataSource,
|
|
973
|
-
data:
|
|
974
|
-
...
|
|
969
|
+
data: dataRes?.data || null,
|
|
970
|
+
...dataRes?.headers ? { headers: dataRes.headers } : {}
|
|
975
971
|
});
|
|
976
972
|
batch.update(dataDocRefDraft, {
|
|
977
973
|
dataSource: updatedDataSource
|
|
@@ -985,8 +981,8 @@ var RootCMSClient = class {
|
|
|
985
981
|
console.log(`published by: ${publishedBy}`);
|
|
986
982
|
}
|
|
987
983
|
async publishDataSources(dataSourceIds, options) {
|
|
988
|
-
const publishedBy =
|
|
989
|
-
const batch =
|
|
984
|
+
const publishedBy = options?.publishedBy || "root-cms-client";
|
|
985
|
+
const batch = options?.batch || this.db.batch();
|
|
990
986
|
for (const id of dataSourceIds) {
|
|
991
987
|
const dataSource = await this.getDataSource(id);
|
|
992
988
|
if (!dataSource) {
|
|
@@ -1009,8 +1005,8 @@ var RootCMSClient = class {
|
|
|
1009
1005
|
};
|
|
1010
1006
|
batch.set(dataDocRefPublished, {
|
|
1011
1007
|
dataSource: updatedDataSource,
|
|
1012
|
-
data:
|
|
1013
|
-
...
|
|
1008
|
+
data: dataRes?.data || null,
|
|
1009
|
+
...dataRes?.headers ? { headers: dataRes.headers } : {}
|
|
1014
1010
|
});
|
|
1015
1011
|
batch.update(dataDocRefDraft, { dataSource: updatedDataSource });
|
|
1016
1012
|
batch.update(dataSourceDocRef, {
|
|
@@ -1018,7 +1014,7 @@ var RootCMSClient = class {
|
|
|
1018
1014
|
publishedBy
|
|
1019
1015
|
});
|
|
1020
1016
|
}
|
|
1021
|
-
if (!
|
|
1017
|
+
if (!options?.batch || options?.commitBatch) {
|
|
1022
1018
|
await batch.commit();
|
|
1023
1019
|
}
|
|
1024
1020
|
}
|
|
@@ -1029,15 +1025,14 @@ var RootCMSClient = class {
|
|
|
1029
1025
|
throw new Error(`unsupported data source: ${dataSource.type}`);
|
|
1030
1026
|
}
|
|
1031
1027
|
async fetchHttpData(dataSource) {
|
|
1032
|
-
var _a, _b, _c;
|
|
1033
1028
|
const url = dataSource.url || "";
|
|
1034
1029
|
if (!url.startsWith("https://")) {
|
|
1035
1030
|
throw new Error(`url not supported: ${url}`);
|
|
1036
1031
|
}
|
|
1037
1032
|
const res = await fetch(url, {
|
|
1038
|
-
method:
|
|
1039
|
-
headers:
|
|
1040
|
-
body:
|
|
1033
|
+
method: dataSource.httpOptions?.method || "GET",
|
|
1034
|
+
headers: dataSource.httpOptions?.headers || [],
|
|
1035
|
+
body: dataSource.httpOptions?.body || void 0
|
|
1041
1036
|
});
|
|
1042
1037
|
if (res.status !== 200) {
|
|
1043
1038
|
const err = await res.text();
|
|
@@ -1053,7 +1048,7 @@ var RootCMSClient = class {
|
|
|
1053
1048
|
* Fetches data from a data source.
|
|
1054
1049
|
*/
|
|
1055
1050
|
async getFromDataSource(dataSourceId, options) {
|
|
1056
|
-
const mode =
|
|
1051
|
+
const mode = options?.mode || "published";
|
|
1057
1052
|
if (!(mode === "draft" || mode === "published")) {
|
|
1058
1053
|
throw new Error(`invalid mode: ${mode}`);
|
|
1059
1054
|
}
|
|
@@ -1143,12 +1138,12 @@ var RootCMSClient = class {
|
|
|
1143
1138
|
const data = {
|
|
1144
1139
|
action,
|
|
1145
1140
|
timestamp: Timestamp2.now(),
|
|
1146
|
-
by:
|
|
1147
|
-
metadata:
|
|
1141
|
+
by: options?.by || "system",
|
|
1142
|
+
metadata: options?.metadata || {}
|
|
1148
1143
|
};
|
|
1149
1144
|
const colRef = this.db.collection(`Projects/${this.projectId}/ActionLogs`);
|
|
1150
1145
|
await colRef.add(data);
|
|
1151
|
-
const metaStr =
|
|
1146
|
+
const metaStr = options?.metadata ? stringifyObj(options.metadata) : "";
|
|
1152
1147
|
console.log(`[${data.timestamp.toMillis()}] action: ${action} ${metaStr}`);
|
|
1153
1148
|
const cmsPluginConfig = this.cmsPlugin.getConfig();
|
|
1154
1149
|
if (cmsPluginConfig.onAction) {
|
|
@@ -1539,8 +1534,7 @@ var VersionsService = class {
|
|
|
1539
1534
|
async saveVersionsToFirestore(versions) {
|
|
1540
1535
|
const batch = this.db.batch();
|
|
1541
1536
|
versions.forEach((version) => {
|
|
1542
|
-
|
|
1543
|
-
if (!version.collection || !version.slug || !((_a = version.sys) == null ? void 0 : _a.modifiedAt)) {
|
|
1537
|
+
if (!version.collection || !version.slug || !version.sys?.modifiedAt) {
|
|
1544
1538
|
return;
|
|
1545
1539
|
}
|
|
1546
1540
|
const modifiedAtMillis = version.sys.modifiedAt.toMillis();
|
|
@@ -1636,10 +1630,10 @@ async function runSaveVersions(rootConfig) {
|
|
|
1636
1630
|
|
|
1637
1631
|
// core/functions.ts
|
|
1638
1632
|
function cron(options) {
|
|
1639
|
-
const rootDir = path2.resolve(
|
|
1633
|
+
const rootDir = path2.resolve(options?.rootDir || process.cwd());
|
|
1640
1634
|
const scheduleOptions = {
|
|
1641
1635
|
schedule: "every 1 mins",
|
|
1642
|
-
...options
|
|
1636
|
+
...options?.scheduleOptions
|
|
1643
1637
|
};
|
|
1644
1638
|
return onSchedule(scheduleOptions, async () => {
|
|
1645
1639
|
const rootConfig = await loadBundledConfig(rootDir, { command: "cms-cron" });
|