@localazy/strapi-plugin 0.1.9 → 0.1.11-rc.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/.eslintrc +6 -2
- package/.nvmrc +1 -1
- package/admin/src/modules/@common/models/supported-content-type-fields.js +8 -0
- package/admin/src/modules/plugin-settings/components/Tree/index.js +2 -0
- package/admin/src/modules/plugin-settings/utils/get-filtered-models-schemas.js +4 -4
- package/admin/src/modules/plugin-settings/utils/get-models-tree.js +3 -1
- package/package.json +1 -1
- package/server/bootstrap.js +15 -1
- package/server/controllers/localazy-transfer-controller.js +45 -47
- package/server/functions/should-set-downloaded-property.js +16 -0
- package/server/models/supported-content-type-fields.js +8 -0
- package/server/services/index.js +2 -0
- package/server/services/strapi-i18n-service.js +4 -3
- package/server/services/strapi-localazy-i18n-service.js +104 -0
- package/server/tests/fixtures/parsed-localazy-entry-to-create-entry-cookbook.js +5761 -0
- package/server/tests/fixtures/parsed-localazy-entry-to-create-entry-restaurant-simple-menu.js +536 -0
- package/server/tests/fixtures/parsed-localazy-entry-to-update-entry.js +35157 -0
- package/server/tests/fixtures/populate-create-update-entry-with-base-entry-cookbook-empty-recipes.js +202 -0
- package/server/tests/fixtures/populate-create-update-entry-with-base-entry-cookbook.js +2700 -0
- package/server/tests/fixtures/populate-create-update-entry-with-base-entry-restaurant-simple-flat-simple.js +47 -0
- package/server/tests/fixtures/populate-create-update-entry-with-base-entry-restaurant-simple-flat-with-media.js +169 -0
- package/server/tests/fixtures/populate-create-update-entry-with-base-entry-restaurant-simple-menu-empty.js +3003 -0
- package/server/tests/fixtures/populate-create-update-entry-with-base-entry-restaurant-simple-menu-with-media.js +2057 -0
- package/server/tests/fixtures/populate-create-update-entry-with-base-entry-sample-json.js +46 -0
- package/server/tests/fixtures/{all-models-with-multimedia.js → strapi-plugin-all-models.js} +717 -540
- package/server/utils/__tests__/get-models-tree.test.js +1 -1
- package/server/utils/__tests__/parsed-localazy-entry-to-create-entry.test.js +74 -107
- package/server/utils/__tests__/parsed-localazy-entry-to-update-entry.test.js +396 -133
- package/server/utils/__tests__/populate-create-update-entry-with-base-entry.test.js +852 -0
- package/server/utils/get-full-populate-object.js +56 -0
- package/server/utils/get-models-tree.js +3 -1
- package/server/utils/model-utils.js +38 -0
- package/server/utils/parsed-localazy-entry-to-create-entry.js +24 -24
- package/server/utils/parsed-localazy-entry-to-update-entry.js +43 -4
- package/server/utils/pick-entries.js +2 -1
- package/server/utils/populate-create-update-entry-with-base-entry.js +222 -0
- package/server/utils/reset-array-keys-deep.js +19 -0
- package/server/utils/transfer-setup-utils.js +14 -0
- package/server/tests/fixtures/restaurant-model.js +0 -230
- package/server/tests/fixtures/restaurants-entries.js +0 -152
- package/server/tests/fixtures/strapi-book-with-multimedia-components-cs.js +0 -31
- package/server/tests/fixtures/stringified-book-cs.js +0 -3
- package/server/tests/fixtures/stringified-book-with-multimedia-components-cs.js +0 -3
- package/server/tests/fixtures/stringified-restaurant-cs.js +0 -3
- package/server/tests/fixtures/stringified-restaurant-de.js +0 -5
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// is taken from
|
|
2
|
+
// https://github.com/Barelydead/strapi-plugin-populate-deep
|
|
3
|
+
// based on the issue
|
|
4
|
+
// https://github.com/strapi/strapi/issues/11836
|
|
5
|
+
|
|
6
|
+
const isEmpty = require("lodash/isEmpty");
|
|
7
|
+
const merge = require("lodash/merge");
|
|
8
|
+
|
|
9
|
+
const getModelPopulationAttributes = (model) => {
|
|
10
|
+
if (model.uid === "plugin::upload.file") {
|
|
11
|
+
const { related, ...attributes } = model.attributes;
|
|
12
|
+
return attributes;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return model.attributes;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const getFullPopulateObject = (modelUid, maxDepth = 20) => {
|
|
19
|
+
if (maxDepth <= 1) {
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
if (modelUid === "admin::user") {
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const populate = {};
|
|
27
|
+
const model = strapi.getModel(modelUid);
|
|
28
|
+
for (const [key, value] of Object.entries(
|
|
29
|
+
getModelPopulationAttributes(model)
|
|
30
|
+
)) {
|
|
31
|
+
if (value) {
|
|
32
|
+
if (value.type === "component") {
|
|
33
|
+
populate[key] = getFullPopulateObject(value.component, maxDepth - 1);
|
|
34
|
+
} else if (value.type === "dynamiczone") {
|
|
35
|
+
const dynamicPopulate = value.components.reduce((prev, cur) => {
|
|
36
|
+
const curPopulate = getFullPopulateObject(cur, maxDepth - 1);
|
|
37
|
+
return curPopulate === true ? prev : merge(prev, curPopulate);
|
|
38
|
+
}, {});
|
|
39
|
+
populate[key] = isEmpty(dynamicPopulate) ? true : dynamicPopulate;
|
|
40
|
+
} else if (value.type === "relation") {
|
|
41
|
+
const relationPopulate = getFullPopulateObject(
|
|
42
|
+
value.target,
|
|
43
|
+
maxDepth - 1
|
|
44
|
+
);
|
|
45
|
+
if (relationPopulate) {
|
|
46
|
+
populate[key] = relationPopulate;
|
|
47
|
+
}
|
|
48
|
+
} else if (value.type === "media") {
|
|
49
|
+
populate[key] = true;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return isEmpty(populate) ? true : { populate };
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
module.exports = getFullPopulateObject;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
const SUPPORTED_CONTENT_TYPE_FIELDS = require("../models/supported-content-type-fields");
|
|
4
|
+
|
|
3
5
|
const getModelTree = (attributes, models) => {
|
|
4
6
|
const currentModelTree = {};
|
|
5
7
|
for (const attribute in attributes) {
|
|
@@ -12,7 +14,7 @@ const getModelTree = (attributes, models) => {
|
|
|
12
14
|
...getModelTree(nestedModel.__schema__.attributes, models),
|
|
13
15
|
};
|
|
14
16
|
} else if (
|
|
15
|
-
|
|
17
|
+
SUPPORTED_CONTENT_TYPE_FIELDS.includes(attributes[attribute].type)
|
|
16
18
|
) {
|
|
17
19
|
currentModelTree[attribute] = false;
|
|
18
20
|
} else {
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const isEmpty = require("lodash/isEmpty");
|
|
4
|
+
|
|
5
|
+
const getAttribute = (model, attribute) => {
|
|
6
|
+
if (isEmpty(model)) {
|
|
7
|
+
return undefined;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const attributeObj = model.attributes[attribute];
|
|
11
|
+
return attributeObj;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const isComponent = (attributeObj) => {
|
|
15
|
+
return attributeObj.type === "component";
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const isRepeatable = (attributeObj) => {
|
|
19
|
+
return isComponent(attributeObj) && !!attributeObj.repeatable;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const isRelation = (attributeObj) => {
|
|
23
|
+
return attributeObj.type === "relation"
|
|
24
|
+
&& attributeObj.target !== "plugin::upload.file";
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const findModel = (models, uid) => {
|
|
28
|
+
const model = models.find((model) => model.uid === uid);
|
|
29
|
+
return model;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
module.exports = {
|
|
33
|
+
getAttribute,
|
|
34
|
+
isComponent,
|
|
35
|
+
isRepeatable,
|
|
36
|
+
isRelation,
|
|
37
|
+
findModel,
|
|
38
|
+
};
|
|
@@ -1,36 +1,24 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
const set = require("lodash/set");
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
return attributeObj;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
const isComponent = (attributeObj) => {
|
|
11
|
-
return attributeObj.type === "component";
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
const isRepeatable = (attributeObj) => {
|
|
15
|
-
return isComponent(attributeObj) && !!attributeObj.repeatable;
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
const findModel = (models, uid) => {
|
|
19
|
-
const model = models.find((model) => model.uid === uid);
|
|
20
|
-
return model;
|
|
21
|
-
};
|
|
4
|
+
const get = require("lodash/get");
|
|
5
|
+
const resetArrayKeysDeep = require("./reset-array-keys-deep");
|
|
6
|
+
const { getAttribute, isComponent, isRepeatable, findModel } = require("./model-utils");
|
|
22
7
|
|
|
23
8
|
const parsedLocalazyEntryToCreateEntry = (
|
|
24
9
|
models,
|
|
25
10
|
parsedLocalazyEntry,
|
|
11
|
+
baseEntry,
|
|
26
12
|
uid,
|
|
27
13
|
locale = ""
|
|
28
14
|
) => {
|
|
29
15
|
const createEntry = {};
|
|
16
|
+
const repeatableComponentsKeystoFilter = [];
|
|
30
17
|
|
|
31
18
|
const toCreateEntry = (
|
|
32
19
|
entry,
|
|
33
20
|
model,
|
|
21
|
+
baseEntry,
|
|
34
22
|
// eslint-disable-next-line no-unused-vars
|
|
35
23
|
key = "",
|
|
36
24
|
prefix = "",
|
|
@@ -39,16 +27,25 @@ const parsedLocalazyEntryToCreateEntry = (
|
|
|
39
27
|
) => {
|
|
40
28
|
if (Array.isArray(entry)) {
|
|
41
29
|
// is array
|
|
42
|
-
|
|
43
|
-
Object.entries(entry).forEach(([, value]) => {
|
|
30
|
+
Object.entries(entry).forEach(([baseEntryItemId, value]) => {
|
|
44
31
|
if (value !== null) {
|
|
45
32
|
if (component && isRepeatableComponent) {
|
|
46
|
-
|
|
47
|
-
|
|
33
|
+
// used for indices filtering in repeatable components
|
|
34
|
+
if (!repeatableComponentsKeystoFilter.includes(prefix)) {
|
|
35
|
+
repeatableComponentsKeystoFilter.push(prefix);
|
|
36
|
+
}
|
|
37
|
+
const baseEntryRepeatableItemId = parseInt(baseEntryItemId);
|
|
38
|
+
const baseEntryRepeateableGroup = get(baseEntry, prefix);
|
|
39
|
+
if (baseEntryRepeateableGroup !== undefined) {
|
|
40
|
+
const localizedEntryRepeatableItemPosition = baseEntryRepeateableGroup.findIndex((repeatableItem) => !!repeatableItem && repeatableItem.id === baseEntryRepeatableItemId);
|
|
41
|
+
if (localizedEntryRepeatableItemPosition > -1) {
|
|
42
|
+
toCreateEntry(value, model, baseEntry, localizedEntryRepeatableItemPosition, `${prefix}.${localizedEntryRepeatableItemPosition}`, component);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
48
45
|
}
|
|
49
46
|
|
|
50
47
|
if (component && !isRepeatableComponent) {
|
|
51
|
-
toCreateEntry(value, model, `${prefix}`, `${prefix}`);
|
|
48
|
+
toCreateEntry(value, model, baseEntry, `${prefix}`, `${prefix}`);
|
|
52
49
|
}
|
|
53
50
|
}
|
|
54
51
|
});
|
|
@@ -70,6 +67,7 @@ const parsedLocalazyEntryToCreateEntry = (
|
|
|
70
67
|
toCreateEntry(
|
|
71
68
|
value,
|
|
72
69
|
componentModel,
|
|
70
|
+
baseEntry,
|
|
73
71
|
objectKey,
|
|
74
72
|
newPrefix,
|
|
75
73
|
component,
|
|
@@ -84,6 +82,7 @@ const parsedLocalazyEntryToCreateEntry = (
|
|
|
84
82
|
toCreateEntry(
|
|
85
83
|
value,
|
|
86
84
|
componentModel,
|
|
85
|
+
baseEntry,
|
|
87
86
|
objectKey,
|
|
88
87
|
newPrefix,
|
|
89
88
|
component,
|
|
@@ -104,11 +103,12 @@ const parsedLocalazyEntryToCreateEntry = (
|
|
|
104
103
|
};
|
|
105
104
|
|
|
106
105
|
const model = findModel(models, uid);
|
|
107
|
-
toCreateEntry(parsedLocalazyEntry, model);
|
|
106
|
+
toCreateEntry(parsedLocalazyEntry, model, baseEntry);
|
|
108
107
|
if (locale) {
|
|
109
108
|
createEntry.locale = locale;
|
|
110
109
|
}
|
|
111
110
|
|
|
111
|
+
resetArrayKeysDeep(createEntry, repeatableComponentsKeystoFilter);
|
|
112
112
|
return createEntry;
|
|
113
113
|
};
|
|
114
114
|
|
|
@@ -3,29 +3,68 @@
|
|
|
3
3
|
const merge = require("lodash/merge");
|
|
4
4
|
const parsedLocalazyEntryToCreateEntry = require("./parsed-localazy-entry-to-create-entry");
|
|
5
5
|
const omitDeep = require("./omit-deep");
|
|
6
|
+
const populateCreateUpdateEntryWithBaseEntry = require("./populate-create-update-entry-with-base-entry");
|
|
6
7
|
|
|
7
|
-
const parsedLocalazyEntryToUpdateEntry = (
|
|
8
|
+
const parsedLocalazyEntryToUpdateEntry = async (
|
|
8
9
|
allModels,
|
|
9
10
|
localazyEntry,
|
|
11
|
+
fullyPopulatedLocalizedEntry,
|
|
10
12
|
currentEntry,
|
|
11
|
-
|
|
13
|
+
baseEntry,
|
|
14
|
+
uid,
|
|
15
|
+
locale
|
|
12
16
|
) => {
|
|
13
17
|
const createEntry = parsedLocalazyEntryToCreateEntry(
|
|
14
18
|
allModels,
|
|
15
19
|
localazyEntry,
|
|
20
|
+
baseEntry,
|
|
16
21
|
uid
|
|
17
22
|
);
|
|
18
|
-
|
|
23
|
+
|
|
24
|
+
let updateEntry = {};
|
|
25
|
+
merge(updateEntry, currentEntry, createEntry);
|
|
19
26
|
updateEntry = omitDeep(updateEntry, [
|
|
20
27
|
"__component",
|
|
21
28
|
"locale",
|
|
22
29
|
"localizations",
|
|
23
30
|
"createdAt",
|
|
31
|
+
"createdBy",
|
|
32
|
+
"updatedAt",
|
|
33
|
+
"updatedBy",
|
|
34
|
+
"publishedAt",
|
|
35
|
+
]);
|
|
36
|
+
|
|
37
|
+
const filteredBaseEntry = omitDeep(baseEntry, [
|
|
38
|
+
// "__component", // do not omit the __component
|
|
39
|
+
"locale",
|
|
40
|
+
"localizations",
|
|
41
|
+
"createdAt",
|
|
42
|
+
"createdBy",
|
|
24
43
|
"updatedAt",
|
|
44
|
+
"updatedBy",
|
|
25
45
|
"publishedAt",
|
|
26
46
|
]);
|
|
47
|
+
const filteredFullyPopulatedLocalizedEntry = omitDeep(fullyPopulatedLocalizedEntry, [
|
|
48
|
+
// "__component", // do not omit the __component
|
|
49
|
+
"locale",
|
|
50
|
+
"localizations",
|
|
51
|
+
"createdAt",
|
|
52
|
+
"createdBy",
|
|
53
|
+
"updatedAt",
|
|
54
|
+
"updatedBy",
|
|
55
|
+
"publishedAt",
|
|
56
|
+
]);
|
|
57
|
+
const populatedEntry = await populateCreateUpdateEntryWithBaseEntry(
|
|
58
|
+
allModels,
|
|
59
|
+
updateEntry,
|
|
60
|
+
filteredBaseEntry,
|
|
61
|
+
filteredFullyPopulatedLocalizedEntry,
|
|
62
|
+
uid,
|
|
63
|
+
locale
|
|
64
|
+
);
|
|
27
65
|
|
|
28
|
-
return updateEntry;
|
|
66
|
+
// return updateEntry;
|
|
67
|
+
return populatedEntry;
|
|
29
68
|
};
|
|
30
69
|
|
|
31
70
|
module.exports = parsedLocalazyEntryToUpdateEntry;
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
const pickEntries = (flatten, pickPaths) => {
|
|
4
4
|
const pickedEntries = {};
|
|
5
5
|
Object.keys(flatten).forEach((key) => {
|
|
6
|
-
const filteredKey = key.replace(/\
|
|
6
|
+
const filteredKey = key.replace(/\[\d+\]/g, "");
|
|
7
|
+
// const filteredKey = key.replace(/\d|[[\]]+/g, "");
|
|
7
8
|
if (pickPaths.includes(filteredKey)) {
|
|
8
9
|
pickedEntries[key] = flatten[key];
|
|
9
10
|
}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const cloneDeep = require("lodash/cloneDeep");
|
|
4
|
+
const set = require("lodash/set");
|
|
5
|
+
const get = require("lodash/get");
|
|
6
|
+
const isEmpty = require("lodash/isEmpty");
|
|
7
|
+
const {
|
|
8
|
+
getAttribute,
|
|
9
|
+
isComponent,
|
|
10
|
+
isRepeatable,
|
|
11
|
+
isRelation,
|
|
12
|
+
findModel
|
|
13
|
+
} = require("./model-utils");
|
|
14
|
+
|
|
15
|
+
const doesExistInPopulatedLocalizedEntry = (val) => {
|
|
16
|
+
if (Array.isArray(val)) {
|
|
17
|
+
// is array
|
|
18
|
+
return !!val.length;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (typeof val === "object") {
|
|
22
|
+
// is object
|
|
23
|
+
return !isEmpty(val);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (val !== Object(val)) {
|
|
27
|
+
// is primitive
|
|
28
|
+
return !!val;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const getNewPrefix = (objectKey, prefix) => {
|
|
33
|
+
return prefix ? `${prefix}.${objectKey}` : objectKey;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const populateCreateUpdateEntryWithBaseEntry = async (
|
|
37
|
+
models,
|
|
38
|
+
createUpdateEntry,
|
|
39
|
+
baseEntry,
|
|
40
|
+
populatedLocalizedEntry,
|
|
41
|
+
uid,
|
|
42
|
+
locale
|
|
43
|
+
) => {
|
|
44
|
+
const populatedEntry = cloneDeep(createUpdateEntry);
|
|
45
|
+
|
|
46
|
+
const populateEntry = async (
|
|
47
|
+
partialBaseEntry,
|
|
48
|
+
model,
|
|
49
|
+
objectKey = "",
|
|
50
|
+
prefix = "",
|
|
51
|
+
component = "",
|
|
52
|
+
isRepeatableComponent = false
|
|
53
|
+
) => {
|
|
54
|
+
if (Array.isArray(partialBaseEntry)) {
|
|
55
|
+
// is array
|
|
56
|
+
const attribute = getAttribute(model, objectKey);
|
|
57
|
+
|
|
58
|
+
if (typeof attribute !== 'undefined') {
|
|
59
|
+
const newPrefix = getNewPrefix(objectKey, prefix);
|
|
60
|
+
const inCreateUpdateEntry = get(createUpdateEntry, newPrefix);
|
|
61
|
+
// TODO: decide whether add || inCreateUpdateEntry === null to the condition
|
|
62
|
+
const isMissingInCreateUpdateEntry = !!(typeof inCreateUpdateEntry === 'undefined');
|
|
63
|
+
if (isMissingInCreateUpdateEntry) {
|
|
64
|
+
const populatedLocalizedEntryVal = get(populatedLocalizedEntry, newPrefix);
|
|
65
|
+
if (doesExistInPopulatedLocalizedEntry(populatedLocalizedEntryVal)) {
|
|
66
|
+
set(populatedEntry, newPrefix, populatedLocalizedEntryVal);
|
|
67
|
+
} else {
|
|
68
|
+
set(populatedEntry, newPrefix, partialBaseEntry);
|
|
69
|
+
}
|
|
70
|
+
} else {
|
|
71
|
+
for (const [objectKey, value] of Object.entries(entry)) {
|
|
72
|
+
await populateEntry(
|
|
73
|
+
value,
|
|
74
|
+
model,
|
|
75
|
+
objectKey,
|
|
76
|
+
newPrefix
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
} else if (isRepeatableComponent) {
|
|
81
|
+
Object.entries(partialBaseEntry).forEach(async ([partialBaseEntryItemIndex, partialBaseEntryItem]) => {
|
|
82
|
+
const newPrefix = `${prefix}.${partialBaseEntryItemIndex}`;
|
|
83
|
+
await populateEntry(
|
|
84
|
+
partialBaseEntryItem,
|
|
85
|
+
model,
|
|
86
|
+
partialBaseEntryItemIndex,
|
|
87
|
+
newPrefix,
|
|
88
|
+
);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
} else if (typeof partialBaseEntry === "object") {
|
|
93
|
+
// is object
|
|
94
|
+
if (partialBaseEntry === null) {
|
|
95
|
+
partialBaseEntry = {};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
for (const [objectKey, value] of Object.entries(partialBaseEntry)) {
|
|
99
|
+
const attribute = getAttribute(model, objectKey);
|
|
100
|
+
if (typeof attribute === 'undefined') {
|
|
101
|
+
// skip...
|
|
102
|
+
continue;
|
|
103
|
+
} else if (isComponent(attribute)) {
|
|
104
|
+
// is component
|
|
105
|
+
const component = attribute.component;
|
|
106
|
+
const componentModel = findModel(models, component);
|
|
107
|
+
|
|
108
|
+
const newPrefix = getNewPrefix(objectKey, prefix);
|
|
109
|
+
const inCreateUpdateEntry = get(createUpdateEntry, newPrefix);
|
|
110
|
+
let isMissingInCreateUpdateEntry;
|
|
111
|
+
if (isRepeatable(attribute)) {
|
|
112
|
+
isMissingInCreateUpdateEntry = !!((typeof inCreateUpdateEntry === 'undefined') || (inCreateUpdateEntry && !inCreateUpdateEntry.length));
|
|
113
|
+
} else {
|
|
114
|
+
isMissingInCreateUpdateEntry = !!(typeof inCreateUpdateEntry === 'undefined' || inCreateUpdateEntry === null);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (isMissingInCreateUpdateEntry) {
|
|
118
|
+
const populatedLocalizedEntryVal = get(populatedLocalizedEntry, newPrefix);
|
|
119
|
+
let valueToSet = value;
|
|
120
|
+
if (doesExistInPopulatedLocalizedEntry(populatedLocalizedEntryVal)) {
|
|
121
|
+
valueToSet = populatedLocalizedEntryVal;
|
|
122
|
+
}
|
|
123
|
+
if (isRepeatable(attribute)) {
|
|
124
|
+
valueToSet = value.map((item) => {
|
|
125
|
+
delete item.id;
|
|
126
|
+
return {
|
|
127
|
+
__component: component,
|
|
128
|
+
...item,
|
|
129
|
+
};
|
|
130
|
+
});
|
|
131
|
+
} else {
|
|
132
|
+
if (!isEmpty(valueToSet)) {
|
|
133
|
+
delete valueToSet.id;
|
|
134
|
+
valueToSet.__component = component;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
set(populatedEntry, newPrefix, valueToSet);
|
|
138
|
+
}
|
|
139
|
+
await populateEntry(
|
|
140
|
+
value,
|
|
141
|
+
componentModel,
|
|
142
|
+
objectKey,
|
|
143
|
+
newPrefix,
|
|
144
|
+
component,
|
|
145
|
+
isRepeatable(attribute),
|
|
146
|
+
);
|
|
147
|
+
} else if (isRelation(attribute)) {
|
|
148
|
+
const newPrefix = getNewPrefix(objectKey, prefix);
|
|
149
|
+
const populatedLocalizedEntryVal = get(populatedLocalizedEntry, newPrefix);
|
|
150
|
+
if (doesExistInPopulatedLocalizedEntry(populatedLocalizedEntryVal)) {
|
|
151
|
+
// skip...
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const isArray = Array.isArray(value);
|
|
156
|
+
let arraiedValue = value;
|
|
157
|
+
if (!isArray) {
|
|
158
|
+
arraiedValue = [value];
|
|
159
|
+
}
|
|
160
|
+
for (const [index, item] of Object.entries(arraiedValue)) {
|
|
161
|
+
if (!isEmpty(item)) {
|
|
162
|
+
const entityId = item.id;
|
|
163
|
+
if (!!entityId) {
|
|
164
|
+
const entryWithLocalizations = await strapi.entityService.findOne(attribute.target, entityId, {
|
|
165
|
+
populate: ['localizations'],
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
const localizedEntry = entryWithLocalizations.localizations.find((item) => item.locale === locale);
|
|
169
|
+
if (!!localizedEntry && localizedEntry.id) {
|
|
170
|
+
if (!isArray) {
|
|
171
|
+
set(populatedEntry, newPrefix, { id: localizedEntry.id });
|
|
172
|
+
} else {
|
|
173
|
+
set(populatedEntry, `${newPrefix}.${index}`, { id: localizedEntry.id });
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
} else {
|
|
180
|
+
const newPrefix = getNewPrefix(objectKey, prefix);
|
|
181
|
+
const inCreateUpdateEntry = get(createUpdateEntry, newPrefix);
|
|
182
|
+
const isMissingInCreateUpdateEntry = !!(typeof inCreateUpdateEntry === 'undefined' || inCreateUpdateEntry === null);
|
|
183
|
+
if (isMissingInCreateUpdateEntry) {
|
|
184
|
+
const populatedLocalizedEntryVal = get(populatedLocalizedEntry, newPrefix);
|
|
185
|
+
if (doesExistInPopulatedLocalizedEntry(populatedLocalizedEntryVal)) {
|
|
186
|
+
set(populatedEntry, newPrefix, populatedLocalizedEntryVal);
|
|
187
|
+
} else {
|
|
188
|
+
set(populatedEntry, newPrefix, value);
|
|
189
|
+
}
|
|
190
|
+
} else {
|
|
191
|
+
await populateEntry(
|
|
192
|
+
value,
|
|
193
|
+
model,
|
|
194
|
+
objectKey,
|
|
195
|
+
newPrefix
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
} else if (partialBaseEntry !== Object(partialBaseEntry)) {
|
|
201
|
+
// is primitive/literal
|
|
202
|
+
const attribute = getAttribute(model, objectKey);
|
|
203
|
+
if (typeof attribute !== 'undefined') {
|
|
204
|
+
const inCreateUpdateEntry = get(createUpdateEntry, prefix);
|
|
205
|
+
const isMissingInCreateUpdateEntry = !!(typeof inCreateUpdateEntry === 'undefined' || inCreateUpdateEntry === null);
|
|
206
|
+
if (isMissingInCreateUpdateEntry) {
|
|
207
|
+
set(populatedEntry, prefix, partialBaseEntry);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
} else {
|
|
211
|
+
// ? TODO: something unknown
|
|
212
|
+
console.info(`Unknown type processed: ${partialBaseEntry}`);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const model = findModel(models, uid);
|
|
217
|
+
await populateEntry(baseEntry, model);
|
|
218
|
+
|
|
219
|
+
return populatedEntry;
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
module.exports = populateCreateUpdateEntryWithBaseEntry;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const set = require("lodash/set");
|
|
2
|
+
const get = require("lodash/get");
|
|
3
|
+
|
|
4
|
+
const resetArrayKeysDeep = (object, keysToFilter) => {
|
|
5
|
+
// sort keys from deep to shallow (so we won't rewrite indices)
|
|
6
|
+
const sortedKeysToFilter = keysToFilter.sort((a, b) => {
|
|
7
|
+
const aLvl = a.match(/\./g)?.length || 0;
|
|
8
|
+
const bLvl = b.match(/\./g)?.length || 0;
|
|
9
|
+
|
|
10
|
+
return bLvl - aLvl;
|
|
11
|
+
})
|
|
12
|
+
for (const key of sortedKeysToFilter) {
|
|
13
|
+
const part = get(object, key);
|
|
14
|
+
const filteredPart = part.filter((item) => item !== undefined);
|
|
15
|
+
set(object, key, filteredPart);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
module.exports = resetArrayKeysDeep;
|
|
@@ -5,6 +5,19 @@ const findSetupModelByCollectionName = (models, collectionName) => {
|
|
|
5
5
|
return models.find((model) => Object.keys(model)[0] === collectionName);
|
|
6
6
|
};
|
|
7
7
|
|
|
8
|
+
const findSetupModelByCollectionUid = (
|
|
9
|
+
contentTransferSetup,
|
|
10
|
+
strapiContentTypesModels,
|
|
11
|
+
collectionUid
|
|
12
|
+
) => {
|
|
13
|
+
const currentModel = strapiContentTypesModels.find(
|
|
14
|
+
(model) => model.uid === collectionUid
|
|
15
|
+
);
|
|
16
|
+
const modelContentTransferSetup = contentTransferSetup.setup
|
|
17
|
+
.find((model) => Object.keys(model)[0] === currentModel.collectionName);
|
|
18
|
+
return modelContentTransferSetup[currentModel.collectionName];
|
|
19
|
+
}
|
|
20
|
+
|
|
8
21
|
const getCollectionsNames = (setup) => {
|
|
9
22
|
return getMainKeysOfNestedArrayObjects(setup);
|
|
10
23
|
};
|
|
@@ -33,6 +46,7 @@ const getPickPaths = (transferSetupModelProps) => {
|
|
|
33
46
|
|
|
34
47
|
module.exports = {
|
|
35
48
|
findSetupModelByCollectionName,
|
|
49
|
+
findSetupModelByCollectionUid,
|
|
36
50
|
getCollectionsNames,
|
|
37
51
|
isCollectionTransferEnabled,
|
|
38
52
|
getPickPaths,
|