@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.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,40 +131,40 @@ 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);
|
|
130
167
|
ctx.body = result;
|
|
131
|
-
},
|
|
132
|
-
async getEntryData(ctx) {
|
|
133
|
-
const { uid, locale } = ctx.request.body;
|
|
134
|
-
if (!uid) {
|
|
135
|
-
return ctx.badRequest("Missing uid parameter");
|
|
136
|
-
}
|
|
137
|
-
try {
|
|
138
|
-
const [contentTypeID, entryID] = uid.split("#");
|
|
139
|
-
const entry = await strapi2.plugin(APP_NAME$1).service("service").getEntryData(contentTypeID, entryID, locale);
|
|
140
|
-
return entry;
|
|
141
|
-
} catch (error) {
|
|
142
|
-
return ctx.badRequest("Failed to get entry data", { error: error.message });
|
|
143
|
-
}
|
|
144
168
|
}
|
|
145
169
|
});
|
|
146
170
|
const controllers = {
|
|
@@ -256,23 +280,35 @@ const routes = [
|
|
|
256
280
|
config: {
|
|
257
281
|
policies: []
|
|
258
282
|
}
|
|
259
|
-
},
|
|
260
|
-
{
|
|
261
|
-
method: "POST",
|
|
262
|
-
path: "/entrydata",
|
|
263
|
-
handler: "controller.getEntryData",
|
|
264
|
-
config: {
|
|
265
|
-
policies: []
|
|
266
|
-
}
|
|
267
283
|
}
|
|
268
284
|
];
|
|
269
|
-
|
|
270
|
-
const
|
|
285
|
+
function getComponentSchemata(schema) {
|
|
286
|
+
const res = {};
|
|
287
|
+
for (let fieldName in schema.attributes) {
|
|
288
|
+
const field = schema.attributes[fieldName];
|
|
289
|
+
if (!field.components || !Array.isArray(field.components) || field.components.length === 0)
|
|
290
|
+
continue;
|
|
291
|
+
for (let type of field.components) {
|
|
292
|
+
const schema2 = strapi.components[type];
|
|
293
|
+
if (schema2 && schema2.attributes)
|
|
294
|
+
res[type] = schema2;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
return res;
|
|
298
|
+
}
|
|
299
|
+
function getContentType(contentTypeID) {
|
|
300
|
+
const contentType = strapi.contentType(contentTypeID);
|
|
271
301
|
if (!contentType?.attributes) {
|
|
272
|
-
|
|
302
|
+
strapi.log.error(`Content type or schema not found: ${contentTypeID}`);
|
|
303
|
+
return null;
|
|
273
304
|
}
|
|
274
|
-
|
|
275
|
-
|
|
305
|
+
const res = {
|
|
306
|
+
entry: contentType,
|
|
307
|
+
components: getComponentSchemata(contentType)
|
|
308
|
+
};
|
|
309
|
+
strapi.log.info("SChema loaded for " + contentTypeID + ". Component schemata loaded: " + Object.keys(res.components).length);
|
|
310
|
+
return res;
|
|
311
|
+
}
|
|
276
312
|
const parsePayload = (payload) => {
|
|
277
313
|
const [contentTypeID, entryID] = payload.element.includes("#") ? payload.element.split("#") : [payload.element, void 0];
|
|
278
314
|
const locale = payload.source.includes("-") ? payload.source.split("-")[0] : payload.source;
|
|
@@ -282,7 +318,7 @@ const getComponentSchema = async (componentName) => {
|
|
|
282
318
|
try {
|
|
283
319
|
return await strapi.components[componentName];
|
|
284
320
|
} catch (error) {
|
|
285
|
-
|
|
321
|
+
strapi.log.error(`Failed to get component schema for ${componentName}:`, error);
|
|
286
322
|
return null;
|
|
287
323
|
}
|
|
288
324
|
};
|
|
@@ -305,27 +341,32 @@ const buildPopulateConfig = async (schema) => {
|
|
|
305
341
|
}
|
|
306
342
|
return populate;
|
|
307
343
|
};
|
|
308
|
-
const getEntry = async (contentTypeID, entryID, locale) => {
|
|
344
|
+
const getEntry = async (contentTypeID, entryID, locale, logError = true) => {
|
|
309
345
|
try {
|
|
310
346
|
const contentType = await strapi.contentTypes[contentTypeID];
|
|
311
347
|
const populateConfig = await buildPopulateConfig(contentType);
|
|
312
348
|
const query = {
|
|
313
349
|
locale,
|
|
350
|
+
documentId: entryID,
|
|
314
351
|
populate: populateConfig
|
|
315
352
|
};
|
|
316
|
-
if (entryID) {
|
|
317
|
-
Object.assign(query, { documentId: entryID });
|
|
318
|
-
}
|
|
319
353
|
const entry = await strapi.documents(contentTypeID).findFirst(query);
|
|
320
|
-
|
|
354
|
+
if (entry) {
|
|
355
|
+
strapi.log.info("Obtained " + contentTypeID + "::" + entryID + " in " + locale);
|
|
356
|
+
return entry;
|
|
357
|
+
}
|
|
321
358
|
} catch (error) {
|
|
322
|
-
|
|
323
|
-
return null;
|
|
359
|
+
strapi.log.error(error.message ?? error);
|
|
324
360
|
}
|
|
361
|
+
strapi.log.warn("Could not find entry " + entryID + " in locale " + locale);
|
|
362
|
+
return null;
|
|
363
|
+
};
|
|
364
|
+
const transformResponse = function(data) {
|
|
365
|
+
data.fields = data.fields.map(
|
|
366
|
+
(item) => item.realType === "blocks" && Array.isArray(item.translatableValue[0]) ? { ...item, translatableValue: item.translatableValue[0] } : item
|
|
367
|
+
);
|
|
368
|
+
return data;
|
|
325
369
|
};
|
|
326
|
-
const transformResponse = (data) => data.map(
|
|
327
|
-
(item) => item.realType === "blocks" && Array.isArray(item.translatableValue[0]) ? { ...item, translatableValue: item.translatableValue[0] } : item
|
|
328
|
-
);
|
|
329
370
|
function jsonToHtml(json) {
|
|
330
371
|
if (!json || !Array.isArray(json)) {
|
|
331
372
|
return "";
|
|
@@ -374,43 +415,37 @@ function formatText(child) {
|
|
|
374
415
|
}
|
|
375
416
|
return text;
|
|
376
417
|
}
|
|
377
|
-
const
|
|
418
|
+
const Logger$4 = {
|
|
419
|
+
log: typeof strapi !== "undefined" ? strapi.log : console,
|
|
420
|
+
info: (val) => Logger$4.log.info(val),
|
|
421
|
+
warn: (val) => Logger$4.log.warn(val),
|
|
422
|
+
error: (val) => Logger$4.log.error(val),
|
|
423
|
+
debug: (val) => Logger$4.log.debug(val)
|
|
424
|
+
};
|
|
425
|
+
async function processComponent(fieldName, value, componentSchema, schemata) {
|
|
378
426
|
const contentFields = [];
|
|
379
|
-
|
|
380
|
-
if (!componentSchema)
|
|
381
|
-
|
|
382
|
-
}
|
|
427
|
+
Logger$4.info("Processing dynamic field " + fieldName);
|
|
428
|
+
if (!componentSchema || !componentSchema.attributes)
|
|
429
|
+
return [];
|
|
383
430
|
const schemaAttributes = componentSchema.attributes || {};
|
|
384
431
|
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,
|
|
432
|
+
const candidates = Array.isArray(dataToProcess) ? dataToProcess : [dataToProcess];
|
|
433
|
+
for (const item of candidates) {
|
|
434
|
+
const processedFields = await processComponentFields(
|
|
435
|
+
item,
|
|
400
436
|
schemaAttributes,
|
|
401
437
|
fieldName,
|
|
402
|
-
|
|
403
|
-
schemaName,
|
|
404
|
-
componentId
|
|
438
|
+
schemata
|
|
405
439
|
);
|
|
406
|
-
|
|
440
|
+
if (processedFields.length > 0)
|
|
441
|
+
contentFields.push(...processedFields);
|
|
407
442
|
}
|
|
408
443
|
return contentFields;
|
|
409
|
-
}
|
|
444
|
+
}
|
|
410
445
|
const shouldSkipField$1 = (key, fieldSchema) => {
|
|
411
446
|
return key === "id" || fieldSchema.private;
|
|
412
447
|
};
|
|
413
|
-
const isTranslatableField
|
|
448
|
+
const isTranslatableField = (type) => {
|
|
414
449
|
return ["string", "text", "blocks", "richtext"].includes(type);
|
|
415
450
|
};
|
|
416
451
|
const getTranslatedValue = (type, value) => {
|
|
@@ -419,64 +454,61 @@ const getTranslatedValue = (type, value) => {
|
|
|
419
454
|
}
|
|
420
455
|
return value.toString();
|
|
421
456
|
};
|
|
422
|
-
const buildTranslatable = (key, fieldSchema, value,
|
|
457
|
+
const buildTranslatable = (key, fieldSchema, value, uuid = "") => {
|
|
423
458
|
return {
|
|
424
459
|
field: key,
|
|
425
460
|
type: ["richtext", "blocks"].includes(fieldSchema.type) ? "html" : "text",
|
|
426
461
|
translatableValue: [value],
|
|
427
462
|
realType: fieldSchema.type,
|
|
428
|
-
|
|
429
|
-
namePath: parentPath,
|
|
430
|
-
id: componentId,
|
|
431
|
-
schemaName
|
|
432
|
-
}
|
|
463
|
+
uuid
|
|
433
464
|
};
|
|
434
465
|
};
|
|
435
|
-
const processComponentFields
|
|
466
|
+
const processComponentFields = async (componentData, schema, parentField, schemata) => {
|
|
436
467
|
const contentFields = [];
|
|
437
|
-
const
|
|
468
|
+
const uuid = crypto__namespace.randomUUID();
|
|
438
469
|
for (const [key, fieldSchema] of Object.entries(schema)) {
|
|
439
470
|
if (shouldSkipField$1(key, fieldSchema)) continue;
|
|
440
471
|
const value = componentData?.[key];
|
|
441
|
-
|
|
472
|
+
if (!value)
|
|
473
|
+
continue;
|
|
442
474
|
if (fieldSchema.type === "component") {
|
|
443
|
-
if (!
|
|
475
|
+
if (!value.__component)
|
|
476
|
+
continue;
|
|
477
|
+
const targetSchema = schemata[value.__component];
|
|
478
|
+
if (!targetSchema)
|
|
479
|
+
continue;
|
|
444
480
|
const nestedFields = await processComponent(
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
value?.id
|
|
481
|
+
`${parentField}.${key}`,
|
|
482
|
+
value,
|
|
483
|
+
targetSchema,
|
|
484
|
+
schemata
|
|
450
485
|
);
|
|
451
|
-
|
|
486
|
+
if (nestedFields.length > 0)
|
|
487
|
+
contentFields.push(...nestedFields);
|
|
452
488
|
continue;
|
|
453
489
|
}
|
|
454
|
-
if (!isTranslatableField
|
|
490
|
+
if (!isTranslatableField(fieldSchema.type)) continue;
|
|
455
491
|
if (value === null || value === void 0 || value === "") continue;
|
|
456
492
|
const translatedValue = getTranslatedValue(fieldSchema.type, value);
|
|
457
493
|
const translatable = buildTranslatable(
|
|
458
494
|
key,
|
|
459
495
|
fieldSchema,
|
|
460
496
|
translatedValue,
|
|
461
|
-
|
|
462
|
-
componentId,
|
|
463
|
-
schemaName
|
|
497
|
+
uuid
|
|
464
498
|
);
|
|
499
|
+
componentData.__tsuid = uuid;
|
|
465
500
|
contentFields.push(translatable);
|
|
466
501
|
}
|
|
467
502
|
return contentFields;
|
|
468
503
|
};
|
|
469
|
-
const
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
return localizableTypes.includes(fieldSchema.type);
|
|
476
|
-
}
|
|
477
|
-
return false;
|
|
504
|
+
const Logger$3 = {
|
|
505
|
+
log: typeof strapi !== "undefined" ? strapi.log : console,
|
|
506
|
+
info: (val) => Logger$3.log.info(val),
|
|
507
|
+
warn: (val) => Logger$3.log.warn(val),
|
|
508
|
+
error: (val) => Logger$3.log.error(val),
|
|
509
|
+
debug: (val) => Logger$3.log.debug(val)
|
|
478
510
|
};
|
|
479
|
-
const DEFAULT_FIELDS = /* @__PURE__ */ new Set([
|
|
511
|
+
const DEFAULT_FIELDS$1 = /* @__PURE__ */ new Set([
|
|
480
512
|
"id",
|
|
481
513
|
"documentId",
|
|
482
514
|
"createdAt",
|
|
@@ -488,45 +520,41 @@ const DEFAULT_FIELDS = /* @__PURE__ */ new Set([
|
|
|
488
520
|
"createdBy"
|
|
489
521
|
]);
|
|
490
522
|
const isEmpty = (value) => value === null || value === void 0 || value === "";
|
|
491
|
-
const
|
|
492
|
-
const processDynamicZone = async (key, value,
|
|
523
|
+
const isSimpleTranslatableField = (fieldSchema) => ["string", "text", "blocks", "richtext"].includes(fieldSchema.type) && fieldSchema.pluginOptions?.i18n?.localized === true;
|
|
524
|
+
const processDynamicZone = async (key, value, schemata) => {
|
|
493
525
|
const results = [];
|
|
494
526
|
for (const component of value) {
|
|
495
527
|
const componentName = component?.__component;
|
|
496
528
|
if (!componentName) continue;
|
|
529
|
+
const schema = schemata[componentName];
|
|
530
|
+
if (!schema) continue;
|
|
497
531
|
const fields = await processComponent(
|
|
498
532
|
key,
|
|
499
|
-
componentName,
|
|
500
533
|
component,
|
|
501
|
-
|
|
502
|
-
|
|
534
|
+
schema,
|
|
535
|
+
schemata
|
|
503
536
|
);
|
|
504
|
-
|
|
537
|
+
if (fields.length > 0)
|
|
538
|
+
results.push(...fields);
|
|
505
539
|
}
|
|
506
540
|
return results;
|
|
507
541
|
};
|
|
508
|
-
const processComponentField = async (key, value, fieldSchema) => {
|
|
542
|
+
const processComponentField = async (key, value, fieldSchema, schemata) => {
|
|
509
543
|
const results = [];
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
fieldSchema.component,
|
|
517
|
-
component.id
|
|
518
|
-
);
|
|
519
|
-
results.push(...fields);
|
|
520
|
-
}
|
|
521
|
-
} else {
|
|
544
|
+
const candidates = Array.isArray(value) ? value : [value];
|
|
545
|
+
for (const component of candidates) {
|
|
546
|
+
const componentName = component?.__component;
|
|
547
|
+
if (!componentName) continue;
|
|
548
|
+
const schema = schemata[componentName];
|
|
549
|
+
if (!schema) continue;
|
|
522
550
|
const fields = await processComponent(
|
|
523
551
|
key,
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
value.id
|
|
552
|
+
component,
|
|
553
|
+
schema,
|
|
554
|
+
schemata
|
|
528
555
|
);
|
|
529
|
-
|
|
556
|
+
if (fields.length > 0)
|
|
557
|
+
results.push(...fields);
|
|
530
558
|
}
|
|
531
559
|
return results;
|
|
532
560
|
};
|
|
@@ -539,38 +567,148 @@ const processRegularField = (key, value, fieldSchema) => {
|
|
|
539
567
|
realType: fieldSchema.type
|
|
540
568
|
};
|
|
541
569
|
};
|
|
542
|
-
|
|
570
|
+
function IsLocalisableSchema(schema) {
|
|
571
|
+
return schema.pluginOptions?.i18n?.localized === true;
|
|
572
|
+
}
|
|
573
|
+
function IsLocalisedField(field) {
|
|
574
|
+
return field.pluginOptions?.i18n?.localized === true;
|
|
575
|
+
}
|
|
576
|
+
const processEntryFields = async (entry, schemaData, _locale) => {
|
|
543
577
|
const contentFields = [];
|
|
578
|
+
const staticContent = {};
|
|
579
|
+
const schema = schemaData.entry.attributes;
|
|
544
580
|
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);
|
|
581
|
+
if (shouldSkipField(key, value))
|
|
551
582
|
continue;
|
|
552
|
-
|
|
553
|
-
if (
|
|
554
|
-
|
|
555
|
-
contentFields.push(...componentFields);
|
|
583
|
+
const fieldSchema = schema[key];
|
|
584
|
+
if (!fieldSchema || !IsLocalisedField(fieldSchema)) {
|
|
585
|
+
Logger$3.debug("SKipping non-local field " + key);
|
|
556
586
|
continue;
|
|
557
587
|
}
|
|
558
|
-
if (
|
|
588
|
+
if (isSimpleTranslatableField(fieldSchema)) {
|
|
589
|
+
Logger$3.debug("Processing simple field " + key);
|
|
559
590
|
const translatedField = processRegularField(key, value, fieldSchema);
|
|
560
591
|
contentFields.push(translatedField);
|
|
592
|
+
continue;
|
|
593
|
+
}
|
|
594
|
+
const zoneInfo = isDynamicZone(fieldSchema, value);
|
|
595
|
+
if (zoneInfo.isZone) {
|
|
596
|
+
if (zoneInfo.hasContent) {
|
|
597
|
+
Logger$3.debug("Processing dynamic zone field " + key);
|
|
598
|
+
const zoneFields = await processDynamicZone(key, value, schemaData.components);
|
|
599
|
+
contentFields.push(...zoneFields);
|
|
600
|
+
staticContent[key] = value;
|
|
601
|
+
}
|
|
602
|
+
continue;
|
|
603
|
+
}
|
|
604
|
+
const componentInfo = isComponent(fieldSchema);
|
|
605
|
+
if (componentInfo.isZone) {
|
|
606
|
+
const componentFields = await processComponentField(key, value, fieldSchema, schemaData.components);
|
|
607
|
+
contentFields.push(...componentFields);
|
|
608
|
+
staticContent[key] = value;
|
|
561
609
|
}
|
|
562
610
|
}
|
|
563
|
-
|
|
611
|
+
Logger$3.info("Process completed");
|
|
612
|
+
return {
|
|
613
|
+
fields: contentFields,
|
|
614
|
+
keep: staticContent
|
|
615
|
+
};
|
|
564
616
|
};
|
|
565
617
|
const shouldSkipField = (key, value) => {
|
|
566
|
-
return DEFAULT_FIELDS.has(key) || isEmpty(value);
|
|
618
|
+
return DEFAULT_FIELDS$1.has(key) || isEmpty(value);
|
|
619
|
+
};
|
|
620
|
+
const isDynamicZone = (fieldSchema, value) => {
|
|
621
|
+
return {
|
|
622
|
+
isZone: fieldSchema.type === "dynamiczone",
|
|
623
|
+
hasContent: Array.isArray(value) && value.length > 0
|
|
624
|
+
};
|
|
567
625
|
};
|
|
568
|
-
const
|
|
569
|
-
return
|
|
626
|
+
const isComponent = (fieldSchema) => {
|
|
627
|
+
return {
|
|
628
|
+
isZone: fieldSchema.type === "dynamiczone",
|
|
629
|
+
hasContent: true
|
|
630
|
+
};
|
|
570
631
|
};
|
|
571
|
-
const
|
|
572
|
-
|
|
632
|
+
const Logger$2 = {
|
|
633
|
+
log: typeof strapi !== "undefined" ? strapi.log : console,
|
|
634
|
+
info: (val) => Logger$2.log.info(val),
|
|
635
|
+
warn: (val) => Logger$2.log.warn(val),
|
|
636
|
+
error: (val) => Logger$2.log.error(val),
|
|
637
|
+
debug: (val) => Logger$2.log.debug(val)
|
|
573
638
|
};
|
|
639
|
+
const DEFAULT_FIELDS = [
|
|
640
|
+
"id",
|
|
641
|
+
"documentId",
|
|
642
|
+
"createdAt",
|
|
643
|
+
"updatedAt",
|
|
644
|
+
,
|
|
645
|
+
"createdBy",
|
|
646
|
+
"updatedBy",
|
|
647
|
+
"publishedAt",
|
|
648
|
+
"locale",
|
|
649
|
+
"localizations"
|
|
650
|
+
];
|
|
651
|
+
const getContentFields = function(schema) {
|
|
652
|
+
const nullFields = [];
|
|
653
|
+
for (let field in schema) {
|
|
654
|
+
if (!DEFAULT_FIELDS.includes(field))
|
|
655
|
+
nullFields.push(field);
|
|
656
|
+
}
|
|
657
|
+
return nullFields;
|
|
658
|
+
};
|
|
659
|
+
const getInvalidOrNullFields = function(document, schema) {
|
|
660
|
+
if (!document)
|
|
661
|
+
return getContentFields(schema);
|
|
662
|
+
const nullFields = [];
|
|
663
|
+
let fieldsValid = 0;
|
|
664
|
+
for (let field in document) {
|
|
665
|
+
if (DEFAULT_FIELDS.includes(field))
|
|
666
|
+
continue;
|
|
667
|
+
if (document[field] === null)
|
|
668
|
+
nullFields.push(field);
|
|
669
|
+
else
|
|
670
|
+
fieldsValid++;
|
|
671
|
+
}
|
|
672
|
+
if (nullFields.length > 0 || fieldsValid > 0)
|
|
673
|
+
return nullFields;
|
|
674
|
+
return getContentFields(schema);
|
|
675
|
+
};
|
|
676
|
+
function appendMissingFields(data, sourceEntry, targetSchema, targetEntry) {
|
|
677
|
+
const nullFields = getInvalidOrNullFields(targetEntry, targetSchema.entry.attributes);
|
|
678
|
+
if (nullFields.length === 0)
|
|
679
|
+
return;
|
|
680
|
+
let count = 0;
|
|
681
|
+
Logger$2.info("Adding missing fields to new locale: " + nullFields.join(", "));
|
|
682
|
+
for (let field of nullFields) {
|
|
683
|
+
if (data[field]) {
|
|
684
|
+
Logger$2.info("Field already present: " + field);
|
|
685
|
+
continue;
|
|
686
|
+
}
|
|
687
|
+
if (!sourceEntry[field]) {
|
|
688
|
+
Logger$2.info("No valid source langauge field value for " + field + " - skipping it.");
|
|
689
|
+
continue;
|
|
690
|
+
}
|
|
691
|
+
if (!targetSchema.entry.attributes[field]) {
|
|
692
|
+
Logger$2.warn("Schema does not contain field " + field);
|
|
693
|
+
continue;
|
|
694
|
+
}
|
|
695
|
+
Logger$2.info("Adding missing field and value for " + field);
|
|
696
|
+
data[field] = sourceEntry[field];
|
|
697
|
+
count++;
|
|
698
|
+
}
|
|
699
|
+
if (count > 0)
|
|
700
|
+
Logger$2.info(count + " missing fields added.");
|
|
701
|
+
}
|
|
702
|
+
async function updateEntry(contentTypeID, entryID, targetLocale, data) {
|
|
703
|
+
strapi.log.info("Updating target entry " + contentTypeID + "::" + entryID + " in locale " + targetLocale);
|
|
704
|
+
const newEntry = await strapi.documents(contentTypeID).update({
|
|
705
|
+
documentId: entryID,
|
|
706
|
+
locale: targetLocale,
|
|
707
|
+
data
|
|
708
|
+
});
|
|
709
|
+
if (!newEntry)
|
|
710
|
+
throw new Error("Cannot update target entry " + contentTypeID + "::" + entryID + " in locale " + targetLocale);
|
|
711
|
+
}
|
|
574
712
|
function htmlToJson(html) {
|
|
575
713
|
function parseHTML(html2) {
|
|
576
714
|
const elements2 = [];
|
|
@@ -763,227 +901,171 @@ function htmlToJson(html) {
|
|
|
763
901
|
}
|
|
764
902
|
return blocks;
|
|
765
903
|
}
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
)
|
|
781
|
-
|
|
904
|
+
const Logger$1 = {
|
|
905
|
+
log: typeof strapi !== "undefined" ? strapi.log : console,
|
|
906
|
+
info: (val) => Logger$1.log.info(val),
|
|
907
|
+
warn: (val) => Logger$1.log.warn(val),
|
|
908
|
+
error: (val) => Logger$1.log.error(val),
|
|
909
|
+
debug: (val) => Logger$1.log.debug(val)
|
|
910
|
+
};
|
|
911
|
+
const removeComponentIds = function(elem) {
|
|
912
|
+
const list = Array.isArray(elem) ? elem : [elem];
|
|
913
|
+
for (let obj of list) {
|
|
914
|
+
if (obj.__component && obj.id)
|
|
915
|
+
delete obj.id;
|
|
916
|
+
for (let key in obj) {
|
|
917
|
+
const child = obj[key];
|
|
918
|
+
if (Array.isArray(child) && Array.length > 0)
|
|
919
|
+
removeComponentIds(child);
|
|
920
|
+
else if (typeof child === "object")
|
|
921
|
+
removeComponentIds(child);
|
|
782
922
|
}
|
|
783
923
|
}
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
924
|
+
};
|
|
925
|
+
function replaceDynamicZones(strapiEntry, replacableFields) {
|
|
926
|
+
const fields = [];
|
|
927
|
+
for (let key in strapiEntry) {
|
|
928
|
+
if (replacableFields[key]) {
|
|
929
|
+
removeComponentIds(replacableFields[key]);
|
|
930
|
+
strapiEntry[key] = replacableFields[key];
|
|
931
|
+
fields.push(key);
|
|
788
932
|
}
|
|
789
933
|
}
|
|
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
|
-
}
|
|
934
|
+
if (fields.length > 0)
|
|
935
|
+
Logger$1.info(fields.length + " dynamic fields/components replaced for later merge: " + fields.join(", "));
|
|
936
|
+
return fields;
|
|
801
937
|
}
|
|
802
|
-
function
|
|
803
|
-
if (
|
|
804
|
-
return
|
|
938
|
+
const mergeValue = function(field, translatable, targetSchema, map) {
|
|
939
|
+
if (translatable.translatableValue.length === 0)
|
|
940
|
+
return false;
|
|
941
|
+
if (targetSchema.attributes[field] === void 0) {
|
|
942
|
+
Logger$1.info("Field " + field + " does not exist in schema. Skipping it");
|
|
943
|
+
Logger$1.info(targetSchema);
|
|
944
|
+
return false;
|
|
805
945
|
}
|
|
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));
|
|
946
|
+
if (translatable.translatableValue[0] === "") {
|
|
947
|
+
Logger$1.info("Skipping empty translated content for field " + field);
|
|
948
|
+
return false;
|
|
821
949
|
}
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
950
|
+
if (translatable.realType === "blocks") {
|
|
951
|
+
Logger$1.info("Merge block field " + field);
|
|
952
|
+
map[field] = htmlToJson(translatable.translatableValue[0] || "");
|
|
953
|
+
return true;
|
|
825
954
|
}
|
|
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);
|
|
955
|
+
if (translatable.type === "text") {
|
|
956
|
+
Logger$1.info("Merge text field " + field);
|
|
957
|
+
map[field] = translatable.translatableValue[0];
|
|
958
|
+
return true;
|
|
959
|
+
}
|
|
960
|
+
Logger$1.warn("Did not process " + field);
|
|
961
|
+
return false;
|
|
962
|
+
};
|
|
963
|
+
const mergeSimpleFields = function(translatables, existingEntry, targetSchema, map) {
|
|
964
|
+
let count = 0;
|
|
965
|
+
for (const candidate of translatables) {
|
|
966
|
+
const field = candidate.field;
|
|
967
|
+
if (!candidate.uuid && mergeValue(field, candidate, targetSchema.entry, map))
|
|
968
|
+
count++;
|
|
969
|
+
}
|
|
970
|
+
if (count > 0) {
|
|
971
|
+
Logger$1.info("Updated " + count + " simple text fields");
|
|
972
|
+
return true;
|
|
973
|
+
}
|
|
974
|
+
return false;
|
|
975
|
+
};
|
|
976
|
+
const buildMapOfUuids = function(existingEntry, schemaMap, map) {
|
|
977
|
+
if (typeof existingEntry !== "object")
|
|
978
|
+
return map;
|
|
979
|
+
const componentName = existingEntry["__component"] ?? "";
|
|
980
|
+
const schema = componentName && schemaMap.components[componentName] ? schemaMap.components[componentName] : null;
|
|
981
|
+
if (componentName && !schema)
|
|
982
|
+
Logger$1.warn("Cannot find component schema " + componentName);
|
|
983
|
+
for (const key of Object.keys(existingEntry)) {
|
|
984
|
+
if (key === "__component")
|
|
985
|
+
continue;
|
|
986
|
+
if (schema !== null && key === "__tsuid") {
|
|
987
|
+
map[existingEntry[key]] = {
|
|
988
|
+
entry: existingEntry,
|
|
989
|
+
schema
|
|
990
|
+
};
|
|
991
|
+
continue;
|
|
921
992
|
}
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
return acc;
|
|
993
|
+
const child = existingEntry[key];
|
|
994
|
+
if (child) {
|
|
995
|
+
if (Array.isArray(child)) {
|
|
996
|
+
for (let e of child)
|
|
997
|
+
buildMapOfUuids(e, schemaMap, map);
|
|
998
|
+
} else
|
|
999
|
+
buildMapOfUuids(child, schemaMap, map);
|
|
930
1000
|
}
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
1001
|
+
}
|
|
1002
|
+
if (existingEntry["__tsuid"]) {
|
|
1003
|
+
delete existingEntry["__tsuid"];
|
|
1004
|
+
Logger$1.info("Removed cusom property __tsuid");
|
|
1005
|
+
}
|
|
1006
|
+
return map;
|
|
1007
|
+
};
|
|
1008
|
+
const mergeDynamicZones = function(translatables, schemaMap, existingEntry) {
|
|
1009
|
+
if (translatables.length === 0) {
|
|
1010
|
+
Logger$1.info("Skipping merging of dynamic zones, because none are present.");
|
|
1011
|
+
return;
|
|
1012
|
+
}
|
|
1013
|
+
const map = {};
|
|
1014
|
+
buildMapOfUuids(existingEntry, schemaMap, map);
|
|
1015
|
+
const mapSize = Object.keys(map).length;
|
|
1016
|
+
if (mapSize === 0) {
|
|
1017
|
+
Logger$1.warn("Could not create a uuid map");
|
|
1018
|
+
return false;
|
|
1019
|
+
}
|
|
1020
|
+
Logger$1.info("Built uuid map with " + mapSize + " entry(s)");
|
|
1021
|
+
let count = 0;
|
|
1022
|
+
for (const translatable of translatables) {
|
|
1023
|
+
if (!translatable.uuid)
|
|
1024
|
+
continue;
|
|
1025
|
+
const uuid = translatable.uuid;
|
|
1026
|
+
if (!map[uuid])
|
|
1027
|
+
continue;
|
|
1028
|
+
const entry = map[uuid];
|
|
1029
|
+
const schema = entry.schema;
|
|
1030
|
+
if (!schema) {
|
|
1031
|
+
Logger$1.warn("Cannot find schema by uuid #" + uuid);
|
|
1032
|
+
continue;
|
|
937
1033
|
}
|
|
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);
|
|
1034
|
+
if (mergeValue(translatable.field, translatable, schema, entry.entry))
|
|
1035
|
+
count++;
|
|
962
1036
|
}
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
1037
|
+
if (count > 0) {
|
|
1038
|
+
Logger$1.info("Updated " + count + " entries in dynamic zones/content blocks");
|
|
1039
|
+
return true;
|
|
1040
|
+
}
|
|
1041
|
+
return false;
|
|
1042
|
+
};
|
|
1043
|
+
function prepareImportData(translatables, keepData, existingEntry, targetSchema) {
|
|
1044
|
+
const result = {};
|
|
1045
|
+
const simpleUpdated = mergeSimpleFields(translatables, existingEntry, targetSchema, result);
|
|
1046
|
+
let otherUpdated = false;
|
|
1047
|
+
const vsFields = replaceDynamicZones(existingEntry, keepData);
|
|
1048
|
+
if (vsFields.length > 0) {
|
|
1049
|
+
if (mergeDynamicZones(translatables, targetSchema, existingEntry)) {
|
|
1050
|
+
vsFields.forEach((field) => result[field] = existingEntry[field]);
|
|
1051
|
+
otherUpdated = true;
|
|
1052
|
+
} else
|
|
1053
|
+
Logger$1.warn("Could not merge dynamic fields");
|
|
1054
|
+
}
|
|
1055
|
+
if (simpleUpdated || otherUpdated)
|
|
1056
|
+
return result;
|
|
1057
|
+
else
|
|
1058
|
+
return null;
|
|
982
1059
|
}
|
|
983
|
-
require("jsonwebtoken");
|
|
984
|
-
const crypto = require("crypto");
|
|
985
1060
|
const TRANSLATIONTUDIO_URL = "https://strapi.translationstudio.tech";
|
|
986
1061
|
const APP_NAME = "translationstudio";
|
|
1062
|
+
const Logger = {
|
|
1063
|
+
log: typeof strapi !== "undefined" ? strapi.log : console,
|
|
1064
|
+
info: (val) => Logger.log.info(val),
|
|
1065
|
+
warn: (val) => Logger.log.warn(val),
|
|
1066
|
+
error: (val) => Logger.log.error(val),
|
|
1067
|
+
debug: (val) => Logger.log.debug(val)
|
|
1068
|
+
};
|
|
987
1069
|
const service = ({ strapi: strapi2 }) => {
|
|
988
1070
|
const pluginStore = strapi2.store({
|
|
989
1071
|
type: "plugin",
|
|
@@ -1001,7 +1083,7 @@ const service = ({ strapi: strapi2 }) => {
|
|
|
1001
1083
|
if (typeof result === "string" && result !== "")
|
|
1002
1084
|
return result;
|
|
1003
1085
|
} catch (err) {
|
|
1004
|
-
|
|
1086
|
+
strapi2.log.warn(err);
|
|
1005
1087
|
}
|
|
1006
1088
|
return TRANSLATIONTUDIO_URL;
|
|
1007
1089
|
},
|
|
@@ -1046,7 +1128,7 @@ const service = ({ strapi: strapi2 }) => {
|
|
|
1046
1128
|
}
|
|
1047
1129
|
},
|
|
1048
1130
|
async generateToken() {
|
|
1049
|
-
const secretKey =
|
|
1131
|
+
const secretKey = crypto__namespace.randomBytes(64).toString("hex");
|
|
1050
1132
|
await pluginStore.set({
|
|
1051
1133
|
key: "token",
|
|
1052
1134
|
value: secretKey
|
|
@@ -1064,9 +1146,15 @@ const service = ({ strapi: strapi2 }) => {
|
|
|
1064
1146
|
},
|
|
1065
1147
|
async exportData(payload) {
|
|
1066
1148
|
const { contentTypeID, entryID, locale } = parsePayload(payload);
|
|
1067
|
-
const contentType =
|
|
1149
|
+
const contentType = getContentType(contentTypeID);
|
|
1150
|
+
if (contentType === null || !IsLocalisableSchema(contentType.entry)) {
|
|
1151
|
+
return {
|
|
1152
|
+
fields: [],
|
|
1153
|
+
keep: {}
|
|
1154
|
+
};
|
|
1155
|
+
}
|
|
1068
1156
|
const entry = await getEntry(contentTypeID, entryID, locale);
|
|
1069
|
-
const contentFields = await processEntryFields(entry, contentType
|
|
1157
|
+
const contentFields = await processEntryFields(entry, contentType);
|
|
1070
1158
|
return transformResponse(contentFields);
|
|
1071
1159
|
},
|
|
1072
1160
|
async importData(payload) {
|
|
@@ -1074,23 +1162,32 @@ const service = ({ strapi: strapi2 }) => {
|
|
|
1074
1162
|
const sourceLocale = payload.source;
|
|
1075
1163
|
const targetLocale = payload.target;
|
|
1076
1164
|
try {
|
|
1077
|
-
const
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1165
|
+
const sourceEntry = await getEntry(contentTypeID, entryID, sourceLocale);
|
|
1166
|
+
if (sourceEntry == null)
|
|
1167
|
+
throw new Error("Cannot find source entry " + contentTypeID + "::" + entryID + " in " + sourceLocale);
|
|
1168
|
+
const targetSchema = getContentType(contentTypeID);
|
|
1169
|
+
if (targetSchema === null || !IsLocalisableSchema(targetSchema.entry))
|
|
1170
|
+
throw new Error("Cannot find schema");
|
|
1171
|
+
const data = prepareImportData(
|
|
1172
|
+
payload.document[0].fields,
|
|
1173
|
+
payload.document[0].keep ?? {},
|
|
1174
|
+
sourceEntry,
|
|
1175
|
+
targetSchema
|
|
1176
|
+
);
|
|
1177
|
+
strapi2.log.info("Loading target language entry");
|
|
1178
|
+
const targetLocaleEntry = await getEntry(contentTypeID, entryID, targetLocale);
|
|
1179
|
+
appendMissingFields(data, sourceEntry, targetSchema, targetLocaleEntry);
|
|
1180
|
+
await updateEntry(
|
|
1181
|
+
contentTypeID,
|
|
1182
|
+
entryID,
|
|
1183
|
+
targetLocale,
|
|
1184
|
+
data
|
|
1185
|
+
);
|
|
1186
|
+
return true;
|
|
1091
1187
|
} catch (error) {
|
|
1092
|
-
|
|
1188
|
+
strapi2.log.error(error);
|
|
1093
1189
|
}
|
|
1190
|
+
return false;
|
|
1094
1191
|
},
|
|
1095
1192
|
async requestTranslation(payload) {
|
|
1096
1193
|
const { license } = await this.getLicense();
|
|
@@ -1126,10 +1223,6 @@ const service = ({ strapi: strapi2 }) => {
|
|
|
1126
1223
|
},
|
|
1127
1224
|
async ping() {
|
|
1128
1225
|
return;
|
|
1129
|
-
},
|
|
1130
|
-
async getEntryData(contentTypeID, entryID, locale) {
|
|
1131
|
-
const entry = await getEntry(contentTypeID, entryID, locale);
|
|
1132
|
-
return entry;
|
|
1133
1226
|
}
|
|
1134
1227
|
};
|
|
1135
1228
|
};
|