@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.
Files changed (42) hide show
  1. package/.eslintrc +6 -2
  2. package/admin/src/modules/@common/models/supported-content-type-fields.js +8 -0
  3. package/admin/src/modules/plugin-settings/components/Tree/index.js +2 -0
  4. package/admin/src/modules/plugin-settings/utils/get-filtered-models-schemas.js +4 -4
  5. package/admin/src/modules/plugin-settings/utils/get-models-tree.js +3 -1
  6. package/package.json +1 -1
  7. package/server/bootstrap.js +15 -1
  8. package/server/controllers/localazy-transfer-controller.js +41 -46
  9. package/server/functions/should-set-downloaded-property.js +16 -0
  10. package/server/models/supported-content-type-fields.js +8 -0
  11. package/server/services/index.js +2 -0
  12. package/server/services/strapi-i18n-service.js +4 -3
  13. package/server/services/strapi-localazy-i18n-service.js +104 -0
  14. package/server/tests/fixtures/parsed-localazy-entry-to-create-entry-cookbook.js +5761 -0
  15. package/server/tests/fixtures/parsed-localazy-entry-to-create-entry-restaurant-simple-menu.js +536 -0
  16. package/server/tests/fixtures/parsed-localazy-entry-to-update-entry.js +35157 -0
  17. package/server/tests/fixtures/populate-create-update-entry-with-base-entry-cookbook-empty-recipes.js +202 -0
  18. package/server/tests/fixtures/populate-create-update-entry-with-base-entry-cookbook.js +2700 -0
  19. package/server/tests/fixtures/populate-create-update-entry-with-base-entry-restaurant-simple-flat-simple.js +47 -0
  20. package/server/tests/fixtures/populate-create-update-entry-with-base-entry-restaurant-simple-flat-with-media.js +169 -0
  21. package/server/tests/fixtures/populate-create-update-entry-with-base-entry-restaurant-simple-menu-empty.js +3003 -0
  22. package/server/tests/fixtures/populate-create-update-entry-with-base-entry-restaurant-simple-menu-with-media.js +2057 -0
  23. package/server/tests/fixtures/populate-create-update-entry-with-base-entry-sample-json.js +46 -0
  24. package/server/tests/fixtures/{all-models-with-multimedia.js → strapi-plugin-all-models.js} +717 -540
  25. package/server/utils/__tests__/get-models-tree.test.js +1 -1
  26. package/server/utils/__tests__/parsed-localazy-entry-to-create-entry.test.js +90 -93
  27. package/server/utils/__tests__/parsed-localazy-entry-to-update-entry.test.js +417 -101
  28. package/server/utils/__tests__/populate-create-update-entry-with-base-entry.test.js +852 -0
  29. package/server/utils/get-full-populate-object.js +56 -0
  30. package/server/utils/get-models-tree.js +3 -1
  31. package/server/utils/model-utils.js +38 -0
  32. package/server/utils/parsed-localazy-entry-to-create-entry.js +1 -18
  33. package/server/utils/parsed-localazy-entry-to-update-entry.js +38 -3
  34. package/server/utils/populate-create-update-entry-with-base-entry.js +222 -0
  35. package/server/utils/transfer-setup-utils.js +14 -0
  36. package/server/tests/fixtures/restaurant-model.js +0 -230
  37. package/server/tests/fixtures/restaurants-entries.js +0 -152
  38. package/server/tests/fixtures/strapi-book-with-multimedia-components-cs.js +0 -31
  39. package/server/tests/fixtures/stringified-book-cs.js +0 -3
  40. package/server/tests/fixtures/stringified-book-with-multimedia-components-cs.js +0 -3
  41. package/server/tests/fixtures/stringified-restaurant-cs.js +0 -3
  42. package/server/tests/fixtures/stringified-restaurant-de.js +0 -5
package/.eslintrc CHANGED
@@ -1,7 +1,11 @@
1
1
  {
2
2
  // "extends": "@strapi-community",
3
3
  "env": {
4
- "jest/globals": true
4
+ "jest/globals": true,
5
+ "es6": true
5
6
  },
6
- "plugins": ["jest"]
7
+ "plugins": ["jest"],
8
+ "parserOptions": {
9
+ "ecmaVersion": "latest"
10
+ }
7
11
  }
@@ -0,0 +1,8 @@
1
+ const SUPPORTED_CONTENT_TYPE_FIELDS = [
2
+ "string",
3
+ "text",
4
+ "richtext",
5
+ "email",
6
+ ];
7
+
8
+ export default SUPPORTED_CONTENT_TYPE_FIELDS;
@@ -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
- "string",
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
- ["string", "text", "richtext"].includes(attributes[attribute].type)
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@localazy/strapi-plugin",
3
- "version": "0.1.10",
3
+ "version": "0.1.11-rc.0",
4
4
  "description": "The official Strapi Plugin by Localazy.",
5
5
  "strapi": {
6
6
  "name": "localazy",
@@ -1,5 +1,19 @@
1
1
  "use strict";
2
2
 
3
- module.exports = () => {
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 parsedLocalazyEntryToCreateEntry = require("../utils/parsed-localazy-entry-to-create-entry");
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.plugin("localazy").service("strapiService");
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
- const setKey = [
326
- isoStrapi,
327
- parsedKey.uid,
328
- parsedKey.id,
329
- ...parsedKey.rest,
330
- ];
331
-
332
- set(parsedLocalazyContent, setKey, value);
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 populate = await StrapiService.getPopulateObject(uid);
363
- const baseEntryDeep = await strapi.entityService.findOne(uid, id, {
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 createEntry = parsedLocalazyEntryToCreateEntry(
408
+ const createdEntry = await strapiLocalazyI18nService.createEntry(
409
+ ctx,
410
+ uid,
396
411
  strapiContentTypesModels,
397
412
  translatedModel,
398
413
  baseEntry,
399
- uid,
400
- isoStrapi
414
+ isoStrapi,
401
415
  );
402
- const createdEntry =
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
- const populate = await StrapiService.getPopulateObject(uid);
425
- const localizedEntry = await strapi.entityService.findOne(
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
- uid
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;
@@ -0,0 +1,8 @@
1
+ const SUPPORTED_CONTENT_TYPE_FIELDS = [
2
+ "string",
3
+ "text",
4
+ "richtext",
5
+ "email",
6
+ ];
7
+
8
+ module.exports = SUPPORTED_CONTENT_TYPE_FIELDS;
@@ -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
+ });