@translationstudio/translationstudio-strapi-extension 1.1.3 → 2.0.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/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 +469 -376
- package/dist/server/index.mjs +450 -375
- package/dist/server/src/controllers/controller.d.ts +0 -1
- package/dist/server/src/controllers/index.d.ts +0 -1
- package/dist/server/src/index.d.ts +5 -6
- 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 +5 -5
- package/dist/server/src/services/service.d.ts +5 -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.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as crypto from "crypto";
|
|
1
2
|
const bootstrap = ({ strapi: strapi2 }) => {
|
|
2
3
|
};
|
|
3
4
|
const destroy = ({ strapi: strapi2 }) => {
|
|
@@ -75,10 +76,15 @@ const controller = ({ strapi: strapi2 }) => ({
|
|
|
75
76
|
ctx.status = 400;
|
|
76
77
|
return;
|
|
77
78
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
79
|
+
try {
|
|
80
|
+
const payload = typeof ctx.request.body === "string" ? JSON.parse(ctx.request.body) : ctx.request.body;
|
|
81
|
+
const result = await strapi2.plugin(APP_NAME$1).service("service").exportData(payload);
|
|
82
|
+
ctx.status = 200;
|
|
83
|
+
ctx.body = [{ fields: result }];
|
|
84
|
+
} catch (ex) {
|
|
85
|
+
ctx.status = 500;
|
|
86
|
+
ctx.body = { error: ex.message ?? "Generic error" };
|
|
87
|
+
}
|
|
82
88
|
},
|
|
83
89
|
async setDevelopmentUrl(ctx) {
|
|
84
90
|
const url = ctx.request.body.url;
|
|
@@ -106,40 +112,40 @@ const controller = ({ strapi: strapi2 }) => ({
|
|
|
106
112
|
ctx.status = 400;
|
|
107
113
|
return;
|
|
108
114
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
115
|
+
try {
|
|
116
|
+
const payload = typeof ctx.request.body === "object" ? ctx.request.body : JSON.parse(ctx.request.body);
|
|
117
|
+
strapi2.log.info("Importing");
|
|
118
|
+
const result = await strapi2.plugin(APP_NAME$1).service("service").importData(payload);
|
|
119
|
+
ctx.body = { success: result };
|
|
120
|
+
ctx.status = 200;
|
|
121
|
+
return;
|
|
122
|
+
} catch (err) {
|
|
123
|
+
strapi2.log.error(err.message ?? err);
|
|
124
|
+
}
|
|
125
|
+
ctx.body = { message: "Could not perform import" };
|
|
126
|
+
ctx.status = 500;
|
|
112
127
|
},
|
|
113
128
|
async ping(ctx) {
|
|
114
|
-
|
|
129
|
+
await strapi2.plugin(APP_NAME$1).service("service").ping();
|
|
115
130
|
ctx.status = 204;
|
|
116
|
-
ctx.body = result;
|
|
117
131
|
},
|
|
118
132
|
async getLanguages(ctx) {
|
|
119
133
|
if (!await this.validateToken(ctx)) {
|
|
120
134
|
ctx.status = 400;
|
|
121
135
|
return;
|
|
122
136
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
137
|
+
try {
|
|
138
|
+
const result = await strapi2.plugin(APP_NAME$1).service("service").getLanguages();
|
|
139
|
+
ctx.status = 200;
|
|
140
|
+
ctx.body = result;
|
|
141
|
+
} catch (err) {
|
|
142
|
+
ctx.status = 400;
|
|
143
|
+
ctx.body = {};
|
|
144
|
+
}
|
|
126
145
|
},
|
|
127
146
|
async getEmail(ctx) {
|
|
128
147
|
const result = await strapi2.plugin(APP_NAME$1).service("service").getEmail(ctx);
|
|
129
148
|
ctx.body = result;
|
|
130
|
-
},
|
|
131
|
-
async getEntryData(ctx) {
|
|
132
|
-
const { uid, locale } = ctx.request.body;
|
|
133
|
-
if (!uid) {
|
|
134
|
-
return ctx.badRequest("Missing uid parameter");
|
|
135
|
-
}
|
|
136
|
-
try {
|
|
137
|
-
const [contentTypeID, entryID] = uid.split("#");
|
|
138
|
-
const entry = await strapi2.plugin(APP_NAME$1).service("service").getEntryData(contentTypeID, entryID, locale);
|
|
139
|
-
return entry;
|
|
140
|
-
} catch (error) {
|
|
141
|
-
return ctx.badRequest("Failed to get entry data", { error: error.message });
|
|
142
|
-
}
|
|
143
149
|
}
|
|
144
150
|
});
|
|
145
151
|
const controllers = {
|
|
@@ -255,23 +261,35 @@ const routes = [
|
|
|
255
261
|
config: {
|
|
256
262
|
policies: []
|
|
257
263
|
}
|
|
258
|
-
},
|
|
259
|
-
{
|
|
260
|
-
method: "POST",
|
|
261
|
-
path: "/entrydata",
|
|
262
|
-
handler: "controller.getEntryData",
|
|
263
|
-
config: {
|
|
264
|
-
policies: []
|
|
265
|
-
}
|
|
266
264
|
}
|
|
267
265
|
];
|
|
268
|
-
|
|
269
|
-
const
|
|
266
|
+
function getComponentSchemata(schema) {
|
|
267
|
+
const res = {};
|
|
268
|
+
for (let fieldName in schema.attributes) {
|
|
269
|
+
const field = schema.attributes[fieldName];
|
|
270
|
+
if (!field.components || !Array.isArray(field.components) || field.components.length === 0)
|
|
271
|
+
continue;
|
|
272
|
+
for (let type of field.components) {
|
|
273
|
+
const schema2 = strapi.components[type];
|
|
274
|
+
if (schema2 && schema2.attributes)
|
|
275
|
+
res[type] = schema2;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
return res;
|
|
279
|
+
}
|
|
280
|
+
function getContentType(contentTypeID) {
|
|
281
|
+
const contentType = strapi.contentType(contentTypeID);
|
|
270
282
|
if (!contentType?.attributes) {
|
|
271
|
-
|
|
283
|
+
strapi.log.error(`Content type or schema not found: ${contentTypeID}`);
|
|
284
|
+
return null;
|
|
272
285
|
}
|
|
273
|
-
|
|
274
|
-
|
|
286
|
+
const res = {
|
|
287
|
+
entry: contentType,
|
|
288
|
+
components: getComponentSchemata(contentType)
|
|
289
|
+
};
|
|
290
|
+
strapi.log.info("SChema loaded for " + contentTypeID + ". Component schemata loaded: " + Object.keys(res.components).length);
|
|
291
|
+
return res;
|
|
292
|
+
}
|
|
275
293
|
const parsePayload = (payload) => {
|
|
276
294
|
const [contentTypeID, entryID] = payload.element.includes("#") ? payload.element.split("#") : [payload.element, void 0];
|
|
277
295
|
const locale = payload.source.includes("-") ? payload.source.split("-")[0] : payload.source;
|
|
@@ -281,7 +299,7 @@ const getComponentSchema = async (componentName) => {
|
|
|
281
299
|
try {
|
|
282
300
|
return await strapi.components[componentName];
|
|
283
301
|
} catch (error) {
|
|
284
|
-
|
|
302
|
+
strapi.log.error(`Failed to get component schema for ${componentName}:`, error);
|
|
285
303
|
return null;
|
|
286
304
|
}
|
|
287
305
|
};
|
|
@@ -304,27 +322,32 @@ const buildPopulateConfig = async (schema) => {
|
|
|
304
322
|
}
|
|
305
323
|
return populate;
|
|
306
324
|
};
|
|
307
|
-
const getEntry = async (contentTypeID, entryID, locale) => {
|
|
325
|
+
const getEntry = async (contentTypeID, entryID, locale, logError = true) => {
|
|
308
326
|
try {
|
|
309
327
|
const contentType = await strapi.contentTypes[contentTypeID];
|
|
310
328
|
const populateConfig = await buildPopulateConfig(contentType);
|
|
311
329
|
const query = {
|
|
312
330
|
locale,
|
|
331
|
+
documentId: entryID,
|
|
313
332
|
populate: populateConfig
|
|
314
333
|
};
|
|
315
|
-
if (entryID) {
|
|
316
|
-
Object.assign(query, { documentId: entryID });
|
|
317
|
-
}
|
|
318
334
|
const entry = await strapi.documents(contentTypeID).findFirst(query);
|
|
319
|
-
|
|
335
|
+
if (entry) {
|
|
336
|
+
strapi.log.info("Obtained " + contentTypeID + "::" + entryID + " in " + locale);
|
|
337
|
+
return entry;
|
|
338
|
+
}
|
|
320
339
|
} catch (error) {
|
|
321
|
-
|
|
322
|
-
return null;
|
|
340
|
+
strapi.log.error(error.message ?? error);
|
|
323
341
|
}
|
|
342
|
+
strapi.log.warn("Could not find entry " + entryID + " in locale " + locale);
|
|
343
|
+
return null;
|
|
344
|
+
};
|
|
345
|
+
const transformResponse = function(data) {
|
|
346
|
+
data.fields = data.fields.map(
|
|
347
|
+
(item) => item.realType === "blocks" && Array.isArray(item.translatableValue[0]) ? { ...item, translatableValue: item.translatableValue[0] } : item
|
|
348
|
+
);
|
|
349
|
+
return data;
|
|
324
350
|
};
|
|
325
|
-
const transformResponse = (data) => data.map(
|
|
326
|
-
(item) => item.realType === "blocks" && Array.isArray(item.translatableValue[0]) ? { ...item, translatableValue: item.translatableValue[0] } : item
|
|
327
|
-
);
|
|
328
351
|
function jsonToHtml(json) {
|
|
329
352
|
if (!json || !Array.isArray(json)) {
|
|
330
353
|
return "";
|
|
@@ -373,43 +396,37 @@ function formatText(child) {
|
|
|
373
396
|
}
|
|
374
397
|
return text;
|
|
375
398
|
}
|
|
376
|
-
const
|
|
399
|
+
const Logger$4 = {
|
|
400
|
+
log: typeof strapi !== "undefined" ? strapi.log : console,
|
|
401
|
+
info: (val) => Logger$4.log.info(val),
|
|
402
|
+
warn: (val) => Logger$4.log.warn(val),
|
|
403
|
+
error: (val) => Logger$4.log.error(val),
|
|
404
|
+
debug: (val) => Logger$4.log.debug(val)
|
|
405
|
+
};
|
|
406
|
+
async function processComponent(fieldName, value, componentSchema, schemata) {
|
|
377
407
|
const contentFields = [];
|
|
378
|
-
|
|
379
|
-
if (!componentSchema)
|
|
380
|
-
|
|
381
|
-
}
|
|
408
|
+
Logger$4.info("Processing dynamic field " + fieldName);
|
|
409
|
+
if (!componentSchema || !componentSchema.attributes)
|
|
410
|
+
return [];
|
|
382
411
|
const schemaAttributes = componentSchema.attributes || {};
|
|
383
412
|
const dataToProcess = value || {};
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
schemaAttributes,
|
|
389
|
-
fieldName,
|
|
390
|
-
componentName,
|
|
391
|
-
schemaName,
|
|
392
|
-
item.id
|
|
393
|
-
);
|
|
394
|
-
contentFields.push(...processedFields);
|
|
395
|
-
}
|
|
396
|
-
} else {
|
|
397
|
-
const processedFields = await processComponentFields$1(
|
|
398
|
-
dataToProcess,
|
|
413
|
+
const candidates = Array.isArray(dataToProcess) ? dataToProcess : [dataToProcess];
|
|
414
|
+
for (const item of candidates) {
|
|
415
|
+
const processedFields = await processComponentFields(
|
|
416
|
+
item,
|
|
399
417
|
schemaAttributes,
|
|
400
418
|
fieldName,
|
|
401
|
-
|
|
402
|
-
schemaName,
|
|
403
|
-
componentId
|
|
419
|
+
schemata
|
|
404
420
|
);
|
|
405
|
-
|
|
421
|
+
if (processedFields.length > 0)
|
|
422
|
+
contentFields.push(...processedFields);
|
|
406
423
|
}
|
|
407
424
|
return contentFields;
|
|
408
|
-
}
|
|
425
|
+
}
|
|
409
426
|
const shouldSkipField$1 = (key, fieldSchema) => {
|
|
410
427
|
return key === "id" || fieldSchema.private;
|
|
411
428
|
};
|
|
412
|
-
const isTranslatableField
|
|
429
|
+
const isTranslatableField = (type) => {
|
|
413
430
|
return ["string", "text", "blocks", "richtext"].includes(type);
|
|
414
431
|
};
|
|
415
432
|
const getTranslatedValue = (type, value) => {
|
|
@@ -418,64 +435,61 @@ const getTranslatedValue = (type, value) => {
|
|
|
418
435
|
}
|
|
419
436
|
return value.toString();
|
|
420
437
|
};
|
|
421
|
-
const buildTranslatable = (key, fieldSchema, value,
|
|
438
|
+
const buildTranslatable = (key, fieldSchema, value, uuid = "") => {
|
|
422
439
|
return {
|
|
423
440
|
field: key,
|
|
424
441
|
type: ["richtext", "blocks"].includes(fieldSchema.type) ? "html" : "text",
|
|
425
442
|
translatableValue: [value],
|
|
426
443
|
realType: fieldSchema.type,
|
|
427
|
-
|
|
428
|
-
namePath: parentPath,
|
|
429
|
-
id: componentId,
|
|
430
|
-
schemaName
|
|
431
|
-
}
|
|
444
|
+
uuid
|
|
432
445
|
};
|
|
433
446
|
};
|
|
434
|
-
const processComponentFields
|
|
447
|
+
const processComponentFields = async (componentData, schema, parentField, schemata) => {
|
|
435
448
|
const contentFields = [];
|
|
436
|
-
const
|
|
449
|
+
const uuid = crypto.randomUUID();
|
|
437
450
|
for (const [key, fieldSchema] of Object.entries(schema)) {
|
|
438
451
|
if (shouldSkipField$1(key, fieldSchema)) continue;
|
|
439
452
|
const value = componentData?.[key];
|
|
440
|
-
|
|
453
|
+
if (!value)
|
|
454
|
+
continue;
|
|
441
455
|
if (fieldSchema.type === "component") {
|
|
442
|
-
if (!
|
|
456
|
+
if (!value.__component)
|
|
457
|
+
continue;
|
|
458
|
+
const targetSchema = schemata[value.__component];
|
|
459
|
+
if (!targetSchema)
|
|
460
|
+
continue;
|
|
443
461
|
const nestedFields = await processComponent(
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
value?.id
|
|
462
|
+
`${parentField}.${key}`,
|
|
463
|
+
value,
|
|
464
|
+
targetSchema,
|
|
465
|
+
schemata
|
|
449
466
|
);
|
|
450
|
-
|
|
467
|
+
if (nestedFields.length > 0)
|
|
468
|
+
contentFields.push(...nestedFields);
|
|
451
469
|
continue;
|
|
452
470
|
}
|
|
453
|
-
if (!isTranslatableField
|
|
471
|
+
if (!isTranslatableField(fieldSchema.type)) continue;
|
|
454
472
|
if (value === null || value === void 0 || value === "") continue;
|
|
455
473
|
const translatedValue = getTranslatedValue(fieldSchema.type, value);
|
|
456
474
|
const translatable = buildTranslatable(
|
|
457
475
|
key,
|
|
458
476
|
fieldSchema,
|
|
459
477
|
translatedValue,
|
|
460
|
-
|
|
461
|
-
componentId,
|
|
462
|
-
schemaName
|
|
478
|
+
uuid
|
|
463
479
|
);
|
|
480
|
+
componentData.__tsuid = uuid;
|
|
464
481
|
contentFields.push(translatable);
|
|
465
482
|
}
|
|
466
483
|
return contentFields;
|
|
467
484
|
};
|
|
468
|
-
const
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
return localizableTypes.includes(fieldSchema.type);
|
|
475
|
-
}
|
|
476
|
-
return false;
|
|
485
|
+
const Logger$3 = {
|
|
486
|
+
log: typeof strapi !== "undefined" ? strapi.log : console,
|
|
487
|
+
info: (val) => Logger$3.log.info(val),
|
|
488
|
+
warn: (val) => Logger$3.log.warn(val),
|
|
489
|
+
error: (val) => Logger$3.log.error(val),
|
|
490
|
+
debug: (val) => Logger$3.log.debug(val)
|
|
477
491
|
};
|
|
478
|
-
const DEFAULT_FIELDS = /* @__PURE__ */ new Set([
|
|
492
|
+
const DEFAULT_FIELDS$1 = /* @__PURE__ */ new Set([
|
|
479
493
|
"id",
|
|
480
494
|
"documentId",
|
|
481
495
|
"createdAt",
|
|
@@ -487,45 +501,41 @@ const DEFAULT_FIELDS = /* @__PURE__ */ new Set([
|
|
|
487
501
|
"createdBy"
|
|
488
502
|
]);
|
|
489
503
|
const isEmpty = (value) => value === null || value === void 0 || value === "";
|
|
490
|
-
const
|
|
491
|
-
const processDynamicZone = async (key, value,
|
|
504
|
+
const isSimpleTranslatableField = (fieldSchema) => ["string", "text", "blocks", "richtext"].includes(fieldSchema.type) && fieldSchema.pluginOptions?.i18n?.localized === true;
|
|
505
|
+
const processDynamicZone = async (key, value, schemata) => {
|
|
492
506
|
const results = [];
|
|
493
507
|
for (const component of value) {
|
|
494
508
|
const componentName = component?.__component;
|
|
495
509
|
if (!componentName) continue;
|
|
510
|
+
const schema = schemata[componentName];
|
|
511
|
+
if (!schema) continue;
|
|
496
512
|
const fields = await processComponent(
|
|
497
513
|
key,
|
|
498
|
-
componentName,
|
|
499
514
|
component,
|
|
500
|
-
|
|
501
|
-
|
|
515
|
+
schema,
|
|
516
|
+
schemata
|
|
502
517
|
);
|
|
503
|
-
|
|
518
|
+
if (fields.length > 0)
|
|
519
|
+
results.push(...fields);
|
|
504
520
|
}
|
|
505
521
|
return results;
|
|
506
522
|
};
|
|
507
|
-
const processComponentField = async (key, value, fieldSchema) => {
|
|
523
|
+
const processComponentField = async (key, value, fieldSchema, schemata) => {
|
|
508
524
|
const results = [];
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
fieldSchema.component,
|
|
516
|
-
component.id
|
|
517
|
-
);
|
|
518
|
-
results.push(...fields);
|
|
519
|
-
}
|
|
520
|
-
} else {
|
|
525
|
+
const candidates = Array.isArray(value) ? value : [value];
|
|
526
|
+
for (const component of candidates) {
|
|
527
|
+
const componentName = component?.__component;
|
|
528
|
+
if (!componentName) continue;
|
|
529
|
+
const schema = schemata[componentName];
|
|
530
|
+
if (!schema) continue;
|
|
521
531
|
const fields = await processComponent(
|
|
522
532
|
key,
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
value.id
|
|
533
|
+
component,
|
|
534
|
+
schema,
|
|
535
|
+
schemata
|
|
527
536
|
);
|
|
528
|
-
|
|
537
|
+
if (fields.length > 0)
|
|
538
|
+
results.push(...fields);
|
|
529
539
|
}
|
|
530
540
|
return results;
|
|
531
541
|
};
|
|
@@ -538,38 +548,148 @@ const processRegularField = (key, value, fieldSchema) => {
|
|
|
538
548
|
realType: fieldSchema.type
|
|
539
549
|
};
|
|
540
550
|
};
|
|
541
|
-
|
|
551
|
+
function IsLocalisableSchema(schema) {
|
|
552
|
+
return schema.pluginOptions?.i18n?.localized === true;
|
|
553
|
+
}
|
|
554
|
+
function IsLocalisedField(field) {
|
|
555
|
+
return field.pluginOptions?.i18n?.localized === true;
|
|
556
|
+
}
|
|
557
|
+
const processEntryFields = async (entry, schemaData, _locale) => {
|
|
542
558
|
const contentFields = [];
|
|
559
|
+
const staticContent = {};
|
|
560
|
+
const schema = schemaData.entry.attributes;
|
|
543
561
|
for (const [key, value] of Object.entries(entry)) {
|
|
544
|
-
if (shouldSkipField(key, value))
|
|
545
|
-
const fieldSchema = schema[key];
|
|
546
|
-
if (!fieldSchema) continue;
|
|
547
|
-
if (isDynamicZone(fieldSchema, value, schema)) {
|
|
548
|
-
const zoneFields = await processDynamicZone(key, value);
|
|
549
|
-
contentFields.push(...zoneFields);
|
|
562
|
+
if (shouldSkipField(key, value))
|
|
550
563
|
continue;
|
|
551
|
-
|
|
552
|
-
if (
|
|
553
|
-
|
|
554
|
-
contentFields.push(...componentFields);
|
|
564
|
+
const fieldSchema = schema[key];
|
|
565
|
+
if (!fieldSchema || !IsLocalisedField(fieldSchema)) {
|
|
566
|
+
Logger$3.debug("SKipping non-local field " + key);
|
|
555
567
|
continue;
|
|
556
568
|
}
|
|
557
|
-
if (
|
|
569
|
+
if (isSimpleTranslatableField(fieldSchema)) {
|
|
570
|
+
Logger$3.debug("Processing simple field " + key);
|
|
558
571
|
const translatedField = processRegularField(key, value, fieldSchema);
|
|
559
572
|
contentFields.push(translatedField);
|
|
573
|
+
continue;
|
|
574
|
+
}
|
|
575
|
+
const zoneInfo = isDynamicZone(fieldSchema, value);
|
|
576
|
+
if (zoneInfo.isZone) {
|
|
577
|
+
if (zoneInfo.hasContent) {
|
|
578
|
+
Logger$3.debug("Processing dynamic zone field " + key);
|
|
579
|
+
const zoneFields = await processDynamicZone(key, value, schemaData.components);
|
|
580
|
+
contentFields.push(...zoneFields);
|
|
581
|
+
staticContent[key] = value;
|
|
582
|
+
}
|
|
583
|
+
continue;
|
|
584
|
+
}
|
|
585
|
+
const componentInfo = isComponent(fieldSchema);
|
|
586
|
+
if (componentInfo.isZone) {
|
|
587
|
+
const componentFields = await processComponentField(key, value, fieldSchema, schemaData.components);
|
|
588
|
+
contentFields.push(...componentFields);
|
|
589
|
+
staticContent[key] = value;
|
|
560
590
|
}
|
|
561
591
|
}
|
|
562
|
-
|
|
592
|
+
Logger$3.info("Process completed");
|
|
593
|
+
return {
|
|
594
|
+
fields: contentFields,
|
|
595
|
+
keep: staticContent
|
|
596
|
+
};
|
|
563
597
|
};
|
|
564
598
|
const shouldSkipField = (key, value) => {
|
|
565
|
-
return DEFAULT_FIELDS.has(key) || isEmpty(value);
|
|
599
|
+
return DEFAULT_FIELDS$1.has(key) || isEmpty(value);
|
|
566
600
|
};
|
|
567
|
-
const isDynamicZone = (fieldSchema, value
|
|
568
|
-
return
|
|
601
|
+
const isDynamicZone = (fieldSchema, value) => {
|
|
602
|
+
return {
|
|
603
|
+
isZone: fieldSchema.type === "dynamiczone",
|
|
604
|
+
hasContent: Array.isArray(value) && value.length > 0
|
|
605
|
+
};
|
|
606
|
+
};
|
|
607
|
+
const isComponent = (fieldSchema) => {
|
|
608
|
+
return {
|
|
609
|
+
isZone: fieldSchema.type === "dynamiczone",
|
|
610
|
+
hasContent: true
|
|
611
|
+
};
|
|
612
|
+
};
|
|
613
|
+
const Logger$2 = {
|
|
614
|
+
log: typeof strapi !== "undefined" ? strapi.log : console,
|
|
615
|
+
info: (val) => Logger$2.log.info(val),
|
|
616
|
+
warn: (val) => Logger$2.log.warn(val),
|
|
617
|
+
error: (val) => Logger$2.log.error(val),
|
|
618
|
+
debug: (val) => Logger$2.log.debug(val)
|
|
619
|
+
};
|
|
620
|
+
const DEFAULT_FIELDS = [
|
|
621
|
+
"id",
|
|
622
|
+
"documentId",
|
|
623
|
+
"createdAt",
|
|
624
|
+
"updatedAt",
|
|
625
|
+
,
|
|
626
|
+
"createdBy",
|
|
627
|
+
"updatedBy",
|
|
628
|
+
"publishedAt",
|
|
629
|
+
"locale",
|
|
630
|
+
"localizations"
|
|
631
|
+
];
|
|
632
|
+
const getContentFields = function(schema) {
|
|
633
|
+
const nullFields = [];
|
|
634
|
+
for (let field in schema) {
|
|
635
|
+
if (!DEFAULT_FIELDS.includes(field))
|
|
636
|
+
nullFields.push(field);
|
|
637
|
+
}
|
|
638
|
+
return nullFields;
|
|
569
639
|
};
|
|
570
|
-
const
|
|
571
|
-
|
|
640
|
+
const getInvalidOrNullFields = function(document, schema) {
|
|
641
|
+
if (!document)
|
|
642
|
+
return getContentFields(schema);
|
|
643
|
+
const nullFields = [];
|
|
644
|
+
let fieldsValid = 0;
|
|
645
|
+
for (let field in document) {
|
|
646
|
+
if (DEFAULT_FIELDS.includes(field))
|
|
647
|
+
continue;
|
|
648
|
+
if (document[field] === null)
|
|
649
|
+
nullFields.push(field);
|
|
650
|
+
else
|
|
651
|
+
fieldsValid++;
|
|
652
|
+
}
|
|
653
|
+
if (nullFields.length > 0 || fieldsValid > 0)
|
|
654
|
+
return nullFields;
|
|
655
|
+
return getContentFields(schema);
|
|
572
656
|
};
|
|
657
|
+
function appendMissingFields(data, sourceEntry, targetSchema, targetEntry) {
|
|
658
|
+
const nullFields = getInvalidOrNullFields(targetEntry, targetSchema.entry.attributes);
|
|
659
|
+
if (nullFields.length === 0)
|
|
660
|
+
return;
|
|
661
|
+
let count = 0;
|
|
662
|
+
Logger$2.info("Adding missing fields to new locale: " + nullFields.join(", "));
|
|
663
|
+
for (let field of nullFields) {
|
|
664
|
+
if (data[field]) {
|
|
665
|
+
Logger$2.info("Field already present: " + field);
|
|
666
|
+
continue;
|
|
667
|
+
}
|
|
668
|
+
if (!sourceEntry[field]) {
|
|
669
|
+
Logger$2.info("No valid source langauge field value for " + field + " - skipping it.");
|
|
670
|
+
continue;
|
|
671
|
+
}
|
|
672
|
+
if (!targetSchema.entry.attributes[field]) {
|
|
673
|
+
Logger$2.warn("Schema does not contain field " + field);
|
|
674
|
+
continue;
|
|
675
|
+
}
|
|
676
|
+
Logger$2.info("Adding missing field and value for " + field);
|
|
677
|
+
data[field] = sourceEntry[field];
|
|
678
|
+
count++;
|
|
679
|
+
}
|
|
680
|
+
if (count > 0)
|
|
681
|
+
Logger$2.info(count + " missing fields added.");
|
|
682
|
+
}
|
|
683
|
+
async function updateEntry(contentTypeID, entryID, targetLocale, data) {
|
|
684
|
+
strapi.log.info("Updating target entry " + contentTypeID + "::" + entryID + " in locale " + targetLocale);
|
|
685
|
+
const newEntry = await strapi.documents(contentTypeID).update({
|
|
686
|
+
documentId: entryID,
|
|
687
|
+
locale: targetLocale,
|
|
688
|
+
data
|
|
689
|
+
});
|
|
690
|
+
if (!newEntry)
|
|
691
|
+
throw new Error("Cannot update target entry " + contentTypeID + "::" + entryID + " in locale " + targetLocale);
|
|
692
|
+
}
|
|
573
693
|
function htmlToJson(html) {
|
|
574
694
|
function parseHTML(html2) {
|
|
575
695
|
const elements2 = [];
|
|
@@ -762,227 +882,171 @@ function htmlToJson(html) {
|
|
|
762
882
|
}
|
|
763
883
|
return blocks;
|
|
764
884
|
}
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
)
|
|
780
|
-
|
|
885
|
+
const Logger$1 = {
|
|
886
|
+
log: typeof strapi !== "undefined" ? strapi.log : console,
|
|
887
|
+
info: (val) => Logger$1.log.info(val),
|
|
888
|
+
warn: (val) => Logger$1.log.warn(val),
|
|
889
|
+
error: (val) => Logger$1.log.error(val),
|
|
890
|
+
debug: (val) => Logger$1.log.debug(val)
|
|
891
|
+
};
|
|
892
|
+
const removeComponentIds = function(elem) {
|
|
893
|
+
const list = Array.isArray(elem) ? elem : [elem];
|
|
894
|
+
for (let obj of list) {
|
|
895
|
+
if (obj.__component && obj.id)
|
|
896
|
+
delete obj.id;
|
|
897
|
+
for (let key in obj) {
|
|
898
|
+
const child = obj[key];
|
|
899
|
+
if (Array.isArray(child) && Array.length > 0)
|
|
900
|
+
removeComponentIds(child);
|
|
901
|
+
else if (typeof child === "object")
|
|
902
|
+
removeComponentIds(child);
|
|
781
903
|
}
|
|
782
904
|
}
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
905
|
+
};
|
|
906
|
+
function replaceDynamicZones(strapiEntry, replacableFields) {
|
|
907
|
+
const fields = [];
|
|
908
|
+
for (let key in strapiEntry) {
|
|
909
|
+
if (replacableFields[key]) {
|
|
910
|
+
removeComponentIds(replacableFields[key]);
|
|
911
|
+
strapiEntry[key] = replacableFields[key];
|
|
912
|
+
fields.push(key);
|
|
787
913
|
}
|
|
788
914
|
}
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
data: localizedData
|
|
793
|
-
});
|
|
794
|
-
if (originalEntry.publishedAt !== null) {
|
|
795
|
-
await strapi.documents(contentTypeID).publish({
|
|
796
|
-
documentId: entryID,
|
|
797
|
-
locale: sourceLocale
|
|
798
|
-
});
|
|
799
|
-
}
|
|
915
|
+
if (fields.length > 0)
|
|
916
|
+
Logger$1.info(fields.length + " dynamic fields/components replaced for later merge: " + fields.join(", "));
|
|
917
|
+
return fields;
|
|
800
918
|
}
|
|
801
|
-
function
|
|
802
|
-
if (
|
|
803
|
-
return
|
|
919
|
+
const mergeValue = function(field, translatable, targetSchema, map) {
|
|
920
|
+
if (translatable.translatableValue.length === 0)
|
|
921
|
+
return false;
|
|
922
|
+
if (targetSchema.attributes[field] === void 0) {
|
|
923
|
+
Logger$1.info("Field " + field + " does not exist in schema. Skipping it");
|
|
924
|
+
Logger$1.info(targetSchema);
|
|
925
|
+
return false;
|
|
804
926
|
}
|
|
805
|
-
if (
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
for (const fieldData of data[0].fields) {
|
|
809
|
-
if (fieldData.realType === "blocks") {
|
|
810
|
-
if (fieldData.translatableValue?.[0]) {
|
|
811
|
-
processedFields[fieldData.field] = htmlToJson(fieldData.translatableValue[0]);
|
|
812
|
-
}
|
|
813
|
-
} else {
|
|
814
|
-
processedFields[fieldData.field] = fieldData.translatableValue?.[0] || null;
|
|
815
|
-
}
|
|
816
|
-
}
|
|
817
|
-
return processedFields;
|
|
818
|
-
}
|
|
819
|
-
return data.map((item) => processDataRecursively(item));
|
|
927
|
+
if (translatable.translatableValue[0] === "") {
|
|
928
|
+
Logger$1.info("Skipping empty translated content for field " + field);
|
|
929
|
+
return false;
|
|
820
930
|
}
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
931
|
+
if (translatable.realType === "blocks") {
|
|
932
|
+
Logger$1.info("Merge block field " + field);
|
|
933
|
+
map[field] = htmlToJson(translatable.translatableValue[0] || "");
|
|
934
|
+
return true;
|
|
824
935
|
}
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
const
|
|
837
|
-
|
|
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
|
-
if (!field.componentInfo) {
|
|
863
|
-
console.warn(`Component info missing for field: ${field.field}`);
|
|
864
|
-
return;
|
|
865
|
-
}
|
|
866
|
-
const componentId = field.componentInfo.id;
|
|
867
|
-
if (!componentsById.has(componentId)) {
|
|
868
|
-
const existingComponent = existingComponents.find((c) => c.id === componentId);
|
|
869
|
-
componentsById.set(componentId, existingComponent ? { ...existingComponent } : {});
|
|
870
|
-
}
|
|
871
|
-
const component = componentsById.get(componentId);
|
|
872
|
-
if (field.realType === "blocks") {
|
|
873
|
-
component[field.field] = htmlToJson(field.translatableValue[0] || "");
|
|
874
|
-
} else {
|
|
875
|
-
component[field.field] = field.translatableValue[0];
|
|
876
|
-
}
|
|
877
|
-
});
|
|
878
|
-
return Array.from(componentsById.values()).map((comp) => {
|
|
879
|
-
if (!existingComponents.find((ec) => ec.id === comp.id)) {
|
|
880
|
-
const { id, ...rest } = comp;
|
|
881
|
-
return rest;
|
|
882
|
-
}
|
|
883
|
-
return comp;
|
|
884
|
-
}).filter((comp) => Object.keys(comp).length > 0);
|
|
885
|
-
}
|
|
886
|
-
function processNestedComponents(fields, pathParts, existingEntry, acc) {
|
|
887
|
-
let current = acc;
|
|
888
|
-
let currentExisting = existingEntry;
|
|
889
|
-
pathParts.forEach((part, index2) => {
|
|
890
|
-
if (!current[part]) {
|
|
891
|
-
current[part] = {};
|
|
892
|
-
if (currentExisting?.[part]?.id) {
|
|
893
|
-
current[part].id = currentExisting[part].id;
|
|
894
|
-
}
|
|
895
|
-
}
|
|
896
|
-
if (index2 === pathParts.length - 1) {
|
|
897
|
-
fields.forEach((field) => {
|
|
898
|
-
if (field.realType === "blocks") {
|
|
899
|
-
current[part][field.field] = htmlToJson(field.translatableValue[0] || "");
|
|
900
|
-
} else {
|
|
901
|
-
current[part][field.field] = field.translatableValue[0];
|
|
902
|
-
}
|
|
903
|
-
});
|
|
904
|
-
} else {
|
|
905
|
-
current = current[part];
|
|
906
|
-
currentExisting = currentExisting?.[part];
|
|
907
|
-
}
|
|
908
|
-
});
|
|
909
|
-
}
|
|
910
|
-
function processComponentFields(componentFieldsMap, acc, existingEntry, targetSchema) {
|
|
911
|
-
componentFieldsMap.forEach((fields, namePath) => {
|
|
912
|
-
if (!fields.length) return;
|
|
913
|
-
const pathParts = namePath.split(".");
|
|
914
|
-
const rootPath = pathParts[0];
|
|
915
|
-
const schema = targetSchema.attributes?.[rootPath];
|
|
916
|
-
if (schema?.repeatable) {
|
|
917
|
-
acc[rootPath] = processRepeatableComponents(fields, existingEntry, rootPath);
|
|
918
|
-
} else {
|
|
919
|
-
processNestedComponents(fields, pathParts, existingEntry, acc);
|
|
936
|
+
if (translatable.type === "text") {
|
|
937
|
+
Logger$1.info("Merge text field " + field);
|
|
938
|
+
map[field] = translatable.translatableValue[0];
|
|
939
|
+
return true;
|
|
940
|
+
}
|
|
941
|
+
Logger$1.warn("Did not process " + field);
|
|
942
|
+
return false;
|
|
943
|
+
};
|
|
944
|
+
const mergeSimpleFields = function(translatables, existingEntry, targetSchema, map) {
|
|
945
|
+
let count = 0;
|
|
946
|
+
for (const candidate of translatables) {
|
|
947
|
+
const field = candidate.field;
|
|
948
|
+
if (!candidate.uuid && mergeValue(field, candidate, targetSchema.entry, map))
|
|
949
|
+
count++;
|
|
950
|
+
}
|
|
951
|
+
if (count > 0) {
|
|
952
|
+
Logger$1.info("Updated " + count + " simple text fields");
|
|
953
|
+
return true;
|
|
954
|
+
}
|
|
955
|
+
return false;
|
|
956
|
+
};
|
|
957
|
+
const buildMapOfUuids = function(existingEntry, schemaMap, map) {
|
|
958
|
+
if (typeof existingEntry !== "object")
|
|
959
|
+
return map;
|
|
960
|
+
const componentName = existingEntry["__component"] ?? "";
|
|
961
|
+
const schema = componentName && schemaMap.components[componentName] ? schemaMap.components[componentName] : null;
|
|
962
|
+
if (componentName && !schema)
|
|
963
|
+
Logger$1.warn("Cannot find component schema " + componentName);
|
|
964
|
+
for (const key of Object.keys(existingEntry)) {
|
|
965
|
+
if (key === "__component")
|
|
966
|
+
continue;
|
|
967
|
+
if (schema !== null && key === "__tsuid") {
|
|
968
|
+
map[existingEntry[key]] = {
|
|
969
|
+
entry: existingEntry,
|
|
970
|
+
schema
|
|
971
|
+
};
|
|
972
|
+
continue;
|
|
920
973
|
}
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
return acc;
|
|
974
|
+
const child = existingEntry[key];
|
|
975
|
+
if (child) {
|
|
976
|
+
if (Array.isArray(child)) {
|
|
977
|
+
for (let e of child)
|
|
978
|
+
buildMapOfUuids(e, schemaMap, map);
|
|
979
|
+
} else
|
|
980
|
+
buildMapOfUuids(child, schemaMap, map);
|
|
929
981
|
}
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
982
|
+
}
|
|
983
|
+
if (existingEntry["__tsuid"]) {
|
|
984
|
+
delete existingEntry["__tsuid"];
|
|
985
|
+
Logger$1.info("Removed cusom property __tsuid");
|
|
986
|
+
}
|
|
987
|
+
return map;
|
|
988
|
+
};
|
|
989
|
+
const mergeDynamicZones = function(translatables, schemaMap, existingEntry) {
|
|
990
|
+
if (translatables.length === 0) {
|
|
991
|
+
Logger$1.info("Skipping merging of dynamic zones, because none are present.");
|
|
992
|
+
return;
|
|
993
|
+
}
|
|
994
|
+
const map = {};
|
|
995
|
+
buildMapOfUuids(existingEntry, schemaMap, map);
|
|
996
|
+
const mapSize = Object.keys(map).length;
|
|
997
|
+
if (mapSize === 0) {
|
|
998
|
+
Logger$1.warn("Could not create a uuid map");
|
|
999
|
+
return false;
|
|
1000
|
+
}
|
|
1001
|
+
Logger$1.info("Built uuid map with " + mapSize + " entry(s)");
|
|
1002
|
+
let count = 0;
|
|
1003
|
+
for (const translatable of translatables) {
|
|
1004
|
+
if (!translatable.uuid)
|
|
1005
|
+
continue;
|
|
1006
|
+
const uuid = translatable.uuid;
|
|
1007
|
+
if (!map[uuid])
|
|
1008
|
+
continue;
|
|
1009
|
+
const entry = map[uuid];
|
|
1010
|
+
const schema = entry.schema;
|
|
1011
|
+
if (!schema) {
|
|
1012
|
+
Logger$1.warn("Cannot find schema by uuid #" + uuid);
|
|
1013
|
+
continue;
|
|
936
1014
|
}
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
}
|
|
940
|
-
function processDynamicZones(dynamicZoneFields, acc, existingEntry) {
|
|
941
|
-
if (dynamicZoneFields.size > 0) {
|
|
942
|
-
const existingDynamicZone = existingEntry?.dynamiczone || [];
|
|
943
|
-
acc.dynamiczone = Array.from(dynamicZoneFields.entries()).sort(([a], [b]) => a - b).map(([_, fields]) => {
|
|
944
|
-
if (!fields[0].componentInfo) {
|
|
945
|
-
console.warn(
|
|
946
|
-
`Component info missing for dynamic zone field: ${fields[0].field}`
|
|
947
|
-
);
|
|
948
|
-
return null;
|
|
949
|
-
}
|
|
950
|
-
const { schemaName } = fields[0].componentInfo;
|
|
951
|
-
const componentData = transformFieldsToData(fields);
|
|
952
|
-
const matchingComponent = existingDynamicZone.find(
|
|
953
|
-
(comp) => comp.__component === schemaName
|
|
954
|
-
);
|
|
955
|
-
return {
|
|
956
|
-
__component: schemaName,
|
|
957
|
-
...componentData,
|
|
958
|
-
...matchingComponent?.id ? { id: matchingComponent.id } : {}
|
|
959
|
-
};
|
|
960
|
-
}).filter(Boolean);
|
|
1015
|
+
if (mergeValue(translatable.field, translatable, schema, entry.entry))
|
|
1016
|
+
count++;
|
|
961
1017
|
}
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
1018
|
+
if (count > 0) {
|
|
1019
|
+
Logger$1.info("Updated " + count + " entries in dynamic zones/content blocks");
|
|
1020
|
+
return true;
|
|
1021
|
+
}
|
|
1022
|
+
return false;
|
|
1023
|
+
};
|
|
1024
|
+
function prepareImportData(translatables, keepData, existingEntry, targetSchema) {
|
|
1025
|
+
const result = {};
|
|
1026
|
+
const simpleUpdated = mergeSimpleFields(translatables, existingEntry, targetSchema, result);
|
|
1027
|
+
let otherUpdated = false;
|
|
1028
|
+
const vsFields = replaceDynamicZones(existingEntry, keepData);
|
|
1029
|
+
if (vsFields.length > 0) {
|
|
1030
|
+
if (mergeDynamicZones(translatables, targetSchema, existingEntry)) {
|
|
1031
|
+
vsFields.forEach((field) => result[field] = existingEntry[field]);
|
|
1032
|
+
otherUpdated = true;
|
|
1033
|
+
} else
|
|
1034
|
+
Logger$1.warn("Could not merge dynamic fields");
|
|
1035
|
+
}
|
|
1036
|
+
if (simpleUpdated || otherUpdated)
|
|
1037
|
+
return result;
|
|
1038
|
+
else
|
|
1039
|
+
return null;
|
|
981
1040
|
}
|
|
982
|
-
require("jsonwebtoken");
|
|
983
|
-
const crypto = require("crypto");
|
|
984
1041
|
const TRANSLATIONTUDIO_URL = "https://strapi.translationstudio.tech";
|
|
985
1042
|
const APP_NAME = "translationstudio";
|
|
1043
|
+
const Logger = {
|
|
1044
|
+
log: typeof strapi !== "undefined" ? strapi.log : console,
|
|
1045
|
+
info: (val) => Logger.log.info(val),
|
|
1046
|
+
warn: (val) => Logger.log.warn(val),
|
|
1047
|
+
error: (val) => Logger.log.error(val),
|
|
1048
|
+
debug: (val) => Logger.log.debug(val)
|
|
1049
|
+
};
|
|
986
1050
|
const service = ({ strapi: strapi2 }) => {
|
|
987
1051
|
const pluginStore = strapi2.store({
|
|
988
1052
|
type: "plugin",
|
|
@@ -1000,7 +1064,7 @@ const service = ({ strapi: strapi2 }) => {
|
|
|
1000
1064
|
if (typeof result === "string" && result !== "")
|
|
1001
1065
|
return result;
|
|
1002
1066
|
} catch (err) {
|
|
1003
|
-
|
|
1067
|
+
strapi2.log.warn(err);
|
|
1004
1068
|
}
|
|
1005
1069
|
return TRANSLATIONTUDIO_URL;
|
|
1006
1070
|
},
|
|
@@ -1063,9 +1127,15 @@ const service = ({ strapi: strapi2 }) => {
|
|
|
1063
1127
|
},
|
|
1064
1128
|
async exportData(payload) {
|
|
1065
1129
|
const { contentTypeID, entryID, locale } = parsePayload(payload);
|
|
1066
|
-
const contentType =
|
|
1130
|
+
const contentType = getContentType(contentTypeID);
|
|
1131
|
+
if (contentType === null || !IsLocalisableSchema(contentType.entry)) {
|
|
1132
|
+
return {
|
|
1133
|
+
fields: [],
|
|
1134
|
+
keep: {}
|
|
1135
|
+
};
|
|
1136
|
+
}
|
|
1067
1137
|
const entry = await getEntry(contentTypeID, entryID, locale);
|
|
1068
|
-
const contentFields = await processEntryFields(entry, contentType
|
|
1138
|
+
const contentFields = await processEntryFields(entry, contentType);
|
|
1069
1139
|
return transformResponse(contentFields);
|
|
1070
1140
|
},
|
|
1071
1141
|
async importData(payload) {
|
|
@@ -1073,23 +1143,32 @@ const service = ({ strapi: strapi2 }) => {
|
|
|
1073
1143
|
const sourceLocale = payload.source;
|
|
1074
1144
|
const targetLocale = payload.target;
|
|
1075
1145
|
try {
|
|
1076
|
-
const
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1146
|
+
const sourceEntry = await getEntry(contentTypeID, entryID, sourceLocale);
|
|
1147
|
+
if (sourceEntry == null)
|
|
1148
|
+
throw new Error("Cannot find source entry " + contentTypeID + "::" + entryID + " in " + sourceLocale);
|
|
1149
|
+
const targetSchema = getContentType(contentTypeID);
|
|
1150
|
+
if (targetSchema === null || !IsLocalisableSchema(targetSchema.entry))
|
|
1151
|
+
throw new Error("Cannot find schema");
|
|
1152
|
+
const data = prepareImportData(
|
|
1153
|
+
payload.document[0].fields,
|
|
1154
|
+
payload.document[0].keep ?? {},
|
|
1155
|
+
sourceEntry,
|
|
1156
|
+
targetSchema
|
|
1157
|
+
);
|
|
1158
|
+
strapi2.log.info("Loading target language entry");
|
|
1159
|
+
const targetLocaleEntry = await getEntry(contentTypeID, entryID, targetLocale);
|
|
1160
|
+
appendMissingFields(data, sourceEntry, targetSchema, targetLocaleEntry);
|
|
1161
|
+
await updateEntry(
|
|
1162
|
+
contentTypeID,
|
|
1163
|
+
entryID,
|
|
1164
|
+
targetLocale,
|
|
1165
|
+
data
|
|
1166
|
+
);
|
|
1167
|
+
return true;
|
|
1090
1168
|
} catch (error) {
|
|
1091
|
-
|
|
1169
|
+
strapi2.log.error(error);
|
|
1092
1170
|
}
|
|
1171
|
+
return false;
|
|
1093
1172
|
},
|
|
1094
1173
|
async requestTranslation(payload) {
|
|
1095
1174
|
const { license } = await this.getLicense();
|
|
@@ -1125,10 +1204,6 @@ const service = ({ strapi: strapi2 }) => {
|
|
|
1125
1204
|
},
|
|
1126
1205
|
async ping() {
|
|
1127
1206
|
return;
|
|
1128
|
-
},
|
|
1129
|
-
async getEntryData(contentTypeID, entryID, locale) {
|
|
1130
|
-
const entry = await getEntry(contentTypeID, entryID, locale);
|
|
1131
|
-
return entry;
|
|
1132
1207
|
}
|
|
1133
1208
|
};
|
|
1134
1209
|
};
|