@translationstudio/translationstudio-strapi-extension 1.1.3 → 2.0.1
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/Types.d.ts +8 -9
- package/dist/_chunks/{App-DkdbSZwI.js → App-C5dxwMbx.js} +0 -1
- package/dist/_chunks/{App-Cq1SRR-L.mjs → App-DxAbaDu8.mjs} +0 -1
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/server/index.js +470 -351
- package/dist/server/index.mjs +451 -350
- package/dist/server/src/index.d.ts +6 -5
- package/dist/server/src/services/functions/exportData/getContentType.d.ts +30 -2
- package/dist/server/src/services/functions/exportData/getEntry.d.ts +3 -1
- package/dist/server/src/services/functions/exportData/processComponent.d.ts +2 -2
- package/dist/server/src/services/functions/exportData/processEntryFields.d.ts +7 -1
- package/dist/server/src/services/functions/exportData/transformResponse.d.ts +7 -1
- package/dist/server/src/services/functions/importData/prepareImportData.d.ts +3 -2
- package/dist/server/src/services/functions/importData/updateEntry.d.ts +3 -2
- package/dist/server/src/services/index.d.ts +6 -5
- package/dist/server/src/services/service.d.ts +6 -5
- package/package.json +14 -2
- package/dist/server/src/services/functions/importData/organizeFields.d.ts +0 -2
- package/dist/server/src/services/functions/importData/processDynamicZones.d.ts +0 -2
- package/dist/server/src/services/functions/importData/processRegularFields.d.ts +0 -2
package/dist/server/index.js
CHANGED
|
@@ -1,4 +1,23 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
const crypto = require("crypto");
|
|
3
|
+
function _interopNamespace(e) {
|
|
4
|
+
if (e && e.__esModule) return e;
|
|
5
|
+
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
|
6
|
+
if (e) {
|
|
7
|
+
for (const k in e) {
|
|
8
|
+
if (k !== "default") {
|
|
9
|
+
const d = Object.getOwnPropertyDescriptor(e, k);
|
|
10
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
11
|
+
enumerable: true,
|
|
12
|
+
get: () => e[k]
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
n.default = e;
|
|
18
|
+
return Object.freeze(n);
|
|
19
|
+
}
|
|
20
|
+
const crypto__namespace = /* @__PURE__ */ _interopNamespace(crypto);
|
|
2
21
|
const bootstrap = ({ strapi: strapi2 }) => {
|
|
3
22
|
};
|
|
4
23
|
const destroy = ({ strapi: strapi2 }) => {
|
|
@@ -76,10 +95,15 @@ const controller = ({ strapi: strapi2 }) => ({
|
|
|
76
95
|
ctx.status = 400;
|
|
77
96
|
return;
|
|
78
97
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
98
|
+
try {
|
|
99
|
+
const payload = typeof ctx.request.body === "string" ? JSON.parse(ctx.request.body) : ctx.request.body;
|
|
100
|
+
const result = await strapi2.plugin(APP_NAME$1).service("service").exportData(payload);
|
|
101
|
+
ctx.status = 200;
|
|
102
|
+
ctx.body = [{ fields: result }];
|
|
103
|
+
} catch (ex) {
|
|
104
|
+
ctx.status = 500;
|
|
105
|
+
ctx.body = { error: ex.message ?? "Generic error" };
|
|
106
|
+
}
|
|
83
107
|
},
|
|
84
108
|
async setDevelopmentUrl(ctx) {
|
|
85
109
|
const url = ctx.request.body.url;
|
|
@@ -107,23 +131,36 @@ const controller = ({ strapi: strapi2 }) => ({
|
|
|
107
131
|
ctx.status = 400;
|
|
108
132
|
return;
|
|
109
133
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
134
|
+
try {
|
|
135
|
+
const payload = typeof ctx.request.body === "object" ? ctx.request.body : JSON.parse(ctx.request.body);
|
|
136
|
+
strapi2.log.info("Importing");
|
|
137
|
+
const result = await strapi2.plugin(APP_NAME$1).service("service").importData(payload);
|
|
138
|
+
ctx.body = { success: result };
|
|
139
|
+
ctx.status = 200;
|
|
140
|
+
return;
|
|
141
|
+
} catch (err) {
|
|
142
|
+
strapi2.log.error(err.message ?? err);
|
|
143
|
+
}
|
|
144
|
+
ctx.body = { message: "Could not perform import" };
|
|
145
|
+
ctx.status = 500;
|
|
113
146
|
},
|
|
114
147
|
async ping(ctx) {
|
|
115
|
-
|
|
148
|
+
await strapi2.plugin(APP_NAME$1).service("service").ping();
|
|
116
149
|
ctx.status = 204;
|
|
117
|
-
ctx.body = result;
|
|
118
150
|
},
|
|
119
151
|
async getLanguages(ctx) {
|
|
120
152
|
if (!await this.validateToken(ctx)) {
|
|
121
153
|
ctx.status = 400;
|
|
122
154
|
return;
|
|
123
155
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
156
|
+
try {
|
|
157
|
+
const result = await strapi2.plugin(APP_NAME$1).service("service").getLanguages();
|
|
158
|
+
ctx.status = 200;
|
|
159
|
+
ctx.body = result;
|
|
160
|
+
} catch (err) {
|
|
161
|
+
ctx.status = 400;
|
|
162
|
+
ctx.body = {};
|
|
163
|
+
}
|
|
127
164
|
},
|
|
128
165
|
async getEmail(ctx) {
|
|
129
166
|
const result = await strapi2.plugin(APP_NAME$1).service("service").getEmail(ctx);
|
|
@@ -257,6 +294,7 @@ const routes = [
|
|
|
257
294
|
policies: []
|
|
258
295
|
}
|
|
259
296
|
},
|
|
297
|
+
/* get entry title */
|
|
260
298
|
{
|
|
261
299
|
method: "POST",
|
|
262
300
|
path: "/entrydata",
|
|
@@ -266,13 +304,33 @@ const routes = [
|
|
|
266
304
|
}
|
|
267
305
|
}
|
|
268
306
|
];
|
|
269
|
-
|
|
270
|
-
const
|
|
307
|
+
function getComponentSchemata(schema) {
|
|
308
|
+
const res = {};
|
|
309
|
+
for (let fieldName in schema.attributes) {
|
|
310
|
+
const field = schema.attributes[fieldName];
|
|
311
|
+
if (!field.components || !Array.isArray(field.components) || field.components.length === 0)
|
|
312
|
+
continue;
|
|
313
|
+
for (let type of field.components) {
|
|
314
|
+
const schema2 = strapi.components[type];
|
|
315
|
+
if (schema2 && schema2.attributes)
|
|
316
|
+
res[type] = schema2;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
return res;
|
|
320
|
+
}
|
|
321
|
+
function getContentType(contentTypeID) {
|
|
322
|
+
const contentType = strapi.contentType(contentTypeID);
|
|
271
323
|
if (!contentType?.attributes) {
|
|
272
|
-
|
|
324
|
+
strapi.log.error(`Content type or schema not found: ${contentTypeID}`);
|
|
325
|
+
return null;
|
|
273
326
|
}
|
|
274
|
-
|
|
275
|
-
|
|
327
|
+
const res = {
|
|
328
|
+
entry: contentType,
|
|
329
|
+
components: getComponentSchemata(contentType)
|
|
330
|
+
};
|
|
331
|
+
strapi.log.info("SChema loaded for " + contentTypeID + ". Component schemata loaded: " + Object.keys(res.components).length);
|
|
332
|
+
return res;
|
|
333
|
+
}
|
|
276
334
|
const parsePayload = (payload) => {
|
|
277
335
|
const [contentTypeID, entryID] = payload.element.includes("#") ? payload.element.split("#") : [payload.element, void 0];
|
|
278
336
|
const locale = payload.source.includes("-") ? payload.source.split("-")[0] : payload.source;
|
|
@@ -282,7 +340,7 @@ const getComponentSchema = async (componentName) => {
|
|
|
282
340
|
try {
|
|
283
341
|
return await strapi.components[componentName];
|
|
284
342
|
} catch (error) {
|
|
285
|
-
|
|
343
|
+
strapi.log.error(`Failed to get component schema for ${componentName}:`, error);
|
|
286
344
|
return null;
|
|
287
345
|
}
|
|
288
346
|
};
|
|
@@ -305,27 +363,32 @@ const buildPopulateConfig = async (schema) => {
|
|
|
305
363
|
}
|
|
306
364
|
return populate;
|
|
307
365
|
};
|
|
308
|
-
const getEntry = async (contentTypeID, entryID, locale) => {
|
|
366
|
+
const getEntry = async (contentTypeID, entryID, locale, logError = true) => {
|
|
309
367
|
try {
|
|
310
368
|
const contentType = await strapi.contentTypes[contentTypeID];
|
|
311
369
|
const populateConfig = await buildPopulateConfig(contentType);
|
|
312
370
|
const query = {
|
|
313
371
|
locale,
|
|
372
|
+
documentId: entryID,
|
|
314
373
|
populate: populateConfig
|
|
315
374
|
};
|
|
316
|
-
if (entryID) {
|
|
317
|
-
Object.assign(query, { documentId: entryID });
|
|
318
|
-
}
|
|
319
375
|
const entry = await strapi.documents(contentTypeID).findFirst(query);
|
|
320
|
-
|
|
376
|
+
if (entry) {
|
|
377
|
+
strapi.log.info("Obtained " + contentTypeID + "::" + entryID + " in " + locale);
|
|
378
|
+
return entry;
|
|
379
|
+
}
|
|
321
380
|
} catch (error) {
|
|
322
|
-
|
|
323
|
-
return null;
|
|
381
|
+
strapi.log.error(error.message ?? error);
|
|
324
382
|
}
|
|
383
|
+
strapi.log.warn("Could not find entry " + entryID + " in locale " + locale);
|
|
384
|
+
return null;
|
|
385
|
+
};
|
|
386
|
+
const transformResponse = function(data) {
|
|
387
|
+
data.fields = data.fields.map(
|
|
388
|
+
(item) => item.realType === "blocks" && Array.isArray(item.translatableValue[0]) ? { ...item, translatableValue: item.translatableValue[0] } : item
|
|
389
|
+
);
|
|
390
|
+
return data;
|
|
325
391
|
};
|
|
326
|
-
const transformResponse = (data) => data.map(
|
|
327
|
-
(item) => item.realType === "blocks" && Array.isArray(item.translatableValue[0]) ? { ...item, translatableValue: item.translatableValue[0] } : item
|
|
328
|
-
);
|
|
329
392
|
function jsonToHtml(json) {
|
|
330
393
|
if (!json || !Array.isArray(json)) {
|
|
331
394
|
return "";
|
|
@@ -374,43 +437,37 @@ function formatText(child) {
|
|
|
374
437
|
}
|
|
375
438
|
return text;
|
|
376
439
|
}
|
|
377
|
-
const
|
|
440
|
+
const Logger$4 = {
|
|
441
|
+
log: typeof strapi !== "undefined" ? strapi.log : console,
|
|
442
|
+
info: (val) => Logger$4.log.info(val),
|
|
443
|
+
warn: (val) => Logger$4.log.warn(val),
|
|
444
|
+
error: (val) => Logger$4.log.error(val),
|
|
445
|
+
debug: (val) => Logger$4.log.debug(val)
|
|
446
|
+
};
|
|
447
|
+
async function processComponent(fieldName, value, componentSchema, schemata) {
|
|
378
448
|
const contentFields = [];
|
|
379
|
-
|
|
380
|
-
if (!componentSchema)
|
|
381
|
-
|
|
382
|
-
}
|
|
449
|
+
Logger$4.info("Processing dynamic field " + fieldName);
|
|
450
|
+
if (!componentSchema || !componentSchema.attributes)
|
|
451
|
+
return [];
|
|
383
452
|
const schemaAttributes = componentSchema.attributes || {};
|
|
384
453
|
const dataToProcess = value || {};
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
schemaAttributes,
|
|
390
|
-
fieldName,
|
|
391
|
-
componentName,
|
|
392
|
-
schemaName,
|
|
393
|
-
item.id
|
|
394
|
-
);
|
|
395
|
-
contentFields.push(...processedFields);
|
|
396
|
-
}
|
|
397
|
-
} else {
|
|
398
|
-
const processedFields = await processComponentFields$1(
|
|
399
|
-
dataToProcess,
|
|
454
|
+
const candidates = Array.isArray(dataToProcess) ? dataToProcess : [dataToProcess];
|
|
455
|
+
for (const item of candidates) {
|
|
456
|
+
const processedFields = await processComponentFields(
|
|
457
|
+
item,
|
|
400
458
|
schemaAttributes,
|
|
401
459
|
fieldName,
|
|
402
|
-
|
|
403
|
-
schemaName,
|
|
404
|
-
componentId
|
|
460
|
+
schemata
|
|
405
461
|
);
|
|
406
|
-
|
|
462
|
+
if (processedFields.length > 0)
|
|
463
|
+
contentFields.push(...processedFields);
|
|
407
464
|
}
|
|
408
465
|
return contentFields;
|
|
409
|
-
}
|
|
466
|
+
}
|
|
410
467
|
const shouldSkipField$1 = (key, fieldSchema) => {
|
|
411
468
|
return key === "id" || fieldSchema.private;
|
|
412
469
|
};
|
|
413
|
-
const isTranslatableField
|
|
470
|
+
const isTranslatableField = (type) => {
|
|
414
471
|
return ["string", "text", "blocks", "richtext"].includes(type);
|
|
415
472
|
};
|
|
416
473
|
const getTranslatedValue = (type, value) => {
|
|
@@ -419,64 +476,61 @@ const getTranslatedValue = (type, value) => {
|
|
|
419
476
|
}
|
|
420
477
|
return value.toString();
|
|
421
478
|
};
|
|
422
|
-
const buildTranslatable = (key, fieldSchema, value,
|
|
479
|
+
const buildTranslatable = (key, fieldSchema, value, uuid = "") => {
|
|
423
480
|
return {
|
|
424
481
|
field: key,
|
|
425
482
|
type: ["richtext", "blocks"].includes(fieldSchema.type) ? "html" : "text",
|
|
426
483
|
translatableValue: [value],
|
|
427
484
|
realType: fieldSchema.type,
|
|
428
|
-
|
|
429
|
-
namePath: parentPath,
|
|
430
|
-
id: componentId,
|
|
431
|
-
schemaName
|
|
432
|
-
}
|
|
485
|
+
uuid
|
|
433
486
|
};
|
|
434
487
|
};
|
|
435
|
-
const processComponentFields
|
|
488
|
+
const processComponentFields = async (componentData, schema, parentField, schemata) => {
|
|
436
489
|
const contentFields = [];
|
|
437
|
-
const
|
|
490
|
+
const uuid = crypto__namespace.randomUUID();
|
|
438
491
|
for (const [key, fieldSchema] of Object.entries(schema)) {
|
|
439
492
|
if (shouldSkipField$1(key, fieldSchema)) continue;
|
|
440
493
|
const value = componentData?.[key];
|
|
441
|
-
|
|
494
|
+
if (!value)
|
|
495
|
+
continue;
|
|
442
496
|
if (fieldSchema.type === "component") {
|
|
443
|
-
if (!
|
|
497
|
+
if (!value.__component)
|
|
498
|
+
continue;
|
|
499
|
+
const targetSchema = schemata[value.__component];
|
|
500
|
+
if (!targetSchema)
|
|
501
|
+
continue;
|
|
444
502
|
const nestedFields = await processComponent(
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
value?.id
|
|
503
|
+
`${parentField}.${key}`,
|
|
504
|
+
value,
|
|
505
|
+
targetSchema,
|
|
506
|
+
schemata
|
|
450
507
|
);
|
|
451
|
-
|
|
508
|
+
if (nestedFields.length > 0)
|
|
509
|
+
contentFields.push(...nestedFields);
|
|
452
510
|
continue;
|
|
453
511
|
}
|
|
454
|
-
if (!isTranslatableField
|
|
512
|
+
if (!isTranslatableField(fieldSchema.type)) continue;
|
|
455
513
|
if (value === null || value === void 0 || value === "") continue;
|
|
456
514
|
const translatedValue = getTranslatedValue(fieldSchema.type, value);
|
|
457
515
|
const translatable = buildTranslatable(
|
|
458
516
|
key,
|
|
459
517
|
fieldSchema,
|
|
460
518
|
translatedValue,
|
|
461
|
-
|
|
462
|
-
componentId,
|
|
463
|
-
schemaName
|
|
519
|
+
uuid
|
|
464
520
|
);
|
|
521
|
+
componentData.__tsuid = uuid;
|
|
465
522
|
contentFields.push(translatable);
|
|
466
523
|
}
|
|
467
524
|
return contentFields;
|
|
468
525
|
};
|
|
469
|
-
const
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
return localizableTypes.includes(fieldSchema.type);
|
|
476
|
-
}
|
|
477
|
-
return false;
|
|
526
|
+
const Logger$3 = {
|
|
527
|
+
log: typeof strapi !== "undefined" ? strapi.log : console,
|
|
528
|
+
info: (val) => Logger$3.log.info(val),
|
|
529
|
+
warn: (val) => Logger$3.log.warn(val),
|
|
530
|
+
error: (val) => Logger$3.log.error(val),
|
|
531
|
+
debug: (val) => Logger$3.log.debug(val)
|
|
478
532
|
};
|
|
479
|
-
const DEFAULT_FIELDS = /* @__PURE__ */ new Set([
|
|
533
|
+
const DEFAULT_FIELDS$1 = /* @__PURE__ */ new Set([
|
|
480
534
|
"id",
|
|
481
535
|
"documentId",
|
|
482
536
|
"createdAt",
|
|
@@ -488,45 +542,41 @@ const DEFAULT_FIELDS = /* @__PURE__ */ new Set([
|
|
|
488
542
|
"createdBy"
|
|
489
543
|
]);
|
|
490
544
|
const isEmpty = (value) => value === null || value === void 0 || value === "";
|
|
491
|
-
const
|
|
492
|
-
const processDynamicZone = async (key, value,
|
|
545
|
+
const isSimpleTranslatableField = (fieldSchema) => ["string", "text", "blocks", "richtext"].includes(fieldSchema.type) && fieldSchema.pluginOptions?.i18n?.localized === true;
|
|
546
|
+
const processDynamicZone = async (key, value, schemata) => {
|
|
493
547
|
const results = [];
|
|
494
548
|
for (const component of value) {
|
|
495
549
|
const componentName = component?.__component;
|
|
496
550
|
if (!componentName) continue;
|
|
551
|
+
const schema = schemata[componentName];
|
|
552
|
+
if (!schema) continue;
|
|
497
553
|
const fields = await processComponent(
|
|
498
554
|
key,
|
|
499
|
-
componentName,
|
|
500
555
|
component,
|
|
501
|
-
|
|
502
|
-
|
|
556
|
+
schema,
|
|
557
|
+
schemata
|
|
503
558
|
);
|
|
504
|
-
|
|
559
|
+
if (fields.length > 0)
|
|
560
|
+
results.push(...fields);
|
|
505
561
|
}
|
|
506
562
|
return results;
|
|
507
563
|
};
|
|
508
|
-
const processComponentField = async (key, value, fieldSchema) => {
|
|
564
|
+
const processComponentField = async (key, value, fieldSchema, schemata) => {
|
|
509
565
|
const results = [];
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
fieldSchema.component,
|
|
517
|
-
component.id
|
|
518
|
-
);
|
|
519
|
-
results.push(...fields);
|
|
520
|
-
}
|
|
521
|
-
} else {
|
|
566
|
+
const candidates = Array.isArray(value) ? value : [value];
|
|
567
|
+
for (const component of candidates) {
|
|
568
|
+
const componentName = component?.__component;
|
|
569
|
+
if (!componentName) continue;
|
|
570
|
+
const schema = schemata[componentName];
|
|
571
|
+
if (!schema) continue;
|
|
522
572
|
const fields = await processComponent(
|
|
523
573
|
key,
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
value.id
|
|
574
|
+
component,
|
|
575
|
+
schema,
|
|
576
|
+
schemata
|
|
528
577
|
);
|
|
529
|
-
|
|
578
|
+
if (fields.length > 0)
|
|
579
|
+
results.push(...fields);
|
|
530
580
|
}
|
|
531
581
|
return results;
|
|
532
582
|
};
|
|
@@ -539,38 +589,148 @@ const processRegularField = (key, value, fieldSchema) => {
|
|
|
539
589
|
realType: fieldSchema.type
|
|
540
590
|
};
|
|
541
591
|
};
|
|
542
|
-
|
|
592
|
+
function IsLocalisableSchema(schema) {
|
|
593
|
+
return schema.pluginOptions?.i18n?.localized === true;
|
|
594
|
+
}
|
|
595
|
+
function IsLocalisedField(field) {
|
|
596
|
+
return field.pluginOptions?.i18n?.localized === true;
|
|
597
|
+
}
|
|
598
|
+
const processEntryFields = async (entry, schemaData, _locale) => {
|
|
543
599
|
const contentFields = [];
|
|
600
|
+
const staticContent = {};
|
|
601
|
+
const schema = schemaData.entry.attributes;
|
|
544
602
|
for (const [key, value] of Object.entries(entry)) {
|
|
545
|
-
if (shouldSkipField(key, value))
|
|
546
|
-
const fieldSchema = schema[key];
|
|
547
|
-
if (!fieldSchema) continue;
|
|
548
|
-
if (isDynamicZone(fieldSchema, value, schema)) {
|
|
549
|
-
const zoneFields = await processDynamicZone(key, value);
|
|
550
|
-
contentFields.push(...zoneFields);
|
|
603
|
+
if (shouldSkipField(key, value))
|
|
551
604
|
continue;
|
|
552
|
-
|
|
553
|
-
if (
|
|
554
|
-
|
|
555
|
-
contentFields.push(...componentFields);
|
|
605
|
+
const fieldSchema = schema[key];
|
|
606
|
+
if (!fieldSchema || !IsLocalisedField(fieldSchema)) {
|
|
607
|
+
Logger$3.debug("SKipping non-local field " + key);
|
|
556
608
|
continue;
|
|
557
609
|
}
|
|
558
|
-
if (
|
|
610
|
+
if (isSimpleTranslatableField(fieldSchema)) {
|
|
611
|
+
Logger$3.debug("Processing simple field " + key);
|
|
559
612
|
const translatedField = processRegularField(key, value, fieldSchema);
|
|
560
613
|
contentFields.push(translatedField);
|
|
614
|
+
continue;
|
|
615
|
+
}
|
|
616
|
+
const zoneInfo = isDynamicZone(fieldSchema, value);
|
|
617
|
+
if (zoneInfo.isZone) {
|
|
618
|
+
if (zoneInfo.hasContent) {
|
|
619
|
+
Logger$3.debug("Processing dynamic zone field " + key);
|
|
620
|
+
const zoneFields = await processDynamicZone(key, value, schemaData.components);
|
|
621
|
+
contentFields.push(...zoneFields);
|
|
622
|
+
staticContent[key] = value;
|
|
623
|
+
}
|
|
624
|
+
continue;
|
|
625
|
+
}
|
|
626
|
+
const componentInfo = isComponent(fieldSchema);
|
|
627
|
+
if (componentInfo.isZone) {
|
|
628
|
+
const componentFields = await processComponentField(key, value, fieldSchema, schemaData.components);
|
|
629
|
+
contentFields.push(...componentFields);
|
|
630
|
+
staticContent[key] = value;
|
|
561
631
|
}
|
|
562
632
|
}
|
|
563
|
-
|
|
633
|
+
Logger$3.info("Process completed");
|
|
634
|
+
return {
|
|
635
|
+
fields: contentFields,
|
|
636
|
+
keep: staticContent
|
|
637
|
+
};
|
|
564
638
|
};
|
|
565
639
|
const shouldSkipField = (key, value) => {
|
|
566
|
-
return DEFAULT_FIELDS.has(key) || isEmpty(value);
|
|
640
|
+
return DEFAULT_FIELDS$1.has(key) || isEmpty(value);
|
|
641
|
+
};
|
|
642
|
+
const isDynamicZone = (fieldSchema, value) => {
|
|
643
|
+
return {
|
|
644
|
+
isZone: fieldSchema.type === "dynamiczone",
|
|
645
|
+
hasContent: Array.isArray(value) && value.length > 0
|
|
646
|
+
};
|
|
567
647
|
};
|
|
568
|
-
const
|
|
569
|
-
return
|
|
648
|
+
const isComponent = (fieldSchema) => {
|
|
649
|
+
return {
|
|
650
|
+
isZone: fieldSchema.type === "dynamiczone",
|
|
651
|
+
hasContent: true
|
|
652
|
+
};
|
|
570
653
|
};
|
|
571
|
-
const
|
|
572
|
-
|
|
654
|
+
const Logger$2 = {
|
|
655
|
+
log: typeof strapi !== "undefined" ? strapi.log : console,
|
|
656
|
+
info: (val) => Logger$2.log.info(val),
|
|
657
|
+
warn: (val) => Logger$2.log.warn(val),
|
|
658
|
+
error: (val) => Logger$2.log.error(val),
|
|
659
|
+
debug: (val) => Logger$2.log.debug(val)
|
|
573
660
|
};
|
|
661
|
+
const DEFAULT_FIELDS = [
|
|
662
|
+
"id",
|
|
663
|
+
"documentId",
|
|
664
|
+
"createdAt",
|
|
665
|
+
"updatedAt",
|
|
666
|
+
,
|
|
667
|
+
"createdBy",
|
|
668
|
+
"updatedBy",
|
|
669
|
+
"publishedAt",
|
|
670
|
+
"locale",
|
|
671
|
+
"localizations"
|
|
672
|
+
];
|
|
673
|
+
const getContentFields = function(schema) {
|
|
674
|
+
const nullFields = [];
|
|
675
|
+
for (let field in schema) {
|
|
676
|
+
if (!DEFAULT_FIELDS.includes(field))
|
|
677
|
+
nullFields.push(field);
|
|
678
|
+
}
|
|
679
|
+
return nullFields;
|
|
680
|
+
};
|
|
681
|
+
const getInvalidOrNullFields = function(document, schema) {
|
|
682
|
+
if (!document)
|
|
683
|
+
return getContentFields(schema);
|
|
684
|
+
const nullFields = [];
|
|
685
|
+
let fieldsValid = 0;
|
|
686
|
+
for (let field in document) {
|
|
687
|
+
if (DEFAULT_FIELDS.includes(field))
|
|
688
|
+
continue;
|
|
689
|
+
if (document[field] === null)
|
|
690
|
+
nullFields.push(field);
|
|
691
|
+
else
|
|
692
|
+
fieldsValid++;
|
|
693
|
+
}
|
|
694
|
+
if (nullFields.length > 0 || fieldsValid > 0)
|
|
695
|
+
return nullFields;
|
|
696
|
+
return getContentFields(schema);
|
|
697
|
+
};
|
|
698
|
+
function appendMissingFields(data, sourceEntry, targetSchema, targetEntry) {
|
|
699
|
+
const nullFields = getInvalidOrNullFields(targetEntry, targetSchema.entry.attributes);
|
|
700
|
+
if (nullFields.length === 0)
|
|
701
|
+
return;
|
|
702
|
+
let count = 0;
|
|
703
|
+
Logger$2.info("Adding missing fields to new locale: " + nullFields.join(", "));
|
|
704
|
+
for (let field of nullFields) {
|
|
705
|
+
if (data[field]) {
|
|
706
|
+
Logger$2.info("Field already present: " + field);
|
|
707
|
+
continue;
|
|
708
|
+
}
|
|
709
|
+
if (!sourceEntry[field]) {
|
|
710
|
+
Logger$2.info("No valid source langauge field value for " + field + " - skipping it.");
|
|
711
|
+
continue;
|
|
712
|
+
}
|
|
713
|
+
if (!targetSchema.entry.attributes[field]) {
|
|
714
|
+
Logger$2.warn("Schema does not contain field " + field);
|
|
715
|
+
continue;
|
|
716
|
+
}
|
|
717
|
+
Logger$2.info("Adding missing field and value for " + field);
|
|
718
|
+
data[field] = sourceEntry[field];
|
|
719
|
+
count++;
|
|
720
|
+
}
|
|
721
|
+
if (count > 0)
|
|
722
|
+
Logger$2.info(count + " missing fields added.");
|
|
723
|
+
}
|
|
724
|
+
async function updateEntry(contentTypeID, entryID, targetLocale, data) {
|
|
725
|
+
strapi.log.info("Updating target entry " + contentTypeID + "::" + entryID + " in locale " + targetLocale);
|
|
726
|
+
const newEntry = await strapi.documents(contentTypeID).update({
|
|
727
|
+
documentId: entryID,
|
|
728
|
+
locale: targetLocale,
|
|
729
|
+
data
|
|
730
|
+
});
|
|
731
|
+
if (!newEntry)
|
|
732
|
+
throw new Error("Cannot update target entry " + contentTypeID + "::" + entryID + " in locale " + targetLocale);
|
|
733
|
+
}
|
|
574
734
|
function htmlToJson(html) {
|
|
575
735
|
function parseHTML(html2) {
|
|
576
736
|
const elements2 = [];
|
|
@@ -763,227 +923,171 @@ function htmlToJson(html) {
|
|
|
763
923
|
}
|
|
764
924
|
return blocks;
|
|
765
925
|
}
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
)
|
|
781
|
-
|
|
926
|
+
const Logger$1 = {
|
|
927
|
+
log: typeof strapi !== "undefined" ? strapi.log : console,
|
|
928
|
+
info: (val) => Logger$1.log.info(val),
|
|
929
|
+
warn: (val) => Logger$1.log.warn(val),
|
|
930
|
+
error: (val) => Logger$1.log.error(val),
|
|
931
|
+
debug: (val) => Logger$1.log.debug(val)
|
|
932
|
+
};
|
|
933
|
+
const removeComponentIds = function(elem) {
|
|
934
|
+
const list = Array.isArray(elem) ? elem : [elem];
|
|
935
|
+
for (let obj of list) {
|
|
936
|
+
if (obj.__component && obj.id)
|
|
937
|
+
delete obj.id;
|
|
938
|
+
for (let key in obj) {
|
|
939
|
+
const child = obj[key];
|
|
940
|
+
if (Array.isArray(child) && Array.length > 0)
|
|
941
|
+
removeComponentIds(child);
|
|
942
|
+
else if (typeof child === "object")
|
|
943
|
+
removeComponentIds(child);
|
|
782
944
|
}
|
|
783
945
|
}
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
946
|
+
};
|
|
947
|
+
function replaceDynamicZones(strapiEntry, replacableFields) {
|
|
948
|
+
const fields = [];
|
|
949
|
+
for (let key in strapiEntry) {
|
|
950
|
+
if (replacableFields[key]) {
|
|
951
|
+
removeComponentIds(replacableFields[key]);
|
|
952
|
+
strapiEntry[key] = replacableFields[key];
|
|
953
|
+
fields.push(key);
|
|
788
954
|
}
|
|
789
955
|
}
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
data: localizedData
|
|
794
|
-
});
|
|
795
|
-
if (originalEntry.publishedAt !== null) {
|
|
796
|
-
await strapi.documents(contentTypeID).publish({
|
|
797
|
-
documentId: entryID,
|
|
798
|
-
locale: sourceLocale
|
|
799
|
-
});
|
|
800
|
-
}
|
|
956
|
+
if (fields.length > 0)
|
|
957
|
+
Logger$1.info(fields.length + " dynamic fields/components replaced for later merge: " + fields.join(", "));
|
|
958
|
+
return fields;
|
|
801
959
|
}
|
|
802
|
-
function
|
|
803
|
-
if (
|
|
804
|
-
return
|
|
960
|
+
const mergeValue = function(field, translatable, targetSchema, map) {
|
|
961
|
+
if (translatable.translatableValue.length === 0)
|
|
962
|
+
return false;
|
|
963
|
+
if (targetSchema.attributes[field] === void 0) {
|
|
964
|
+
Logger$1.info("Field " + field + " does not exist in schema. Skipping it");
|
|
965
|
+
Logger$1.info(targetSchema);
|
|
966
|
+
return false;
|
|
805
967
|
}
|
|
806
|
-
if (
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
for (const fieldData of data[0].fields) {
|
|
810
|
-
if (fieldData.realType === "blocks") {
|
|
811
|
-
if (fieldData.translatableValue?.[0]) {
|
|
812
|
-
processedFields[fieldData.field] = htmlToJson(fieldData.translatableValue[0]);
|
|
813
|
-
}
|
|
814
|
-
} else {
|
|
815
|
-
processedFields[fieldData.field] = fieldData.translatableValue?.[0] || null;
|
|
816
|
-
}
|
|
817
|
-
}
|
|
818
|
-
return processedFields;
|
|
819
|
-
}
|
|
820
|
-
return data.map((item) => processDataRecursively(item));
|
|
968
|
+
if (translatable.translatableValue[0] === "") {
|
|
969
|
+
Logger$1.info("Skipping empty translated content for field " + field);
|
|
970
|
+
return false;
|
|
821
971
|
}
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
972
|
+
if (translatable.realType === "blocks") {
|
|
973
|
+
Logger$1.info("Merge block field " + field);
|
|
974
|
+
map[field] = htmlToJson(translatable.translatableValue[0] || "");
|
|
975
|
+
return true;
|
|
825
976
|
}
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
const
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
if (!field.componentInfo) {
|
|
864
|
-
console.warn(`Component info missing for field: ${field.field}`);
|
|
865
|
-
return;
|
|
866
|
-
}
|
|
867
|
-
const componentId = field.componentInfo.id;
|
|
868
|
-
if (!componentsById.has(componentId)) {
|
|
869
|
-
const existingComponent = existingComponents.find((c) => c.id === componentId);
|
|
870
|
-
componentsById.set(componentId, existingComponent ? { ...existingComponent } : {});
|
|
871
|
-
}
|
|
872
|
-
const component = componentsById.get(componentId);
|
|
873
|
-
if (field.realType === "blocks") {
|
|
874
|
-
component[field.field] = htmlToJson(field.translatableValue[0] || "");
|
|
875
|
-
} else {
|
|
876
|
-
component[field.field] = field.translatableValue[0];
|
|
877
|
-
}
|
|
878
|
-
});
|
|
879
|
-
return Array.from(componentsById.values()).map((comp) => {
|
|
880
|
-
if (!existingComponents.find((ec) => ec.id === comp.id)) {
|
|
881
|
-
const { id, ...rest } = comp;
|
|
882
|
-
return rest;
|
|
883
|
-
}
|
|
884
|
-
return comp;
|
|
885
|
-
}).filter((comp) => Object.keys(comp).length > 0);
|
|
886
|
-
}
|
|
887
|
-
function processNestedComponents(fields, pathParts, existingEntry, acc) {
|
|
888
|
-
let current = acc;
|
|
889
|
-
let currentExisting = existingEntry;
|
|
890
|
-
pathParts.forEach((part, index2) => {
|
|
891
|
-
if (!current[part]) {
|
|
892
|
-
current[part] = {};
|
|
893
|
-
if (currentExisting?.[part]?.id) {
|
|
894
|
-
current[part].id = currentExisting[part].id;
|
|
895
|
-
}
|
|
896
|
-
}
|
|
897
|
-
if (index2 === pathParts.length - 1) {
|
|
898
|
-
fields.forEach((field) => {
|
|
899
|
-
if (field.realType === "blocks") {
|
|
900
|
-
current[part][field.field] = htmlToJson(field.translatableValue[0] || "");
|
|
901
|
-
} else {
|
|
902
|
-
current[part][field.field] = field.translatableValue[0];
|
|
903
|
-
}
|
|
904
|
-
});
|
|
905
|
-
} else {
|
|
906
|
-
current = current[part];
|
|
907
|
-
currentExisting = currentExisting?.[part];
|
|
908
|
-
}
|
|
909
|
-
});
|
|
910
|
-
}
|
|
911
|
-
function processComponentFields(componentFieldsMap, acc, existingEntry, targetSchema) {
|
|
912
|
-
componentFieldsMap.forEach((fields, namePath) => {
|
|
913
|
-
if (!fields.length) return;
|
|
914
|
-
const pathParts = namePath.split(".");
|
|
915
|
-
const rootPath = pathParts[0];
|
|
916
|
-
const schema = targetSchema.attributes?.[rootPath];
|
|
917
|
-
if (schema?.repeatable) {
|
|
918
|
-
acc[rootPath] = processRepeatableComponents(fields, existingEntry, rootPath);
|
|
919
|
-
} else {
|
|
920
|
-
processNestedComponents(fields, pathParts, existingEntry, acc);
|
|
977
|
+
if (translatable.type === "text") {
|
|
978
|
+
Logger$1.info("Merge text field " + field);
|
|
979
|
+
map[field] = translatable.translatableValue[0];
|
|
980
|
+
return true;
|
|
981
|
+
}
|
|
982
|
+
Logger$1.warn("Did not process " + field);
|
|
983
|
+
return false;
|
|
984
|
+
};
|
|
985
|
+
const mergeSimpleFields = function(translatables, existingEntry, targetSchema, map) {
|
|
986
|
+
let count = 0;
|
|
987
|
+
for (const candidate of translatables) {
|
|
988
|
+
const field = candidate.field;
|
|
989
|
+
if (!candidate.uuid && mergeValue(field, candidate, targetSchema.entry, map))
|
|
990
|
+
count++;
|
|
991
|
+
}
|
|
992
|
+
if (count > 0) {
|
|
993
|
+
Logger$1.info("Updated " + count + " simple text fields");
|
|
994
|
+
return true;
|
|
995
|
+
}
|
|
996
|
+
return false;
|
|
997
|
+
};
|
|
998
|
+
const buildMapOfUuids = function(existingEntry, schemaMap, map) {
|
|
999
|
+
if (typeof existingEntry !== "object")
|
|
1000
|
+
return map;
|
|
1001
|
+
const componentName = existingEntry["__component"] ?? "";
|
|
1002
|
+
const schema = componentName && schemaMap.components[componentName] ? schemaMap.components[componentName] : null;
|
|
1003
|
+
if (componentName && !schema)
|
|
1004
|
+
Logger$1.warn("Cannot find component schema " + componentName);
|
|
1005
|
+
for (const key of Object.keys(existingEntry)) {
|
|
1006
|
+
if (key === "__component")
|
|
1007
|
+
continue;
|
|
1008
|
+
if (schema !== null && key === "__tsuid") {
|
|
1009
|
+
map[existingEntry[key]] = {
|
|
1010
|
+
entry: existingEntry,
|
|
1011
|
+
schema
|
|
1012
|
+
};
|
|
1013
|
+
continue;
|
|
921
1014
|
}
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
return acc;
|
|
1015
|
+
const child = existingEntry[key];
|
|
1016
|
+
if (child) {
|
|
1017
|
+
if (Array.isArray(child)) {
|
|
1018
|
+
for (let e of child)
|
|
1019
|
+
buildMapOfUuids(e, schemaMap, map);
|
|
1020
|
+
} else
|
|
1021
|
+
buildMapOfUuids(child, schemaMap, map);
|
|
930
1022
|
}
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
1023
|
+
}
|
|
1024
|
+
if (existingEntry["__tsuid"]) {
|
|
1025
|
+
delete existingEntry["__tsuid"];
|
|
1026
|
+
Logger$1.info("Removed cusom property __tsuid");
|
|
1027
|
+
}
|
|
1028
|
+
return map;
|
|
1029
|
+
};
|
|
1030
|
+
const mergeDynamicZones = function(translatables, schemaMap, existingEntry) {
|
|
1031
|
+
if (translatables.length === 0) {
|
|
1032
|
+
Logger$1.info("Skipping merging of dynamic zones, because none are present.");
|
|
1033
|
+
return;
|
|
1034
|
+
}
|
|
1035
|
+
const map = {};
|
|
1036
|
+
buildMapOfUuids(existingEntry, schemaMap, map);
|
|
1037
|
+
const mapSize = Object.keys(map).length;
|
|
1038
|
+
if (mapSize === 0) {
|
|
1039
|
+
Logger$1.warn("Could not create a uuid map");
|
|
1040
|
+
return false;
|
|
1041
|
+
}
|
|
1042
|
+
Logger$1.info("Built uuid map with " + mapSize + " entry(s)");
|
|
1043
|
+
let count = 0;
|
|
1044
|
+
for (const translatable of translatables) {
|
|
1045
|
+
if (!translatable.uuid)
|
|
1046
|
+
continue;
|
|
1047
|
+
const uuid = translatable.uuid;
|
|
1048
|
+
if (!map[uuid])
|
|
1049
|
+
continue;
|
|
1050
|
+
const entry = map[uuid];
|
|
1051
|
+
const schema = entry.schema;
|
|
1052
|
+
if (!schema) {
|
|
1053
|
+
Logger$1.warn("Cannot find schema by uuid #" + uuid);
|
|
1054
|
+
continue;
|
|
937
1055
|
}
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
}
|
|
941
|
-
function processDynamicZones(dynamicZoneFields, acc, existingEntry) {
|
|
942
|
-
if (dynamicZoneFields.size > 0) {
|
|
943
|
-
const existingDynamicZone = existingEntry?.dynamiczone || [];
|
|
944
|
-
acc.dynamiczone = Array.from(dynamicZoneFields.entries()).sort(([a], [b]) => a - b).map(([_, fields]) => {
|
|
945
|
-
if (!fields[0].componentInfo) {
|
|
946
|
-
console.warn(
|
|
947
|
-
`Component info missing for dynamic zone field: ${fields[0].field}`
|
|
948
|
-
);
|
|
949
|
-
return null;
|
|
950
|
-
}
|
|
951
|
-
const { schemaName } = fields[0].componentInfo;
|
|
952
|
-
const componentData = transformFieldsToData(fields);
|
|
953
|
-
const matchingComponent = existingDynamicZone.find(
|
|
954
|
-
(comp) => comp.__component === schemaName
|
|
955
|
-
);
|
|
956
|
-
return {
|
|
957
|
-
__component: schemaName,
|
|
958
|
-
...componentData,
|
|
959
|
-
...matchingComponent?.id ? { id: matchingComponent.id } : {}
|
|
960
|
-
};
|
|
961
|
-
}).filter(Boolean);
|
|
1056
|
+
if (mergeValue(translatable.field, translatable, schema, entry.entry))
|
|
1057
|
+
count++;
|
|
962
1058
|
}
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
1059
|
+
if (count > 0) {
|
|
1060
|
+
Logger$1.info("Updated " + count + " entries in dynamic zones/content blocks");
|
|
1061
|
+
return true;
|
|
1062
|
+
}
|
|
1063
|
+
return false;
|
|
1064
|
+
};
|
|
1065
|
+
function prepareImportData(translatables, keepData, existingEntry, targetSchema) {
|
|
1066
|
+
const result = {};
|
|
1067
|
+
const simpleUpdated = mergeSimpleFields(translatables, existingEntry, targetSchema, result);
|
|
1068
|
+
let otherUpdated = false;
|
|
1069
|
+
const vsFields = replaceDynamicZones(existingEntry, keepData);
|
|
1070
|
+
if (vsFields.length > 0) {
|
|
1071
|
+
if (mergeDynamicZones(translatables, targetSchema, existingEntry)) {
|
|
1072
|
+
vsFields.forEach((field) => result[field] = existingEntry[field]);
|
|
1073
|
+
otherUpdated = true;
|
|
1074
|
+
} else
|
|
1075
|
+
Logger$1.warn("Could not merge dynamic fields");
|
|
1076
|
+
}
|
|
1077
|
+
if (simpleUpdated || otherUpdated)
|
|
1078
|
+
return result;
|
|
1079
|
+
else
|
|
1080
|
+
return null;
|
|
982
1081
|
}
|
|
983
|
-
require("jsonwebtoken");
|
|
984
|
-
const crypto = require("crypto");
|
|
985
1082
|
const TRANSLATIONTUDIO_URL = "https://strapi.translationstudio.tech";
|
|
986
1083
|
const APP_NAME = "translationstudio";
|
|
1084
|
+
const Logger = {
|
|
1085
|
+
log: typeof strapi !== "undefined" ? strapi.log : console,
|
|
1086
|
+
info: (val) => Logger.log.info(val),
|
|
1087
|
+
warn: (val) => Logger.log.warn(val),
|
|
1088
|
+
error: (val) => Logger.log.error(val),
|
|
1089
|
+
debug: (val) => Logger.log.debug(val)
|
|
1090
|
+
};
|
|
987
1091
|
const service = ({ strapi: strapi2 }) => {
|
|
988
1092
|
const pluginStore = strapi2.store({
|
|
989
1093
|
type: "plugin",
|
|
@@ -1001,7 +1105,7 @@ const service = ({ strapi: strapi2 }) => {
|
|
|
1001
1105
|
if (typeof result === "string" && result !== "")
|
|
1002
1106
|
return result;
|
|
1003
1107
|
} catch (err) {
|
|
1004
|
-
|
|
1108
|
+
strapi2.log.warn(err);
|
|
1005
1109
|
}
|
|
1006
1110
|
return TRANSLATIONTUDIO_URL;
|
|
1007
1111
|
},
|
|
@@ -1046,7 +1150,7 @@ const service = ({ strapi: strapi2 }) => {
|
|
|
1046
1150
|
}
|
|
1047
1151
|
},
|
|
1048
1152
|
async generateToken() {
|
|
1049
|
-
const secretKey =
|
|
1153
|
+
const secretKey = crypto__namespace.randomBytes(64).toString("hex");
|
|
1050
1154
|
await pluginStore.set({
|
|
1051
1155
|
key: "token",
|
|
1052
1156
|
value: secretKey
|
|
@@ -1064,9 +1168,15 @@ const service = ({ strapi: strapi2 }) => {
|
|
|
1064
1168
|
},
|
|
1065
1169
|
async exportData(payload) {
|
|
1066
1170
|
const { contentTypeID, entryID, locale } = parsePayload(payload);
|
|
1067
|
-
const contentType =
|
|
1171
|
+
const contentType = getContentType(contentTypeID);
|
|
1172
|
+
if (contentType === null || !IsLocalisableSchema(contentType.entry)) {
|
|
1173
|
+
return {
|
|
1174
|
+
fields: [],
|
|
1175
|
+
keep: {}
|
|
1176
|
+
};
|
|
1177
|
+
}
|
|
1068
1178
|
const entry = await getEntry(contentTypeID, entryID, locale);
|
|
1069
|
-
const contentFields = await processEntryFields(entry, contentType
|
|
1179
|
+
const contentFields = await processEntryFields(entry, contentType);
|
|
1070
1180
|
return transformResponse(contentFields);
|
|
1071
1181
|
},
|
|
1072
1182
|
async importData(payload) {
|
|
@@ -1074,23 +1184,32 @@ const service = ({ strapi: strapi2 }) => {
|
|
|
1074
1184
|
const sourceLocale = payload.source;
|
|
1075
1185
|
const targetLocale = payload.target;
|
|
1076
1186
|
try {
|
|
1077
|
-
const
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1187
|
+
const sourceEntry = await getEntry(contentTypeID, entryID, sourceLocale);
|
|
1188
|
+
if (sourceEntry == null)
|
|
1189
|
+
throw new Error("Cannot find source entry " + contentTypeID + "::" + entryID + " in " + sourceLocale);
|
|
1190
|
+
const targetSchema = getContentType(contentTypeID);
|
|
1191
|
+
if (targetSchema === null || !IsLocalisableSchema(targetSchema.entry))
|
|
1192
|
+
throw new Error("Cannot find schema");
|
|
1193
|
+
const data = prepareImportData(
|
|
1194
|
+
payload.document[0].fields,
|
|
1195
|
+
payload.document[0].keep ?? {},
|
|
1196
|
+
sourceEntry,
|
|
1197
|
+
targetSchema
|
|
1198
|
+
);
|
|
1199
|
+
strapi2.log.info("Loading target language entry");
|
|
1200
|
+
const targetLocaleEntry = await getEntry(contentTypeID, entryID, targetLocale);
|
|
1201
|
+
appendMissingFields(data, sourceEntry, targetSchema, targetLocaleEntry);
|
|
1202
|
+
await updateEntry(
|
|
1203
|
+
contentTypeID,
|
|
1204
|
+
entryID,
|
|
1205
|
+
targetLocale,
|
|
1206
|
+
data
|
|
1207
|
+
);
|
|
1208
|
+
return true;
|
|
1091
1209
|
} catch (error) {
|
|
1092
|
-
|
|
1210
|
+
strapi2.log.error(error);
|
|
1093
1211
|
}
|
|
1212
|
+
return false;
|
|
1094
1213
|
},
|
|
1095
1214
|
async requestTranslation(payload) {
|
|
1096
1215
|
const { license } = await this.getLicense();
|