@stackbit/cms-core 0.1.3 → 0.1.4-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/common/common-types.d.ts +1 -9
- package/dist/common/common-types.d.ts.map +1 -1
- package/dist/consts.d.ts +1 -24
- package/dist/consts.d.ts.map +1 -1
- package/dist/consts.js +5 -25
- package/dist/consts.js.map +1 -1
- package/dist/content-store-types.d.ts +42 -39
- package/dist/content-store-types.d.ts.map +1 -1
- package/dist/content-store-utils.d.ts +10 -0
- package/dist/content-store-utils.d.ts.map +1 -0
- package/dist/content-store-utils.js +139 -0
- package/dist/content-store-utils.js.map +1 -0
- package/dist/content-store.d.ts +18 -5
- package/dist/content-store.d.ts.map +1 -1
- package/dist/content-store.js +177 -962
- package/dist/content-store.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/types/search-filter.d.ts +42 -0
- package/dist/types/search-filter.d.ts.map +1 -0
- package/dist/types/search-filter.js +3 -0
- package/dist/types/search-filter.js.map +1 -0
- package/dist/utils/create-update-csi-docs.d.ts +69 -0
- package/dist/utils/create-update-csi-docs.d.ts.map +1 -0
- package/dist/utils/create-update-csi-docs.js +386 -0
- package/dist/utils/create-update-csi-docs.js.map +1 -0
- package/dist/utils/csi-to-store-docs-converter.d.ts +15 -0
- package/dist/utils/csi-to-store-docs-converter.d.ts.map +1 -0
- package/dist/utils/csi-to-store-docs-converter.js +287 -0
- package/dist/utils/csi-to-store-docs-converter.js.map +1 -0
- package/dist/utils/search-utils.d.ts +21 -0
- package/dist/utils/search-utils.d.ts.map +1 -0
- package/dist/utils/search-utils.js +323 -0
- package/dist/utils/search-utils.js.map +1 -0
- package/dist/utils/store-to-api-docs-converter.d.ts +5 -0
- package/dist/utils/store-to-api-docs-converter.d.ts.map +1 -0
- package/dist/utils/store-to-api-docs-converter.js +247 -0
- package/dist/utils/store-to-api-docs-converter.js.map +1 -0
- package/package.json +7 -5
- package/src/common/common-types.ts +1 -10
- package/src/consts.ts +1 -26
- package/src/content-store-types.ts +59 -45
- package/src/content-store-utils.ts +150 -0
- package/src/content-store.ts +168 -1090
- package/src/index.ts +3 -2
- package/src/types/search-filter.ts +53 -0
- package/src/utils/create-update-csi-docs.ts +457 -0
- package/src/utils/csi-to-store-docs-converter.ts +366 -0
- package/src/utils/search-utils.ts +437 -0
- package/src/utils/store-to-api-docs-converter.ts +246 -0
- package/dist/content-source-interface.d.ts +0 -338
- package/dist/content-source-interface.d.ts.map +0 -1
- package/dist/content-source-interface.js +0 -28
- package/dist/content-source-interface.js.map +0 -1
- package/src/content-source-interface.ts +0 -495
package/dist/content-store.js
CHANGED
|
@@ -3,16 +3,19 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.ContentStore = void 0;
|
|
7
7
|
const lodash_1 = __importDefault(require("lodash"));
|
|
8
|
-
const slugify_1 = __importDefault(require("slugify"));
|
|
9
8
|
const path_1 = __importDefault(require("path"));
|
|
10
9
|
const sanitize_filename_1 = __importDefault(require("sanitize-filename"));
|
|
10
|
+
const types_1 = require("@stackbit/types");
|
|
11
11
|
const sdk_1 = require("@stackbit/sdk");
|
|
12
12
|
const utils_1 = require("@stackbit/utils");
|
|
13
|
-
const content_source_interface_1 = require("./content-source-interface");
|
|
14
|
-
const common_schema_1 = require("./common/common-schema");
|
|
15
13
|
const timer_1 = require("./utils/timer");
|
|
14
|
+
const search_utils_1 = require("./utils/search-utils");
|
|
15
|
+
const csi_to_store_docs_converter_1 = require("./utils/csi-to-store-docs-converter");
|
|
16
|
+
const content_store_utils_1 = require("./content-store-utils");
|
|
17
|
+
const store_to_api_docs_converter_1 = require("./utils/store-to-api-docs-converter");
|
|
18
|
+
const create_update_csi_docs_1 = require("./utils/create-update-csi-docs");
|
|
16
19
|
class ContentStore {
|
|
17
20
|
constructor(options) {
|
|
18
21
|
this.contentSources = [];
|
|
@@ -40,7 +43,7 @@ class ContentStore {
|
|
|
40
43
|
thisArg: this,
|
|
41
44
|
// Group the deferred calls by content source ID.
|
|
42
45
|
groupResolver: ({ contentSourceInstance }) => {
|
|
43
|
-
return getContentSourceIdForContentSource(contentSourceInstance);
|
|
46
|
+
return (0, content_store_utils_1.getContentSourceIdForContentSource)(contentSourceInstance);
|
|
44
47
|
},
|
|
45
48
|
// When the loadContentSourceData call is called multiple times with
|
|
46
49
|
// different "init" values, ensure that the deferred call will be
|
|
@@ -145,9 +148,9 @@ class ContentStore {
|
|
|
145
148
|
deletedAssets: []
|
|
146
149
|
};
|
|
147
150
|
for (const contentSourceInstance of this.contentSources) {
|
|
148
|
-
const contentSourceId = getContentSourceIdForContentSource(contentSourceInstance);
|
|
151
|
+
const contentSourceId = (0, content_store_utils_1.getContentSourceIdForContentSource)(contentSourceInstance);
|
|
149
152
|
this.logger.debug(`call onFilesChange for contentSource: ${contentSourceId}`);
|
|
150
|
-
const { schemaChanged, contentChangeEvent } = (_b = (_a = contentSourceInstance.onFilesChange) === null || _a === void 0 ? void 0 : _a.call(contentSourceInstance, { updatedFiles: updatedFiles })) !== null && _b !== void 0 ? _b : {};
|
|
153
|
+
const { schemaChanged, contentChangeEvent } = (_b = (await ((_a = contentSourceInstance.onFilesChange) === null || _a === void 0 ? void 0 : _a.call(contentSourceInstance, { updatedFiles: updatedFiles })))) !== null && _b !== void 0 ? _b : {};
|
|
151
154
|
this.logger.debug(`schemaChanged: ${schemaChanged}, has contentChangeEvent: ${!!contentChangeEvent}`);
|
|
152
155
|
// if schema is changed, there is no need to return contentChanges
|
|
153
156
|
// because schema changes reloads everything and implies content changes
|
|
@@ -185,8 +188,8 @@ class ContentStore {
|
|
|
185
188
|
this.contentUpdatesWatchTimer.startTimer();
|
|
186
189
|
}
|
|
187
190
|
async loadContentSourceData({ contentSourceInstance, init }) {
|
|
188
|
-
var _a, _b, _c, _d;
|
|
189
|
-
const contentSourceId = getContentSourceIdForContentSource(contentSourceInstance);
|
|
191
|
+
var _a, _b, _c, _d, _e;
|
|
192
|
+
const contentSourceId = (0, content_store_utils_1.getContentSourceIdForContentSource)(contentSourceInstance);
|
|
190
193
|
this.logger.debug('loadContentSourceData', { contentSourceId, init });
|
|
191
194
|
if (init) {
|
|
192
195
|
await contentSourceInstance.init({
|
|
@@ -206,7 +209,8 @@ class ContentStore {
|
|
|
206
209
|
const locales = await (contentSourceInstance === null || contentSourceInstance === void 0 ? void 0 : contentSourceInstance.getLocales());
|
|
207
210
|
const defaultLocaleCode = (_a = locales === null || locales === void 0 ? void 0 : locales.find((locale) => locale.default)) === null || _a === void 0 ? void 0 : _a.code;
|
|
208
211
|
// for older versions of stackbit, it uses models to extend content source models
|
|
209
|
-
let
|
|
212
|
+
let modelsNoImage = [];
|
|
213
|
+
let imageModel;
|
|
210
214
|
if (this.rawStackbitConfig) {
|
|
211
215
|
const result = await (0, sdk_1.extendConfig)({
|
|
212
216
|
config: this.rawStackbitConfig,
|
|
@@ -216,32 +220,57 @@ class ContentStore {
|
|
|
216
220
|
this.userLogger.warn(error.message);
|
|
217
221
|
}
|
|
218
222
|
const config = await this.handleConfigAssets(result.config);
|
|
219
|
-
|
|
223
|
+
const modelsWithImageModel = (_c = config === null || config === void 0 ? void 0 : config.models) !== null && _c !== void 0 ? _c : [];
|
|
224
|
+
const imageModelIndex = modelsWithImageModel.findIndex((model) => (0, sdk_1.isImageModel)(model));
|
|
225
|
+
if (imageModelIndex > -1) {
|
|
226
|
+
imageModel = modelsWithImageModel[imageModelIndex];
|
|
227
|
+
modelsWithImageModel.splice(imageModelIndex, 1);
|
|
228
|
+
}
|
|
229
|
+
modelsNoImage = modelsWithImageModel;
|
|
220
230
|
// TODO: load presets externally from config, and create additional map
|
|
221
231
|
// that maps presetIds by model name instead of storing that map inside every model
|
|
222
|
-
//
|
|
223
|
-
this.presets = config === null || config === void 0 ? void 0 : config.presets
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
232
|
+
// Augment presets with srcType and srcProjectId if they don't exist
|
|
233
|
+
this.presets = lodash_1.default.reduce(Object.keys((_d = config === null || config === void 0 ? void 0 : config.presets) !== null && _d !== void 0 ? _d : {}), (accum, presetId) => {
|
|
234
|
+
var _a, _b, _c;
|
|
235
|
+
const preset = (_a = config === null || config === void 0 ? void 0 : config.presets) === null || _a === void 0 ? void 0 : _a[presetId];
|
|
236
|
+
lodash_1.default.set(accum, [presetId], {
|
|
237
|
+
...preset,
|
|
238
|
+
srcType: (_b = preset === null || preset === void 0 ? void 0 : preset.srcType) !== null && _b !== void 0 ? _b : contentSourceInstance.getContentSourceType(),
|
|
239
|
+
srcProjectId: (_c = preset === null || preset === void 0 ? void 0 : preset.srcProjectId) !== null && _c !== void 0 ? _c : contentSourceInstance.getProjectId()
|
|
240
|
+
});
|
|
241
|
+
return accum;
|
|
242
|
+
}, {});
|
|
243
|
+
}
|
|
244
|
+
if ((_e = this.rawStackbitConfig) === null || _e === void 0 ? void 0 : _e.mapModels) {
|
|
245
|
+
const srcType = contentSourceInstance.getContentSourceType();
|
|
246
|
+
const srcProjectId = contentSourceInstance.getProjectId();
|
|
247
|
+
const modelsWithSource = modelsNoImage.map((model) => ({
|
|
248
|
+
srcType,
|
|
249
|
+
srcProjectId,
|
|
250
|
+
...model
|
|
251
|
+
}));
|
|
252
|
+
const mappedModels = this.rawStackbitConfig.mapModels({
|
|
253
|
+
models: modelsWithSource
|
|
254
|
+
});
|
|
255
|
+
modelsNoImage = mappedModels.map((model) => {
|
|
256
|
+
const { srcType, srcProjectId, ...rest } = model;
|
|
257
|
+
return rest;
|
|
230
258
|
});
|
|
231
259
|
}
|
|
260
|
+
const models = imageModel ? [...modelsNoImage, imageModel] : modelsNoImage;
|
|
232
261
|
const modelMap = lodash_1.default.keyBy(models, 'name');
|
|
233
|
-
const
|
|
262
|
+
const csiModelMap = lodash_1.default.keyBy(csiModels, 'name');
|
|
263
|
+
const csiDocuments = await contentSourceInstance.getDocuments({ modelMap: csiModelMap });
|
|
234
264
|
const csiAssets = await contentSourceInstance.getAssets();
|
|
235
265
|
const csiDocumentMap = lodash_1.default.keyBy(csiDocuments, 'id');
|
|
236
266
|
const csiAssetMap = lodash_1.default.keyBy(csiAssets, 'id');
|
|
237
|
-
const
|
|
238
|
-
const contentStoreDocuments = mapCSIDocumentsToStoreDocuments({
|
|
267
|
+
const contentStoreDocuments = (0, csi_to_store_docs_converter_1.mapCSIDocumentsToStoreDocuments)({
|
|
239
268
|
csiDocuments,
|
|
240
269
|
contentSourceInstance,
|
|
241
270
|
modelMap,
|
|
242
271
|
defaultLocaleCode
|
|
243
272
|
});
|
|
244
|
-
const contentStoreAssets = mapCSIAssetsToStoreAssets({
|
|
273
|
+
const contentStoreAssets = (0, csi_to_store_docs_converter_1.mapCSIAssetsToStoreAssets)({
|
|
245
274
|
csiAssets,
|
|
246
275
|
contentSourceInstance,
|
|
247
276
|
defaultLocaleCode
|
|
@@ -353,13 +382,13 @@ class ContentStore {
|
|
|
353
382
|
});
|
|
354
383
|
});
|
|
355
384
|
// map csi documents and assets to content store documents and assets
|
|
356
|
-
const documents = mapCSIDocumentsToStoreDocuments({
|
|
385
|
+
const documents = (0, csi_to_store_docs_converter_1.mapCSIDocumentsToStoreDocuments)({
|
|
357
386
|
csiDocuments: contentChangeEvent.documents,
|
|
358
387
|
contentSourceInstance: contentSourceData.instance,
|
|
359
388
|
modelMap: contentSourceData.modelMap,
|
|
360
389
|
defaultLocaleCode: contentSourceData.defaultLocaleCode
|
|
361
390
|
});
|
|
362
|
-
const assets = mapCSIAssetsToStoreAssets({
|
|
391
|
+
const assets = (0, csi_to_store_docs_converter_1.mapCSIAssetsToStoreAssets)({
|
|
363
392
|
csiAssets: contentChangeEvent.assets,
|
|
364
393
|
contentSourceInstance: contentSourceData.instance,
|
|
365
394
|
defaultLocaleCode: contentSourceData.defaultLocaleCode
|
|
@@ -431,25 +460,56 @@ class ContentStore {
|
|
|
431
460
|
return (_a = this.presets) !== null && _a !== void 0 ? _a : {};
|
|
432
461
|
}
|
|
433
462
|
getContentSourceEnvironment({ srcProjectId, srcType }) {
|
|
434
|
-
const contentSourceId = getContentSourceId(srcType, srcProjectId);
|
|
463
|
+
const contentSourceId = (0, content_store_utils_1.getContentSourceId)(srcType, srcProjectId);
|
|
435
464
|
const contentSourceData = this.getContentSourceDataByIdOrThrow(contentSourceId);
|
|
436
465
|
return contentSourceData.instance.getProjectEnvironment();
|
|
437
466
|
}
|
|
438
|
-
hasAccess({ srcType, srcProjectId, user }) {
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
467
|
+
async hasAccess({ srcType, srcProjectId, user }) {
|
|
468
|
+
let contentSourceDataArr;
|
|
469
|
+
if (srcType && srcProjectId) {
|
|
470
|
+
const contentSourceId = (0, content_store_utils_1.getContentSourceId)(srcType, srcProjectId);
|
|
471
|
+
const contentSourceData = this.getContentSourceDataByIdOrThrow(contentSourceId);
|
|
472
|
+
contentSourceDataArr = [contentSourceData];
|
|
473
|
+
}
|
|
474
|
+
else {
|
|
475
|
+
contentSourceDataArr = Object.values(this.contentSourceDataById);
|
|
476
|
+
}
|
|
477
|
+
return (0, utils_1.reducePromise)(contentSourceDataArr, async (accum, contentSourceData) => {
|
|
478
|
+
const srcType = contentSourceData.type;
|
|
479
|
+
const srcProjectId = contentSourceData.projectId;
|
|
480
|
+
const userContext = (0, content_store_utils_1.getUserContextForSrcType)(srcType, user);
|
|
481
|
+
let result = await contentSourceData.instance.hasAccess({ userContext });
|
|
482
|
+
// backwards compatibility with older CSI version
|
|
483
|
+
if (typeof result === 'boolean') {
|
|
484
|
+
result = {
|
|
485
|
+
hasConnection: result,
|
|
486
|
+
hasPermissions: result
|
|
487
|
+
};
|
|
488
|
+
}
|
|
489
|
+
return {
|
|
490
|
+
hasConnection: accum.hasConnection && result.hasConnection,
|
|
491
|
+
hasPermissions: accum.hasPermissions && result.hasPermissions,
|
|
492
|
+
contentSources: accum.contentSources.concat({
|
|
493
|
+
srcType,
|
|
494
|
+
srcProjectId,
|
|
495
|
+
...result
|
|
496
|
+
})
|
|
497
|
+
};
|
|
498
|
+
}, {
|
|
499
|
+
hasConnection: true,
|
|
500
|
+
hasPermissions: true,
|
|
501
|
+
contentSources: []
|
|
502
|
+
});
|
|
443
503
|
}
|
|
444
504
|
hasChanges({ srcType, srcProjectId, documents }) {
|
|
445
505
|
let result;
|
|
446
506
|
if (srcType && srcProjectId) {
|
|
447
|
-
const contentSourceId = getContentSourceId(srcType, srcProjectId);
|
|
507
|
+
const contentSourceId = (0, content_store_utils_1.getContentSourceId)(srcType, srcProjectId);
|
|
448
508
|
const contentSourceData = this.getContentSourceDataByIdOrThrow(contentSourceId);
|
|
449
509
|
result = [...contentSourceData.documents, ...contentSourceData.assets];
|
|
450
510
|
}
|
|
451
511
|
else if (documents && documents.length > 0) {
|
|
452
|
-
const documentsBySourceId = lodash_1.default.groupBy(documents, (document) => getContentSourceId(document.srcType, document.srcProjectId));
|
|
512
|
+
const documentsBySourceId = lodash_1.default.groupBy(documents, (document) => (0, content_store_utils_1.getContentSourceId)(document.srcType, document.srcProjectId));
|
|
453
513
|
result = lodash_1.default.reduce(documentsBySourceId, (result, documents, contentSourceId) => {
|
|
454
514
|
const contentSourceData = this.getContentSourceDataByIdOrThrow(contentSourceId);
|
|
455
515
|
for (const document of documents) {
|
|
@@ -479,7 +539,7 @@ class ContentStore {
|
|
|
479
539
|
};
|
|
480
540
|
}
|
|
481
541
|
getDocument({ srcDocumentId, srcProjectId, srcType }) {
|
|
482
|
-
const contentSourceId = getContentSourceId(srcType, srcProjectId);
|
|
542
|
+
const contentSourceId = (0, content_store_utils_1.getContentSourceId)(srcType, srcProjectId);
|
|
483
543
|
const contentSourceData = this.getContentSourceDataByIdOrThrow(contentSourceId);
|
|
484
544
|
return contentSourceData.documentMap[srcDocumentId];
|
|
485
545
|
}
|
|
@@ -489,7 +549,7 @@ class ContentStore {
|
|
|
489
549
|
}, []);
|
|
490
550
|
}
|
|
491
551
|
getAsset({ srcAssetId, srcProjectId, srcType }) {
|
|
492
|
-
const contentSourceId = getContentSourceId(srcType, srcProjectId);
|
|
552
|
+
const contentSourceId = (0, content_store_utils_1.getContentSourceId)(srcType, srcProjectId);
|
|
493
553
|
const contentSourceData = this.getContentSourceDataByIdOrThrow(contentSourceId);
|
|
494
554
|
return contentSourceData.assetMap[srcAssetId];
|
|
495
555
|
}
|
|
@@ -501,21 +561,21 @@ class ContentStore {
|
|
|
501
561
|
getLocalizedApiObjects({ locale }) {
|
|
502
562
|
return lodash_1.default.reduce(this.contentSourceDataById, (objects, contentSourceData) => {
|
|
503
563
|
locale = locale !== null && locale !== void 0 ? locale : contentSourceData.defaultLocaleCode;
|
|
504
|
-
const documentObjects = mapDocumentsToLocalizedApiObjects(contentSourceData.documents, locale);
|
|
505
|
-
const imageObjects = mapAssetsToLocalizedApiImages(contentSourceData.assets, locale);
|
|
564
|
+
const documentObjects = (0, store_to_api_docs_converter_1.mapDocumentsToLocalizedApiObjects)(contentSourceData.documents, locale);
|
|
565
|
+
const imageObjects = (0, store_to_api_docs_converter_1.mapAssetsToLocalizedApiImages)(contentSourceData.assets, locale);
|
|
506
566
|
return objects.concat(documentObjects, imageObjects);
|
|
507
567
|
}, []);
|
|
508
568
|
}
|
|
509
569
|
getApiAssets({ srcType, srcProjectId, pageSize = 20, pageNum = 1, searchQuery } = {}) {
|
|
510
570
|
let assets;
|
|
511
571
|
if (srcProjectId && srcType) {
|
|
512
|
-
const contentSourceId = getContentSourceId(srcType, srcProjectId);
|
|
572
|
+
const contentSourceId = (0, content_store_utils_1.getContentSourceId)(srcType, srcProjectId);
|
|
513
573
|
const contentSourceData = this.getContentSourceDataByIdOrThrow(contentSourceId);
|
|
514
|
-
assets = mapStoreAssetsToAPIAssets(contentSourceData.assets, contentSourceData.defaultLocaleCode);
|
|
574
|
+
assets = (0, store_to_api_docs_converter_1.mapStoreAssetsToAPIAssets)(contentSourceData.assets, contentSourceData.defaultLocaleCode);
|
|
515
575
|
}
|
|
516
576
|
else {
|
|
517
577
|
assets = lodash_1.default.reduce(this.contentSourceDataById, (result, contentSourceData) => {
|
|
518
|
-
const assets = mapStoreAssetsToAPIAssets(contentSourceData.assets, contentSourceData.defaultLocaleCode);
|
|
578
|
+
const assets = (0, store_to_api_docs_converter_1.mapStoreAssetsToAPIAssets)(contentSourceData.assets, contentSourceData.defaultLocaleCode);
|
|
519
579
|
return result.concat(assets);
|
|
520
580
|
}, []);
|
|
521
581
|
}
|
|
@@ -537,7 +597,7 @@ class ContentStore {
|
|
|
537
597
|
}
|
|
538
598
|
async createAndLinkDocument({ srcType, srcProjectId, srcDocumentId, fieldPath, modelName, object, index, locale, user }) {
|
|
539
599
|
this.logger.debug('createAndLinkDocument', { srcType, srcProjectId, srcDocumentId, fieldPath, modelName, index, locale });
|
|
540
|
-
const contentSourceId = getContentSourceId(srcType, srcProjectId);
|
|
600
|
+
const contentSourceId = (0, content_store_utils_1.getContentSourceId)(srcType, srcProjectId);
|
|
541
601
|
const contentSourceData = this.getContentSourceDataByIdOrThrow(contentSourceId);
|
|
542
602
|
// get the document that is being updated
|
|
543
603
|
const document = contentSourceData.documentMap[srcDocumentId];
|
|
@@ -554,7 +614,7 @@ class ContentStore {
|
|
|
554
614
|
}
|
|
555
615
|
// get the 'reference' model field in the updated document that will be used to link the new document
|
|
556
616
|
locale = locale !== null && locale !== void 0 ? locale : contentSourceData.defaultLocaleCode;
|
|
557
|
-
const modelField = getModelFieldForFieldAtPath(document, model, fieldPath, csiModelMap, locale);
|
|
617
|
+
const modelField = (0, content_store_utils_1.getModelFieldForFieldAtPath)(document, model, fieldPath, csiModelMap, locale);
|
|
558
618
|
if (!modelField) {
|
|
559
619
|
throw Error(`the "fieldPath" points to non existing model field: ${fieldPath.join('.')}`);
|
|
560
620
|
}
|
|
@@ -579,7 +639,7 @@ class ContentStore {
|
|
|
579
639
|
user: user
|
|
580
640
|
});
|
|
581
641
|
// update the document by linking the field to the created document
|
|
582
|
-
const userContext = getUserContextForSrcType(srcType, user);
|
|
642
|
+
const userContext = (0, content_store_utils_1.getUserContextForSrcType)(srcType, user);
|
|
583
643
|
const field = {
|
|
584
644
|
type: 'reference',
|
|
585
645
|
refType: 'document',
|
|
@@ -613,7 +673,7 @@ class ContentStore {
|
|
|
613
673
|
async uploadAndLinkAsset({ srcType, srcProjectId, srcDocumentId, fieldPath, asset, index, locale, user }) {
|
|
614
674
|
this.logger.debug('uploadAndLinkAsset', { srcType, srcProjectId, srcDocumentId, fieldPath, index, locale });
|
|
615
675
|
// get the document that is being updated
|
|
616
|
-
const contentSourceId = getContentSourceId(srcType, srcProjectId);
|
|
676
|
+
const contentSourceId = (0, content_store_utils_1.getContentSourceId)(srcType, srcProjectId);
|
|
617
677
|
const contentSourceData = this.getContentSourceDataByIdOrThrow(contentSourceId);
|
|
618
678
|
const document = contentSourceData.documentMap[srcDocumentId];
|
|
619
679
|
const csiDocument = contentSourceData.csiDocumentMap[srcDocumentId];
|
|
@@ -629,7 +689,7 @@ class ContentStore {
|
|
|
629
689
|
}
|
|
630
690
|
// get the 'reference' model field in the updated document that will be used to link the new asset
|
|
631
691
|
locale = locale !== null && locale !== void 0 ? locale : contentSourceData.defaultLocaleCode;
|
|
632
|
-
const modelField = getModelFieldForFieldAtPath(document, csiModel, fieldPath, csiModelMap, locale);
|
|
692
|
+
const modelField = (0, content_store_utils_1.getModelFieldForFieldAtPath)(document, csiModel, fieldPath, csiModelMap, locale);
|
|
633
693
|
if (!modelField) {
|
|
634
694
|
throw Error(`the "fieldPath" points to non existing model field: ${fieldPath.join('.')}`);
|
|
635
695
|
}
|
|
@@ -638,7 +698,7 @@ class ContentStore {
|
|
|
638
698
|
throw Error(`error in "uploadAndLinkAsset", this operation can only be used on reference and image fields: ${fieldPath.join('.')}`);
|
|
639
699
|
}
|
|
640
700
|
// upload the new asset
|
|
641
|
-
const userContext = getUserContextForSrcType(srcType, user);
|
|
701
|
+
const userContext = (0, content_store_utils_1.getUserContextForSrcType)(srcType, user);
|
|
642
702
|
const result = await contentSourceData.instance.uploadAsset({
|
|
643
703
|
url: asset.url,
|
|
644
704
|
fileName: asset.metadata.name,
|
|
@@ -679,22 +739,22 @@ class ContentStore {
|
|
|
679
739
|
}
|
|
680
740
|
async createDocument({ srcType, srcProjectId, modelName, object, locale, user }) {
|
|
681
741
|
this.logger.debug('createDocument', { srcType, srcProjectId, modelName, locale });
|
|
682
|
-
const contentSourceId = getContentSourceId(srcType, srcProjectId);
|
|
742
|
+
const contentSourceId = (0, content_store_utils_1.getContentSourceId)(srcType, srcProjectId);
|
|
683
743
|
const contentSourceData = this.getContentSourceDataByIdOrThrow(contentSourceId);
|
|
684
744
|
const modelMap = contentSourceData.modelMap;
|
|
685
|
-
const
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
locale = locale !== null && locale !== void 0 ? locale : contentSourceData.defaultLocaleCode;
|
|
690
|
-
const userContext = getUserContextForSrcType(srcType, user);
|
|
691
|
-
const result = await createDocumentRecursively({
|
|
745
|
+
const csiModelMap = contentSourceData.csiModelMap;
|
|
746
|
+
const userContext = (0, content_store_utils_1.getUserContextForSrcType)(srcType, user);
|
|
747
|
+
const resolvedLocale = locale !== null && locale !== void 0 ? locale : contentSourceData.defaultLocaleCode;
|
|
748
|
+
const result = await (0, create_update_csi_docs_1.createDocumentRecursively)({
|
|
692
749
|
object,
|
|
693
|
-
|
|
750
|
+
modelName,
|
|
694
751
|
modelMap,
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
752
|
+
createDocument: (0, create_update_csi_docs_1.getCreateDocumentThunk)({
|
|
753
|
+
locale: resolvedLocale,
|
|
754
|
+
csiModelMap,
|
|
755
|
+
userContext,
|
|
756
|
+
contentSourceInstance: contentSourceData.instance
|
|
757
|
+
})
|
|
698
758
|
});
|
|
699
759
|
this.logger.debug('created document', { srcType, srcProjectId, srcDocumentId: result.document.id, modelName });
|
|
700
760
|
// do not update cache in contentSourceData.documents and documentMap,
|
|
@@ -706,9 +766,9 @@ class ContentStore {
|
|
|
706
766
|
}
|
|
707
767
|
async updateDocument({ srcType, srcProjectId, srcDocumentId, updateOperations, user }) {
|
|
708
768
|
this.logger.debug('updateDocument');
|
|
709
|
-
const contentSourceId = getContentSourceId(srcType, srcProjectId);
|
|
769
|
+
const contentSourceId = (0, content_store_utils_1.getContentSourceId)(srcType, srcProjectId);
|
|
710
770
|
const contentSourceData = this.getContentSourceDataByIdOrThrow(contentSourceId);
|
|
711
|
-
const userContext = getUserContextForSrcType(srcType, user);
|
|
771
|
+
const userContext = (0, content_store_utils_1.getUserContextForSrcType)(srcType, user);
|
|
712
772
|
const document = contentSourceData.documentMap[srcDocumentId];
|
|
713
773
|
const csiDocument = contentSourceData.csiDocumentMap[srcDocumentId];
|
|
714
774
|
if (!document || !csiDocument) {
|
|
@@ -724,17 +784,20 @@ class ContentStore {
|
|
|
724
784
|
const operations = await (0, utils_1.mapPromise)(updateOperations, async (updateOperation) => {
|
|
725
785
|
var _a;
|
|
726
786
|
const locale = (_a = updateOperation.locale) !== null && _a !== void 0 ? _a : contentSourceData.defaultLocaleCode;
|
|
727
|
-
const modelField = getModelFieldForFieldAtPath(document, model, updateOperation.fieldPath, modelMap, locale);
|
|
787
|
+
const modelField = (0, content_store_utils_1.getModelFieldForFieldAtPath)(document, model, updateOperation.fieldPath, modelMap, locale);
|
|
728
788
|
switch (updateOperation.opType) {
|
|
729
789
|
case 'set':
|
|
730
|
-
const field = await convertOperationField({
|
|
790
|
+
const field = await (0, create_update_csi_docs_1.convertOperationField)({
|
|
731
791
|
operationField: updateOperation.field,
|
|
732
792
|
fieldPath: updateOperation.fieldPath,
|
|
733
|
-
locale: updateOperation.locale,
|
|
734
793
|
modelField,
|
|
735
794
|
modelMap,
|
|
736
|
-
|
|
737
|
-
|
|
795
|
+
createDocument: (0, create_update_csi_docs_1.getCreateDocumentThunk)({
|
|
796
|
+
locale: updateOperation.locale,
|
|
797
|
+
csiModelMap,
|
|
798
|
+
userContext,
|
|
799
|
+
contentSourceInstance: contentSourceData.instance
|
|
800
|
+
})
|
|
738
801
|
});
|
|
739
802
|
return {
|
|
740
803
|
...updateOperation,
|
|
@@ -744,14 +807,17 @@ class ContentStore {
|
|
|
744
807
|
case 'unset':
|
|
745
808
|
return { ...updateOperation, modelField };
|
|
746
809
|
case 'insert':
|
|
747
|
-
const item = await convertOperationField({
|
|
810
|
+
const item = await (0, create_update_csi_docs_1.convertOperationField)({
|
|
748
811
|
operationField: updateOperation.item,
|
|
749
812
|
fieldPath: updateOperation.fieldPath,
|
|
750
|
-
locale: updateOperation.locale,
|
|
751
813
|
modelField,
|
|
752
814
|
modelMap,
|
|
753
|
-
|
|
754
|
-
|
|
815
|
+
createDocument: (0, create_update_csi_docs_1.getCreateDocumentThunk)({
|
|
816
|
+
locale: updateOperation.locale,
|
|
817
|
+
csiModelMap,
|
|
818
|
+
userContext,
|
|
819
|
+
contentSourceInstance: contentSourceData.instance
|
|
820
|
+
})
|
|
755
821
|
});
|
|
756
822
|
return {
|
|
757
823
|
...updateOperation,
|
|
@@ -778,22 +844,24 @@ class ContentStore {
|
|
|
778
844
|
}
|
|
779
845
|
async duplicateDocument({ srcType, srcProjectId, srcDocumentId, object, user }) {
|
|
780
846
|
this.logger.debug('duplicateDocument');
|
|
781
|
-
const contentSourceId = getContentSourceId(srcType, srcProjectId);
|
|
847
|
+
const contentSourceId = (0, content_store_utils_1.getContentSourceId)(srcType, srcProjectId);
|
|
782
848
|
const contentSourceData = this.getContentSourceDataByIdOrThrow(contentSourceId);
|
|
783
849
|
const document = contentSourceData.documentMap[srcDocumentId];
|
|
784
850
|
if (!document) {
|
|
785
851
|
throw new Error(`no document with id '${srcDocumentId}' was found in ${contentSourceData.id}`);
|
|
786
852
|
}
|
|
787
853
|
const modelMap = contentSourceData.modelMap;
|
|
854
|
+
const csiModelMap = contentSourceData.csiModelMap;
|
|
788
855
|
const model = modelMap[document.srcModelName];
|
|
789
|
-
|
|
856
|
+
const csiModel = csiModelMap[document.srcModelName];
|
|
857
|
+
if (!model || !csiModel) {
|
|
790
858
|
throw new Error(`no model with name '${document.srcModelName}' was found`);
|
|
791
859
|
}
|
|
792
|
-
const userContext = getUserContextForSrcType(srcType, user);
|
|
860
|
+
const userContext = (0, content_store_utils_1.getUserContextForSrcType)(srcType, user);
|
|
793
861
|
// TODO: take the data from the provided 'object' and merge them with
|
|
794
862
|
// DocumentFields of the existing Document:
|
|
795
863
|
// Option 1: Map the DocumentFields of the existing Document into flat
|
|
796
|
-
// object with '$$ref' and '
|
|
864
|
+
// object with '$$ref' and '$$type' properties for references and
|
|
797
865
|
// nested objects (needs to be implemented), and then merge it with
|
|
798
866
|
// the provided object recursively, and then pass that object to
|
|
799
867
|
// createNestedObjectRecursively()
|
|
@@ -809,12 +877,14 @@ class ContentStore {
|
|
|
809
877
|
modelFields: model.fields,
|
|
810
878
|
modelMap: contentSourceData.modelMap
|
|
811
879
|
});
|
|
880
|
+
// When passing model and modelMap to contentSourceInstance, we have to pass
|
|
881
|
+
// the original models (i.e., csiModel and csiModelMap) that we've received
|
|
882
|
+
// from that contentSourceInstance. We can't pass internal models as they
|
|
883
|
+
// might
|
|
812
884
|
const documentResult = await contentSourceData.instance.createDocument({
|
|
813
885
|
updateOperationFields,
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
// TODO: pass csiModelMap
|
|
817
|
-
modelMap,
|
|
886
|
+
model: csiModel,
|
|
887
|
+
modelMap: csiModelMap,
|
|
818
888
|
locale: contentSourceData.defaultLocaleCode,
|
|
819
889
|
userContext
|
|
820
890
|
});
|
|
@@ -822,10 +892,10 @@ class ContentStore {
|
|
|
822
892
|
}
|
|
823
893
|
async uploadAssets({ srcType, srcProjectId, assets, locale, user }) {
|
|
824
894
|
this.logger.debug('uploadAssets');
|
|
825
|
-
const contentSourceId = getContentSourceId(srcType, srcProjectId);
|
|
895
|
+
const contentSourceId = (0, content_store_utils_1.getContentSourceId)(srcType, srcProjectId);
|
|
826
896
|
const contentSourceData = this.getContentSourceDataByIdOrThrow(contentSourceId);
|
|
827
897
|
const sourceAssets = [];
|
|
828
|
-
const userContext = getUserContextForSrcType(srcType, user);
|
|
898
|
+
const userContext = (0, content_store_utils_1.getUserContextForSrcType)(srcType, user);
|
|
829
899
|
locale = locale !== null && locale !== void 0 ? locale : contentSourceData.defaultLocaleCode;
|
|
830
900
|
for (const asset of assets) {
|
|
831
901
|
let base64 = undefined;
|
|
@@ -845,17 +915,17 @@ class ContentStore {
|
|
|
845
915
|
});
|
|
846
916
|
sourceAssets.push(sourceAsset);
|
|
847
917
|
}
|
|
848
|
-
const storeAssets = mapCSIAssetsToStoreAssets({
|
|
918
|
+
const storeAssets = (0, csi_to_store_docs_converter_1.mapCSIAssetsToStoreAssets)({
|
|
849
919
|
csiAssets: sourceAssets,
|
|
850
920
|
contentSourceInstance: contentSourceData.instance,
|
|
851
921
|
defaultLocaleCode: contentSourceData.defaultLocaleCode
|
|
852
922
|
});
|
|
853
|
-
return mapStoreAssetsToAPIAssets(storeAssets, locale);
|
|
923
|
+
return (0, store_to_api_docs_converter_1.mapStoreAssetsToAPIAssets)(storeAssets, locale);
|
|
854
924
|
}
|
|
855
925
|
async deleteDocument({ srcType, srcProjectId, srcDocumentId, user }) {
|
|
856
926
|
this.logger.debug('deleteDocument');
|
|
857
|
-
const userContext = getUserContextForSrcType(srcType, user);
|
|
858
|
-
const contentSourceId = getContentSourceId(srcType, srcProjectId);
|
|
927
|
+
const userContext = (0, content_store_utils_1.getUserContextForSrcType)(srcType, user);
|
|
928
|
+
const contentSourceId = (0, content_store_utils_1.getContentSourceId)(srcType, srcProjectId);
|
|
859
929
|
const contentSourceData = this.getContentSourceDataByIdOrThrow(contentSourceId);
|
|
860
930
|
const csiDocument = contentSourceData.csiDocumentMap[srcDocumentId];
|
|
861
931
|
if (!csiDocument) {
|
|
@@ -869,13 +939,13 @@ class ContentStore {
|
|
|
869
939
|
}
|
|
870
940
|
async validateDocuments({ objects, locale, user }) {
|
|
871
941
|
this.logger.debug('validateDocuments');
|
|
872
|
-
const objectsBySourceId = lodash_1.default.groupBy(objects, (object) => getContentSourceId(object.srcType, object.srcProjectId));
|
|
942
|
+
const objectsBySourceId = lodash_1.default.groupBy(objects, (object) => (0, content_store_utils_1.getContentSourceId)(object.srcType, object.srcProjectId));
|
|
873
943
|
let errors = [];
|
|
874
944
|
for (const [contentSourceId, contentSourceObjects] of Object.entries(objectsBySourceId)) {
|
|
875
945
|
const contentSourceData = this.getContentSourceDataByIdOrThrow(contentSourceId);
|
|
876
946
|
locale = locale !== null && locale !== void 0 ? locale : contentSourceData.defaultLocaleCode;
|
|
877
947
|
const { documents, assets } = getCSIDocumentsAndAssetsFromContentSourceDataByIds(contentSourceData, contentSourceObjects);
|
|
878
|
-
const userContext = getUserContextForSrcType(contentSourceData.type, user);
|
|
948
|
+
const userContext = (0, content_store_utils_1.getUserContextForSrcType)(contentSourceData.type, user);
|
|
879
949
|
const internalValidationErrors = internalValidateContent(documents, assets, contentSourceData);
|
|
880
950
|
const validationResult = await contentSourceData.instance.validateDocuments({ documents, assets, locale, userContext });
|
|
881
951
|
errors = errors.concat(internalValidationErrors, validationResult.errors.map((validationError) => ({
|
|
@@ -904,12 +974,28 @@ class ContentStore {
|
|
|
904
974
|
);
|
|
905
975
|
*/
|
|
906
976
|
}
|
|
977
|
+
async searchDocuments(data) {
|
|
978
|
+
this.logger.debug('searchDocuments');
|
|
979
|
+
const objectsBySourceId = lodash_1.default.groupBy(data.models, (object) => (0, content_store_utils_1.getContentSourceId)(object.srcType, object.srcProjectId));
|
|
980
|
+
const documents = [];
|
|
981
|
+
const schema = {};
|
|
982
|
+
Object.keys(objectsBySourceId).forEach((contentSourceId) => {
|
|
983
|
+
const contentSourceData = this.getContentSourceDataByIdOrThrow(contentSourceId);
|
|
984
|
+
documents.push(...contentSourceData.documents);
|
|
985
|
+
lodash_1.default.set(schema, [contentSourceData.type, contentSourceData.projectId], contentSourceData.modelMap);
|
|
986
|
+
});
|
|
987
|
+
return (0, search_utils_1.searchDocuments)({
|
|
988
|
+
...data,
|
|
989
|
+
documents,
|
|
990
|
+
schema
|
|
991
|
+
});
|
|
992
|
+
}
|
|
907
993
|
async publishDocuments({ objects, user }) {
|
|
908
994
|
this.logger.debug('publishDocuments');
|
|
909
|
-
const objectsBySourceId = lodash_1.default.groupBy(objects, (object) => getContentSourceId(object.srcType, object.srcProjectId));
|
|
995
|
+
const objectsBySourceId = lodash_1.default.groupBy(objects, (object) => (0, content_store_utils_1.getContentSourceId)(object.srcType, object.srcProjectId));
|
|
910
996
|
for (const [contentSourceId, contentSourceObjects] of Object.entries(objectsBySourceId)) {
|
|
911
997
|
const contentSourceData = this.getContentSourceDataByIdOrThrow(contentSourceId);
|
|
912
|
-
const userContext = getUserContextForSrcType(contentSourceData.type, user);
|
|
998
|
+
const userContext = (0, content_store_utils_1.getUserContextForSrcType)(contentSourceData.type, user);
|
|
913
999
|
const { documents, assets } = getCSIDocumentsAndAssetsFromContentSourceDataByIds(contentSourceData, contentSourceObjects);
|
|
914
1000
|
await contentSourceData.instance.publishDocuments({ documents, assets, userContext });
|
|
915
1001
|
}
|
|
@@ -923,881 +1009,10 @@ class ContentStore {
|
|
|
923
1009
|
}
|
|
924
1010
|
}
|
|
925
1011
|
exports.ContentStore = ContentStore;
|
|
926
|
-
function getContentSourceId(contentSourceType, srcProjectId) {
|
|
927
|
-
return contentSourceType + ':' + srcProjectId;
|
|
928
|
-
}
|
|
929
|
-
exports.getContentSourceId = getContentSourceId;
|
|
930
|
-
function getUserContextForSrcType(srcType, user) {
|
|
931
|
-
var _a;
|
|
932
|
-
return (_a = user === null || user === void 0 ? void 0 : user.connections) === null || _a === void 0 ? void 0 : _a.find((connection) => connection.type === srcType);
|
|
933
|
-
}
|
|
934
|
-
function mapCSIAssetsToStoreAssets({ csiAssets, contentSourceInstance, defaultLocaleCode }) {
|
|
935
|
-
const extra = {
|
|
936
|
-
srcType: contentSourceInstance.getContentSourceType(),
|
|
937
|
-
srcProjectId: contentSourceInstance.getProjectId(),
|
|
938
|
-
srcProjectUrl: contentSourceInstance.getProjectManageUrl(),
|
|
939
|
-
srcEnvironment: contentSourceInstance.getProjectEnvironment()
|
|
940
|
-
};
|
|
941
|
-
return csiAssets.map((csiAsset) => sourceAssetToStoreAsset({ csiAsset, defaultLocaleCode, extra }));
|
|
942
|
-
}
|
|
943
|
-
function sourceAssetToStoreAsset({ csiAsset, defaultLocaleCode, extra }) {
|
|
944
|
-
return {
|
|
945
|
-
type: 'asset',
|
|
946
|
-
...extra,
|
|
947
|
-
srcObjectId: csiAsset.id,
|
|
948
|
-
srcObjectUrl: csiAsset.manageUrl,
|
|
949
|
-
srcObjectLabel: getObjectLabel(csiAsset.fields, common_schema_1.IMAGE_MODEL, defaultLocaleCode),
|
|
950
|
-
srcModelName: common_schema_1.IMAGE_MODEL.name,
|
|
951
|
-
srcModelLabel: common_schema_1.IMAGE_MODEL.label,
|
|
952
|
-
isChanged: csiAsset.status === 'added' || csiAsset.status === 'modified',
|
|
953
|
-
status: csiAsset.status,
|
|
954
|
-
createdAt: csiAsset.createdAt,
|
|
955
|
-
createdBy: csiAsset.createdBy,
|
|
956
|
-
updatedAt: csiAsset.updatedAt,
|
|
957
|
-
updatedBy: csiAsset.updatedBy,
|
|
958
|
-
fields: {
|
|
959
|
-
title: {
|
|
960
|
-
label: 'Title',
|
|
961
|
-
...csiAsset.fields.title
|
|
962
|
-
},
|
|
963
|
-
file: {
|
|
964
|
-
label: 'File',
|
|
965
|
-
...csiAsset.fields.file
|
|
966
|
-
}
|
|
967
|
-
}
|
|
968
|
-
};
|
|
969
|
-
}
|
|
970
|
-
function mapCSIDocumentsToStoreDocuments({ csiDocuments, contentSourceInstance, modelMap, defaultLocaleCode }) {
|
|
971
|
-
const extra = {
|
|
972
|
-
srcType: contentSourceInstance.getContentSourceType(),
|
|
973
|
-
srcProjectId: contentSourceInstance.getProjectId(),
|
|
974
|
-
srcProjectUrl: contentSourceInstance.getProjectManageUrl(),
|
|
975
|
-
srcEnvironment: contentSourceInstance.getProjectEnvironment()
|
|
976
|
-
};
|
|
977
|
-
return csiDocuments.map((csiDocument) => mapCSIDocumentToStoreDocument({ csiDocument, model: modelMap[csiDocument.modelName], modelMap, defaultLocaleCode, extra }));
|
|
978
|
-
}
|
|
979
|
-
function mapCSIDocumentToStoreDocument({ csiDocument, model, modelMap, defaultLocaleCode, extra }) {
|
|
980
|
-
var _a, _b;
|
|
981
|
-
return {
|
|
982
|
-
type: 'document',
|
|
983
|
-
...extra,
|
|
984
|
-
srcObjectId: csiDocument.id,
|
|
985
|
-
srcObjectUrl: csiDocument.manageUrl,
|
|
986
|
-
srcObjectLabel: getObjectLabel(csiDocument.fields, model, defaultLocaleCode),
|
|
987
|
-
srcModelLabel: (_a = model.label) !== null && _a !== void 0 ? _a : lodash_1.default.startCase(csiDocument.modelName),
|
|
988
|
-
srcModelName: csiDocument.modelName,
|
|
989
|
-
isChanged: csiDocument.status === 'added' || csiDocument.status === 'modified',
|
|
990
|
-
status: csiDocument.status,
|
|
991
|
-
createdAt: csiDocument.createdAt,
|
|
992
|
-
createdBy: csiDocument.createdBy,
|
|
993
|
-
updatedAt: csiDocument.updatedAt,
|
|
994
|
-
updatedBy: csiDocument.updatedBy,
|
|
995
|
-
fields: mapCSIFieldsToStoreFields({
|
|
996
|
-
csiDocumentFields: csiDocument.fields,
|
|
997
|
-
modelFields: (_b = model.fields) !== null && _b !== void 0 ? _b : [],
|
|
998
|
-
context: {
|
|
999
|
-
modelMap,
|
|
1000
|
-
defaultLocaleCode
|
|
1001
|
-
}
|
|
1002
|
-
})
|
|
1003
|
-
};
|
|
1004
|
-
}
|
|
1005
|
-
function mapCSIFieldsToStoreFields({ csiDocumentFields, modelFields, context }) {
|
|
1006
|
-
return modelFields.reduce((result, modelField) => {
|
|
1007
|
-
const csiDocumentField = csiDocumentFields[modelField.name];
|
|
1008
|
-
const docField = mapCSIFieldToStoreField({
|
|
1009
|
-
csiDocumentField,
|
|
1010
|
-
modelField,
|
|
1011
|
-
context
|
|
1012
|
-
});
|
|
1013
|
-
docField.label = modelField.label;
|
|
1014
|
-
result[modelField.name] = docField;
|
|
1015
|
-
return result;
|
|
1016
|
-
}, {});
|
|
1017
|
-
}
|
|
1018
|
-
function mapCSIFieldToStoreField({ csiDocumentField, modelField, context }) {
|
|
1019
|
-
if (!csiDocumentField) {
|
|
1020
|
-
const isUnset = ['object', 'model', 'reference', 'richText', 'markdown', 'image', 'file', 'json'].includes(modelField.type);
|
|
1021
|
-
return {
|
|
1022
|
-
type: modelField.type,
|
|
1023
|
-
...(isUnset ? { isUnset } : null),
|
|
1024
|
-
...(modelField.type === 'list' ? { items: [] } : null)
|
|
1025
|
-
};
|
|
1026
|
-
}
|
|
1027
|
-
// TODO: check if need to add "options" to "enum" and subtype/min/max to "number"
|
|
1028
|
-
switch (modelField.type) {
|
|
1029
|
-
case 'object':
|
|
1030
|
-
return mapObjectField(csiDocumentField, modelField, context);
|
|
1031
|
-
case 'model':
|
|
1032
|
-
return mapModelField(csiDocumentField, modelField, context);
|
|
1033
|
-
case 'list':
|
|
1034
|
-
return mapListField(csiDocumentField, modelField, context);
|
|
1035
|
-
case 'richText':
|
|
1036
|
-
return mapRichTextField(csiDocumentField);
|
|
1037
|
-
case 'markdown':
|
|
1038
|
-
return mapMarkdownField(csiDocumentField);
|
|
1039
|
-
default:
|
|
1040
|
-
return csiDocumentField;
|
|
1041
|
-
}
|
|
1042
|
-
}
|
|
1043
|
-
function mapObjectField(csiDocumentField, modelField, context) {
|
|
1044
|
-
var _a, _b, _c;
|
|
1045
|
-
if (!(0, content_source_interface_1.isLocalizedField)(csiDocumentField)) {
|
|
1046
|
-
return {
|
|
1047
|
-
type: csiDocumentField.type,
|
|
1048
|
-
srcObjectLabel: getObjectLabel((_a = csiDocumentField.fields) !== null && _a !== void 0 ? _a : {}, modelField !== null && modelField !== void 0 ? modelField : [], context.defaultLocaleCode),
|
|
1049
|
-
fields: mapCSIFieldsToStoreFields({
|
|
1050
|
-
csiDocumentFields: (_b = csiDocumentField.fields) !== null && _b !== void 0 ? _b : {},
|
|
1051
|
-
modelFields: (_c = modelField.fields) !== null && _c !== void 0 ? _c : [],
|
|
1052
|
-
context
|
|
1053
|
-
})
|
|
1054
|
-
};
|
|
1055
|
-
}
|
|
1056
|
-
return {
|
|
1057
|
-
type: csiDocumentField.type,
|
|
1058
|
-
localized: true,
|
|
1059
|
-
locales: lodash_1.default.mapValues(csiDocumentField.locales, (locale) => {
|
|
1060
|
-
var _a, _b, _c;
|
|
1061
|
-
return {
|
|
1062
|
-
locale: locale.locale,
|
|
1063
|
-
srcObjectLabel: getObjectLabel((_a = locale.fields) !== null && _a !== void 0 ? _a : {}, modelField, locale.locale),
|
|
1064
|
-
fields: mapCSIFieldsToStoreFields({
|
|
1065
|
-
csiDocumentFields: (_b = locale.fields) !== null && _b !== void 0 ? _b : {},
|
|
1066
|
-
modelFields: (_c = modelField.fields) !== null && _c !== void 0 ? _c : [],
|
|
1067
|
-
context
|
|
1068
|
-
})
|
|
1069
|
-
};
|
|
1070
|
-
})
|
|
1071
|
-
};
|
|
1072
|
-
}
|
|
1073
|
-
function mapModelField(csiDocumentField, modelField, context) {
|
|
1074
|
-
var _a, _b, _c, _d;
|
|
1075
|
-
if (!(0, content_source_interface_1.isLocalizedField)(csiDocumentField)) {
|
|
1076
|
-
const model = context.modelMap[csiDocumentField.modelName];
|
|
1077
|
-
return {
|
|
1078
|
-
type: csiDocumentField.type,
|
|
1079
|
-
srcObjectLabel: getObjectLabel((_a = csiDocumentField.fields) !== null && _a !== void 0 ? _a : {}, model, context.defaultLocaleCode),
|
|
1080
|
-
srcModelName: csiDocumentField.modelName,
|
|
1081
|
-
srcModelLabel: (_b = model.label) !== null && _b !== void 0 ? _b : lodash_1.default.startCase(model.name),
|
|
1082
|
-
fields: mapCSIFieldsToStoreFields({
|
|
1083
|
-
csiDocumentFields: (_c = csiDocumentField.fields) !== null && _c !== void 0 ? _c : {},
|
|
1084
|
-
modelFields: (_d = model.fields) !== null && _d !== void 0 ? _d : [],
|
|
1085
|
-
context
|
|
1086
|
-
})
|
|
1087
|
-
};
|
|
1088
|
-
}
|
|
1089
|
-
return {
|
|
1090
|
-
type: csiDocumentField.type,
|
|
1091
|
-
localized: true,
|
|
1092
|
-
locales: lodash_1.default.mapValues(csiDocumentField.locales, (locale) => {
|
|
1093
|
-
var _a, _b, _c, _d;
|
|
1094
|
-
const model = context.modelMap[locale.modelName];
|
|
1095
|
-
return {
|
|
1096
|
-
locale: locale.locale,
|
|
1097
|
-
srcObjectLabel: getObjectLabel((_a = locale.fields) !== null && _a !== void 0 ? _a : {}, model, locale.locale),
|
|
1098
|
-
srcModelName: locale.modelName,
|
|
1099
|
-
srcModelLabel: (_b = model.label) !== null && _b !== void 0 ? _b : lodash_1.default.startCase(model.name),
|
|
1100
|
-
fields: mapCSIFieldsToStoreFields({
|
|
1101
|
-
csiDocumentFields: (_c = locale.fields) !== null && _c !== void 0 ? _c : {},
|
|
1102
|
-
modelFields: (_d = model.fields) !== null && _d !== void 0 ? _d : [],
|
|
1103
|
-
context
|
|
1104
|
-
})
|
|
1105
|
-
};
|
|
1106
|
-
})
|
|
1107
|
-
};
|
|
1108
|
-
}
|
|
1109
|
-
function mapListField(csiDocumentField, modelField, context) {
|
|
1110
|
-
if (!(0, content_source_interface_1.isLocalizedField)(csiDocumentField)) {
|
|
1111
|
-
return {
|
|
1112
|
-
type: csiDocumentField.type,
|
|
1113
|
-
items: csiDocumentField.items.map((item) => {
|
|
1114
|
-
var _a;
|
|
1115
|
-
return mapCSIFieldToStoreField({
|
|
1116
|
-
csiDocumentField: item,
|
|
1117
|
-
modelField: (_a = modelField.items) !== null && _a !== void 0 ? _a : { type: 'string' },
|
|
1118
|
-
context
|
|
1119
|
-
});
|
|
1120
|
-
})
|
|
1121
|
-
};
|
|
1122
|
-
}
|
|
1123
|
-
return {
|
|
1124
|
-
type: csiDocumentField.type,
|
|
1125
|
-
localized: true,
|
|
1126
|
-
locales: lodash_1.default.mapValues(csiDocumentField.locales, (locale) => {
|
|
1127
|
-
var _a;
|
|
1128
|
-
return {
|
|
1129
|
-
locale: locale.locale,
|
|
1130
|
-
items: ((_a = locale.items) !== null && _a !== void 0 ? _a : []).map((item) => {
|
|
1131
|
-
var _a;
|
|
1132
|
-
return mapCSIFieldToStoreField({
|
|
1133
|
-
csiDocumentField: item,
|
|
1134
|
-
modelField: (_a = modelField.items) !== null && _a !== void 0 ? _a : { type: 'string' },
|
|
1135
|
-
context
|
|
1136
|
-
});
|
|
1137
|
-
})
|
|
1138
|
-
};
|
|
1139
|
-
})
|
|
1140
|
-
};
|
|
1141
|
-
}
|
|
1142
|
-
function mapRichTextField(csiDocumentField) {
|
|
1143
|
-
if (!(0, content_source_interface_1.isLocalizedField)(csiDocumentField)) {
|
|
1144
|
-
return {
|
|
1145
|
-
...csiDocumentField,
|
|
1146
|
-
multiElement: true
|
|
1147
|
-
};
|
|
1148
|
-
}
|
|
1149
|
-
return {
|
|
1150
|
-
type: csiDocumentField.type,
|
|
1151
|
-
localized: true,
|
|
1152
|
-
locales: lodash_1.default.mapValues(csiDocumentField.locales, (locale) => {
|
|
1153
|
-
return {
|
|
1154
|
-
...locale,
|
|
1155
|
-
multiElement: true
|
|
1156
|
-
};
|
|
1157
|
-
})
|
|
1158
|
-
};
|
|
1159
|
-
}
|
|
1160
|
-
function mapMarkdownField(csiDocumentField) {
|
|
1161
|
-
if (!(0, content_source_interface_1.isLocalizedField)(csiDocumentField)) {
|
|
1162
|
-
return {
|
|
1163
|
-
type: 'markdown',
|
|
1164
|
-
value: csiDocumentField.value,
|
|
1165
|
-
multiElement: true
|
|
1166
|
-
};
|
|
1167
|
-
}
|
|
1168
|
-
return {
|
|
1169
|
-
type: 'markdown',
|
|
1170
|
-
localized: true,
|
|
1171
|
-
locales: lodash_1.default.mapValues(csiDocumentField.locales, (locale) => {
|
|
1172
|
-
return {
|
|
1173
|
-
...locale,
|
|
1174
|
-
multiElement: true
|
|
1175
|
-
};
|
|
1176
|
-
})
|
|
1177
|
-
};
|
|
1178
|
-
}
|
|
1179
1012
|
function mapStoreFieldsToOperationFields({ documentFields, modelFields, modelMap }) {
|
|
1180
1013
|
// TODO: implement
|
|
1181
1014
|
throw new Error(`duplicateDocument not implemented yet`);
|
|
1182
1015
|
}
|
|
1183
|
-
function getContentSourceIdForContentSource(contentSource) {
|
|
1184
|
-
return getContentSourceId(contentSource.getContentSourceType(), contentSource.getProjectId());
|
|
1185
|
-
}
|
|
1186
|
-
function extractTokensFromString(input) {
|
|
1187
|
-
return input.match(/(?<={)[^}]+(?=})/g) || [];
|
|
1188
|
-
}
|
|
1189
|
-
function sanitizeSlug(slug) {
|
|
1190
|
-
return slug
|
|
1191
|
-
.split('/')
|
|
1192
|
-
.map((part) => (0, slugify_1.default)(part, { lower: true }))
|
|
1193
|
-
.join('/');
|
|
1194
|
-
}
|
|
1195
|
-
function getObjectLabel(documentFields, modelOrObjectField, locale) {
|
|
1196
|
-
const labelField = modelOrObjectField.labelField;
|
|
1197
|
-
let label = null;
|
|
1198
|
-
if (labelField) {
|
|
1199
|
-
const field = lodash_1.default.get(documentFields, labelField, null);
|
|
1200
|
-
if (field && ['string', 'url', 'slug', 'text', 'markdown', 'number', 'enum', 'date', 'datetime', 'color', 'image', 'file'].includes(field.type)) {
|
|
1201
|
-
if ((0, content_source_interface_1.isLocalizedField)(field) && locale) {
|
|
1202
|
-
label = lodash_1.default.get(field, ['locales', locale, 'value'], null);
|
|
1203
|
-
}
|
|
1204
|
-
else if (!(0, content_source_interface_1.isLocalizedField)(field)) {
|
|
1205
|
-
label = lodash_1.default.get(field, 'value', null);
|
|
1206
|
-
}
|
|
1207
|
-
}
|
|
1208
|
-
}
|
|
1209
|
-
if (!label) {
|
|
1210
|
-
label = lodash_1.default.get(modelOrObjectField, 'label');
|
|
1211
|
-
}
|
|
1212
|
-
if (!label && lodash_1.default.has(modelOrObjectField, 'name')) {
|
|
1213
|
-
label = lodash_1.default.startCase(lodash_1.default.get(modelOrObjectField, 'name'));
|
|
1214
|
-
}
|
|
1215
|
-
return label;
|
|
1216
|
-
}
|
|
1217
|
-
function mapDocumentsToLocalizedApiObjects(documents, locale) {
|
|
1218
|
-
return documents.map((document) => documentToLocalizedApiObject(document, locale));
|
|
1219
|
-
}
|
|
1220
|
-
function documentToLocalizedApiObject(document, locale) {
|
|
1221
|
-
const { type, fields, ...rest } = document;
|
|
1222
|
-
return {
|
|
1223
|
-
type: 'object',
|
|
1224
|
-
...rest,
|
|
1225
|
-
fields: toLocalizedAPIFields(fields, locale)
|
|
1226
|
-
};
|
|
1227
|
-
}
|
|
1228
|
-
function toLocalizedAPIFields(docFields, locale) {
|
|
1229
|
-
return lodash_1.default.mapValues(docFields, (docField) => toLocalizedAPIField(docField, locale));
|
|
1230
|
-
}
|
|
1231
|
-
function toLocalizedAPIField(docField, locale, isListItem = false) {
|
|
1232
|
-
const hasUnsetFlag = ['object', 'model', 'reference', 'richText', 'markdown', 'image', 'file', 'json'].includes(docField.type);
|
|
1233
|
-
let docFieldLocalized;
|
|
1234
|
-
let unset = false;
|
|
1235
|
-
if (docField.localized) {
|
|
1236
|
-
const { locales, localized, ...base } = docField;
|
|
1237
|
-
const localeProps = locale ? locales[locale] : undefined;
|
|
1238
|
-
docFieldLocalized = {
|
|
1239
|
-
...base,
|
|
1240
|
-
...localeProps,
|
|
1241
|
-
...(hasUnsetFlag && !localeProps ? { isUnset: true } : null)
|
|
1242
|
-
};
|
|
1243
|
-
}
|
|
1244
|
-
else {
|
|
1245
|
-
docFieldLocalized = docField;
|
|
1246
|
-
}
|
|
1247
|
-
locale = locale !== null && locale !== void 0 ? locale : docFieldLocalized.locale;
|
|
1248
|
-
const commonProps = isListItem
|
|
1249
|
-
? null
|
|
1250
|
-
: {
|
|
1251
|
-
localized: !!docField.localized,
|
|
1252
|
-
...(locale ? { locale } : null)
|
|
1253
|
-
};
|
|
1254
|
-
if (docFieldLocalized.type === 'object' || docFieldLocalized.type === 'model') {
|
|
1255
|
-
return {
|
|
1256
|
-
...docFieldLocalized,
|
|
1257
|
-
type: 'object',
|
|
1258
|
-
...commonProps,
|
|
1259
|
-
...(docFieldLocalized.isUnset
|
|
1260
|
-
? null
|
|
1261
|
-
: {
|
|
1262
|
-
fields: toLocalizedAPIFields(docFieldLocalized.fields, locale)
|
|
1263
|
-
})
|
|
1264
|
-
};
|
|
1265
|
-
}
|
|
1266
|
-
else if (docFieldLocalized.type === 'reference') {
|
|
1267
|
-
const { type, refType, ...rest } = docFieldLocalized;
|
|
1268
|
-
// if reference field isUnset === true, it behaves like a regular object
|
|
1269
|
-
if (rest.isUnset) {
|
|
1270
|
-
return {
|
|
1271
|
-
type: 'object',
|
|
1272
|
-
...rest,
|
|
1273
|
-
...commonProps
|
|
1274
|
-
};
|
|
1275
|
-
}
|
|
1276
|
-
return {
|
|
1277
|
-
type: 'unresolved_reference',
|
|
1278
|
-
refType: refType === 'asset' ? 'image' : 'object',
|
|
1279
|
-
...rest,
|
|
1280
|
-
...commonProps
|
|
1281
|
-
};
|
|
1282
|
-
}
|
|
1283
|
-
else if (docFieldLocalized.type === 'list') {
|
|
1284
|
-
// items can be undefined if the requested locale doesn't exist on a localized field
|
|
1285
|
-
const { items, ...rest } = docFieldLocalized;
|
|
1286
|
-
return {
|
|
1287
|
-
...rest,
|
|
1288
|
-
...commonProps,
|
|
1289
|
-
items: (items !== null && items !== void 0 ? items : []).map((field) => toLocalizedAPIField(field, locale, true))
|
|
1290
|
-
};
|
|
1291
|
-
}
|
|
1292
|
-
else {
|
|
1293
|
-
return {
|
|
1294
|
-
...docFieldLocalized,
|
|
1295
|
-
...commonProps
|
|
1296
|
-
};
|
|
1297
|
-
}
|
|
1298
|
-
}
|
|
1299
|
-
function mapAssetsToLocalizedApiImages(assets, locale) {
|
|
1300
|
-
return assets.map((asset) => assetToLocalizedApiImage(asset, locale));
|
|
1301
|
-
}
|
|
1302
|
-
function assetToLocalizedApiImage(asset, locale) {
|
|
1303
|
-
const { type, fields, ...rest } = asset;
|
|
1304
|
-
return {
|
|
1305
|
-
type: 'image',
|
|
1306
|
-
...rest,
|
|
1307
|
-
fields: localizeAssetFields(fields, locale)
|
|
1308
|
-
};
|
|
1309
|
-
}
|
|
1310
|
-
function localizeAssetFields(assetFields, locale) {
|
|
1311
|
-
var _a, _b;
|
|
1312
|
-
const fields = {
|
|
1313
|
-
title: {
|
|
1314
|
-
type: 'string',
|
|
1315
|
-
value: null
|
|
1316
|
-
},
|
|
1317
|
-
url: {
|
|
1318
|
-
type: 'string',
|
|
1319
|
-
value: null
|
|
1320
|
-
}
|
|
1321
|
-
};
|
|
1322
|
-
const titleFieldNonLocalized = getDocumentFieldForLocale(assetFields.title, locale);
|
|
1323
|
-
fields.title.value = titleFieldNonLocalized === null || titleFieldNonLocalized === void 0 ? void 0 : titleFieldNonLocalized.value;
|
|
1324
|
-
fields.title.locale = locale !== null && locale !== void 0 ? locale : titleFieldNonLocalized === null || titleFieldNonLocalized === void 0 ? void 0 : titleFieldNonLocalized.locale;
|
|
1325
|
-
const assetFileField = assetFields.file;
|
|
1326
|
-
if (assetFileField.localized) {
|
|
1327
|
-
if (locale) {
|
|
1328
|
-
fields.url.value = (_b = (_a = assetFileField.locales[locale]) === null || _a === void 0 ? void 0 : _a.url) !== null && _b !== void 0 ? _b : null;
|
|
1329
|
-
fields.url.locale = locale;
|
|
1330
|
-
}
|
|
1331
|
-
}
|
|
1332
|
-
else {
|
|
1333
|
-
fields.url.value = assetFileField.url;
|
|
1334
|
-
fields.url.locale = assetFileField.locale;
|
|
1335
|
-
}
|
|
1336
|
-
return fields;
|
|
1337
|
-
}
|
|
1338
|
-
function mapStoreAssetsToAPIAssets(assets, locale) {
|
|
1339
|
-
return assets.map((asset) => storeAssetToAPIAsset(asset, locale));
|
|
1340
|
-
}
|
|
1341
|
-
function storeAssetToAPIAsset(asset, locale) {
|
|
1342
|
-
var _a, _b;
|
|
1343
|
-
const assetTitleField = asset.fields.title;
|
|
1344
|
-
const localizedTitleField = assetTitleField.localized ? assetTitleField.locales[locale] : assetTitleField;
|
|
1345
|
-
const assetFileField = asset.fields.file;
|
|
1346
|
-
const localizedFileField = assetFileField.localized ? assetFileField.locales[locale] : assetFileField;
|
|
1347
|
-
return {
|
|
1348
|
-
objectId: asset.srcObjectId,
|
|
1349
|
-
createdAt: asset.createdAt,
|
|
1350
|
-
url: localizedFileField.url,
|
|
1351
|
-
...(0, utils_1.omitByNil)({
|
|
1352
|
-
title: localizedTitleField.value,
|
|
1353
|
-
fileName: localizedFileField.fileName,
|
|
1354
|
-
contentType: localizedFileField.contentType,
|
|
1355
|
-
size: localizedFileField.size,
|
|
1356
|
-
width: (_a = localizedFileField.dimensions) === null || _a === void 0 ? void 0 : _a.width,
|
|
1357
|
-
height: (_b = localizedFileField.dimensions) === null || _b === void 0 ? void 0 : _b.height
|
|
1358
|
-
})
|
|
1359
|
-
};
|
|
1360
|
-
}
|
|
1361
|
-
/**
|
|
1362
|
-
* Iterates recursively objects with $$type and $$ref, creating nested objects
|
|
1363
|
-
* as needed and returns standard ContentSourceInterface Documents
|
|
1364
|
-
*/
|
|
1365
|
-
async function createDocumentRecursively({ object, model, modelMap, locale, userContext, contentSourceInstance }) {
|
|
1366
|
-
var _a;
|
|
1367
|
-
if (model.type === 'page') {
|
|
1368
|
-
const tokens = extractTokensFromString(String(model.urlPath));
|
|
1369
|
-
const slugField = lodash_1.default.last(tokens);
|
|
1370
|
-
if (object && slugField && slugField in object) {
|
|
1371
|
-
const slugFieldValue = object[slugField];
|
|
1372
|
-
object[slugField] = sanitizeSlug(slugFieldValue);
|
|
1373
|
-
}
|
|
1374
|
-
}
|
|
1375
|
-
const nestedResult = await createNestedObjectRecursively({
|
|
1376
|
-
object,
|
|
1377
|
-
modelFields: (_a = model.fields) !== null && _a !== void 0 ? _a : [],
|
|
1378
|
-
fieldPath: [],
|
|
1379
|
-
modelMap,
|
|
1380
|
-
locale,
|
|
1381
|
-
userContext,
|
|
1382
|
-
contentSourceInstance
|
|
1383
|
-
});
|
|
1384
|
-
const document = await contentSourceInstance.createDocument({
|
|
1385
|
-
updateOperationFields: nestedResult.fields,
|
|
1386
|
-
// TODO: pass csiModel
|
|
1387
|
-
model,
|
|
1388
|
-
// TODO: pass csiModelMap
|
|
1389
|
-
modelMap,
|
|
1390
|
-
locale,
|
|
1391
|
-
userContext
|
|
1392
|
-
});
|
|
1393
|
-
return {
|
|
1394
|
-
document: document,
|
|
1395
|
-
newRefDocuments: nestedResult.newRefDocuments
|
|
1396
|
-
};
|
|
1397
|
-
}
|
|
1398
|
-
async function createNestedObjectRecursively({ object, modelFields, fieldPath, modelMap, locale, userContext, contentSourceInstance }) {
|
|
1399
|
-
object = object !== null && object !== void 0 ? object : {};
|
|
1400
|
-
const result = {
|
|
1401
|
-
fields: {},
|
|
1402
|
-
newRefDocuments: []
|
|
1403
|
-
};
|
|
1404
|
-
const objectFieldNames = Object.keys(object);
|
|
1405
|
-
for (const modelField of modelFields) {
|
|
1406
|
-
const fieldName = modelField.name;
|
|
1407
|
-
let value;
|
|
1408
|
-
if (fieldName in object) {
|
|
1409
|
-
value = object[fieldName];
|
|
1410
|
-
lodash_1.default.pull(objectFieldNames, fieldName);
|
|
1411
|
-
}
|
|
1412
|
-
else if (modelField.const) {
|
|
1413
|
-
value = modelField.const;
|
|
1414
|
-
}
|
|
1415
|
-
else if (!lodash_1.default.isNil(modelField.default)) {
|
|
1416
|
-
value = modelField.default;
|
|
1417
|
-
}
|
|
1418
|
-
if (!lodash_1.default.isNil(value)) {
|
|
1419
|
-
const fieldResult = await createNestedField({
|
|
1420
|
-
value,
|
|
1421
|
-
modelField,
|
|
1422
|
-
fieldPath: fieldPath.concat(fieldName),
|
|
1423
|
-
modelMap,
|
|
1424
|
-
locale,
|
|
1425
|
-
userContext,
|
|
1426
|
-
contentSourceInstance
|
|
1427
|
-
});
|
|
1428
|
-
result.fields[fieldName] = fieldResult.field;
|
|
1429
|
-
result.newRefDocuments = result.newRefDocuments.concat(fieldResult.newRefDocuments);
|
|
1430
|
-
}
|
|
1431
|
-
}
|
|
1432
|
-
if (objectFieldNames.length > 0) {
|
|
1433
|
-
throw new Error(`no model fields found when creating a document with fields: '${objectFieldNames.join(', ')}'`);
|
|
1434
|
-
}
|
|
1435
|
-
return result;
|
|
1436
|
-
}
|
|
1437
|
-
async function createNestedField({ value, modelField, fieldPath, modelMap, locale, userContext, contentSourceInstance }) {
|
|
1438
|
-
var _a;
|
|
1439
|
-
if (modelField.type === 'object') {
|
|
1440
|
-
const result = await createNestedObjectRecursively({
|
|
1441
|
-
object: value,
|
|
1442
|
-
modelFields: modelField.fields,
|
|
1443
|
-
fieldPath,
|
|
1444
|
-
modelMap,
|
|
1445
|
-
locale,
|
|
1446
|
-
userContext,
|
|
1447
|
-
contentSourceInstance
|
|
1448
|
-
});
|
|
1449
|
-
return {
|
|
1450
|
-
field: {
|
|
1451
|
-
type: 'object',
|
|
1452
|
-
fields: result.fields
|
|
1453
|
-
},
|
|
1454
|
-
newRefDocuments: result.newRefDocuments
|
|
1455
|
-
};
|
|
1456
|
-
}
|
|
1457
|
-
else if (modelField.type === 'model') {
|
|
1458
|
-
let { $$type, ...rest } = value;
|
|
1459
|
-
const modelNames = modelField.models;
|
|
1460
|
-
// for backward compatibility check if the object has 'type' instead of '$$type' because older projects use
|
|
1461
|
-
// the 'type' property in default values
|
|
1462
|
-
if (!$$type && 'type' in rest) {
|
|
1463
|
-
$$type = rest.type;
|
|
1464
|
-
rest = lodash_1.default.omit(rest, 'type');
|
|
1465
|
-
}
|
|
1466
|
-
const modelName = $$type !== null && $$type !== void 0 ? $$type : (modelNames.length === 1 ? modelNames[0] : null);
|
|
1467
|
-
if (!modelName) {
|
|
1468
|
-
throw new Error(`no $$type was specified for nested model`);
|
|
1469
|
-
}
|
|
1470
|
-
const model = modelMap[modelName];
|
|
1471
|
-
if (!model) {
|
|
1472
|
-
throw new Error(`no model with name '${modelName}' was found`);
|
|
1473
|
-
}
|
|
1474
|
-
const result = await createNestedObjectRecursively({
|
|
1475
|
-
object: rest,
|
|
1476
|
-
modelFields: (_a = model.fields) !== null && _a !== void 0 ? _a : [],
|
|
1477
|
-
fieldPath,
|
|
1478
|
-
modelMap,
|
|
1479
|
-
locale,
|
|
1480
|
-
userContext,
|
|
1481
|
-
contentSourceInstance
|
|
1482
|
-
});
|
|
1483
|
-
return {
|
|
1484
|
-
field: {
|
|
1485
|
-
type: 'model',
|
|
1486
|
-
modelName: modelName,
|
|
1487
|
-
fields: result.fields
|
|
1488
|
-
},
|
|
1489
|
-
newRefDocuments: result.newRefDocuments
|
|
1490
|
-
};
|
|
1491
|
-
}
|
|
1492
|
-
else if (modelField.type === 'image') {
|
|
1493
|
-
let refId;
|
|
1494
|
-
if (lodash_1.default.isPlainObject(value)) {
|
|
1495
|
-
refId = value.$$ref;
|
|
1496
|
-
}
|
|
1497
|
-
else {
|
|
1498
|
-
refId = value;
|
|
1499
|
-
}
|
|
1500
|
-
if (!refId) {
|
|
1501
|
-
throw new Error(`reference field must specify a value`);
|
|
1502
|
-
}
|
|
1503
|
-
return {
|
|
1504
|
-
field: {
|
|
1505
|
-
type: 'reference',
|
|
1506
|
-
refType: 'asset',
|
|
1507
|
-
refId: refId
|
|
1508
|
-
},
|
|
1509
|
-
newRefDocuments: []
|
|
1510
|
-
};
|
|
1511
|
-
}
|
|
1512
|
-
else if (modelField.type === 'reference') {
|
|
1513
|
-
let { $$ref: refId = null, $$type: modelName = null, ...rest } = lodash_1.default.isPlainObject(value) ? value : { $$ref: value };
|
|
1514
|
-
if (refId) {
|
|
1515
|
-
return {
|
|
1516
|
-
field: {
|
|
1517
|
-
type: 'reference',
|
|
1518
|
-
refType: 'document',
|
|
1519
|
-
refId: refId
|
|
1520
|
-
},
|
|
1521
|
-
newRefDocuments: []
|
|
1522
|
-
};
|
|
1523
|
-
}
|
|
1524
|
-
else {
|
|
1525
|
-
const modelNames = modelField.models;
|
|
1526
|
-
if (!modelName) {
|
|
1527
|
-
// for backward compatibility check if the object has 'type' instead of '$$type' because older projects use
|
|
1528
|
-
// the 'type' property in default values
|
|
1529
|
-
if ('type' in rest) {
|
|
1530
|
-
modelName = rest.type;
|
|
1531
|
-
rest = lodash_1.default.omit(rest, 'type');
|
|
1532
|
-
}
|
|
1533
|
-
else if (modelNames.length === 1) {
|
|
1534
|
-
modelName = modelNames[0];
|
|
1535
|
-
}
|
|
1536
|
-
}
|
|
1537
|
-
const model = modelMap[modelName];
|
|
1538
|
-
if (!model) {
|
|
1539
|
-
throw new Error(`no model with name '${modelName}' was found`);
|
|
1540
|
-
}
|
|
1541
|
-
const { document, newRefDocuments } = await createDocumentRecursively({
|
|
1542
|
-
object: rest,
|
|
1543
|
-
model: model,
|
|
1544
|
-
modelMap,
|
|
1545
|
-
locale,
|
|
1546
|
-
userContext,
|
|
1547
|
-
contentSourceInstance
|
|
1548
|
-
});
|
|
1549
|
-
return {
|
|
1550
|
-
field: {
|
|
1551
|
-
type: 'reference',
|
|
1552
|
-
refType: 'document',
|
|
1553
|
-
refId: document.id
|
|
1554
|
-
},
|
|
1555
|
-
newRefDocuments: [document, ...newRefDocuments]
|
|
1556
|
-
};
|
|
1557
|
-
}
|
|
1558
|
-
}
|
|
1559
|
-
else if (modelField.type === 'list') {
|
|
1560
|
-
if (!Array.isArray(value)) {
|
|
1561
|
-
throw new Error(`value for list field must be array`);
|
|
1562
|
-
}
|
|
1563
|
-
const itemsField = modelField.items;
|
|
1564
|
-
if (!itemsField) {
|
|
1565
|
-
throw new Error(`list field does not define items`);
|
|
1566
|
-
}
|
|
1567
|
-
const arrayResult = await (0, utils_1.mapPromise)(value, async (item, index) => {
|
|
1568
|
-
return createNestedField({
|
|
1569
|
-
value: item,
|
|
1570
|
-
modelField: itemsField,
|
|
1571
|
-
fieldPath: fieldPath.concat(index),
|
|
1572
|
-
modelMap,
|
|
1573
|
-
locale,
|
|
1574
|
-
userContext,
|
|
1575
|
-
contentSourceInstance
|
|
1576
|
-
});
|
|
1577
|
-
});
|
|
1578
|
-
return {
|
|
1579
|
-
field: {
|
|
1580
|
-
type: 'list',
|
|
1581
|
-
items: arrayResult.map((result) => result.field)
|
|
1582
|
-
},
|
|
1583
|
-
newRefDocuments: arrayResult.reduce((result, { newRefDocuments }) => result.concat(newRefDocuments), [])
|
|
1584
|
-
};
|
|
1585
|
-
}
|
|
1586
|
-
return {
|
|
1587
|
-
field: {
|
|
1588
|
-
type: modelField.type,
|
|
1589
|
-
value: value
|
|
1590
|
-
},
|
|
1591
|
-
newRefDocuments: []
|
|
1592
|
-
};
|
|
1593
|
-
}
|
|
1594
|
-
function getModelFieldForFieldAtPath(document, model, fieldPath, modelMap, locale) {
|
|
1595
|
-
if (lodash_1.default.isEmpty(fieldPath)) {
|
|
1596
|
-
throw new Error('the fieldPath can not be empty');
|
|
1597
|
-
}
|
|
1598
|
-
function getField(docField, modelField, fieldPath) {
|
|
1599
|
-
const fieldName = lodash_1.default.head(fieldPath);
|
|
1600
|
-
if (typeof fieldName === 'undefined') {
|
|
1601
|
-
throw new Error('the first fieldPath item must be string');
|
|
1602
|
-
}
|
|
1603
|
-
const childFieldPath = lodash_1.default.tail(fieldPath);
|
|
1604
|
-
let childDocField;
|
|
1605
|
-
let childModelField;
|
|
1606
|
-
switch (docField.type) {
|
|
1607
|
-
case 'object':
|
|
1608
|
-
const localizedObjectField = getDocumentFieldForLocale(docField, locale);
|
|
1609
|
-
if (!localizedObjectField) {
|
|
1610
|
-
throw new Error(`locale for field was not found`);
|
|
1611
|
-
}
|
|
1612
|
-
if (localizedObjectField.isUnset) {
|
|
1613
|
-
throw new Error(`field is not set`);
|
|
1614
|
-
}
|
|
1615
|
-
childDocField = localizedObjectField.fields[fieldName];
|
|
1616
|
-
childModelField = lodash_1.default.find(modelField.fields, (field) => field.name === fieldName);
|
|
1617
|
-
if (!childDocField || !childModelField) {
|
|
1618
|
-
throw new Error(`field ${fieldName} doesn't exist`);
|
|
1619
|
-
}
|
|
1620
|
-
if (childFieldPath.length === 0) {
|
|
1621
|
-
return childModelField;
|
|
1622
|
-
}
|
|
1623
|
-
return getField(childDocField, childModelField, childFieldPath);
|
|
1624
|
-
case 'model':
|
|
1625
|
-
const localizedModelField = getDocumentFieldForLocale(docField, locale);
|
|
1626
|
-
if (!localizedModelField) {
|
|
1627
|
-
throw new Error(`locale for field was not found`);
|
|
1628
|
-
}
|
|
1629
|
-
if (localizedModelField.isUnset) {
|
|
1630
|
-
throw new Error(`field is not set`);
|
|
1631
|
-
}
|
|
1632
|
-
const modelName = localizedModelField.srcModelName;
|
|
1633
|
-
const childModel = modelMap[modelName];
|
|
1634
|
-
if (!childModel) {
|
|
1635
|
-
throw new Error(`model ${modelName} doesn't exist`);
|
|
1636
|
-
}
|
|
1637
|
-
childModelField = lodash_1.default.find(childModel.fields, (field) => field.name === fieldName);
|
|
1638
|
-
childDocField = localizedModelField.fields[fieldName];
|
|
1639
|
-
if (!childDocField || !childModelField) {
|
|
1640
|
-
throw new Error(`field ${fieldName} doesn't exist`);
|
|
1641
|
-
}
|
|
1642
|
-
if (childFieldPath.length === 0) {
|
|
1643
|
-
return childModelField;
|
|
1644
|
-
}
|
|
1645
|
-
return getField(childDocField, childModelField, childFieldPath);
|
|
1646
|
-
case 'list':
|
|
1647
|
-
const localizedListField = getDocumentFieldForLocale(docField, locale);
|
|
1648
|
-
if (!localizedListField) {
|
|
1649
|
-
throw new Error(`locale for field was not found`);
|
|
1650
|
-
}
|
|
1651
|
-
const listItem = localizedListField.items && localizedListField.items[fieldName];
|
|
1652
|
-
const listItemsModel = modelField.items;
|
|
1653
|
-
if (!listItem || !listItemsModel) {
|
|
1654
|
-
throw new Error(`field ${fieldName} doesn't exist`);
|
|
1655
|
-
}
|
|
1656
|
-
if (childFieldPath.length === 0) {
|
|
1657
|
-
return modelField;
|
|
1658
|
-
}
|
|
1659
|
-
if (!Array.isArray(listItemsModel)) {
|
|
1660
|
-
return getField(listItem, listItemsModel, childFieldPath);
|
|
1661
|
-
}
|
|
1662
|
-
else {
|
|
1663
|
-
const fieldListItems = listItemsModel.find((listItemsModel) => listItemsModel.type === listItem.type);
|
|
1664
|
-
if (!fieldListItems) {
|
|
1665
|
-
throw new Error('cannot find matching field model');
|
|
1666
|
-
}
|
|
1667
|
-
return getField(listItem, fieldListItems, childFieldPath);
|
|
1668
|
-
}
|
|
1669
|
-
default:
|
|
1670
|
-
if (!lodash_1.default.isEmpty(childFieldPath)) {
|
|
1671
|
-
throw new Error('illegal fieldPath');
|
|
1672
|
-
}
|
|
1673
|
-
return modelField;
|
|
1674
|
-
}
|
|
1675
|
-
}
|
|
1676
|
-
const fieldName = lodash_1.default.head(fieldPath);
|
|
1677
|
-
const childFieldPath = lodash_1.default.tail(fieldPath);
|
|
1678
|
-
if (typeof fieldName !== 'string') {
|
|
1679
|
-
throw new Error('the first fieldPath item must be string');
|
|
1680
|
-
}
|
|
1681
|
-
const childDocField = document.fields[fieldName];
|
|
1682
|
-
const childModelField = lodash_1.default.find(model.fields, { name: fieldName });
|
|
1683
|
-
if (!childDocField || !childModelField) {
|
|
1684
|
-
throw new Error(`field ${fieldName} doesn't exist`);
|
|
1685
|
-
}
|
|
1686
|
-
if (childFieldPath.length === 0) {
|
|
1687
|
-
return childModelField;
|
|
1688
|
-
}
|
|
1689
|
-
return getField(childDocField, childModelField, childFieldPath);
|
|
1690
|
-
}
|
|
1691
|
-
async function convertOperationField({ operationField, fieldPath, modelField, modelMap, locale, userContext, contentSourceInstance }) {
|
|
1692
|
-
// for insert operations, the modelField will be of the list, so get the modelField of the list items
|
|
1693
|
-
const modelFieldOrListItems = modelField.type === 'list' ? modelField.items : modelField;
|
|
1694
|
-
switch (operationField.type) {
|
|
1695
|
-
case 'object': {
|
|
1696
|
-
const result = await createNestedObjectRecursively({
|
|
1697
|
-
object: operationField.object,
|
|
1698
|
-
modelFields: modelFieldOrListItems.fields,
|
|
1699
|
-
fieldPath: fieldPath,
|
|
1700
|
-
modelMap,
|
|
1701
|
-
locale,
|
|
1702
|
-
userContext,
|
|
1703
|
-
contentSourceInstance
|
|
1704
|
-
});
|
|
1705
|
-
return {
|
|
1706
|
-
type: operationField.type,
|
|
1707
|
-
fields: result.fields
|
|
1708
|
-
};
|
|
1709
|
-
}
|
|
1710
|
-
case 'model': {
|
|
1711
|
-
const model = modelMap[operationField.modelName];
|
|
1712
|
-
if (!model) {
|
|
1713
|
-
throw new Error(`error updating document, could not find document model: '${operationField.modelName}'`);
|
|
1714
|
-
}
|
|
1715
|
-
const result = await createNestedObjectRecursively({
|
|
1716
|
-
object: operationField.object,
|
|
1717
|
-
modelFields: model.fields,
|
|
1718
|
-
fieldPath,
|
|
1719
|
-
modelMap,
|
|
1720
|
-
locale,
|
|
1721
|
-
userContext,
|
|
1722
|
-
contentSourceInstance
|
|
1723
|
-
});
|
|
1724
|
-
return {
|
|
1725
|
-
type: operationField.type,
|
|
1726
|
-
modelName: operationField.modelName,
|
|
1727
|
-
fields: result.fields
|
|
1728
|
-
};
|
|
1729
|
-
}
|
|
1730
|
-
case 'list': {
|
|
1731
|
-
if (modelField.type !== 'list') {
|
|
1732
|
-
throw new Error(`'the operation field type '${operationField.type}' does not match the model field type '${modelField.type}'`);
|
|
1733
|
-
}
|
|
1734
|
-
const result = await (0, utils_1.mapPromise)(operationField.items, async (item, index) => {
|
|
1735
|
-
const result = await createNestedField({
|
|
1736
|
-
value: item,
|
|
1737
|
-
modelField: modelField.items,
|
|
1738
|
-
fieldPath,
|
|
1739
|
-
modelMap,
|
|
1740
|
-
locale,
|
|
1741
|
-
userContext,
|
|
1742
|
-
contentSourceInstance
|
|
1743
|
-
});
|
|
1744
|
-
return result.field;
|
|
1745
|
-
});
|
|
1746
|
-
return {
|
|
1747
|
-
type: operationField.type,
|
|
1748
|
-
items: result
|
|
1749
|
-
};
|
|
1750
|
-
}
|
|
1751
|
-
case 'string':
|
|
1752
|
-
// When inserting new string value into a list, the client does not
|
|
1753
|
-
// send value. Set an empty string value.
|
|
1754
|
-
if (typeof operationField.value !== 'string') {
|
|
1755
|
-
return {
|
|
1756
|
-
type: operationField.type,
|
|
1757
|
-
value: ''
|
|
1758
|
-
};
|
|
1759
|
-
}
|
|
1760
|
-
return operationField;
|
|
1761
|
-
case 'enum':
|
|
1762
|
-
// When inserting new enum value into a list, the client does not
|
|
1763
|
-
// send value. Set first option as the value.
|
|
1764
|
-
if (typeof operationField.value !== 'string') {
|
|
1765
|
-
if (modelFieldOrListItems.type !== 'enum') {
|
|
1766
|
-
throw new Error(`'the operation field type 'enum' does not match the model field type '${modelFieldOrListItems.type}'`);
|
|
1767
|
-
}
|
|
1768
|
-
const option = modelFieldOrListItems.options[0];
|
|
1769
|
-
const optionValue = typeof option === 'object' ? option.value : option;
|
|
1770
|
-
return {
|
|
1771
|
-
type: operationField.type,
|
|
1772
|
-
value: optionValue
|
|
1773
|
-
};
|
|
1774
|
-
}
|
|
1775
|
-
return operationField;
|
|
1776
|
-
case 'image':
|
|
1777
|
-
return operationField;
|
|
1778
|
-
default:
|
|
1779
|
-
return operationField;
|
|
1780
|
-
}
|
|
1781
|
-
}
|
|
1782
|
-
function getDocumentFieldForLocale(docField, locale) {
|
|
1783
|
-
if (docField.localized) {
|
|
1784
|
-
if (!locale) {
|
|
1785
|
-
return null;
|
|
1786
|
-
}
|
|
1787
|
-
const { localized, locales, ...base } = docField;
|
|
1788
|
-
const localizedField = locales[locale];
|
|
1789
|
-
if (!localizedField) {
|
|
1790
|
-
return null;
|
|
1791
|
-
}
|
|
1792
|
-
return {
|
|
1793
|
-
...base,
|
|
1794
|
-
...localizedField
|
|
1795
|
-
};
|
|
1796
|
-
}
|
|
1797
|
-
else {
|
|
1798
|
-
return docField;
|
|
1799
|
-
}
|
|
1800
|
-
}
|
|
1801
1016
|
function getCSIDocumentsAndAssetsFromContentSourceDataByIds(contentSourceData, objects) {
|
|
1802
1017
|
const documents = [];
|
|
1803
1018
|
const assets = [];
|
|
@@ -1818,7 +1033,7 @@ function internalValidateContent(documents, assets, contentSourceData) {
|
|
|
1818
1033
|
const errors = [];
|
|
1819
1034
|
lodash_1.default.forEach(documents, (document) => {
|
|
1820
1035
|
lodash_1.default.forEach(document.fields, (documentField, fieldName) => {
|
|
1821
|
-
const localizedField = (0,
|
|
1036
|
+
const localizedField = (0, types_1.getLocalizedFieldForLocale)(documentField);
|
|
1822
1037
|
errors.push(...validateDocumentFields(document, localizedField, [fieldName], contentSourceData));
|
|
1823
1038
|
});
|
|
1824
1039
|
});
|
|
@@ -1828,13 +1043,13 @@ function validateDocumentFields(document, documentField, fieldPath, contentSourc
|
|
|
1828
1043
|
const errors = [];
|
|
1829
1044
|
if (documentField.type === 'object') {
|
|
1830
1045
|
lodash_1.default.forEach(documentField.fields, (documentField, fieldName) => {
|
|
1831
|
-
const localizedField = (0,
|
|
1046
|
+
const localizedField = (0, types_1.getLocalizedFieldForLocale)(documentField);
|
|
1832
1047
|
errors.push(...validateDocumentFields(document, localizedField, fieldPath.concat(fieldName), contentSourceData));
|
|
1833
1048
|
});
|
|
1834
1049
|
}
|
|
1835
1050
|
else if (documentField.type === 'model') {
|
|
1836
1051
|
lodash_1.default.forEach(documentField.fields, (documentField, fieldName) => {
|
|
1837
|
-
const localizedField = (0,
|
|
1052
|
+
const localizedField = (0, types_1.getLocalizedFieldForLocale)(documentField);
|
|
1838
1053
|
errors.push(...validateDocumentFields(document, localizedField, fieldPath.concat(fieldName), contentSourceData));
|
|
1839
1054
|
});
|
|
1840
1055
|
}
|
|
@@ -1853,7 +1068,7 @@ function validateDocumentFields(document, documentField, fieldPath, contentSourc
|
|
|
1853
1068
|
}
|
|
1854
1069
|
else if (documentField.type === 'list') {
|
|
1855
1070
|
lodash_1.default.forEach(documentField.items, (documentField, i) => {
|
|
1856
|
-
const localizedField = (0,
|
|
1071
|
+
const localizedField = (0, types_1.getLocalizedFieldForLocale)(documentField);
|
|
1857
1072
|
errors.push(...validateDocumentFields(document, documentField, fieldPath.concat(i), contentSourceData));
|
|
1858
1073
|
});
|
|
1859
1074
|
}
|