@localazy/strapi-plugin 0.1.10 → 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/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 +41 -46
- 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 +90 -93
- package/server/utils/__tests__/parsed-localazy-entry-to-update-entry.test.js +417 -101
- 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 +1 -18
- package/server/utils/parsed-localazy-entry-to-update-entry.js +38 -3
- package/server/utils/populate-create-update-entry-with-base-entry.js +222 -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
package/.eslintrc
CHANGED
|
@@ -30,6 +30,7 @@ function Tree(props) {
|
|
|
30
30
|
|
|
31
31
|
const hasTruthyValue = Object.values(flattened).some(v => v);
|
|
32
32
|
const hasFalsyValue = Object.values(flattened).some(v => !v && v !== null);
|
|
33
|
+
const hasAllNullValue = Object.values(flattened).every(v => v === null);
|
|
33
34
|
|
|
34
35
|
if (key === "__model__") {
|
|
35
36
|
return false;
|
|
@@ -45,6 +46,7 @@ function Tree(props) {
|
|
|
45
46
|
>
|
|
46
47
|
{isSubbranchObject && (
|
|
47
48
|
<Checkbox
|
|
49
|
+
disabled={hasAllNullValue}
|
|
48
50
|
checked={hasTruthyValue && !hasFalsyValue}
|
|
49
51
|
indeterminate={hasTruthyValue && hasFalsyValue}
|
|
50
52
|
onChange={() => onTreeItemClick(flattenedKeys, hasTruthyValue && !hasFalsyValue)}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import baseSupportedContentTypeFields from "../../@common/models/supported-content-type-fields";
|
|
2
|
+
|
|
1
3
|
const SUPPORTED_CONTENT_TYPE_FIELDS = [
|
|
2
|
-
|
|
3
|
-
"text",
|
|
4
|
-
"richtext",
|
|
5
|
-
// "relation", // relation cannot be supported field type
|
|
4
|
+
...baseSupportedContentTypeFields,
|
|
6
5
|
"component",
|
|
6
|
+
// "relation", // relation cannot be supported field type
|
|
7
7
|
];
|
|
8
8
|
|
|
9
9
|
export default (models) => {
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import SUPPORTED_CONTENT_TYPE_FIELDS from "../../@common/models/supported-content-type-fields";
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Supported kinds of models are expected by the function, needs to be checked before calling the function
|
|
3
5
|
*/
|
|
@@ -27,7 +29,7 @@ const getModelsTree = (allModels, localizableModels = []) => {
|
|
|
27
29
|
),
|
|
28
30
|
};
|
|
29
31
|
} else if (
|
|
30
|
-
|
|
32
|
+
SUPPORTED_CONTENT_TYPE_FIELDS.includes(attributes[attribute].type)
|
|
31
33
|
) {
|
|
32
34
|
// field might not be localizable
|
|
33
35
|
if (isComponentAttributes) {
|
package/package.json
CHANGED
package/server/bootstrap.js
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
const getFullPopulateObject = require('./utils/get-full-populate-object')
|
|
4
|
+
|
|
5
|
+
module.exports = ({ strapi }) => {
|
|
4
6
|
// bootstrap phase
|
|
7
|
+
// Subscribe to the lifecycles that we are intrested in.
|
|
8
|
+
strapi.db.lifecycles.subscribe((event) => {
|
|
9
|
+
if (event.action === 'beforeFindMany' || event.action === 'beforeFindOne') {
|
|
10
|
+
const populate = event.params?.populate;
|
|
11
|
+
|
|
12
|
+
if (populate && populate[0] === 'deep') {
|
|
13
|
+
const depth = populate[1] ?? 5
|
|
14
|
+
const modelObject = getFullPopulateObject(event.model.uid, depth);
|
|
15
|
+
event.params.populate = modelObject.populate
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
});
|
|
5
19
|
};
|
|
@@ -4,6 +4,7 @@ const flattenObject = require("../utils/flatten-object");
|
|
|
4
4
|
const {
|
|
5
5
|
getCollectionsNames,
|
|
6
6
|
findSetupModelByCollectionName,
|
|
7
|
+
findSetupModelByCollectionUid,
|
|
7
8
|
isCollectionTransferEnabled,
|
|
8
9
|
getPickPaths,
|
|
9
10
|
} = require("../utils/transfer-setup-utils");
|
|
@@ -13,10 +14,8 @@ const {
|
|
|
13
14
|
isoLocalazyToStrapi,
|
|
14
15
|
isoStrapiToLocalazy,
|
|
15
16
|
} = require("../utils/iso-locales-utils");
|
|
16
|
-
const
|
|
17
|
-
const parsedLocalazyEntryToUpdateEntry = require("../utils/parsed-localazy-entry-to-update-entry");
|
|
17
|
+
const shouldSetDownloadedProperty = require("../functions/should-set-downloaded-property");
|
|
18
18
|
const set = require("lodash/set");
|
|
19
|
-
const merge = require("lodash/merge");
|
|
20
19
|
const isEmpty = require("lodash/isEmpty");
|
|
21
20
|
|
|
22
21
|
module.exports = {
|
|
@@ -160,7 +159,9 @@ module.exports = {
|
|
|
160
159
|
const messageReport = [];
|
|
161
160
|
|
|
162
161
|
// Strapi service
|
|
163
|
-
const StrapiService = strapi
|
|
162
|
+
const StrapiService = strapi
|
|
163
|
+
.plugin("localazy")
|
|
164
|
+
.service("strapiService");
|
|
164
165
|
|
|
165
166
|
// Strapi i18n Service
|
|
166
167
|
const StrapiI18nService = strapi
|
|
@@ -176,6 +177,14 @@ module.exports = {
|
|
|
176
177
|
const LocalazyDownloadService = strapi
|
|
177
178
|
.plugin("localazy")
|
|
178
179
|
.service("localazyDownloadService");
|
|
180
|
+
const strapiLocalazyI18nService = strapi
|
|
181
|
+
.plugin("localazy")
|
|
182
|
+
.service("strapiLocalazyI18nService");
|
|
183
|
+
|
|
184
|
+
const contentTransferSetup = await strapi
|
|
185
|
+
.plugin("localazy")
|
|
186
|
+
.service("pluginSettingsService")
|
|
187
|
+
.getContentTransferSetup();
|
|
179
188
|
|
|
180
189
|
const user = await LocalazyUserService.getUser();
|
|
181
190
|
|
|
@@ -308,6 +317,7 @@ module.exports = {
|
|
|
308
317
|
* Parse Localazy content
|
|
309
318
|
*/
|
|
310
319
|
const parsedLocalazyContent = {};
|
|
320
|
+
const strapiContentTypesModels = await StrapiService.getModels();
|
|
311
321
|
for (const [isoLocalazy, keys] of Object.entries(localazyContent)) {
|
|
312
322
|
const isoStrapi = isoLocalazyToStrapi(isoLocalazy);
|
|
313
323
|
if (!isoStrapi) {
|
|
@@ -322,21 +332,29 @@ module.exports = {
|
|
|
322
332
|
const value = localazyEntry.value;
|
|
323
333
|
|
|
324
334
|
const parsedKey = StrapiI18nService.parseLocalazyKey(key);
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
335
|
+
|
|
336
|
+
const modelContentTransferSetup = findSetupModelByCollectionUid(
|
|
337
|
+
contentTransferSetup,
|
|
338
|
+
strapiContentTypesModels,
|
|
339
|
+
parsedKey.uid
|
|
340
|
+
);
|
|
341
|
+
|
|
342
|
+
if (shouldSetDownloadedProperty(modelContentTransferSetup, parsedKey.rest)) {
|
|
343
|
+
const setKey = [
|
|
344
|
+
isoStrapi,
|
|
345
|
+
parsedKey.uid,
|
|
346
|
+
parsedKey.id,
|
|
347
|
+
...parsedKey.rest,
|
|
348
|
+
];
|
|
349
|
+
|
|
350
|
+
set(parsedLocalazyContent, setKey, value);
|
|
351
|
+
}
|
|
333
352
|
}
|
|
334
353
|
}
|
|
335
354
|
|
|
336
355
|
/**
|
|
337
356
|
* Iterate over parsed Localazy content and insert/update content in Strapi
|
|
338
357
|
*/
|
|
339
|
-
const strapiContentTypesModels = await StrapiService.getModels();
|
|
340
358
|
for (const [isoStrapi, contentTypes] of Object.entries(
|
|
341
359
|
parsedLocalazyContent
|
|
342
360
|
)) {
|
|
@@ -359,14 +377,9 @@ module.exports = {
|
|
|
359
377
|
/**
|
|
360
378
|
* Get original source language entry
|
|
361
379
|
*/
|
|
362
|
-
const
|
|
363
|
-
|
|
364
|
-
populate,
|
|
365
|
-
});
|
|
366
|
-
let baseEntry = await strapi.entityService.findOne(uid, id, {
|
|
367
|
-
populate: "*",
|
|
380
|
+
const baseEntry = await strapi.entityService.findOne(uid, id, {
|
|
381
|
+
populate: "deep",
|
|
368
382
|
});
|
|
369
|
-
baseEntry = merge(baseEntry, baseEntryDeep);
|
|
370
383
|
|
|
371
384
|
if (isEmpty(baseEntry)) {
|
|
372
385
|
const message = `Source language entry ${uid}[${id}] does not exist anymore, skipping...`;
|
|
@@ -392,20 +405,15 @@ module.exports = {
|
|
|
392
405
|
if (!baseEntryCurrentLanguageLocalizationInfo) {
|
|
393
406
|
// create new entry
|
|
394
407
|
try {
|
|
395
|
-
const
|
|
408
|
+
const createdEntry = await strapiLocalazyI18nService.createEntry(
|
|
409
|
+
ctx,
|
|
410
|
+
uid,
|
|
396
411
|
strapiContentTypesModels,
|
|
397
412
|
translatedModel,
|
|
398
413
|
baseEntry,
|
|
399
|
-
|
|
400
|
-
isoStrapi
|
|
414
|
+
isoStrapi,
|
|
401
415
|
);
|
|
402
|
-
|
|
403
|
-
await StrapiI18nService.createLocalizationForAnExistingEntry(
|
|
404
|
-
ctx,
|
|
405
|
-
uid,
|
|
406
|
-
baseEntry,
|
|
407
|
-
createEntry
|
|
408
|
-
);
|
|
416
|
+
|
|
409
417
|
messageReport.push(
|
|
410
418
|
`Created new entry ${uid}[${createdEntry.id}] in language ${isoStrapi}`
|
|
411
419
|
);
|
|
@@ -421,29 +429,16 @@ module.exports = {
|
|
|
421
429
|
try {
|
|
422
430
|
const localizedEntryId =
|
|
423
431
|
baseEntryCurrentLanguageLocalizationInfo.id;
|
|
424
|
-
|
|
425
|
-
const
|
|
432
|
+
|
|
433
|
+
const updatedEntry = await strapiLocalazyI18nService.updateEntry(
|
|
426
434
|
uid,
|
|
427
435
|
localizedEntryId,
|
|
428
|
-
{
|
|
429
|
-
populate,
|
|
430
|
-
}
|
|
431
|
-
);
|
|
432
|
-
|
|
433
|
-
const updateEntry = parsedLocalazyEntryToUpdateEntry(
|
|
434
436
|
strapiContentTypesModels,
|
|
435
437
|
translatedModel,
|
|
436
|
-
localizedEntry,
|
|
437
438
|
baseEntry,
|
|
438
|
-
|
|
439
|
+
isoStrapi,
|
|
439
440
|
);
|
|
440
441
|
|
|
441
|
-
const updatedEntry =
|
|
442
|
-
await StrapiI18nService.updateLocalizationForAnExistingEntry(
|
|
443
|
-
uid,
|
|
444
|
-
localizedEntryId,
|
|
445
|
-
updateEntry
|
|
446
|
-
);
|
|
447
442
|
messageReport.push(
|
|
448
443
|
`Updated ${uid}[${updatedEntry.id}] (${isoStrapi})`
|
|
449
444
|
);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const get = require("lodash/get");
|
|
2
|
+
|
|
3
|
+
const shouldSetDownloadedProperty = (
|
|
4
|
+
modelContentTransferSetup,
|
|
5
|
+
parsedKeyRest,
|
|
6
|
+
) => {
|
|
7
|
+
if (!modelContentTransferSetup.__model__) {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const filteredParsedKeyRest = parsedKeyRest
|
|
12
|
+
.filter((partialKey) => isNaN(parseInt(partialKey)));
|
|
13
|
+
return !!get(modelContentTransferSetup, filteredParsedKeyRest);
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
module.exports = shouldSetDownloadedProperty;
|
package/server/services/index.js
CHANGED
|
@@ -8,6 +8,7 @@ const localazyUploadService = require("./localazy-upload-service");
|
|
|
8
8
|
const localazyDownloadService = require("./localazy-download-service");
|
|
9
9
|
const localazyPubApiService = require("./localazy-pubapi-service");
|
|
10
10
|
const strapiI18nService = require("./strapi-i18n-service");
|
|
11
|
+
const strapiLocalazyI18nService = require("./strapi-localazy-i18n-service");
|
|
11
12
|
|
|
12
13
|
module.exports = {
|
|
13
14
|
localazyUserService,
|
|
@@ -18,4 +19,5 @@ module.exports = {
|
|
|
18
19
|
localazyDownloadService,
|
|
19
20
|
localazyPubApiService,
|
|
20
21
|
strapiI18nService,
|
|
22
|
+
strapiLocalazyI18nService,
|
|
21
23
|
};
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
const { isoLocalazyToStrapi } = require("../utils/iso-locales-utils.js");
|
|
4
4
|
const intlDisplayName = require("../utils/intl-display-name.js");
|
|
5
5
|
const merge = require("lodash/merge");
|
|
6
|
+
const cloneDeep = require("lodash/cloneDeep");
|
|
6
7
|
const omitDeep = require("../utils/omit-deep.js");
|
|
7
8
|
|
|
8
9
|
module.exports = ({ strapi }) => ({
|
|
@@ -79,7 +80,7 @@ module.exports = ({ strapi }) => ({
|
|
|
79
80
|
// this might not be localizable (then method is missing, skip)
|
|
80
81
|
const contentTypeController = strapi.controller(uid);
|
|
81
82
|
const newLocalizationCtx = { ...ctx };
|
|
82
|
-
newLocalizationCtx.is = () => false; // else throws an error in createLocalization
|
|
83
|
+
newLocalizationCtx.is = () => false; // ! else throws an error in createLocalization
|
|
83
84
|
newLocalizationCtx.params.id = baseEntry.id;
|
|
84
85
|
|
|
85
86
|
const newEntryLocale = newEntry.locale;
|
|
@@ -87,7 +88,7 @@ module.exports = ({ strapi }) => ({
|
|
|
87
88
|
"locale",
|
|
88
89
|
"id",
|
|
89
90
|
"createdAt",
|
|
90
|
-
"publishedAt", // sets as draft (no timestamp)
|
|
91
|
+
"publishedAt", // * sets as draft (no timestamp)
|
|
91
92
|
"updatedAt",
|
|
92
93
|
]);
|
|
93
94
|
filteredNewEntry.locale = newEntryLocale;
|
|
@@ -101,7 +102,7 @@ module.exports = ({ strapi }) => ({
|
|
|
101
102
|
baseEntry.id,
|
|
102
103
|
newEntryLocale
|
|
103
104
|
);
|
|
104
|
-
const mergedEntry = merge(baseEntry, insertedEntry);
|
|
105
|
+
const mergedEntry = merge(cloneDeep(baseEntry), insertedEntry);
|
|
105
106
|
|
|
106
107
|
return mergedEntry;
|
|
107
108
|
} catch (e) {
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const parsedLocalazyEntryToCreateEntry = require("../utils/parsed-localazy-entry-to-create-entry");
|
|
4
|
+
const parsedLocalazyEntryToUpdateEntry = require("../utils/parsed-localazy-entry-to-update-entry");
|
|
5
|
+
|
|
6
|
+
module.exports = ({ strapi }) => ({
|
|
7
|
+
async createEntry(
|
|
8
|
+
ctx,
|
|
9
|
+
uid,
|
|
10
|
+
strapiContentTypesModels,
|
|
11
|
+
translatedModel,
|
|
12
|
+
baseEntry,
|
|
13
|
+
isoStrapi,
|
|
14
|
+
) {
|
|
15
|
+
// * The entry will be created and then updated as the structures differ
|
|
16
|
+
// * It's one extra database call, but the complexity of recursive code to maintain does worth it
|
|
17
|
+
|
|
18
|
+
// Strapi i18n Service
|
|
19
|
+
const StrapiI18nService = strapi
|
|
20
|
+
.plugin("localazy")
|
|
21
|
+
.service("strapiI18nService");
|
|
22
|
+
|
|
23
|
+
const createEntry = parsedLocalazyEntryToCreateEntry(
|
|
24
|
+
strapiContentTypesModels,
|
|
25
|
+
translatedModel,
|
|
26
|
+
baseEntry,
|
|
27
|
+
uid,
|
|
28
|
+
isoStrapi,
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
const createdEntry =
|
|
32
|
+
await StrapiI18nService.createLocalizationForAnExistingEntry(
|
|
33
|
+
ctx,
|
|
34
|
+
uid,
|
|
35
|
+
baseEntry,
|
|
36
|
+
createEntry,
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
await this.updateEntry(
|
|
40
|
+
uid,
|
|
41
|
+
createdEntry.id,
|
|
42
|
+
strapiContentTypesModels,
|
|
43
|
+
translatedModel,
|
|
44
|
+
baseEntry,
|
|
45
|
+
isoStrapi,
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
return createdEntry;
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
async updateEntry(
|
|
52
|
+
uid,
|
|
53
|
+
localizedEntryId,
|
|
54
|
+
strapiContentTypesModels,
|
|
55
|
+
translatedModel,
|
|
56
|
+
baseEntry,
|
|
57
|
+
isoStrapi,
|
|
58
|
+
) {
|
|
59
|
+
// Strapi Service
|
|
60
|
+
const StrapiService = strapi
|
|
61
|
+
.plugin("localazy")
|
|
62
|
+
.service("strapiService");
|
|
63
|
+
|
|
64
|
+
// Strapi i18n Service
|
|
65
|
+
const StrapiI18nService = strapi
|
|
66
|
+
.plugin("localazy")
|
|
67
|
+
.service("strapiI18nService");
|
|
68
|
+
|
|
69
|
+
const populate = await StrapiService.getPopulateObject(uid);
|
|
70
|
+
const localizedEntry = await strapi.entityService.findOne(
|
|
71
|
+
uid,
|
|
72
|
+
localizedEntryId,
|
|
73
|
+
{
|
|
74
|
+
populate,
|
|
75
|
+
}
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
const fullyPopulatedLocalizedEntry = await strapi.entityService.findOne(
|
|
79
|
+
uid,
|
|
80
|
+
localizedEntryId,
|
|
81
|
+
{
|
|
82
|
+
populate: "deep",
|
|
83
|
+
}
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
const updateEntry = await parsedLocalazyEntryToUpdateEntry(
|
|
87
|
+
strapiContentTypesModels,
|
|
88
|
+
translatedModel,
|
|
89
|
+
fullyPopulatedLocalizedEntry,
|
|
90
|
+
localizedEntry,
|
|
91
|
+
baseEntry,
|
|
92
|
+
uid,
|
|
93
|
+
isoStrapi
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
const updatedEntry = await StrapiI18nService.updateLocalizationForAnExistingEntry(
|
|
97
|
+
uid,
|
|
98
|
+
localizedEntryId,
|
|
99
|
+
updateEntry
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
return updatedEntry;
|
|
103
|
+
}
|
|
104
|
+
});
|