@stackbit/cms-core 0.1.3 → 0.1.4-alpha.0
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/content-source-interface.d.ts +9 -14
- package/dist/content-source-interface.d.ts.map +1 -1
- package/dist/content-source-interface.js.map +1 -1
- package/dist/content-store-types.d.ts +25 -24
- package/dist/content-store-types.d.ts.map +1 -1
- package/dist/content-store-utils.d.ts +9 -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 +17 -4
- package/dist/content-store.d.ts.map +1 -1
- package/dist/content-store.js +147 -949
- package/dist/content-store.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- 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 +68 -0
- package/dist/utils/create-update-csi-docs.d.ts.map +1 -0
- package/dist/utils/create-update-csi-docs.js +376 -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 +6 -5
- package/src/content-source-interface.ts +6 -15
- package/src/content-store-types.ts +23 -10
- package/src/content-store-utils.ts +149 -0
- package/src/content-store.ts +137 -1079
- package/src/index.ts +3 -1
- package/src/types/search-filter.ts +53 -0
- package/src/utils/create-update-csi-docs.ts +440 -0
- package/src/utils/csi-to-store-docs-converter.ts +365 -0
- package/src/utils/search-utils.ts +436 -0
- package/src/utils/store-to-api-docs-converter.ts +246 -0
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"));
|
|
11
10
|
const sdk_1 = require("@stackbit/sdk");
|
|
12
11
|
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
12
|
const timer_1 = require("./utils/timer");
|
|
13
|
+
const search_utils_1 = require("./utils/search-utils");
|
|
14
|
+
const content_source_interface_1 = require("./content-source-interface");
|
|
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({
|
|
@@ -219,10 +222,19 @@ class ContentStore {
|
|
|
219
222
|
models = (_c = config === null || config === void 0 ? void 0 : config.models) !== null && _c !== void 0 ? _c : [];
|
|
220
223
|
// TODO: load presets externally from config, and create additional map
|
|
221
224
|
// 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
|
|
225
|
+
// Augment presets with srcType and srcProjectId if they don't exist
|
|
226
|
+
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) => {
|
|
227
|
+
var _a, _b, _c;
|
|
228
|
+
const preset = (_a = config === null || config === void 0 ? void 0 : config.presets) === null || _a === void 0 ? void 0 : _a[presetId];
|
|
229
|
+
lodash_1.default.set(accum, [presetId], {
|
|
230
|
+
...preset,
|
|
231
|
+
srcType: (_b = preset === null || preset === void 0 ? void 0 : preset.srcType) !== null && _b !== void 0 ? _b : contentSourceInstance.getContentSourceType(),
|
|
232
|
+
srcProjectId: (_c = preset === null || preset === void 0 ? void 0 : preset.srcProjectId) !== null && _c !== void 0 ? _c : contentSourceInstance.getProjectId()
|
|
233
|
+
});
|
|
234
|
+
return accum;
|
|
235
|
+
}, {});
|
|
224
236
|
}
|
|
225
|
-
if ((
|
|
237
|
+
if ((_e = this.rawStackbitConfig) === null || _e === void 0 ? void 0 : _e.mapModels) {
|
|
226
238
|
models = this.rawStackbitConfig.mapModels({
|
|
227
239
|
models: models,
|
|
228
240
|
contentSourceType: contentSourceInstance.getContentSourceType(),
|
|
@@ -235,13 +247,13 @@ class ContentStore {
|
|
|
235
247
|
const csiDocumentMap = lodash_1.default.keyBy(csiDocuments, 'id');
|
|
236
248
|
const csiAssetMap = lodash_1.default.keyBy(csiAssets, 'id');
|
|
237
249
|
const csiModelMap = lodash_1.default.keyBy(csiModels, 'name');
|
|
238
|
-
const contentStoreDocuments = mapCSIDocumentsToStoreDocuments({
|
|
250
|
+
const contentStoreDocuments = (0, csi_to_store_docs_converter_1.mapCSIDocumentsToStoreDocuments)({
|
|
239
251
|
csiDocuments,
|
|
240
252
|
contentSourceInstance,
|
|
241
253
|
modelMap,
|
|
242
254
|
defaultLocaleCode
|
|
243
255
|
});
|
|
244
|
-
const contentStoreAssets = mapCSIAssetsToStoreAssets({
|
|
256
|
+
const contentStoreAssets = (0, csi_to_store_docs_converter_1.mapCSIAssetsToStoreAssets)({
|
|
245
257
|
csiAssets,
|
|
246
258
|
contentSourceInstance,
|
|
247
259
|
defaultLocaleCode
|
|
@@ -353,13 +365,13 @@ class ContentStore {
|
|
|
353
365
|
});
|
|
354
366
|
});
|
|
355
367
|
// map csi documents and assets to content store documents and assets
|
|
356
|
-
const documents = mapCSIDocumentsToStoreDocuments({
|
|
368
|
+
const documents = (0, csi_to_store_docs_converter_1.mapCSIDocumentsToStoreDocuments)({
|
|
357
369
|
csiDocuments: contentChangeEvent.documents,
|
|
358
370
|
contentSourceInstance: contentSourceData.instance,
|
|
359
371
|
modelMap: contentSourceData.modelMap,
|
|
360
372
|
defaultLocaleCode: contentSourceData.defaultLocaleCode
|
|
361
373
|
});
|
|
362
|
-
const assets = mapCSIAssetsToStoreAssets({
|
|
374
|
+
const assets = (0, csi_to_store_docs_converter_1.mapCSIAssetsToStoreAssets)({
|
|
363
375
|
csiAssets: contentChangeEvent.assets,
|
|
364
376
|
contentSourceInstance: contentSourceData.instance,
|
|
365
377
|
defaultLocaleCode: contentSourceData.defaultLocaleCode
|
|
@@ -431,25 +443,56 @@ class ContentStore {
|
|
|
431
443
|
return (_a = this.presets) !== null && _a !== void 0 ? _a : {};
|
|
432
444
|
}
|
|
433
445
|
getContentSourceEnvironment({ srcProjectId, srcType }) {
|
|
434
|
-
const contentSourceId = getContentSourceId(srcType, srcProjectId);
|
|
446
|
+
const contentSourceId = (0, content_store_utils_1.getContentSourceId)(srcType, srcProjectId);
|
|
435
447
|
const contentSourceData = this.getContentSourceDataByIdOrThrow(contentSourceId);
|
|
436
448
|
return contentSourceData.instance.getProjectEnvironment();
|
|
437
449
|
}
|
|
438
|
-
hasAccess({ srcType, srcProjectId, user }) {
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
450
|
+
async hasAccess({ srcType, srcProjectId, user }) {
|
|
451
|
+
let contentSourceDataArr;
|
|
452
|
+
if (srcType && srcProjectId) {
|
|
453
|
+
const contentSourceId = (0, content_store_utils_1.getContentSourceId)(srcType, srcProjectId);
|
|
454
|
+
const contentSourceData = this.getContentSourceDataByIdOrThrow(contentSourceId);
|
|
455
|
+
contentSourceDataArr = [contentSourceData];
|
|
456
|
+
}
|
|
457
|
+
else {
|
|
458
|
+
contentSourceDataArr = Object.values(this.contentSourceDataById);
|
|
459
|
+
}
|
|
460
|
+
return (0, utils_1.reducePromise)(contentSourceDataArr, async (accum, contentSourceData) => {
|
|
461
|
+
const srcType = contentSourceData.type;
|
|
462
|
+
const srcProjectId = contentSourceData.projectId;
|
|
463
|
+
const userContext = (0, content_store_utils_1.getUserContextForSrcType)(srcType, user);
|
|
464
|
+
let result = await contentSourceData.instance.hasAccess({ userContext });
|
|
465
|
+
// backwards compatibility with older CSI version
|
|
466
|
+
if (typeof result === 'boolean') {
|
|
467
|
+
result = {
|
|
468
|
+
hasConnection: result,
|
|
469
|
+
hasPermissions: result
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
return {
|
|
473
|
+
hasConnection: accum.hasConnection && result.hasConnection,
|
|
474
|
+
hasPermissions: accum.hasPermissions && result.hasPermissions,
|
|
475
|
+
contentSources: accum.contentSources.concat({
|
|
476
|
+
srcType,
|
|
477
|
+
srcProjectId,
|
|
478
|
+
...result
|
|
479
|
+
})
|
|
480
|
+
};
|
|
481
|
+
}, {
|
|
482
|
+
hasConnection: true,
|
|
483
|
+
hasPermissions: true,
|
|
484
|
+
contentSources: []
|
|
485
|
+
});
|
|
443
486
|
}
|
|
444
487
|
hasChanges({ srcType, srcProjectId, documents }) {
|
|
445
488
|
let result;
|
|
446
489
|
if (srcType && srcProjectId) {
|
|
447
|
-
const contentSourceId = getContentSourceId(srcType, srcProjectId);
|
|
490
|
+
const contentSourceId = (0, content_store_utils_1.getContentSourceId)(srcType, srcProjectId);
|
|
448
491
|
const contentSourceData = this.getContentSourceDataByIdOrThrow(contentSourceId);
|
|
449
492
|
result = [...contentSourceData.documents, ...contentSourceData.assets];
|
|
450
493
|
}
|
|
451
494
|
else if (documents && documents.length > 0) {
|
|
452
|
-
const documentsBySourceId = lodash_1.default.groupBy(documents, (document) => getContentSourceId(document.srcType, document.srcProjectId));
|
|
495
|
+
const documentsBySourceId = lodash_1.default.groupBy(documents, (document) => (0, content_store_utils_1.getContentSourceId)(document.srcType, document.srcProjectId));
|
|
453
496
|
result = lodash_1.default.reduce(documentsBySourceId, (result, documents, contentSourceId) => {
|
|
454
497
|
const contentSourceData = this.getContentSourceDataByIdOrThrow(contentSourceId);
|
|
455
498
|
for (const document of documents) {
|
|
@@ -479,7 +522,7 @@ class ContentStore {
|
|
|
479
522
|
};
|
|
480
523
|
}
|
|
481
524
|
getDocument({ srcDocumentId, srcProjectId, srcType }) {
|
|
482
|
-
const contentSourceId = getContentSourceId(srcType, srcProjectId);
|
|
525
|
+
const contentSourceId = (0, content_store_utils_1.getContentSourceId)(srcType, srcProjectId);
|
|
483
526
|
const contentSourceData = this.getContentSourceDataByIdOrThrow(contentSourceId);
|
|
484
527
|
return contentSourceData.documentMap[srcDocumentId];
|
|
485
528
|
}
|
|
@@ -489,7 +532,7 @@ class ContentStore {
|
|
|
489
532
|
}, []);
|
|
490
533
|
}
|
|
491
534
|
getAsset({ srcAssetId, srcProjectId, srcType }) {
|
|
492
|
-
const contentSourceId = getContentSourceId(srcType, srcProjectId);
|
|
535
|
+
const contentSourceId = (0, content_store_utils_1.getContentSourceId)(srcType, srcProjectId);
|
|
493
536
|
const contentSourceData = this.getContentSourceDataByIdOrThrow(contentSourceId);
|
|
494
537
|
return contentSourceData.assetMap[srcAssetId];
|
|
495
538
|
}
|
|
@@ -501,21 +544,21 @@ class ContentStore {
|
|
|
501
544
|
getLocalizedApiObjects({ locale }) {
|
|
502
545
|
return lodash_1.default.reduce(this.contentSourceDataById, (objects, contentSourceData) => {
|
|
503
546
|
locale = locale !== null && locale !== void 0 ? locale : contentSourceData.defaultLocaleCode;
|
|
504
|
-
const documentObjects = mapDocumentsToLocalizedApiObjects(contentSourceData.documents, locale);
|
|
505
|
-
const imageObjects = mapAssetsToLocalizedApiImages(contentSourceData.assets, locale);
|
|
547
|
+
const documentObjects = (0, store_to_api_docs_converter_1.mapDocumentsToLocalizedApiObjects)(contentSourceData.documents, locale);
|
|
548
|
+
const imageObjects = (0, store_to_api_docs_converter_1.mapAssetsToLocalizedApiImages)(contentSourceData.assets, locale);
|
|
506
549
|
return objects.concat(documentObjects, imageObjects);
|
|
507
550
|
}, []);
|
|
508
551
|
}
|
|
509
552
|
getApiAssets({ srcType, srcProjectId, pageSize = 20, pageNum = 1, searchQuery } = {}) {
|
|
510
553
|
let assets;
|
|
511
554
|
if (srcProjectId && srcType) {
|
|
512
|
-
const contentSourceId = getContentSourceId(srcType, srcProjectId);
|
|
555
|
+
const contentSourceId = (0, content_store_utils_1.getContentSourceId)(srcType, srcProjectId);
|
|
513
556
|
const contentSourceData = this.getContentSourceDataByIdOrThrow(contentSourceId);
|
|
514
|
-
assets = mapStoreAssetsToAPIAssets(contentSourceData.assets, contentSourceData.defaultLocaleCode);
|
|
557
|
+
assets = (0, store_to_api_docs_converter_1.mapStoreAssetsToAPIAssets)(contentSourceData.assets, contentSourceData.defaultLocaleCode);
|
|
515
558
|
}
|
|
516
559
|
else {
|
|
517
560
|
assets = lodash_1.default.reduce(this.contentSourceDataById, (result, contentSourceData) => {
|
|
518
|
-
const assets = mapStoreAssetsToAPIAssets(contentSourceData.assets, contentSourceData.defaultLocaleCode);
|
|
561
|
+
const assets = (0, store_to_api_docs_converter_1.mapStoreAssetsToAPIAssets)(contentSourceData.assets, contentSourceData.defaultLocaleCode);
|
|
519
562
|
return result.concat(assets);
|
|
520
563
|
}, []);
|
|
521
564
|
}
|
|
@@ -537,7 +580,7 @@ class ContentStore {
|
|
|
537
580
|
}
|
|
538
581
|
async createAndLinkDocument({ srcType, srcProjectId, srcDocumentId, fieldPath, modelName, object, index, locale, user }) {
|
|
539
582
|
this.logger.debug('createAndLinkDocument', { srcType, srcProjectId, srcDocumentId, fieldPath, modelName, index, locale });
|
|
540
|
-
const contentSourceId = getContentSourceId(srcType, srcProjectId);
|
|
583
|
+
const contentSourceId = (0, content_store_utils_1.getContentSourceId)(srcType, srcProjectId);
|
|
541
584
|
const contentSourceData = this.getContentSourceDataByIdOrThrow(contentSourceId);
|
|
542
585
|
// get the document that is being updated
|
|
543
586
|
const document = contentSourceData.documentMap[srcDocumentId];
|
|
@@ -554,7 +597,7 @@ class ContentStore {
|
|
|
554
597
|
}
|
|
555
598
|
// get the 'reference' model field in the updated document that will be used to link the new document
|
|
556
599
|
locale = locale !== null && locale !== void 0 ? locale : contentSourceData.defaultLocaleCode;
|
|
557
|
-
const modelField = getModelFieldForFieldAtPath(document, model, fieldPath, csiModelMap, locale);
|
|
600
|
+
const modelField = (0, content_store_utils_1.getModelFieldForFieldAtPath)(document, model, fieldPath, csiModelMap, locale);
|
|
558
601
|
if (!modelField) {
|
|
559
602
|
throw Error(`the "fieldPath" points to non existing model field: ${fieldPath.join('.')}`);
|
|
560
603
|
}
|
|
@@ -579,7 +622,7 @@ class ContentStore {
|
|
|
579
622
|
user: user
|
|
580
623
|
});
|
|
581
624
|
// update the document by linking the field to the created document
|
|
582
|
-
const userContext = getUserContextForSrcType(srcType, user);
|
|
625
|
+
const userContext = (0, content_store_utils_1.getUserContextForSrcType)(srcType, user);
|
|
583
626
|
const field = {
|
|
584
627
|
type: 'reference',
|
|
585
628
|
refType: 'document',
|
|
@@ -613,7 +656,7 @@ class ContentStore {
|
|
|
613
656
|
async uploadAndLinkAsset({ srcType, srcProjectId, srcDocumentId, fieldPath, asset, index, locale, user }) {
|
|
614
657
|
this.logger.debug('uploadAndLinkAsset', { srcType, srcProjectId, srcDocumentId, fieldPath, index, locale });
|
|
615
658
|
// get the document that is being updated
|
|
616
|
-
const contentSourceId = getContentSourceId(srcType, srcProjectId);
|
|
659
|
+
const contentSourceId = (0, content_store_utils_1.getContentSourceId)(srcType, srcProjectId);
|
|
617
660
|
const contentSourceData = this.getContentSourceDataByIdOrThrow(contentSourceId);
|
|
618
661
|
const document = contentSourceData.documentMap[srcDocumentId];
|
|
619
662
|
const csiDocument = contentSourceData.csiDocumentMap[srcDocumentId];
|
|
@@ -629,7 +672,7 @@ class ContentStore {
|
|
|
629
672
|
}
|
|
630
673
|
// get the 'reference' model field in the updated document that will be used to link the new asset
|
|
631
674
|
locale = locale !== null && locale !== void 0 ? locale : contentSourceData.defaultLocaleCode;
|
|
632
|
-
const modelField = getModelFieldForFieldAtPath(document, csiModel, fieldPath, csiModelMap, locale);
|
|
675
|
+
const modelField = (0, content_store_utils_1.getModelFieldForFieldAtPath)(document, csiModel, fieldPath, csiModelMap, locale);
|
|
633
676
|
if (!modelField) {
|
|
634
677
|
throw Error(`the "fieldPath" points to non existing model field: ${fieldPath.join('.')}`);
|
|
635
678
|
}
|
|
@@ -638,7 +681,7 @@ class ContentStore {
|
|
|
638
681
|
throw Error(`error in "uploadAndLinkAsset", this operation can only be used on reference and image fields: ${fieldPath.join('.')}`);
|
|
639
682
|
}
|
|
640
683
|
// upload the new asset
|
|
641
|
-
const userContext = getUserContextForSrcType(srcType, user);
|
|
684
|
+
const userContext = (0, content_store_utils_1.getUserContextForSrcType)(srcType, user);
|
|
642
685
|
const result = await contentSourceData.instance.uploadAsset({
|
|
643
686
|
url: asset.url,
|
|
644
687
|
fileName: asset.metadata.name,
|
|
@@ -679,22 +722,22 @@ class ContentStore {
|
|
|
679
722
|
}
|
|
680
723
|
async createDocument({ srcType, srcProjectId, modelName, object, locale, user }) {
|
|
681
724
|
this.logger.debug('createDocument', { srcType, srcProjectId, modelName, locale });
|
|
682
|
-
const contentSourceId = getContentSourceId(srcType, srcProjectId);
|
|
725
|
+
const contentSourceId = (0, content_store_utils_1.getContentSourceId)(srcType, srcProjectId);
|
|
683
726
|
const contentSourceData = this.getContentSourceDataByIdOrThrow(contentSourceId);
|
|
684
727
|
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({
|
|
728
|
+
const csiModelMap = contentSourceData.csiModelMap;
|
|
729
|
+
const userContext = (0, content_store_utils_1.getUserContextForSrcType)(srcType, user);
|
|
730
|
+
const resolvedLocale = locale !== null && locale !== void 0 ? locale : contentSourceData.defaultLocaleCode;
|
|
731
|
+
const result = await (0, create_update_csi_docs_1.createDocumentRecursively)({
|
|
692
732
|
object,
|
|
693
|
-
|
|
733
|
+
modelName,
|
|
694
734
|
modelMap,
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
735
|
+
createDocument: (0, create_update_csi_docs_1.getCreateDocumentThunk)({
|
|
736
|
+
locale: resolvedLocale,
|
|
737
|
+
csiModelMap,
|
|
738
|
+
userContext,
|
|
739
|
+
contentSourceInstance: contentSourceData.instance
|
|
740
|
+
})
|
|
698
741
|
});
|
|
699
742
|
this.logger.debug('created document', { srcType, srcProjectId, srcDocumentId: result.document.id, modelName });
|
|
700
743
|
// do not update cache in contentSourceData.documents and documentMap,
|
|
@@ -706,9 +749,9 @@ class ContentStore {
|
|
|
706
749
|
}
|
|
707
750
|
async updateDocument({ srcType, srcProjectId, srcDocumentId, updateOperations, user }) {
|
|
708
751
|
this.logger.debug('updateDocument');
|
|
709
|
-
const contentSourceId = getContentSourceId(srcType, srcProjectId);
|
|
752
|
+
const contentSourceId = (0, content_store_utils_1.getContentSourceId)(srcType, srcProjectId);
|
|
710
753
|
const contentSourceData = this.getContentSourceDataByIdOrThrow(contentSourceId);
|
|
711
|
-
const userContext = getUserContextForSrcType(srcType, user);
|
|
754
|
+
const userContext = (0, content_store_utils_1.getUserContextForSrcType)(srcType, user);
|
|
712
755
|
const document = contentSourceData.documentMap[srcDocumentId];
|
|
713
756
|
const csiDocument = contentSourceData.csiDocumentMap[srcDocumentId];
|
|
714
757
|
if (!document || !csiDocument) {
|
|
@@ -724,17 +767,20 @@ class ContentStore {
|
|
|
724
767
|
const operations = await (0, utils_1.mapPromise)(updateOperations, async (updateOperation) => {
|
|
725
768
|
var _a;
|
|
726
769
|
const locale = (_a = updateOperation.locale) !== null && _a !== void 0 ? _a : contentSourceData.defaultLocaleCode;
|
|
727
|
-
const modelField = getModelFieldForFieldAtPath(document, model, updateOperation.fieldPath, modelMap, locale);
|
|
770
|
+
const modelField = (0, content_store_utils_1.getModelFieldForFieldAtPath)(document, model, updateOperation.fieldPath, modelMap, locale);
|
|
728
771
|
switch (updateOperation.opType) {
|
|
729
772
|
case 'set':
|
|
730
|
-
const field = await convertOperationField({
|
|
773
|
+
const field = await (0, create_update_csi_docs_1.convertOperationField)({
|
|
731
774
|
operationField: updateOperation.field,
|
|
732
775
|
fieldPath: updateOperation.fieldPath,
|
|
733
|
-
locale: updateOperation.locale,
|
|
734
776
|
modelField,
|
|
735
777
|
modelMap,
|
|
736
|
-
|
|
737
|
-
|
|
778
|
+
createDocument: (0, create_update_csi_docs_1.getCreateDocumentThunk)({
|
|
779
|
+
locale: updateOperation.locale,
|
|
780
|
+
csiModelMap,
|
|
781
|
+
userContext,
|
|
782
|
+
contentSourceInstance: contentSourceData.instance
|
|
783
|
+
})
|
|
738
784
|
});
|
|
739
785
|
return {
|
|
740
786
|
...updateOperation,
|
|
@@ -744,14 +790,17 @@ class ContentStore {
|
|
|
744
790
|
case 'unset':
|
|
745
791
|
return { ...updateOperation, modelField };
|
|
746
792
|
case 'insert':
|
|
747
|
-
const item = await convertOperationField({
|
|
793
|
+
const item = await (0, create_update_csi_docs_1.convertOperationField)({
|
|
748
794
|
operationField: updateOperation.item,
|
|
749
795
|
fieldPath: updateOperation.fieldPath,
|
|
750
|
-
locale: updateOperation.locale,
|
|
751
796
|
modelField,
|
|
752
797
|
modelMap,
|
|
753
|
-
|
|
754
|
-
|
|
798
|
+
createDocument: (0, create_update_csi_docs_1.getCreateDocumentThunk)({
|
|
799
|
+
locale: updateOperation.locale,
|
|
800
|
+
csiModelMap,
|
|
801
|
+
userContext,
|
|
802
|
+
contentSourceInstance: contentSourceData.instance
|
|
803
|
+
})
|
|
755
804
|
});
|
|
756
805
|
return {
|
|
757
806
|
...updateOperation,
|
|
@@ -778,22 +827,24 @@ class ContentStore {
|
|
|
778
827
|
}
|
|
779
828
|
async duplicateDocument({ srcType, srcProjectId, srcDocumentId, object, user }) {
|
|
780
829
|
this.logger.debug('duplicateDocument');
|
|
781
|
-
const contentSourceId = getContentSourceId(srcType, srcProjectId);
|
|
830
|
+
const contentSourceId = (0, content_store_utils_1.getContentSourceId)(srcType, srcProjectId);
|
|
782
831
|
const contentSourceData = this.getContentSourceDataByIdOrThrow(contentSourceId);
|
|
783
832
|
const document = contentSourceData.documentMap[srcDocumentId];
|
|
784
833
|
if (!document) {
|
|
785
834
|
throw new Error(`no document with id '${srcDocumentId}' was found in ${contentSourceData.id}`);
|
|
786
835
|
}
|
|
787
836
|
const modelMap = contentSourceData.modelMap;
|
|
837
|
+
const csiModelMap = contentSourceData.csiModelMap;
|
|
788
838
|
const model = modelMap[document.srcModelName];
|
|
789
|
-
|
|
839
|
+
const csiModel = csiModelMap[document.srcModelName];
|
|
840
|
+
if (!model || !csiModel) {
|
|
790
841
|
throw new Error(`no model with name '${document.srcModelName}' was found`);
|
|
791
842
|
}
|
|
792
|
-
const userContext = getUserContextForSrcType(srcType, user);
|
|
843
|
+
const userContext = (0, content_store_utils_1.getUserContextForSrcType)(srcType, user);
|
|
793
844
|
// TODO: take the data from the provided 'object' and merge them with
|
|
794
845
|
// DocumentFields of the existing Document:
|
|
795
846
|
// Option 1: Map the DocumentFields of the existing Document into flat
|
|
796
|
-
// object with '$$ref' and '
|
|
847
|
+
// object with '$$ref' and '$$type' properties for references and
|
|
797
848
|
// nested objects (needs to be implemented), and then merge it with
|
|
798
849
|
// the provided object recursively, and then pass that object to
|
|
799
850
|
// createNestedObjectRecursively()
|
|
@@ -809,12 +860,14 @@ class ContentStore {
|
|
|
809
860
|
modelFields: model.fields,
|
|
810
861
|
modelMap: contentSourceData.modelMap
|
|
811
862
|
});
|
|
863
|
+
// When passing model and modelMap to contentSourceInstance, we have to pass
|
|
864
|
+
// the original models (i.e., csiModel and csiModelMap) that we've received
|
|
865
|
+
// from that contentSourceInstance. We can't pass internal models as they
|
|
866
|
+
// might
|
|
812
867
|
const documentResult = await contentSourceData.instance.createDocument({
|
|
813
868
|
updateOperationFields,
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
// TODO: pass csiModelMap
|
|
817
|
-
modelMap,
|
|
869
|
+
model: csiModel,
|
|
870
|
+
modelMap: csiModelMap,
|
|
818
871
|
locale: contentSourceData.defaultLocaleCode,
|
|
819
872
|
userContext
|
|
820
873
|
});
|
|
@@ -822,10 +875,10 @@ class ContentStore {
|
|
|
822
875
|
}
|
|
823
876
|
async uploadAssets({ srcType, srcProjectId, assets, locale, user }) {
|
|
824
877
|
this.logger.debug('uploadAssets');
|
|
825
|
-
const contentSourceId = getContentSourceId(srcType, srcProjectId);
|
|
878
|
+
const contentSourceId = (0, content_store_utils_1.getContentSourceId)(srcType, srcProjectId);
|
|
826
879
|
const contentSourceData = this.getContentSourceDataByIdOrThrow(contentSourceId);
|
|
827
880
|
const sourceAssets = [];
|
|
828
|
-
const userContext = getUserContextForSrcType(srcType, user);
|
|
881
|
+
const userContext = (0, content_store_utils_1.getUserContextForSrcType)(srcType, user);
|
|
829
882
|
locale = locale !== null && locale !== void 0 ? locale : contentSourceData.defaultLocaleCode;
|
|
830
883
|
for (const asset of assets) {
|
|
831
884
|
let base64 = undefined;
|
|
@@ -845,17 +898,17 @@ class ContentStore {
|
|
|
845
898
|
});
|
|
846
899
|
sourceAssets.push(sourceAsset);
|
|
847
900
|
}
|
|
848
|
-
const storeAssets = mapCSIAssetsToStoreAssets({
|
|
901
|
+
const storeAssets = (0, csi_to_store_docs_converter_1.mapCSIAssetsToStoreAssets)({
|
|
849
902
|
csiAssets: sourceAssets,
|
|
850
903
|
contentSourceInstance: contentSourceData.instance,
|
|
851
904
|
defaultLocaleCode: contentSourceData.defaultLocaleCode
|
|
852
905
|
});
|
|
853
|
-
return mapStoreAssetsToAPIAssets(storeAssets, locale);
|
|
906
|
+
return (0, store_to_api_docs_converter_1.mapStoreAssetsToAPIAssets)(storeAssets, locale);
|
|
854
907
|
}
|
|
855
908
|
async deleteDocument({ srcType, srcProjectId, srcDocumentId, user }) {
|
|
856
909
|
this.logger.debug('deleteDocument');
|
|
857
|
-
const userContext = getUserContextForSrcType(srcType, user);
|
|
858
|
-
const contentSourceId = getContentSourceId(srcType, srcProjectId);
|
|
910
|
+
const userContext = (0, content_store_utils_1.getUserContextForSrcType)(srcType, user);
|
|
911
|
+
const contentSourceId = (0, content_store_utils_1.getContentSourceId)(srcType, srcProjectId);
|
|
859
912
|
const contentSourceData = this.getContentSourceDataByIdOrThrow(contentSourceId);
|
|
860
913
|
const csiDocument = contentSourceData.csiDocumentMap[srcDocumentId];
|
|
861
914
|
if (!csiDocument) {
|
|
@@ -869,13 +922,13 @@ class ContentStore {
|
|
|
869
922
|
}
|
|
870
923
|
async validateDocuments({ objects, locale, user }) {
|
|
871
924
|
this.logger.debug('validateDocuments');
|
|
872
|
-
const objectsBySourceId = lodash_1.default.groupBy(objects, (object) => getContentSourceId(object.srcType, object.srcProjectId));
|
|
925
|
+
const objectsBySourceId = lodash_1.default.groupBy(objects, (object) => (0, content_store_utils_1.getContentSourceId)(object.srcType, object.srcProjectId));
|
|
873
926
|
let errors = [];
|
|
874
927
|
for (const [contentSourceId, contentSourceObjects] of Object.entries(objectsBySourceId)) {
|
|
875
928
|
const contentSourceData = this.getContentSourceDataByIdOrThrow(contentSourceId);
|
|
876
929
|
locale = locale !== null && locale !== void 0 ? locale : contentSourceData.defaultLocaleCode;
|
|
877
930
|
const { documents, assets } = getCSIDocumentsAndAssetsFromContentSourceDataByIds(contentSourceData, contentSourceObjects);
|
|
878
|
-
const userContext = getUserContextForSrcType(contentSourceData.type, user);
|
|
931
|
+
const userContext = (0, content_store_utils_1.getUserContextForSrcType)(contentSourceData.type, user);
|
|
879
932
|
const internalValidationErrors = internalValidateContent(documents, assets, contentSourceData);
|
|
880
933
|
const validationResult = await contentSourceData.instance.validateDocuments({ documents, assets, locale, userContext });
|
|
881
934
|
errors = errors.concat(internalValidationErrors, validationResult.errors.map((validationError) => ({
|
|
@@ -904,12 +957,28 @@ class ContentStore {
|
|
|
904
957
|
);
|
|
905
958
|
*/
|
|
906
959
|
}
|
|
960
|
+
async searchDocuments(data) {
|
|
961
|
+
this.logger.debug('searchDocuments');
|
|
962
|
+
const objectsBySourceId = lodash_1.default.groupBy(data.models, (object) => (0, content_store_utils_1.getContentSourceId)(object.srcType, object.srcProjectId));
|
|
963
|
+
const documents = [];
|
|
964
|
+
const schema = {};
|
|
965
|
+
Object.keys(objectsBySourceId).forEach((contentSourceId) => {
|
|
966
|
+
const contentSourceData = this.getContentSourceDataByIdOrThrow(contentSourceId);
|
|
967
|
+
documents.push(...contentSourceData.documents);
|
|
968
|
+
lodash_1.default.set(schema, [contentSourceData.type, contentSourceData.projectId], contentSourceData.modelMap);
|
|
969
|
+
});
|
|
970
|
+
return (0, search_utils_1.searchDocuments)({
|
|
971
|
+
...data,
|
|
972
|
+
documents,
|
|
973
|
+
schema
|
|
974
|
+
});
|
|
975
|
+
}
|
|
907
976
|
async publishDocuments({ objects, user }) {
|
|
908
977
|
this.logger.debug('publishDocuments');
|
|
909
|
-
const objectsBySourceId = lodash_1.default.groupBy(objects, (object) => getContentSourceId(object.srcType, object.srcProjectId));
|
|
978
|
+
const objectsBySourceId = lodash_1.default.groupBy(objects, (object) => (0, content_store_utils_1.getContentSourceId)(object.srcType, object.srcProjectId));
|
|
910
979
|
for (const [contentSourceId, contentSourceObjects] of Object.entries(objectsBySourceId)) {
|
|
911
980
|
const contentSourceData = this.getContentSourceDataByIdOrThrow(contentSourceId);
|
|
912
|
-
const userContext = getUserContextForSrcType(contentSourceData.type, user);
|
|
981
|
+
const userContext = (0, content_store_utils_1.getUserContextForSrcType)(contentSourceData.type, user);
|
|
913
982
|
const { documents, assets } = getCSIDocumentsAndAssetsFromContentSourceDataByIds(contentSourceData, contentSourceObjects);
|
|
914
983
|
await contentSourceData.instance.publishDocuments({ documents, assets, userContext });
|
|
915
984
|
}
|
|
@@ -923,881 +992,10 @@ class ContentStore {
|
|
|
923
992
|
}
|
|
924
993
|
}
|
|
925
994
|
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
995
|
function mapStoreFieldsToOperationFields({ documentFields, modelFields, modelMap }) {
|
|
1180
996
|
// TODO: implement
|
|
1181
997
|
throw new Error(`duplicateDocument not implemented yet`);
|
|
1182
998
|
}
|
|
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
999
|
function getCSIDocumentsAndAssetsFromContentSourceDataByIds(contentSourceData, objects) {
|
|
1802
1000
|
const documents = [];
|
|
1803
1001
|
const assets = [];
|