@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
package/.eslintrc
CHANGED
package/.nvmrc
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
16
|
|
@@ -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,9 @@ 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
|
|
19
|
+
const isEmpty = require("lodash/isEmpty");
|
|
20
20
|
|
|
21
21
|
module.exports = {
|
|
22
22
|
async upload(ctx) {
|
|
@@ -159,7 +159,9 @@ module.exports = {
|
|
|
159
159
|
const messageReport = [];
|
|
160
160
|
|
|
161
161
|
// Strapi service
|
|
162
|
-
const StrapiService = strapi
|
|
162
|
+
const StrapiService = strapi
|
|
163
|
+
.plugin("localazy")
|
|
164
|
+
.service("strapiService");
|
|
163
165
|
|
|
164
166
|
// Strapi i18n Service
|
|
165
167
|
const StrapiI18nService = strapi
|
|
@@ -175,6 +177,14 @@ module.exports = {
|
|
|
175
177
|
const LocalazyDownloadService = strapi
|
|
176
178
|
.plugin("localazy")
|
|
177
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();
|
|
178
188
|
|
|
179
189
|
const user = await LocalazyUserService.getUser();
|
|
180
190
|
|
|
@@ -307,6 +317,7 @@ module.exports = {
|
|
|
307
317
|
* Parse Localazy content
|
|
308
318
|
*/
|
|
309
319
|
const parsedLocalazyContent = {};
|
|
320
|
+
const strapiContentTypesModels = await StrapiService.getModels();
|
|
310
321
|
for (const [isoLocalazy, keys] of Object.entries(localazyContent)) {
|
|
311
322
|
const isoStrapi = isoLocalazyToStrapi(isoLocalazy);
|
|
312
323
|
if (!isoStrapi) {
|
|
@@ -321,21 +332,29 @@ module.exports = {
|
|
|
321
332
|
const value = localazyEntry.value;
|
|
322
333
|
|
|
323
334
|
const parsedKey = StrapiI18nService.parseLocalazyKey(key);
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
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
|
+
}
|
|
332
352
|
}
|
|
333
353
|
}
|
|
334
354
|
|
|
335
355
|
/**
|
|
336
356
|
* Iterate over parsed Localazy content and insert/update content in Strapi
|
|
337
357
|
*/
|
|
338
|
-
const strapiContentTypesModels = await StrapiService.getModels();
|
|
339
358
|
for (const [isoStrapi, contentTypes] of Object.entries(
|
|
340
359
|
parsedLocalazyContent
|
|
341
360
|
)) {
|
|
@@ -358,16 +377,11 @@ module.exports = {
|
|
|
358
377
|
/**
|
|
359
378
|
* Get original source language entry
|
|
360
379
|
*/
|
|
361
|
-
const
|
|
362
|
-
|
|
363
|
-
populate,
|
|
364
|
-
});
|
|
365
|
-
let baseEntry = await strapi.entityService.findOne(uid, id, {
|
|
366
|
-
populate: "*",
|
|
380
|
+
const baseEntry = await strapi.entityService.findOne(uid, id, {
|
|
381
|
+
populate: "deep",
|
|
367
382
|
});
|
|
368
|
-
baseEntry = merge(baseEntry, baseEntryDeep);
|
|
369
383
|
|
|
370
|
-
if (
|
|
384
|
+
if (isEmpty(baseEntry)) {
|
|
371
385
|
const message = `Source language entry ${uid}[${id}] does not exist anymore, skipping...`;
|
|
372
386
|
throw new Error(message);
|
|
373
387
|
}
|
|
@@ -391,19 +405,15 @@ module.exports = {
|
|
|
391
405
|
if (!baseEntryCurrentLanguageLocalizationInfo) {
|
|
392
406
|
// create new entry
|
|
393
407
|
try {
|
|
394
|
-
const
|
|
408
|
+
const createdEntry = await strapiLocalazyI18nService.createEntry(
|
|
409
|
+
ctx,
|
|
410
|
+
uid,
|
|
395
411
|
strapiContentTypesModels,
|
|
396
412
|
translatedModel,
|
|
397
|
-
|
|
398
|
-
isoStrapi
|
|
413
|
+
baseEntry,
|
|
414
|
+
isoStrapi,
|
|
399
415
|
);
|
|
400
|
-
|
|
401
|
-
await StrapiI18nService.createLocalizationForAnExistingEntry(
|
|
402
|
-
ctx,
|
|
403
|
-
uid,
|
|
404
|
-
baseEntry,
|
|
405
|
-
createEntry
|
|
406
|
-
);
|
|
416
|
+
|
|
407
417
|
messageReport.push(
|
|
408
418
|
`Created new entry ${uid}[${createdEntry.id}] in language ${isoStrapi}`
|
|
409
419
|
);
|
|
@@ -419,28 +429,16 @@ module.exports = {
|
|
|
419
429
|
try {
|
|
420
430
|
const localizedEntryId =
|
|
421
431
|
baseEntryCurrentLanguageLocalizationInfo.id;
|
|
422
|
-
|
|
423
|
-
const
|
|
432
|
+
|
|
433
|
+
const updatedEntry = await strapiLocalazyI18nService.updateEntry(
|
|
424
434
|
uid,
|
|
425
435
|
localizedEntryId,
|
|
426
|
-
{
|
|
427
|
-
populate,
|
|
428
|
-
}
|
|
429
|
-
);
|
|
430
|
-
|
|
431
|
-
const updateEntry = parsedLocalazyEntryToUpdateEntry(
|
|
432
436
|
strapiContentTypesModels,
|
|
433
437
|
translatedModel,
|
|
434
|
-
|
|
435
|
-
|
|
438
|
+
baseEntry,
|
|
439
|
+
isoStrapi,
|
|
436
440
|
);
|
|
437
441
|
|
|
438
|
-
const updatedEntry =
|
|
439
|
-
await StrapiI18nService.updateLocalizationForAnExistingEntry(
|
|
440
|
-
uid,
|
|
441
|
-
localizedEntryId,
|
|
442
|
-
updateEntry
|
|
443
|
-
);
|
|
444
442
|
messageReport.push(
|
|
445
443
|
`Updated ${uid}[${updatedEntry.id}] (${isoStrapi})`
|
|
446
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
|
+
});
|