@blinkk/root-cms 1.0.0-rc.0 → 1.0.0-rc.10
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 +4 -3
- package/dist/cli.js +67 -34
- package/dist/client.js +346 -0
- package/dist/core/client.d.ts +196 -0
- package/dist/core/core.d.ts +56 -0
- package/dist/{project.d.ts → core/project.d.ts} +1 -1
- package/dist/core.js +415 -109
- package/dist/functions.js +29 -20
- package/dist/plugin.js +29 -20
- package/dist/project.js +4 -1
- package/dist/richtext/richtext.d.ts +65 -0
- package/dist/richtext.js +119 -0
- package/dist/{schema-49de9659.d.ts → schema-710fda8a.d.ts} +16 -1
- package/dist/ui/signin.css +44 -57
- package/dist/ui/signin.js +1318 -706
- package/dist/ui/ui.css +97 -44
- package/dist/ui/ui.js +23832 -10136
- package/package.json +41 -25
- package/dist/core.d.ts +0 -108
- /package/dist/{functions.d.ts → core/functions.d.ts} +0 -0
- /package/dist/{plugin.d.ts → core/plugin.d.ts} +0 -0
package/dist/client.js
ADDED
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
// core/client.ts
|
|
2
|
+
import crypto from "node:crypto";
|
|
3
|
+
import {
|
|
4
|
+
FieldValue,
|
|
5
|
+
getFirestore
|
|
6
|
+
} from "firebase-admin/firestore";
|
|
7
|
+
var RootCMSClient = class {
|
|
8
|
+
constructor(rootConfig) {
|
|
9
|
+
this.rootConfig = rootConfig;
|
|
10
|
+
this.cmsPlugin = getCmsPlugin(rootConfig);
|
|
11
|
+
const cmsPluginOptions = this.cmsPlugin.getConfig();
|
|
12
|
+
this.projectId = cmsPluginOptions.id || "default";
|
|
13
|
+
this.app = this.cmsPlugin.getFirebaseApp();
|
|
14
|
+
this.db = getFirestore(this.app);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Retrieves doc data from Root.js CMS.
|
|
18
|
+
*/
|
|
19
|
+
async getDoc(collectionId, slug, options) {
|
|
20
|
+
const rawData = await this.getRawDoc(collectionId, slug, options);
|
|
21
|
+
if (rawData) {
|
|
22
|
+
return unmarshalData(rawData);
|
|
23
|
+
}
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Retrieves raw doc data as stored in the database. Only use this if you know
|
|
28
|
+
* what you are doing.
|
|
29
|
+
*/
|
|
30
|
+
async getRawDoc(collectionId, slug, options) {
|
|
31
|
+
const mode = options.mode;
|
|
32
|
+
const modeCollection = mode === "draft" ? "Drafts" : "Published";
|
|
33
|
+
slug = slug.replaceAll("/", "--");
|
|
34
|
+
const dbPath = `Projects/${this.projectId}/Collections/${collectionId}/${modeCollection}/${slug}`;
|
|
35
|
+
const docRef = this.db.doc(dbPath);
|
|
36
|
+
const doc = await docRef.get();
|
|
37
|
+
if (doc.exists) {
|
|
38
|
+
return doc.data();
|
|
39
|
+
}
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
async setRawDoc(collectionId, slug, data, options) {
|
|
43
|
+
const mode = options.mode;
|
|
44
|
+
const modeCollection = mode === "draft" ? "Drafts" : "Published";
|
|
45
|
+
const dbPath = `Projects/${this.projectId}/Collections/${collectionId}/${modeCollection}/${slug}`;
|
|
46
|
+
const docRef = this.db.doc(dbPath);
|
|
47
|
+
await docRef.set(data);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Lists docs from a Root.js CMS collection.
|
|
51
|
+
*/
|
|
52
|
+
async listDocs(collectionId, options) {
|
|
53
|
+
const mode = options.mode;
|
|
54
|
+
const modeCollection = mode === "draft" ? "Drafts" : "Published";
|
|
55
|
+
const dbPath = `Projects/${this.projectId}/Collections/${collectionId}/${modeCollection}`;
|
|
56
|
+
let query = this.db.collection(dbPath);
|
|
57
|
+
if (options.limit) {
|
|
58
|
+
query = query.limit(options.limit);
|
|
59
|
+
}
|
|
60
|
+
if (options.offset) {
|
|
61
|
+
query = query.offset(options.offset);
|
|
62
|
+
}
|
|
63
|
+
if (options.orderBy) {
|
|
64
|
+
query = query.orderBy(options.orderBy, options.orderByDirection);
|
|
65
|
+
}
|
|
66
|
+
if (options.query) {
|
|
67
|
+
query = options.query(query);
|
|
68
|
+
}
|
|
69
|
+
const results = await query.get();
|
|
70
|
+
const docs = [];
|
|
71
|
+
results.forEach((result) => {
|
|
72
|
+
const doc = unmarshalData(result.data());
|
|
73
|
+
docs.push(doc);
|
|
74
|
+
});
|
|
75
|
+
return { docs };
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Returns the number of docs in a Root.js CMS collection.
|
|
79
|
+
*/
|
|
80
|
+
async getDocsCount(collectionId, options) {
|
|
81
|
+
const mode = options.mode;
|
|
82
|
+
const modeCollection = mode === "draft" ? "Drafts" : "Published";
|
|
83
|
+
const dbPath = `Projects/${this.projectId}/Collections/${collectionId}/${modeCollection}`;
|
|
84
|
+
let query = this.db.collection(dbPath);
|
|
85
|
+
if (options.query) {
|
|
86
|
+
query = options.query(query);
|
|
87
|
+
}
|
|
88
|
+
const results = await query.count().get();
|
|
89
|
+
const count = results.data().count;
|
|
90
|
+
return count;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Publishes scheduled docs.
|
|
94
|
+
*/
|
|
95
|
+
async publishScheduledDocs() {
|
|
96
|
+
const projectCollectionsPath = `Projects/${this.projectId}/Collections`;
|
|
97
|
+
const now = Math.ceil((/* @__PURE__ */ new Date()).getTime());
|
|
98
|
+
const snapshot = await this.db.collectionGroup("Scheduled").get();
|
|
99
|
+
const docs = snapshot.docs.filter((d) => {
|
|
100
|
+
var _a;
|
|
101
|
+
if (!d.ref.path.startsWith(projectCollectionsPath)) {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
const data = d.data() || {};
|
|
105
|
+
const scheduledAt = (_a = data.sys) == null ? void 0 : _a.scheduledAt;
|
|
106
|
+
return scheduledAt && scheduledAt.toMillis && scheduledAt.toMillis() <= now;
|
|
107
|
+
}).map((d) => {
|
|
108
|
+
const dbPath = d.ref.path;
|
|
109
|
+
const segments = dbPath.split("/");
|
|
110
|
+
const slug = segments.at(-1);
|
|
111
|
+
const collection = segments.at(-3);
|
|
112
|
+
const id = `${collection}/${slug}`;
|
|
113
|
+
return {
|
|
114
|
+
data: d.data(),
|
|
115
|
+
id,
|
|
116
|
+
collection,
|
|
117
|
+
slug
|
|
118
|
+
};
|
|
119
|
+
});
|
|
120
|
+
if (docs.length === 0) {
|
|
121
|
+
console.log("no docs to schedule");
|
|
122
|
+
return [];
|
|
123
|
+
}
|
|
124
|
+
let batchCount = 0;
|
|
125
|
+
const batch = this.db.batch();
|
|
126
|
+
const publishedDocs = [];
|
|
127
|
+
for (const doc of docs) {
|
|
128
|
+
const { id, collection, slug, data } = doc;
|
|
129
|
+
const draftRef = this.db.doc(
|
|
130
|
+
`${projectCollectionsPath}/${collection}/Drafts/${slug}`
|
|
131
|
+
);
|
|
132
|
+
const scheduledRef = this.db.doc(
|
|
133
|
+
`${projectCollectionsPath}/${collection}/Scheduled/${slug}`
|
|
134
|
+
);
|
|
135
|
+
const publishedRef = this.db.doc(
|
|
136
|
+
`${projectCollectionsPath}/${collection}/Published/${slug}`
|
|
137
|
+
);
|
|
138
|
+
const { scheduledAt, scheduledBy, ...sys } = data.sys || {};
|
|
139
|
+
const firstPublishedAt = sys.firstPublishedAt ?? scheduledAt;
|
|
140
|
+
const firstPublishedBy = sys.firstPublishedBy ?? (scheduledBy || "");
|
|
141
|
+
batch.set(publishedRef, {
|
|
142
|
+
id,
|
|
143
|
+
collection,
|
|
144
|
+
slug,
|
|
145
|
+
fields: data.fields || {},
|
|
146
|
+
sys: {
|
|
147
|
+
...sys,
|
|
148
|
+
firstPublishedAt,
|
|
149
|
+
firstPublishedBy,
|
|
150
|
+
publishedAt: FieldValue.serverTimestamp(),
|
|
151
|
+
publishedBy: scheduledBy || ""
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
batchCount += 1;
|
|
155
|
+
batch.delete(scheduledRef);
|
|
156
|
+
batchCount += 1;
|
|
157
|
+
batch.update(draftRef, {
|
|
158
|
+
"sys.scheduledAt": FieldValue.delete(),
|
|
159
|
+
"sys.scheduledBy": FieldValue.delete(),
|
|
160
|
+
"sys.firstPublishedAt": firstPublishedAt,
|
|
161
|
+
"sys.firstPublishedBy": firstPublishedBy,
|
|
162
|
+
"sys.publishedAt": FieldValue.serverTimestamp(),
|
|
163
|
+
"sys.publishedBy": scheduledBy || ""
|
|
164
|
+
});
|
|
165
|
+
batchCount += 1;
|
|
166
|
+
publishedDocs.push(doc);
|
|
167
|
+
if (batchCount >= 498) {
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
await batch.commit();
|
|
172
|
+
console.log(`published ${publishedDocs.length} docs!`);
|
|
173
|
+
return publishedDocs;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Loads translations saved in the translations collection, optionally
|
|
177
|
+
* filtered by tag.
|
|
178
|
+
*
|
|
179
|
+
* Returns a map like:
|
|
180
|
+
* ```
|
|
181
|
+
* {
|
|
182
|
+
* "<hash>": {"source": "Hello", "es": "Hola", "fr": "Bonjour"},
|
|
183
|
+
* }
|
|
184
|
+
* ```
|
|
185
|
+
*/
|
|
186
|
+
async loadTranslations(options) {
|
|
187
|
+
const dbPath = `Projects/${this.projectId}/Translations`;
|
|
188
|
+
let query = this.db.collection(dbPath);
|
|
189
|
+
if (options == null ? void 0 : options.tags) {
|
|
190
|
+
query = query.where("tags", "array-contains-any", options.tags);
|
|
191
|
+
}
|
|
192
|
+
const querySnapshot = await query.get();
|
|
193
|
+
const translationsMap = {};
|
|
194
|
+
querySnapshot.forEach((doc) => {
|
|
195
|
+
const hash = doc.id;
|
|
196
|
+
translationsMap[hash] = doc.data();
|
|
197
|
+
});
|
|
198
|
+
return translationsMap;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Saves a map of translations, e.g.:
|
|
202
|
+
* ```
|
|
203
|
+
* await client.saveTranslations({
|
|
204
|
+
* "Hello": {"es": "Hola", "fr": "Bonjour"},
|
|
205
|
+
* });
|
|
206
|
+
* ```
|
|
207
|
+
*/
|
|
208
|
+
async saveTranslations(translations, tags) {
|
|
209
|
+
const translationsPath = `Projects/${this.projectId}/Translations`;
|
|
210
|
+
const batch = this.db.batch();
|
|
211
|
+
let batchCount = 0;
|
|
212
|
+
Object.entries(translations).forEach(([source, sourceTranslations]) => {
|
|
213
|
+
const hash = this.getTranslationKey(source);
|
|
214
|
+
const translationRef = this.db.doc(`${translationsPath}/${hash}`);
|
|
215
|
+
const data = {
|
|
216
|
+
...sourceTranslations,
|
|
217
|
+
source: this.normalizeString(source)
|
|
218
|
+
};
|
|
219
|
+
if (tags) {
|
|
220
|
+
data.tags = tags;
|
|
221
|
+
}
|
|
222
|
+
batch.update(translationRef, data);
|
|
223
|
+
batchCount += 1;
|
|
224
|
+
});
|
|
225
|
+
if (batchCount > 500) {
|
|
226
|
+
throw new Error("up to 500 translations can be saved at a time.");
|
|
227
|
+
}
|
|
228
|
+
await batch.commit();
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Returns the "key" used for a translation as stored in the db. Translations
|
|
232
|
+
* are stored under `Projects/<project id>/Translations/<sha1 hash>`.
|
|
233
|
+
*/
|
|
234
|
+
getTranslationKey(source) {
|
|
235
|
+
const sha1 = crypto.createHash("sha1").update(this.normalizeString(source)).digest("hex");
|
|
236
|
+
return sha1;
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Cleans a string that's used for translations. Performs the following:
|
|
240
|
+
* - Removes any leading/trailing whitespace
|
|
241
|
+
* - Removes spaces at the end of any line
|
|
242
|
+
*/
|
|
243
|
+
normalizeString(str) {
|
|
244
|
+
const lines = String(str).trim().split("\n").map((line) => line.trimEnd());
|
|
245
|
+
return lines.join("\n");
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Loads translations for a particular locale.
|
|
249
|
+
*
|
|
250
|
+
* Returns a map like:
|
|
251
|
+
* ```
|
|
252
|
+
* {
|
|
253
|
+
* "Hello": "Bonjour",
|
|
254
|
+
* }
|
|
255
|
+
* ```
|
|
256
|
+
*/
|
|
257
|
+
async loadTranslationsForLocale(locale, options) {
|
|
258
|
+
const translationsMap = await this.loadTranslations(options);
|
|
259
|
+
return translationsForLocale(translationsMap, locale);
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
function getCmsPlugin(rootConfig) {
|
|
263
|
+
const plugins = rootConfig.plugins || [];
|
|
264
|
+
const plugin = plugins.find((plugin2) => plugin2.name === "root-cms");
|
|
265
|
+
if (!plugin) {
|
|
266
|
+
throw new Error("could not find root-cms plugin config in root.config.ts");
|
|
267
|
+
}
|
|
268
|
+
return plugin;
|
|
269
|
+
}
|
|
270
|
+
function unmarshalData(data) {
|
|
271
|
+
const result = {};
|
|
272
|
+
for (const key in data) {
|
|
273
|
+
const val = data[key];
|
|
274
|
+
if (isObject(val)) {
|
|
275
|
+
if (val.toMillis) {
|
|
276
|
+
result[key] = val.toMillis();
|
|
277
|
+
} else if (Object.hasOwn(val, "_array") && Array.isArray(val._array)) {
|
|
278
|
+
const arr = val._array.map((arrayKey) => {
|
|
279
|
+
return {
|
|
280
|
+
...unmarshalData(val[arrayKey] || {}),
|
|
281
|
+
_arrayKey: arrayKey
|
|
282
|
+
};
|
|
283
|
+
});
|
|
284
|
+
result[key] = arr;
|
|
285
|
+
} else {
|
|
286
|
+
result[key] = unmarshalData(val);
|
|
287
|
+
}
|
|
288
|
+
} else {
|
|
289
|
+
result[key] = val;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
return result;
|
|
293
|
+
}
|
|
294
|
+
function normalizeData(data) {
|
|
295
|
+
return unmarshalData(data);
|
|
296
|
+
}
|
|
297
|
+
function marshalArray(arr) {
|
|
298
|
+
if (!Array.isArray(arr)) {
|
|
299
|
+
return arr;
|
|
300
|
+
}
|
|
301
|
+
const arrObject = { _array: [] };
|
|
302
|
+
for (const item of arr) {
|
|
303
|
+
const key = randString(6);
|
|
304
|
+
arrObject[key] = item;
|
|
305
|
+
arrObject._array.push(key);
|
|
306
|
+
}
|
|
307
|
+
return arrObject;
|
|
308
|
+
}
|
|
309
|
+
function unmarshalArray(arrObject) {
|
|
310
|
+
if (!Array.isArray(arrObject == null ? void 0 : arrObject._array)) {
|
|
311
|
+
return [];
|
|
312
|
+
}
|
|
313
|
+
const arr = arrObject._array.map((k) => arrObject[k]);
|
|
314
|
+
return arr;
|
|
315
|
+
}
|
|
316
|
+
function isObject(data) {
|
|
317
|
+
return typeof data === "object" && !Array.isArray(data) && data !== null;
|
|
318
|
+
}
|
|
319
|
+
function randString(len) {
|
|
320
|
+
const result = [];
|
|
321
|
+
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
322
|
+
for (let i = 0; i < len; i++) {
|
|
323
|
+
const rand = Math.floor(Math.random() * chars.length);
|
|
324
|
+
result.push(chars.charAt(rand));
|
|
325
|
+
}
|
|
326
|
+
return result.join("");
|
|
327
|
+
}
|
|
328
|
+
function translationsForLocale(translationsMap, locale) {
|
|
329
|
+
const localeTranslations = {};
|
|
330
|
+
Object.values(translationsMap).forEach((string) => {
|
|
331
|
+
const source = string.source;
|
|
332
|
+
const translation = string[locale] || string.en || string.source;
|
|
333
|
+
localeTranslations[source] = translation;
|
|
334
|
+
});
|
|
335
|
+
return localeTranslations;
|
|
336
|
+
}
|
|
337
|
+
export {
|
|
338
|
+
RootCMSClient,
|
|
339
|
+
getCmsPlugin,
|
|
340
|
+
marshalArray,
|
|
341
|
+
normalizeData,
|
|
342
|
+
translationsForLocale,
|
|
343
|
+
unmarshalArray,
|
|
344
|
+
unmarshalData
|
|
345
|
+
};
|
|
346
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vY29yZS9jbGllbnQudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImltcG9ydCBjcnlwdG8gZnJvbSAnbm9kZTpjcnlwdG8nO1xuaW1wb3J0IHtQbHVnaW4sIFJvb3RDb25maWd9IGZyb20gJ0BibGlua2svcm9vdCc7XG5pbXBvcnQge0FwcH0gZnJvbSAnZmlyZWJhc2UtYWRtaW4vYXBwJztcbmltcG9ydCB7XG4gIEZpZWxkVmFsdWUsXG4gIEZpcmVzdG9yZSxcbiAgUXVlcnksXG4gIFRpbWVzdGFtcCxcbiAgZ2V0RmlyZXN0b3JlLFxufSBmcm9tICdmaXJlYmFzZS1hZG1pbi9maXJlc3RvcmUnO1xuaW1wb3J0IHtDTVNQbHVnaW59IGZyb20gJy4vcGx1Z2luLmpzJztcblxuZXhwb3J0IGludGVyZmFjZSBEb2M8RmllbGRzID0gYW55PiB7XG4gIC8qKiBUaGUgaWQgb2YgdGhlIGRvYywgZS5nLiBcIlBhZ2VzL2Zvby1iYXJcIi4gKi9cbiAgaWQ6IHN0cmluZztcbiAgLyoqIFRoZSBjb2xsZWN0aW9uIGlkIG9mIHRoZSBkb2MsIGUuZy4gXCJQYWdlc1wiLiAqL1xuICBjb2xsZWN0aW9uSWQ6IHN0cmluZztcbiAgLyoqIFRoZSBzbHVnIG9mIHRoZSBkb2MsIGUuZy4gXCJmb28tYmFyXCIuICovXG4gIHNsdWc6IHN0cmluZztcbiAgc3lzOiB7XG4gICAgY3JlYXRlZEF0OiBudW1iZXI7XG4gICAgY3JlYXRlZEJ5OiBzdHJpbmc7XG4gICAgbW9kaWZpZWRBdDogbnVtYmVyO1xuICAgIG1vZGlmaWVkQnk6IHN0cmluZztcbiAgICBmaXJzdFB1Ymxpc2hlZEF0PzogbnVtYmVyO1xuICAgIGZpcnN0UHVibGlzaGVkQnk/OiBzdHJpbmc7XG4gICAgcHVibGlzaGVkQXQ/OiBudW1iZXI7XG4gICAgcHVibGlzaGVkQnk/OiBzdHJpbmc7XG4gICAgbG9jYWxlcz86IHN0cmluZ1tdO1xuICB9O1xuICBmaWVsZHM6IEZpZWxkcztcbn1cblxuZXhwb3J0IHR5cGUgRG9jTW9kZSA9ICdkcmFmdCcgfCAncHVibGlzaGVkJztcblxuZXhwb3J0IGludGVyZmFjZSBHZXREb2NPcHRpb25zIHtcbiAgLyoqIE1vZGUsIGVpdGhlciBcImRyYWZ0XCIgb3IgXCJwdWJsaXNoZWRcIi4gKi9cbiAgbW9kZTogRG9jTW9kZTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTZXREb2NPcHRpb25zIHtcbiAgLyoqIE1vZGUsIGVpdGhlciBcImRyYWZ0XCIgb3IgXCJwdWJsaXNoZWRcIi4gKi9cbiAgbW9kZTogRG9jTW9kZTtcbiAgLyoqXG4gICAqIEVtYWlsIG9mIHVzZXIgbW9kaWZ5aW5nIHRoZSBkb2MuIElmIGJsYW5rLCBkZWZhdWx0cyB0byBgcm9vdC1jbXMtY2xpZW50YC5cbiAgICovXG4gIG1vZGlmaWVkQnk/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTGlzdERvY3NPcHRpb25zIHtcbiAgbW9kZTogRG9jTW9kZTtcbiAgb2Zmc2V0PzogbnVtYmVyO1xuICBsaW1pdD86IG51bWJlcjtcbiAgb3JkZXJCeT86IHN0cmluZztcbiAgb3JkZXJCeURpcmVjdGlvbj86ICdhc2MnIHwgJ2Rlc2MnO1xuICBxdWVyeT86IChxdWVyeTogUXVlcnkpID0+IFF1ZXJ5O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEdldENvdW50T3B0aW9ucyB7XG4gIG1vZGU6IERvY01vZGU7XG4gIHF1ZXJ5PzogKHF1ZXJ5OiBRdWVyeSkgPT4gUXVlcnk7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHJhbnNsYXRpb24ge1xuICBbbG9jYWxlOiBzdHJpbmddOiBzdHJpbmc7XG4gIHNvdXJjZTogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRyYW5zbGF0aW9uc01hcCB7XG4gIFtoYXNoOiBzdHJpbmddOiBUcmFuc2xhdGlvbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBMb2NhbGVUcmFuc2xhdGlvbnMge1xuICBbc291cmNlOiBzdHJpbmddOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTG9hZFRyYW5zbGF0aW9uc09wdGlvbnMge1xuICB0YWdzPzogc3RyaW5nW107XG59XG5cbmV4cG9ydCBjbGFzcyBSb290Q01TQ2xpZW50IHtcbiAgcHJpdmF0ZSByZWFkb25seSByb290Q29uZmlnOiBSb290Q29uZmlnO1xuICBwcml2YXRlIHJlYWRvbmx5IGNtc1BsdWdpbjogQ01TUGx1Z2luO1xuICBwcml2YXRlIHJlYWRvbmx5IHByb2plY3RJZDogc3RyaW5nO1xuICBwcml2YXRlIHJlYWRvbmx5IGFwcDogQXBwO1xuICBwcml2YXRlIHJlYWRvbmx5IGRiOiBGaXJlc3RvcmU7XG5cbiAgY29uc3RydWN0b3Iocm9vdENvbmZpZzogUm9vdENvbmZpZykge1xuICAgIHRoaXMucm9vdENvbmZpZyA9IHJvb3RDb25maWc7XG4gICAgdGhpcy5jbXNQbHVnaW4gPSBnZXRDbXNQbHVnaW4ocm9vdENvbmZpZyk7XG5cbiAgICBjb25zdCBjbXNQbHVnaW5PcHRpb25zID0gdGhpcy5jbXNQbHVnaW4uZ2V0Q29uZmlnKCk7XG4gICAgdGhpcy5wcm9qZWN0SWQgPSBjbXNQbHVnaW5PcHRpb25zLmlkIHx8ICdkZWZhdWx0JztcbiAgICB0aGlzLmFwcCA9IHRoaXMuY21zUGx1Z2luLmdldEZpcmViYXNlQXBwKCk7XG4gICAgdGhpcy5kYiA9IGdldEZpcmVzdG9yZSh0aGlzLmFwcCk7XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmVzIGRvYyBkYXRhIGZyb20gUm9vdC5qcyBDTVMuXG4gICAqL1xuICBhc3luYyBnZXREb2M8RmllbGRzID0gYW55PihcbiAgICBjb2xsZWN0aW9uSWQ6IHN0cmluZyxcbiAgICBzbHVnOiBzdHJpbmcsXG4gICAgb3B0aW9uczogR2V0RG9jT3B0aW9uc1xuICApOiBQcm9taXNlPERvYzxGaWVsZHM+IHwgbnVsbD4ge1xuICAgIGNvbnN0IHJhd0RhdGEgPSBhd2FpdCB0aGlzLmdldFJhd0RvYyhjb2xsZWN0aW9uSWQsIHNsdWcsIG9wdGlvbnMpO1xuICAgIGlmIChyYXdEYXRhKSB7XG4gICAgICByZXR1cm4gdW5tYXJzaGFsRGF0YShyYXdEYXRhKSBhcyBEb2M8RmllbGRzPjtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmVzIHJhdyBkb2MgZGF0YSBhcyBzdG9yZWQgaW4gdGhlIGRhdGFiYXNlLiBPbmx5IHVzZSB0aGlzIGlmIHlvdSBrbm93XG4gICAqIHdoYXQgeW91IGFyZSBkb2luZy5cbiAgICovXG4gIGFzeW5jIGdldFJhd0RvYyhcbiAgICBjb2xsZWN0aW9uSWQ6IHN0cmluZyxcbiAgICBzbHVnOiBzdHJpbmcsXG4gICAgb3B0aW9uczogR2V0RG9jT3B0aW9uc1xuICApOiBQcm9taXNlPGFueSB8IG51bGw+IHtcbiAgICBjb25zdCBtb2RlID0gb3B0aW9ucy5tb2RlO1xuICAgIGNvbnN0IG1vZGVDb2xsZWN0aW9uID0gbW9kZSA9PT0gJ2RyYWZ0JyA/ICdEcmFmdHMnIDogJ1B1Ymxpc2hlZCc7XG4gICAgLy8gU2x1Z3Mgd2l0aCBzbGFzaGVzIGFyZSBlbmNvZGVkIGFzIGAtLWAgaW4gdGhlIERCLlxuICAgIHNsdWcgPSBzbHVnLnJlcGxhY2VBbGwoJy8nLCAnLS0nKTtcbiAgICBjb25zdCBkYlBhdGggPSBgUHJvamVjdHMvJHt0aGlzLnByb2plY3RJZH0vQ29sbGVjdGlvbnMvJHtjb2xsZWN0aW9uSWR9LyR7bW9kZUNvbGxlY3Rpb259LyR7c2x1Z31gO1xuICAgIGNvbnN0IGRvY1JlZiA9IHRoaXMuZGIuZG9jKGRiUGF0aCk7XG4gICAgY29uc3QgZG9jID0gYXdhaXQgZG9jUmVmLmdldCgpO1xuICAgIGlmIChkb2MuZXhpc3RzKSB7XG4gICAgICByZXR1cm4gZG9jLmRhdGEoKTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBhc3luYyBzZXRSYXdEb2MoXG4gICAgY29sbGVjdGlvbklkOiBzdHJpbmcsXG4gICAgc2x1Zzogc3RyaW5nLFxuICAgIGRhdGE6IGFueSxcbiAgICBvcHRpb25zOiBTZXREb2NPcHRpb25zXG4gICkge1xuICAgIGNvbnN0IG1vZGUgPSBvcHRpb25zLm1vZGU7XG4gICAgY29uc3QgbW9kZUNvbGxlY3Rpb24gPSBtb2RlID09PSAnZHJhZnQnID8gJ0RyYWZ0cycgOiAnUHVibGlzaGVkJztcbiAgICBjb25zdCBkYlBhdGggPSBgUHJvamVjdHMvJHt0aGlzLnByb2plY3RJZH0vQ29sbGVjdGlvbnMvJHtjb2xsZWN0aW9uSWR9LyR7bW9kZUNvbGxlY3Rpb259LyR7c2x1Z31gO1xuICAgIGNvbnN0IGRvY1JlZiA9IHRoaXMuZGIuZG9jKGRiUGF0aCk7XG4gICAgYXdhaXQgZG9jUmVmLnNldChkYXRhKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMaXN0cyBkb2NzIGZyb20gYSBSb290LmpzIENNUyBjb2xsZWN0aW9uLlxuICAgKi9cbiAgYXN5bmMgbGlzdERvY3M8VD4oXG4gICAgY29sbGVjdGlvbklkOiBzdHJpbmcsXG4gICAgb3B0aW9uczogTGlzdERvY3NPcHRpb25zXG4gICk6IFByb21pc2U8e2RvY3M6IFRbXX0+IHtcbiAgICBjb25zdCBtb2RlID0gb3B0aW9ucy5tb2RlO1xuICAgIGNvbnN0IG1vZGVDb2xsZWN0aW9uID0gbW9kZSA9PT0gJ2RyYWZ0JyA/ICdEcmFmdHMnIDogJ1B1Ymxpc2hlZCc7XG4gICAgY29uc3QgZGJQYXRoID0gYFByb2plY3RzLyR7dGhpcy5wcm9qZWN0SWR9L0NvbGxlY3Rpb25zLyR7Y29sbGVjdGlvbklkfS8ke21vZGVDb2xsZWN0aW9ufWA7XG4gICAgbGV0IHF1ZXJ5OiBRdWVyeSA9IHRoaXMuZGIuY29sbGVjdGlvbihkYlBhdGgpO1xuICAgIGlmIChvcHRpb25zLmxpbWl0KSB7XG4gICAgICBxdWVyeSA9IHF1ZXJ5LmxpbWl0KG9wdGlvbnMubGltaXQpO1xuICAgIH1cbiAgICBpZiAob3B0aW9ucy5vZmZzZXQpIHtcbiAgICAgIHF1ZXJ5ID0gcXVlcnkub2Zmc2V0KG9wdGlvbnMub2Zmc2V0KTtcbiAgICB9XG4gICAgaWYgKG9wdGlvbnMub3JkZXJCeSkge1xuICAgICAgcXVlcnkgPSBxdWVyeS5vcmRlckJ5KG9wdGlvbnMub3JkZXJCeSwgb3B0aW9ucy5vcmRlckJ5RGlyZWN0aW9uKTtcbiAgICB9XG4gICAgaWYgKG9wdGlvbnMucXVlcnkpIHtcbiAgICAgIHF1ZXJ5ID0gb3B0aW9ucy5xdWVyeShxdWVyeSk7XG4gICAgfVxuICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBxdWVyeS5nZXQoKTtcbiAgICBjb25zdCBkb2NzOiBUW10gPSBbXTtcbiAgICByZXN1bHRzLmZvckVhY2goKHJlc3VsdCkgPT4ge1xuICAgICAgY29uc3QgZG9jID0gdW5tYXJzaGFsRGF0YShyZXN1bHQuZGF0YSgpKSBhcyBUO1xuICAgICAgZG9jcy5wdXNoKGRvYyk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHtkb2NzfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgZG9jcyBpbiBhIFJvb3QuanMgQ01TIGNvbGxlY3Rpb24uXG4gICAqL1xuICBhc3luYyBnZXREb2NzQ291bnQoY29sbGVjdGlvbklkOiBzdHJpbmcsIG9wdGlvbnM6IEdldENvdW50T3B0aW9ucykge1xuICAgIGNvbnN0IG1vZGUgPSBvcHRpb25zLm1vZGU7XG4gICAgY29uc3QgbW9kZUNvbGxlY3Rpb24gPSBtb2RlID09PSAnZHJhZnQnID8gJ0RyYWZ0cycgOiAnUHVibGlzaGVkJztcbiAgICBjb25zdCBkYlBhdGggPSBgUHJvamVjdHMvJHt0aGlzLnByb2plY3RJZH0vQ29sbGVjdGlvbnMvJHtjb2xsZWN0aW9uSWR9LyR7bW9kZUNvbGxlY3Rpb259YDtcbiAgICBsZXQgcXVlcnk6IFF1ZXJ5ID0gdGhpcy5kYi5jb2xsZWN0aW9uKGRiUGF0aCk7XG4gICAgaWYgKG9wdGlvbnMucXVlcnkpIHtcbiAgICAgIHF1ZXJ5ID0gb3B0aW9ucy5xdWVyeShxdWVyeSk7XG4gICAgfVxuICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBxdWVyeS5jb3VudCgpLmdldCgpO1xuICAgIGNvbnN0IGNvdW50ID0gcmVzdWx0cy5kYXRhKCkuY291bnQ7XG4gICAgcmV0dXJuIGNvdW50O1xuICB9XG5cbiAgLyoqXG4gICAqIFB1Ymxpc2hlcyBzY2hlZHVsZWQgZG9jcy5cbiAgICovXG4gIGFzeW5jIHB1Ymxpc2hTY2hlZHVsZWREb2NzKCkge1xuICAgIGNvbnN0IHByb2plY3RDb2xsZWN0aW9uc1BhdGggPSBgUHJvamVjdHMvJHt0aGlzLnByb2plY3RJZH0vQ29sbGVjdGlvbnNgO1xuICAgIGNvbnN0IG5vdyA9IE1hdGguY2VpbChuZXcgRGF0ZSgpLmdldFRpbWUoKSk7XG5cbiAgICBjb25zdCBzbmFwc2hvdCA9IGF3YWl0IHRoaXMuZGIuY29sbGVjdGlvbkdyb3VwKCdTY2hlZHVsZWQnKS5nZXQoKTtcbiAgICBjb25zdCBkb2NzID0gc25hcHNob3QuZG9jc1xuICAgICAgLmZpbHRlcigoZCkgPT4ge1xuICAgICAgICAvLyBGaWx0ZXIgZG9jcyBieSBwcm9qZWN0LlxuICAgICAgICBpZiAoIWQucmVmLnBhdGguc3RhcnRzV2l0aChwcm9qZWN0Q29sbGVjdGlvbnNQYXRoKSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICAvLyBGaWx0ZXIgZG9jcyB3aGVyZSBzY2hlZHVsZWRBdCBpcyBpbiB0aGUgcGFzdC5cbiAgICAgICAgLy8gTk9URShzdGV2ZW5sZSk6IHRoZSBmaWx0ZXJpbmcgaXMgZG9uZSBtYW51YWxseSBpbnN0ZWFkIG9mIHVzaW5nIGEgcXVlcnlcbiAgICAgICAgLy8gdG8gYXZvaWQgaGF2aW5nIHRvIGNyZWF0ZSBhbiBpbmRleCBpbiBmaXJlc3RvcmUuXG4gICAgICAgIGNvbnN0IGRhdGEgPSBkLmRhdGEoKSB8fCB7fTtcbiAgICAgICAgY29uc3Qgc2NoZWR1bGVkQXQ6IFRpbWVzdGFtcCB8IHVuZGVmaW5lZCA9IGRhdGEuc3lzPy5zY2hlZHVsZWRBdDtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICBzY2hlZHVsZWRBdCAmJiBzY2hlZHVsZWRBdC50b01pbGxpcyAmJiBzY2hlZHVsZWRBdC50b01pbGxpcygpIDw9IG5vd1xuICAgICAgICApO1xuICAgICAgfSlcbiAgICAgIC5tYXAoKGQpID0+IHtcbiAgICAgICAgY29uc3QgZGJQYXRoID0gZC5yZWYucGF0aDtcbiAgICAgICAgY29uc3Qgc2VnbWVudHMgPSBkYlBhdGguc3BsaXQoJy8nKTtcbiAgICAgICAgY29uc3Qgc2x1ZyA9IHNlZ21lbnRzLmF0KC0xKTtcbiAgICAgICAgY29uc3QgY29sbGVjdGlvbiA9IHNlZ21lbnRzLmF0KC0zKTtcbiAgICAgICAgY29uc3QgaWQgPSBgJHtjb2xsZWN0aW9ufS8ke3NsdWd9YDtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBkYXRhOiBkLmRhdGEoKSxcbiAgICAgICAgICBpZCxcbiAgICAgICAgICBjb2xsZWN0aW9uLFxuICAgICAgICAgIHNsdWcsXG4gICAgICAgIH07XG4gICAgICB9KTtcblxuICAgIGlmIChkb2NzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgY29uc29sZS5sb2coJ25vIGRvY3MgdG8gc2NoZWR1bGUnKTtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG5cbiAgICAvLyBFYWNoIHRyYW5zYWN0aW9uIG9yIGJhdGNoIGNhbiB3cml0ZSBhIG1heCBvZiA1MDAgb3BzLlxuICAgIC8vIGh0dHBzOi8vZmlyZWJhc2UuZ29vZ2xlLmNvbS9kb2NzL2ZpcmVzdG9yZS9tYW5hZ2UtZGF0YS90cmFuc2FjdGlvbnNcbiAgICBsZXQgYmF0Y2hDb3VudCA9IDA7XG4gICAgY29uc3QgYmF0Y2ggPSB0aGlzLmRiLmJhdGNoKCk7XG4gICAgY29uc3QgcHVibGlzaGVkRG9jczogYW55W10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IGRvYyBvZiBkb2NzKSB7XG4gICAgICBjb25zdCB7aWQsIGNvbGxlY3Rpb24sIHNsdWcsIGRhdGF9ID0gZG9jO1xuICAgICAgY29uc3QgZHJhZnRSZWYgPSB0aGlzLmRiLmRvYyhcbiAgICAgICAgYCR7cHJvamVjdENvbGxlY3Rpb25zUGF0aH0vJHtjb2xsZWN0aW9ufS9EcmFmdHMvJHtzbHVnfWBcbiAgICAgICk7XG4gICAgICBjb25zdCBzY2hlZHVsZWRSZWYgPSB0aGlzLmRiLmRvYyhcbiAgICAgICAgYCR7cHJvamVjdENvbGxlY3Rpb25zUGF0aH0vJHtjb2xsZWN0aW9ufS9TY2hlZHVsZWQvJHtzbHVnfWBcbiAgICAgICk7XG4gICAgICBjb25zdCBwdWJsaXNoZWRSZWYgPSB0aGlzLmRiLmRvYyhcbiAgICAgICAgYCR7cHJvamVjdENvbGxlY3Rpb25zUGF0aH0vJHtjb2xsZWN0aW9ufS9QdWJsaXNoZWQvJHtzbHVnfWBcbiAgICAgICk7XG4gICAgICBjb25zdCB7c2NoZWR1bGVkQXQsIHNjaGVkdWxlZEJ5LCAuLi5zeXN9ID0gZGF0YS5zeXMgfHwge307XG5cbiAgICAgIC8vIE9ubHkgdXBkYXRlIGBmaXJzdFB1Ymxpc2hlZGAgaWYgaXQgZG9lc24ndCBhbHJlYWR5IGV4aXN0LlxuICAgICAgY29uc3QgZmlyc3RQdWJsaXNoZWRBdCA9IHN5cy5maXJzdFB1Ymxpc2hlZEF0ID8/IHNjaGVkdWxlZEF0O1xuICAgICAgY29uc3QgZmlyc3RQdWJsaXNoZWRCeSA9IHN5cy5maXJzdFB1Ymxpc2hlZEJ5ID8/IChzY2hlZHVsZWRCeSB8fCAnJyk7XG5cbiAgICAgIC8vIFNhdmUgcHVibGlzaGVkIGRvYy5cbiAgICAgIGJhdGNoLnNldChwdWJsaXNoZWRSZWYsIHtcbiAgICAgICAgaWQsXG4gICAgICAgIGNvbGxlY3Rpb24sXG4gICAgICAgIHNsdWcsXG4gICAgICAgIGZpZWxkczogZGF0YS5maWVsZHMgfHwge30sXG4gICAgICAgIHN5czoge1xuICAgICAgICAgIC4uLnN5cyxcbiAgICAgICAgICBmaXJzdFB1Ymxpc2hlZEF0OiBmaXJzdFB1Ymxpc2hlZEF0LFxuICAgICAgICAgIGZpcnN0UHVibGlzaGVkQnk6IGZpcnN0UHVibGlzaGVkQnksXG4gICAgICAgICAgcHVibGlzaGVkQXQ6IEZpZWxkVmFsdWUuc2VydmVyVGltZXN0YW1wKCksXG4gICAgICAgICAgcHVibGlzaGVkQnk6IHNjaGVkdWxlZEJ5IHx8ICcnLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgICBiYXRjaENvdW50ICs9IDE7XG5cbiAgICAgIC8vIFJlbW92ZSBwdWJsaXNoZWQgZG9jLlxuICAgICAgYmF0Y2guZGVsZXRlKHNjaGVkdWxlZFJlZik7XG4gICAgICBiYXRjaENvdW50ICs9IDE7XG5cbiAgICAgIC8vIFVwZGF0ZSB0aGUgZHJhZnQgZG9jIHRvIHJlbW92ZSBgc2NoZWR1bGVkQXRgIGFuZCBgc2NoZWR1bGVkQnlgIGZpZWxkc1xuICAgICAgLy8gYW5kIHVwZGF0ZSB0aGUgYHB1Ymxpc2hlZEF0YCBhbmQgYHB1Ymxpc2hlZEJ5YCBmaWVsZHMuXG4gICAgICBiYXRjaC51cGRhdGUoZHJhZnRSZWYsIHtcbiAgICAgICAgJ3N5cy5zY2hlZHVsZWRBdCc6IEZpZWxkVmFsdWUuZGVsZXRlKCksXG4gICAgICAgICdzeXMuc2NoZWR1bGVkQnknOiBGaWVsZFZhbHVlLmRlbGV0ZSgpLFxuICAgICAgICAnc3lzLmZpcnN0UHVibGlzaGVkQXQnOiBmaXJzdFB1Ymxpc2hlZEF0LFxuICAgICAgICAnc3lzLmZpcnN0UHVibGlzaGVkQnknOiBmaXJzdFB1Ymxpc2hlZEJ5LFxuICAgICAgICAnc3lzLnB1Ymxpc2hlZEF0JzogRmllbGRWYWx1ZS5zZXJ2ZXJUaW1lc3RhbXAoKSxcbiAgICAgICAgJ3N5cy5wdWJsaXNoZWRCeSc6IHNjaGVkdWxlZEJ5IHx8ICcnLFxuICAgICAgfSk7XG4gICAgICBiYXRjaENvdW50ICs9IDE7XG5cbiAgICAgIHB1Ymxpc2hlZERvY3MucHVzaChkb2MpO1xuXG4gICAgICBpZiAoYmF0Y2hDb3VudCA+PSA0OTgpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgYXdhaXQgYmF0Y2guY29tbWl0KCk7XG4gICAgY29uc29sZS5sb2coYHB1Ymxpc2hlZCAke3B1Ymxpc2hlZERvY3MubGVuZ3RofSBkb2NzIWApO1xuICAgIHJldHVybiBwdWJsaXNoZWREb2NzO1xuICB9XG5cbiAgLyoqXG4gICAqIExvYWRzIHRyYW5zbGF0aW9ucyBzYXZlZCBpbiB0aGUgdHJhbnNsYXRpb25zIGNvbGxlY3Rpb24sIG9wdGlvbmFsbHlcbiAgICogZmlsdGVyZWQgYnkgdGFnLlxuICAgKlxuICAgKiBSZXR1cm5zIGEgbWFwIGxpa2U6XG4gICAqIGBgYFxuICAgKiB7XG4gICAqICAgXCI8aGFzaD5cIjoge1wic291cmNlXCI6IFwiSGVsbG9cIiwgXCJlc1wiOiBcIkhvbGFcIiwgXCJmclwiOiBcIkJvbmpvdXJcIn0sXG4gICAqIH1cbiAgICogYGBgXG4gICAqL1xuICBhc3luYyBsb2FkVHJhbnNsYXRpb25zKFxuICAgIG9wdGlvbnM/OiBMb2FkVHJhbnNsYXRpb25zT3B0aW9uc1xuICApOiBQcm9taXNlPFRyYW5zbGF0aW9uc01hcD4ge1xuICAgIGNvbnN0IGRiUGF0aCA9IGBQcm9qZWN0cy8ke3RoaXMucHJvamVjdElkfS9UcmFuc2xhdGlvbnNgO1xuICAgIGxldCBxdWVyeTogUXVlcnkgPSB0aGlzLmRiLmNvbGxlY3Rpb24oZGJQYXRoKTtcbiAgICBpZiAob3B0aW9ucz8udGFncykge1xuICAgICAgcXVlcnkgPSBxdWVyeS53aGVyZSgndGFncycsICdhcnJheS1jb250YWlucy1hbnknLCBvcHRpb25zLnRhZ3MpO1xuICAgIH1cblxuICAgIGNvbnN0IHF1ZXJ5U25hcHNob3QgPSBhd2FpdCBxdWVyeS5nZXQoKTtcbiAgICBjb25zdCB0cmFuc2xhdGlvbnNNYXA6IFRyYW5zbGF0aW9uc01hcCA9IHt9O1xuICAgIHF1ZXJ5U25hcHNob3QuZm9yRWFjaCgoZG9jKSA9PiB7XG4gICAgICBjb25zdCBoYXNoID0gZG9jLmlkO1xuICAgICAgdHJhbnNsYXRpb25zTWFwW2hhc2hdID0gZG9jLmRhdGEoKSBhcyBUcmFuc2xhdGlvbjtcbiAgICB9KTtcbiAgICByZXR1cm4gdHJhbnNsYXRpb25zTWFwO1xuICB9XG5cbiAgLyoqXG4gICAqIFNhdmVzIGEgbWFwIG9mIHRyYW5zbGF0aW9ucywgZS5nLjpcbiAgICogYGBgXG4gICAqIGF3YWl0IGNsaWVudC5zYXZlVHJhbnNsYXRpb25zKHtcbiAgICogICBcIkhlbGxvXCI6IHtcImVzXCI6IFwiSG9sYVwiLCBcImZyXCI6IFwiQm9uam91clwifSxcbiAgICogfSk7XG4gICAqIGBgYFxuICAgKi9cbiAgYXN5bmMgc2F2ZVRyYW5zbGF0aW9ucyhcbiAgICB0cmFuc2xhdGlvbnM6IHtcbiAgICAgIFtzb3VyY2U6IHN0cmluZ106IHtbbG9jYWxlOiBzdHJpbmddOiBzdHJpbmd9O1xuICAgIH0sXG4gICAgdGFncz86IHN0cmluZ1tdXG4gICkge1xuICAgIGNvbnN0IHRyYW5zbGF0aW9uc1BhdGggPSBgUHJvamVjdHMvJHt0aGlzLnByb2plY3RJZH0vVHJhbnNsYXRpb25zYDtcbiAgICBjb25zdCBiYXRjaCA9IHRoaXMuZGIuYmF0Y2goKTtcbiAgICBsZXQgYmF0Y2hDb3VudCA9IDA7XG4gICAgT2JqZWN0LmVudHJpZXModHJhbnNsYXRpb25zKS5mb3JFYWNoKChbc291cmNlLCBzb3VyY2VUcmFuc2xhdGlvbnNdKSA9PiB7XG4gICAgICBjb25zdCBoYXNoID0gdGhpcy5nZXRUcmFuc2xhdGlvbktleShzb3VyY2UpO1xuICAgICAgY29uc3QgdHJhbnNsYXRpb25SZWYgPSB0aGlzLmRiLmRvYyhgJHt0cmFuc2xhdGlvbnNQYXRofS8ke2hhc2h9YCk7XG4gICAgICBjb25zdCBkYXRhOiBhbnkgPSB7XG4gICAgICAgIC4uLnNvdXJjZVRyYW5zbGF0aW9ucyxcbiAgICAgICAgc291cmNlOiB0aGlzLm5vcm1hbGl6ZVN0cmluZyhzb3VyY2UpLFxuICAgICAgfTtcbiAgICAgIGlmICh0YWdzKSB7XG4gICAgICAgIGRhdGEudGFncyA9IHRhZ3M7XG4gICAgICB9XG4gICAgICBiYXRjaC51cGRhdGUodHJhbnNsYXRpb25SZWYsIGRhdGEpO1xuICAgICAgYmF0Y2hDb3VudCArPSAxO1xuICAgIH0pO1xuICAgIGlmIChiYXRjaENvdW50ID4gNTAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3VwIHRvIDUwMCB0cmFuc2xhdGlvbnMgY2FuIGJlIHNhdmVkIGF0IGEgdGltZS4nKTtcbiAgICB9XG4gICAgYXdhaXQgYmF0Y2guY29tbWl0KCk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgXCJrZXlcIiB1c2VkIGZvciBhIHRyYW5zbGF0aW9uIGFzIHN0b3JlZCBpbiB0aGUgZGIuIFRyYW5zbGF0aW9uc1xuICAgKiBhcmUgc3RvcmVkIHVuZGVyIGBQcm9qZWN0cy88cHJvamVjdCBpZD4vVHJhbnNsYXRpb25zLzxzaGExIGhhc2g+YC5cbiAgICovXG4gIGdldFRyYW5zbGF0aW9uS2V5KHNvdXJjZTogc3RyaW5nKSB7XG4gICAgY29uc3Qgc2hhMSA9IGNyeXB0b1xuICAgICAgLmNyZWF0ZUhhc2goJ3NoYTEnKVxuICAgICAgLnVwZGF0ZSh0aGlzLm5vcm1hbGl6ZVN0cmluZyhzb3VyY2UpKVxuICAgICAgLmRpZ2VzdCgnaGV4Jyk7XG4gICAgcmV0dXJuIHNoYTE7XG4gIH1cblxuICAvKipcbiAgICogQ2xlYW5zIGEgc3RyaW5nIHRoYXQncyB1c2VkIGZvciB0cmFuc2xhdGlvbnMuIFBlcmZvcm1zIHRoZSBmb2xsb3dpbmc6XG4gICAqIC0gUmVtb3ZlcyBhbnkgbGVhZGluZy90cmFpbGluZyB3aGl0ZXNwYWNlXG4gICAqIC0gUmVtb3ZlcyBzcGFjZXMgYXQgdGhlIGVuZCBvZiBhbnkgbGluZVxuICAgKi9cbiAgbm9ybWFsaXplU3RyaW5nKHN0cjogc3RyaW5nKSB7XG4gICAgY29uc3QgbGluZXMgPSBTdHJpbmcoc3RyKVxuICAgICAgLnRyaW0oKVxuICAgICAgLnNwbGl0KCdcXG4nKVxuICAgICAgLm1hcCgobGluZSkgPT4gbGluZS50cmltRW5kKCkpO1xuICAgIHJldHVybiBsaW5lcy5qb2luKCdcXG4nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMb2FkcyB0cmFuc2xhdGlvbnMgZm9yIGEgcGFydGljdWxhciBsb2NhbGUuXG4gICAqXG4gICAqIFJldHVybnMgYSBtYXAgbGlrZTpcbiAgICogYGBgXG4gICAqIHtcbiAgICogICBcIkhlbGxvXCI6IFwiQm9uam91clwiLFxuICAgKiB9XG4gICAqIGBgYFxuICAgKi9cbiAgYXN5bmMgbG9hZFRyYW5zbGF0aW9uc0ZvckxvY2FsZShcbiAgICBsb2NhbGU6IHN0cmluZyxcbiAgICBvcHRpb25zPzogTG9hZFRyYW5zbGF0aW9uc09wdGlvbnNcbiAgKTogUHJvbWlzZTxMb2NhbGVUcmFuc2xhdGlvbnM+IHtcbiAgICBjb25zdCB0cmFuc2xhdGlvbnNNYXAgPSBhd2FpdCB0aGlzLmxvYWRUcmFuc2xhdGlvbnMob3B0aW9ucyk7XG4gICAgcmV0dXJuIHRyYW5zbGF0aW9uc0ZvckxvY2FsZSh0cmFuc2xhdGlvbnNNYXAsIGxvY2FsZSk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldENtc1BsdWdpbihyb290Q29uZmlnOiBSb290Q29uZmlnKTogQ01TUGx1Z2luIHtcbiAgY29uc3QgcGx1Z2luczogUGx1Z2luW10gPSByb290Q29uZmlnLnBsdWdpbnMgfHwgW107XG4gIGNvbnN0IHBsdWdpbiA9IHBsdWdpbnMuZmluZCgocGx1Z2luKSA9PiBwbHVnaW4ubmFtZSA9PT0gJ3Jvb3QtY21zJyk7XG4gIGlmICghcGx1Z2luKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdjb3VsZCBub3QgZmluZCByb290LWNtcyBwbHVnaW4gY29uZmlnIGluIHJvb3QuY29uZmlnLnRzJyk7XG4gIH1cbiAgcmV0dXJuIHBsdWdpbiBhcyBDTVNQbHVnaW47XG59XG5cbi8qKlxuICogV2Fsa3MgdGhlIGRhdGEgdHJlZSBhbmQgY29udmVydHMgYW55IFRpbWVzdGFtcCBvYmplY3RzIHRvIG1pbGxpcyBhbmQgYW55XG4gKiBfYXJyYXkgbWFwcyB0byBub3JtYWwgYXJyYXlzLlxuICpcbiAqIEUuZy46XG4gKlxuICogbm9ybWFsaXplRGF0YSh7XG4gKiAgIHN5czoge21vZGlmaWVkQXQ6IFRpbWVzdGFtcCgxMjMpfSxcbiAqICAgZmllbGRzOiB7XG4gKiAgICAgX2FycmF5OiBbJ2FzZGYnXSxcbiAqICAgICBhc2RmOiB7dGl0bGU6ICdoZWxsbyd9XG4gKiAgIH1cbiAqIH0pXG4gKiAvLyA9PiB7c3lzOiB7bW9kaWZpZWRBdDogMTIzfSwgZmllbGRzOiB7Zm9vOiBbe3RpdGxlOiAnaGVsbG8nfV19fVxuICovXG5leHBvcnQgZnVuY3Rpb24gdW5tYXJzaGFsRGF0YShkYXRhOiBhbnkpOiBhbnkge1xuICBjb25zdCByZXN1bHQ6IGFueSA9IHt9O1xuICBmb3IgKGNvbnN0IGtleSBpbiBkYXRhKSB7XG4gICAgY29uc3QgdmFsID0gZGF0YVtrZXldO1xuICAgIGlmIChpc09iamVjdCh2YWwpKSB7XG4gICAgICBpZiAodmFsLnRvTWlsbGlzKSB7XG4gICAgICAgIHJlc3VsdFtrZXldID0gdmFsLnRvTWlsbGlzKCk7XG4gICAgICB9IGVsc2UgaWYgKE9iamVjdC5oYXNPd24odmFsLCAnX2FycmF5JykgJiYgQXJyYXkuaXNBcnJheSh2YWwuX2FycmF5KSkge1xuICAgICAgICBjb25zdCBhcnIgPSB2YWwuX2FycmF5Lm1hcCgoYXJyYXlLZXk6IHN0cmluZykgPT4ge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAuLi51bm1hcnNoYWxEYXRhKHZhbFthcnJheUtleV0gfHwge30pLFxuICAgICAgICAgICAgX2FycmF5S2V5OiBhcnJheUtleSxcbiAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICAgICAgcmVzdWx0W2tleV0gPSBhcnI7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXN1bHRba2V5XSA9IHVubWFyc2hhbERhdGEodmFsKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmVzdWx0W2tleV0gPSB2YWw7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKiBAZGVwcmVjYXRlZCBVc2UgYHVubWFyc2hhbERhdGEoKWAgaW5zdGVhZC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVEYXRhKGRhdGE6IGFueSk6IGFueSB7XG4gIHJldHVybiB1bm1hcnNoYWxEYXRhKGRhdGEpO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEFycmF5T2JqZWN0IHtcbiAgW2tleTogc3RyaW5nXTogYW55O1xuICBfYXJyYXk6IHN0cmluZ1tdO1xufVxuXG4vKipcbiAqIFNlcmlhbGl6ZXMgYW4gYXJyYXkgaW50byBhbiBgQXJyYXlPYmplY3RgLCBlLmcuOlxuICpcbiAqIGBgYFxuICogbWFyc2hhbEFycmF5KFsxLCAyLCAzXSlcbiAqIC8vID0+IHthOiAxLCBiOiAyLCBjOiAzLCBfYXJyYXk6IFsnYScsICdiJywgJ2MnXX1cbiAqIGBgYFxuICpcbiAqIFRoaXMgZGF0YWJhc2Ugc3RvcmFnZSBtZXRob2QgbWFrZXMgaXQgZWFzaWVyIHRvIHVwZGF0ZSBhIHNpbmdsZSBmaWVsZCBpbiBhXG4gKiBkZWVwbHkgbmVzdGVkIGFycmF5IG9iamVjdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1hcnNoYWxBcnJheShhcnI6IGFueVtdKTogQXJyYXlPYmplY3Qge1xuICBpZiAoIUFycmF5LmlzQXJyYXkoYXJyKSkge1xuICAgIHJldHVybiBhcnI7XG4gIH1cbiAgY29uc3QgYXJyT2JqZWN0OiBBcnJheU9iamVjdCA9IHtfYXJyYXk6IFtdfTtcbiAgZm9yIChjb25zdCBpdGVtIG9mIGFycikge1xuICAgIGNvbnN0IGtleSA9IHJhbmRTdHJpbmcoNik7XG4gICAgYXJyT2JqZWN0W2tleV0gPSBpdGVtO1xuICAgIGFyck9iamVjdC5fYXJyYXkucHVzaChrZXkpO1xuICB9XG4gIHJldHVybiBhcnJPYmplY3Q7XG59XG5cbi8qKlxuICogQ29udmVydHMgYW4gYEFycmF5T2JqZWN0YCB0byBhIG5vcm1hbCBhcnJheS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVubWFyc2hhbEFycmF5KGFyck9iamVjdDogQXJyYXlPYmplY3QpOiBhbnlbXSB7XG4gIGlmICghQXJyYXkuaXNBcnJheShhcnJPYmplY3Q/Ll9hcnJheSkpIHtcbiAgICByZXR1cm4gW107XG4gIH1cbiAgY29uc3QgYXJyID0gYXJyT2JqZWN0Ll9hcnJheS5tYXAoKGs6IHN0cmluZykgPT4gYXJyT2JqZWN0W2tdKTtcbiAgcmV0dXJuIGFycjtcbn1cblxuZnVuY3Rpb24gaXNPYmplY3QoZGF0YTogYW55KTogYm9vbGVhbiB7XG4gIHJldHVybiB0eXBlb2YgZGF0YSA9PT0gJ29iamVjdCcgJiYgIUFycmF5LmlzQXJyYXkoZGF0YSkgJiYgZGF0YSAhPT0gbnVsbDtcbn1cblxuZnVuY3Rpb24gcmFuZFN0cmluZyhsZW46IG51bWJlcik6IHN0cmluZyB7XG4gIGNvbnN0IHJlc3VsdCA9IFtdO1xuICBjb25zdCBjaGFycyA9XG4gICAgJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5JztcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgIGNvbnN0IHJhbmQgPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBjaGFycy5sZW5ndGgpO1xuICAgIHJlc3VsdC5wdXNoKGNoYXJzLmNoYXJBdChyYW5kKSk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdC5qb2luKCcnKTtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBhIHRyYW5zbGF0aW9ucyBtYXAgZnJvbSBgbG9hZFRyYW5zbGF0aW9ucygpYCB0byBhIG1hcCBvZiBzb3VyY2UgdG9cbiAqIHRyYW5zbGF0ZWQgc3RyaW5nIGZvciBhIHBhcnRpY3VsYXIgbG9jYWxlLlxuICpcbiAqIFJldHVybnMgYSBtYXAgbGlrZTpcbiAqIGBgYFxuICoge1xuICogICBcIkhlbGxvXCI6IFwiQm9uam91clwiLFxuICogfVxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0cmFuc2xhdGlvbnNGb3JMb2NhbGUoXG4gIHRyYW5zbGF0aW9uc01hcDogVHJhbnNsYXRpb25zTWFwLFxuICBsb2NhbGU6IHN0cmluZ1xuKSB7XG4gIGNvbnN0IGxvY2FsZVRyYW5zbGF0aW9uczogTG9jYWxlVHJhbnNsYXRpb25zID0ge307XG4gIE9iamVjdC52YWx1ZXModHJhbnNsYXRpb25zTWFwKS5mb3JFYWNoKChzdHJpbmcpID0+IHtcbiAgICBjb25zdCBzb3VyY2UgPSBzdHJpbmcuc291cmNlO1xuICAgIGNvbnN0IHRyYW5zbGF0aW9uID0gc3RyaW5nW2xvY2FsZV0gfHwgc3RyaW5nLmVuIHx8IHN0cmluZy5zb3VyY2U7XG4gICAgbG9jYWxlVHJhbnNsYXRpb25zW3NvdXJjZV0gPSB0cmFuc2xhdGlvbjtcbiAgfSk7XG4gIHJldHVybiBsb2NhbGVUcmFuc2xhdGlvbnM7XG59XG4iXSwKICAibWFwcGluZ3MiOiAiO0FBQUEsT0FBTyxZQUFZO0FBR25CO0FBQUEsRUFDRTtBQUFBLEVBSUE7QUFBQSxPQUNLO0FBdUVBLElBQU0sZ0JBQU4sTUFBb0I7QUFBQSxFQU96QixZQUFZLFlBQXdCO0FBQ2xDLFNBQUssYUFBYTtBQUNsQixTQUFLLFlBQVksYUFBYSxVQUFVO0FBRXhDLFVBQU0sbUJBQW1CLEtBQUssVUFBVSxVQUFVO0FBQ2xELFNBQUssWUFBWSxpQkFBaUIsTUFBTTtBQUN4QyxTQUFLLE1BQU0sS0FBSyxVQUFVLGVBQWU7QUFDekMsU0FBSyxLQUFLLGFBQWEsS0FBSyxHQUFHO0FBQUEsRUFDakM7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQUtBLE1BQU0sT0FDSixjQUNBLE1BQ0EsU0FDNkI7QUFDN0IsVUFBTSxVQUFVLE1BQU0sS0FBSyxVQUFVLGNBQWMsTUFBTSxPQUFPO0FBQ2hFLFFBQUksU0FBUztBQUNYLGFBQU8sY0FBYyxPQUFPO0FBQUEsSUFDOUI7QUFDQSxXQUFPO0FBQUEsRUFDVDtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFNQSxNQUFNLFVBQ0osY0FDQSxNQUNBLFNBQ3FCO0FBQ3JCLFVBQU0sT0FBTyxRQUFRO0FBQ3JCLFVBQU0saUJBQWlCLFNBQVMsVUFBVSxXQUFXO0FBRXJELFdBQU8sS0FBSyxXQUFXLEtBQUssSUFBSTtBQUNoQyxV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
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { RootConfig } from '@blinkk/root';
|
|
2
|
+
import { Query } from 'firebase-admin/firestore';
|
|
3
|
+
import { CMSPlugin } from './plugin.js';
|
|
4
|
+
import 'firebase-admin/app';
|
|
5
|
+
import 'firebase-admin/auth';
|
|
6
|
+
|
|
7
|
+
interface Doc<Fields = any> {
|
|
8
|
+
/** The id of the doc, e.g. "Pages/foo-bar". */
|
|
9
|
+
id: string;
|
|
10
|
+
/** The collection id of the doc, e.g. "Pages". */
|
|
11
|
+
collectionId: string;
|
|
12
|
+
/** The slug of the doc, e.g. "foo-bar". */
|
|
13
|
+
slug: string;
|
|
14
|
+
sys: {
|
|
15
|
+
createdAt: number;
|
|
16
|
+
createdBy: string;
|
|
17
|
+
modifiedAt: number;
|
|
18
|
+
modifiedBy: string;
|
|
19
|
+
firstPublishedAt?: number;
|
|
20
|
+
firstPublishedBy?: string;
|
|
21
|
+
publishedAt?: number;
|
|
22
|
+
publishedBy?: string;
|
|
23
|
+
locales?: string[];
|
|
24
|
+
};
|
|
25
|
+
fields: Fields;
|
|
26
|
+
}
|
|
27
|
+
type DocMode = 'draft' | 'published';
|
|
28
|
+
interface GetDocOptions {
|
|
29
|
+
/** Mode, either "draft" or "published". */
|
|
30
|
+
mode: DocMode;
|
|
31
|
+
}
|
|
32
|
+
interface SetDocOptions {
|
|
33
|
+
/** Mode, either "draft" or "published". */
|
|
34
|
+
mode: DocMode;
|
|
35
|
+
/**
|
|
36
|
+
* Email of user modifying the doc. If blank, defaults to `root-cms-client`.
|
|
37
|
+
*/
|
|
38
|
+
modifiedBy?: string;
|
|
39
|
+
}
|
|
40
|
+
interface ListDocsOptions {
|
|
41
|
+
mode: DocMode;
|
|
42
|
+
offset?: number;
|
|
43
|
+
limit?: number;
|
|
44
|
+
orderBy?: string;
|
|
45
|
+
orderByDirection?: 'asc' | 'desc';
|
|
46
|
+
query?: (query: Query) => Query;
|
|
47
|
+
}
|
|
48
|
+
interface GetCountOptions {
|
|
49
|
+
mode: DocMode;
|
|
50
|
+
query?: (query: Query) => Query;
|
|
51
|
+
}
|
|
52
|
+
interface Translation {
|
|
53
|
+
[locale: string]: string;
|
|
54
|
+
source: string;
|
|
55
|
+
}
|
|
56
|
+
interface TranslationsMap {
|
|
57
|
+
[hash: string]: Translation;
|
|
58
|
+
}
|
|
59
|
+
interface LocaleTranslations {
|
|
60
|
+
[source: string]: string;
|
|
61
|
+
}
|
|
62
|
+
interface LoadTranslationsOptions {
|
|
63
|
+
tags?: string[];
|
|
64
|
+
}
|
|
65
|
+
declare class RootCMSClient {
|
|
66
|
+
private readonly rootConfig;
|
|
67
|
+
private readonly cmsPlugin;
|
|
68
|
+
private readonly projectId;
|
|
69
|
+
private readonly app;
|
|
70
|
+
private readonly db;
|
|
71
|
+
constructor(rootConfig: RootConfig);
|
|
72
|
+
/**
|
|
73
|
+
* Retrieves doc data from Root.js CMS.
|
|
74
|
+
*/
|
|
75
|
+
getDoc<Fields = any>(collectionId: string, slug: string, options: GetDocOptions): Promise<Doc<Fields> | null>;
|
|
76
|
+
/**
|
|
77
|
+
* Retrieves raw doc data as stored in the database. Only use this if you know
|
|
78
|
+
* what you are doing.
|
|
79
|
+
*/
|
|
80
|
+
getRawDoc(collectionId: string, slug: string, options: GetDocOptions): Promise<any | null>;
|
|
81
|
+
setRawDoc(collectionId: string, slug: string, data: any, options: SetDocOptions): Promise<void>;
|
|
82
|
+
/**
|
|
83
|
+
* Lists docs from a Root.js CMS collection.
|
|
84
|
+
*/
|
|
85
|
+
listDocs<T>(collectionId: string, options: ListDocsOptions): Promise<{
|
|
86
|
+
docs: T[];
|
|
87
|
+
}>;
|
|
88
|
+
/**
|
|
89
|
+
* Returns the number of docs in a Root.js CMS collection.
|
|
90
|
+
*/
|
|
91
|
+
getDocsCount(collectionId: string, options: GetCountOptions): Promise<number>;
|
|
92
|
+
/**
|
|
93
|
+
* Publishes scheduled docs.
|
|
94
|
+
*/
|
|
95
|
+
publishScheduledDocs(): Promise<any[]>;
|
|
96
|
+
/**
|
|
97
|
+
* Loads translations saved in the translations collection, optionally
|
|
98
|
+
* filtered by tag.
|
|
99
|
+
*
|
|
100
|
+
* Returns a map like:
|
|
101
|
+
* ```
|
|
102
|
+
* {
|
|
103
|
+
* "<hash>": {"source": "Hello", "es": "Hola", "fr": "Bonjour"},
|
|
104
|
+
* }
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
107
|
+
loadTranslations(options?: LoadTranslationsOptions): Promise<TranslationsMap>;
|
|
108
|
+
/**
|
|
109
|
+
* Saves a map of translations, e.g.:
|
|
110
|
+
* ```
|
|
111
|
+
* await client.saveTranslations({
|
|
112
|
+
* "Hello": {"es": "Hola", "fr": "Bonjour"},
|
|
113
|
+
* });
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
116
|
+
saveTranslations(translations: {
|
|
117
|
+
[source: string]: {
|
|
118
|
+
[locale: string]: string;
|
|
119
|
+
};
|
|
120
|
+
}, tags?: string[]): Promise<void>;
|
|
121
|
+
/**
|
|
122
|
+
* Returns the "key" used for a translation as stored in the db. Translations
|
|
123
|
+
* are stored under `Projects/<project id>/Translations/<sha1 hash>`.
|
|
124
|
+
*/
|
|
125
|
+
getTranslationKey(source: string): string;
|
|
126
|
+
/**
|
|
127
|
+
* Cleans a string that's used for translations. Performs the following:
|
|
128
|
+
* - Removes any leading/trailing whitespace
|
|
129
|
+
* - Removes spaces at the end of any line
|
|
130
|
+
*/
|
|
131
|
+
normalizeString(str: string): string;
|
|
132
|
+
/**
|
|
133
|
+
* Loads translations for a particular locale.
|
|
134
|
+
*
|
|
135
|
+
* Returns a map like:
|
|
136
|
+
* ```
|
|
137
|
+
* {
|
|
138
|
+
* "Hello": "Bonjour",
|
|
139
|
+
* }
|
|
140
|
+
* ```
|
|
141
|
+
*/
|
|
142
|
+
loadTranslationsForLocale(locale: string, options?: LoadTranslationsOptions): Promise<LocaleTranslations>;
|
|
143
|
+
}
|
|
144
|
+
declare function getCmsPlugin(rootConfig: RootConfig): CMSPlugin;
|
|
145
|
+
/**
|
|
146
|
+
* Walks the data tree and converts any Timestamp objects to millis and any
|
|
147
|
+
* _array maps to normal arrays.
|
|
148
|
+
*
|
|
149
|
+
* E.g.:
|
|
150
|
+
*
|
|
151
|
+
* normalizeData({
|
|
152
|
+
* sys: {modifiedAt: Timestamp(123)},
|
|
153
|
+
* fields: {
|
|
154
|
+
* _array: ['asdf'],
|
|
155
|
+
* asdf: {title: 'hello'}
|
|
156
|
+
* }
|
|
157
|
+
* })
|
|
158
|
+
* // => {sys: {modifiedAt: 123}, fields: {foo: [{title: 'hello'}]}}
|
|
159
|
+
*/
|
|
160
|
+
declare function unmarshalData(data: any): any;
|
|
161
|
+
/** @deprecated Use `unmarshalData()` instead. */
|
|
162
|
+
declare function normalizeData(data: any): any;
|
|
163
|
+
interface ArrayObject {
|
|
164
|
+
[key: string]: any;
|
|
165
|
+
_array: string[];
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Serializes an array into an `ArrayObject`, e.g.:
|
|
169
|
+
*
|
|
170
|
+
* ```
|
|
171
|
+
* marshalArray([1, 2, 3])
|
|
172
|
+
* // => {a: 1, b: 2, c: 3, _array: ['a', 'b', 'c']}
|
|
173
|
+
* ```
|
|
174
|
+
*
|
|
175
|
+
* This database storage method makes it easier to update a single field in a
|
|
176
|
+
* deeply nested array object.
|
|
177
|
+
*/
|
|
178
|
+
declare function marshalArray(arr: any[]): ArrayObject;
|
|
179
|
+
/**
|
|
180
|
+
* Converts an `ArrayObject` to a normal array.
|
|
181
|
+
*/
|
|
182
|
+
declare function unmarshalArray(arrObject: ArrayObject): any[];
|
|
183
|
+
/**
|
|
184
|
+
* Converts a translations map from `loadTranslations()` to a map of source to
|
|
185
|
+
* translated string for a particular locale.
|
|
186
|
+
*
|
|
187
|
+
* Returns a map like:
|
|
188
|
+
* ```
|
|
189
|
+
* {
|
|
190
|
+
* "Hello": "Bonjour",
|
|
191
|
+
* }
|
|
192
|
+
* ```
|
|
193
|
+
*/
|
|
194
|
+
declare function translationsForLocale(translationsMap: TranslationsMap, locale: string): LocaleTranslations;
|
|
195
|
+
|
|
196
|
+
export { ArrayObject, Doc, DocMode, GetCountOptions, GetDocOptions, ListDocsOptions, LoadTranslationsOptions, LocaleTranslations, RootCMSClient, SetDocOptions, Translation, TranslationsMap, getCmsPlugin, marshalArray, normalizeData, translationsForLocale, unmarshalArray, unmarshalData };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { LoadTranslationsOptions, TranslationsMap, LocaleTranslations } from './client.js';
|
|
2
|
+
export { ArrayObject, Doc, DocMode, GetCountOptions, GetDocOptions, ListDocsOptions, RootCMSClient, SetDocOptions, Translation, getCmsPlugin, marshalArray, normalizeData, translationsForLocale, unmarshalArray, unmarshalData } from './client.js';
|
|
3
|
+
import { RootConfig } from '@blinkk/root';
|
|
4
|
+
import { Query } from 'firebase-admin/firestore';
|
|
5
|
+
export { s as schema } from '../schema-710fda8a.js';
|
|
6
|
+
import './plugin.js';
|
|
7
|
+
import 'firebase-admin/app';
|
|
8
|
+
import 'firebase-admin/auth';
|
|
9
|
+
import 'preact';
|
|
10
|
+
|
|
11
|
+
/** @deprecated Use client.ts instead. */
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Retrieves a doc from Root.js CMS.
|
|
15
|
+
* @deprecated Use RootCMSClient.getDoc() instead.
|
|
16
|
+
*/
|
|
17
|
+
declare function getDoc<T>(rootConfig: RootConfig, collectionId: string, slug: string, options: {
|
|
18
|
+
mode: 'draft' | 'published';
|
|
19
|
+
}): Promise<T | null>;
|
|
20
|
+
/**
|
|
21
|
+
* Lists docs from a Root.js CMS collection.
|
|
22
|
+
* @deprecated Use RootCMSClient.listDocs() instead.
|
|
23
|
+
*/
|
|
24
|
+
declare function listDocs<T>(rootConfig: RootConfig, collectionId: string, options: {
|
|
25
|
+
mode: 'draft' | 'published';
|
|
26
|
+
offset?: number;
|
|
27
|
+
limit?: number;
|
|
28
|
+
orderBy?: string;
|
|
29
|
+
orderByDirection?: 'asc' | 'desc';
|
|
30
|
+
query?: (query: Query) => Query;
|
|
31
|
+
}): Promise<{
|
|
32
|
+
docs: T[];
|
|
33
|
+
}>;
|
|
34
|
+
/**
|
|
35
|
+
* Returns the number of docs in a Root.js CMS collection.
|
|
36
|
+
* @deprecated Use RootCMSClient.getDocsCount() instead.
|
|
37
|
+
*/
|
|
38
|
+
declare function numDocs(rootConfig: RootConfig, collectionId: string, options: {
|
|
39
|
+
mode: 'draft' | 'published';
|
|
40
|
+
query?: (query: Query) => Query;
|
|
41
|
+
}): Promise<number>;
|
|
42
|
+
/**
|
|
43
|
+
* Publishes scheduled docs.
|
|
44
|
+
* @deprecated Use RootCMSClient.publishScheduledDocs() instead.
|
|
45
|
+
*/
|
|
46
|
+
declare function publishScheduledDocs(rootConfig: RootConfig): Promise<any[]>;
|
|
47
|
+
/**
|
|
48
|
+
* @deprecated Use `RootCMSClient.loadTranslations()`.
|
|
49
|
+
*/
|
|
50
|
+
declare function loadTranslations(rootConfig: RootConfig, options?: LoadTranslationsOptions): Promise<TranslationsMap>;
|
|
51
|
+
/**
|
|
52
|
+
* @deprecated Use `RootCMSClient.loadTranslationsForLocale()`.
|
|
53
|
+
*/
|
|
54
|
+
declare function loadTranslationsForLocale(rootConfig: RootConfig, locale: string, options?: LoadTranslationsOptions): Promise<LocaleTranslations>;
|
|
55
|
+
|
|
56
|
+
export { LoadTranslationsOptions, LocaleTranslations, TranslationsMap, getDoc, listDocs, loadTranslations, loadTranslationsForLocale, numDocs, publishScheduledDocs };
|