gt-sanity 2.0.15 → 2.0.17
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/index.cjs +157 -89
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +45 -29
- package/dist/index.d.ts +45 -29
- package/dist/index.js +157 -89
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/adapter/core.ts +8 -7
- package/src/adapter/types.ts +1 -1
- package/src/components/TranslationsProvider.tsx +42 -18
- package/src/configuration/baseDocumentLevelConfig/documentLevelPatch.test.ts +10 -2
- package/src/configuration/baseDocumentLevelConfig/documentLevelPatch.ts +17 -6
- package/src/configuration/baseDocumentLevelConfig/helpers/createI18nDocAndPatchMetadata.ts +1 -1
- package/src/configuration/baseDocumentLevelConfig/helpers/patchI18nDoc.test.ts +2 -1
- package/src/configuration/baseDocumentLevelConfig/helpers/patchI18nDoc.ts +3 -3
- package/src/hooks/useSecrets.ts +1 -1
- package/src/index.ts +3 -2
- package/src/sanity-api/resolveRefs.ts +21 -10
- package/src/serialization/BaseDocumentMerger.ts +56 -32
- package/src/serialization/BaseSerializationConfig.ts +30 -11
- package/src/serialization/__tests__/BaseDocumentDeserializer/baseDeserialization.test.ts +75 -69
- package/src/serialization/__tests__/BaseDocumentDeserializer/documentLevelDeserialization.test.ts +10 -14
- package/src/serialization/__tests__/BaseDocumentDeserializer/fieldLevelDeserialization.test.ts +10 -14
- package/src/serialization/__tests__/BaseDocumentMerger/baseMerge.test.ts +5 -9
- package/src/serialization/__tests__/BaseDocumentMerger/documentLevelMerge.test.ts +17 -19
- package/src/serialization/__tests__/BaseDocumentMerger/fieldLevelMerge.test.ts +33 -26
- package/src/serialization/__tests__/BaseDocumentMerger/utils.ts +20 -23
- package/src/serialization/__tests__/BaseDocumentSerializer/baseSerialization.test.ts +23 -23
- package/src/serialization/__tests__/BaseDocumentSerializer/documentLevelSerialization.test.ts +6 -6
- package/src/serialization/__tests__/BaseDocumentSerializer/fieldLevelSerialization.test.ts +8 -8
- package/src/serialization/__tests__/BaseDocumentSerializer/utils.ts +12 -10
- package/src/serialization/__tests__/__fixtures__/inlineSchema.ts +4 -1
- package/src/serialization/__tests__/__fixtures__/schema.ts +15 -6
- package/src/serialization/__tests__/global.setup.ts +7 -3
- package/src/serialization/__tests__/helpers.ts +11 -11
- package/src/serialization/data.ts +3 -3
- package/src/serialization/deserialize/BaseDocumentDeserializer.ts +41 -29
- package/src/serialization/index.ts +6 -1
- package/src/serialization/serialize/fieldFilters.ts +52 -30
- package/src/serialization/serialize/index.ts +48 -21
- package/src/serialization/types.ts +32 -17
- package/src/types.ts +1 -1
- package/src/utils/__tests__/documentIds.test.ts +2 -1
- package/src/utils/__tests__/forEachMatchingField.test.ts +1 -1
- package/src/utils/applyDocuments.ts +16 -14
- package/src/utils/batchProcessor.ts +21 -18
- package/src/utils/importUtils.ts +16 -10
- package/src/utils/serialize.ts +2 -1
package/dist/index.cjs
CHANGED
|
@@ -43,7 +43,7 @@ class GTConfig {
|
|
|
43
43
|
additionalDeserializers;
|
|
44
44
|
additionalBlockDeserializers;
|
|
45
45
|
static instance;
|
|
46
|
-
constructor(secretsNamespace, languageField, sourceLocale, locales, singletons, singletonMapping, ignoreFields, dedupeFields, skipFields, translateDocuments, additionalStopTypes = [], additionalSerializers = {}, additionalDeserializers = {}, additionalBlockDeserializers = []) {
|
|
46
|
+
constructor(secretsNamespace, languageField, sourceLocale, locales, singletons, singletonMapping, ignoreFields, dedupeFields, skipFields, translateDocuments, additionalStopTypes = [], additionalSerializers = {}, additionalDeserializers = { types: {} }, additionalBlockDeserializers = []) {
|
|
47
47
|
this.secretsNamespace = secretsNamespace, this.languageField = languageField, this.sourceLocale = sourceLocale, this.locales = locales, this.singletons = singletons, this.singletonMapping = singletonMapping, this.ignoreFields = ignoreFields, this.dedupeFields = dedupeFields, this.skipFields = skipFields, this.translateDocuments = translateDocuments, this.additionalStopTypes = additionalStopTypes, this.additionalSerializers = additionalSerializers, this.additionalDeserializers = additionalDeserializers, this.additionalBlockDeserializers = additionalBlockDeserializers;
|
|
48
48
|
}
|
|
49
49
|
static getInstance() {
|
|
@@ -59,12 +59,12 @@ class GTConfig {
|
|
|
59
59
|
[],
|
|
60
60
|
[],
|
|
61
61
|
[],
|
|
62
|
-
{},
|
|
62
|
+
{ types: {} },
|
|
63
63
|
{},
|
|
64
64
|
[]
|
|
65
65
|
)), this.instance;
|
|
66
66
|
}
|
|
67
|
-
init(secretsNamespace, languageField, sourceLocale, locales, singletons, singletonMapping, ignoreFields, dedupeFields, skipFields, translateDocuments, additionalStopTypes = [], additionalSerializers = {}, additionalDeserializers = {}, additionalBlockDeserializers = []) {
|
|
67
|
+
init(secretsNamespace, languageField, sourceLocale, locales, singletons, singletonMapping, ignoreFields, dedupeFields, skipFields, translateDocuments, additionalStopTypes = [], additionalSerializers = {}, additionalDeserializers = { types: {} }, additionalBlockDeserializers = []) {
|
|
68
68
|
this.secretsNamespace = secretsNamespace, this.languageField = languageField, this.sourceLocale = sourceLocale, this.locales = locales, this.singletons = singletons, this.singletonMapping = singletonMapping, this.ignoreFields = ignoreFields, this.dedupeFields = dedupeFields, this.skipFields = skipFields, this.translateDocuments = translateDocuments, this.additionalStopTypes = additionalStopTypes, this.additionalSerializers = additionalSerializers, this.additionalDeserializers = additionalDeserializers, this.additionalBlockDeserializers = additionalBlockDeserializers;
|
|
69
69
|
}
|
|
70
70
|
getSecretsNamespace() {
|
|
@@ -122,31 +122,37 @@ const pluginConfig = GTConfig.getInstance(), theme = theme$1.buildTheme(), BaseT
|
|
|
122
122
|
!loadingSecrets && secrets && children
|
|
123
123
|
] });
|
|
124
124
|
return /* @__PURE__ */ jsxRuntime.jsx(ui.ThemeProvider, { theme, children: /* @__PURE__ */ jsxRuntime.jsx(ui.ToastProvider, { paddingY: 7, children: showContainer ? /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { padding, children: content }) : content }) });
|
|
125
|
-
}, reconcileArray = (origArray, translatedArray) => {
|
|
125
|
+
}, isRecord$4 = (value) => typeof value == "object" && value !== null && !Array.isArray(value), reconcileArray = (origArray, translatedArray) => {
|
|
126
126
|
if (translatedArray && translatedArray.some((el) => typeof el == "string"))
|
|
127
127
|
return translatedArray;
|
|
128
128
|
const combined = JSON.parse(JSON.stringify(origArray));
|
|
129
|
-
return translatedArray.forEach((
|
|
130
|
-
if (!
|
|
129
|
+
return translatedArray.forEach((translatedItem) => {
|
|
130
|
+
if (!isRecord$4(translatedItem) || !translatedItem._key)
|
|
131
131
|
return;
|
|
132
132
|
const foundBlockIdx = origArray.findIndex(
|
|
133
|
-
(origBlock) => origBlock._key ===
|
|
133
|
+
(origBlock) => isRecord$4(origBlock) && origBlock._key === translatedItem._key
|
|
134
134
|
);
|
|
135
135
|
foundBlockIdx < 0 ? console.warn(
|
|
136
136
|
`This block no longer exists on the original document. Was it removed? ${JSON.stringify(
|
|
137
|
-
|
|
137
|
+
translatedItem
|
|
138
138
|
)}`
|
|
139
|
-
) : origArray[foundBlockIdx]._type === "block" || origArray[foundBlockIdx]._type === "span" ? combined[foundBlockIdx] =
|
|
139
|
+
) : isRecord$4(origArray[foundBlockIdx]) && (origArray[foundBlockIdx]._type === "block" || origArray[foundBlockIdx]._type === "span") ? combined[foundBlockIdx] = translatedItem : isRecord$4(origArray[foundBlockIdx]) && (combined[foundBlockIdx] = reconcileObject(
|
|
140
140
|
origArray[foundBlockIdx],
|
|
141
|
-
|
|
142
|
-
);
|
|
141
|
+
translatedItem
|
|
142
|
+
));
|
|
143
143
|
}), combined;
|
|
144
144
|
}, reconcileObject = (origObject, translatedObject) => {
|
|
145
145
|
if (typeof translatedObject != "object" || !Object.keys(translatedObject).length)
|
|
146
146
|
return origObject;
|
|
147
147
|
const updatedObj = JSON.parse(JSON.stringify(origObject));
|
|
148
148
|
return Object.entries(translatedObject).forEach(([key, value]) => {
|
|
149
|
-
!value || key[0] === "_" || (typeof value == "string" ? updatedObj[key] = value : Array.isArray(value) ? updatedObj[key] = reconcileArray(
|
|
149
|
+
!value || key[0] === "_" || (typeof value == "string" ? updatedObj[key] = value : Array.isArray(value) ? updatedObj[key] = reconcileArray(
|
|
150
|
+
Array.isArray(origObject[key]) ? origObject[key] : [],
|
|
151
|
+
value
|
|
152
|
+
) : isRecord$4(value) && (updatedObj[key] = reconcileObject(
|
|
153
|
+
isRecord$4(origObject[key]) ? origObject[key] : {},
|
|
154
|
+
value
|
|
155
|
+
)));
|
|
150
156
|
}), updatedObj;
|
|
151
157
|
}, fieldLevelMerge = (translatedFields, baseDoc, localeId, baseLang = "en") => {
|
|
152
158
|
const merged = {};
|
|
@@ -161,8 +167,11 @@ const pluginConfig = GTConfig.getInstance(), theme = theme$1.buildTheme(), BaseT
|
|
|
161
167
|
translatedFields
|
|
162
168
|
)[0].value;
|
|
163
169
|
let valToPatch;
|
|
164
|
-
typeof translatedVal == "string" ? valToPatch = translatedVal : Array.isArray(translatedVal) && translatedVal.length ? valToPatch = reconcileArray(
|
|
165
|
-
origVal ??
|
|
170
|
+
typeof translatedVal == "string" ? valToPatch = translatedVal : Array.isArray(translatedVal) && translatedVal.length ? valToPatch = reconcileArray(
|
|
171
|
+
origVal ?? [],
|
|
172
|
+
translatedVal
|
|
173
|
+
) : typeof translatedVal == "object" && Object.keys(translatedVal).length && (valToPatch = reconcileObject(
|
|
174
|
+
isRecord$4(origVal) ? origVal : {},
|
|
166
175
|
translatedVal
|
|
167
176
|
));
|
|
168
177
|
const destinationPath = [
|
|
@@ -173,7 +182,10 @@ const pluginConfig = GTConfig.getInstance(), theme = theme$1.buildTheme(), BaseT
|
|
|
173
182
|
];
|
|
174
183
|
merged[mutator.arrayToJSONMatchPath(destinationPath)] = valToPatch;
|
|
175
184
|
}), merged;
|
|
176
|
-
}, documentLevelMerge = (translatedFields, baseDoc) => reconcileObject(
|
|
185
|
+
}, documentLevelMerge = (translatedFields, baseDoc) => reconcileObject(
|
|
186
|
+
baseDoc,
|
|
187
|
+
translatedFields
|
|
188
|
+
), BaseDocumentMerger = {
|
|
177
189
|
fieldLevelMerge,
|
|
178
190
|
documentLevelMerge,
|
|
179
191
|
reconcileArray,
|
|
@@ -240,7 +252,7 @@ function decode(base64) {
|
|
|
240
252
|
bytes[i] = binary.charCodeAt(i);
|
|
241
253
|
return new TextDecoder().decode(bytes);
|
|
242
254
|
}
|
|
243
|
-
const defaultStopTypes = [
|
|
255
|
+
const isRecord$3 = (value) => typeof value == "object" && value !== null && !Array.isArray(value), defaultStopTypes = [
|
|
244
256
|
"reference",
|
|
245
257
|
"date",
|
|
246
258
|
"datetime",
|
|
@@ -283,13 +295,19 @@ const defaultStopTypes = [
|
|
|
283
295
|
}, customDeserializers = { types: {} }, customBlockDeserializers = [
|
|
284
296
|
// handle marks with data-gt-internal
|
|
285
297
|
{
|
|
286
|
-
deserialize(
|
|
298
|
+
deserialize(node2, next2) {
|
|
299
|
+
if (node2.nodeType !== 1)
|
|
300
|
+
return;
|
|
301
|
+
const el = node2;
|
|
287
302
|
if (!el.hasChildNodes() || !el.getAttribute("data-gt-internal"))
|
|
288
303
|
return;
|
|
289
304
|
const { html, data } = detachGTData(el.outerHTML), block = blockTools.htmlToBlocks(html, blockContentType)[0], children = next2(el.childNodes);
|
|
290
305
|
let markDefs = [];
|
|
291
|
-
return "markDefs" in block && (markDefs = block.markDefs ?? []), data?.markDef && markDefs.push(data.markDef), children && children.forEach((child) => {
|
|
292
|
-
|
|
306
|
+
return "markDefs" in block && (markDefs = block.markDefs ?? []), data?.markDef && markDefs.push(data.markDef), Array.isArray(children) && children.forEach((child) => {
|
|
307
|
+
if (!isRecord$3(child))
|
|
308
|
+
return;
|
|
309
|
+
const marks = Array.isArray(child.marks) ? child.marks : [];
|
|
310
|
+
child.marks = data?.markDef?._key ? [...marks, data.markDef._key] : marks;
|
|
293
311
|
}), {
|
|
294
312
|
...block,
|
|
295
313
|
markDefs,
|
|
@@ -299,7 +317,10 @@ const defaultStopTypes = [
|
|
|
299
317
|
},
|
|
300
318
|
//handle undeclared styles
|
|
301
319
|
{
|
|
302
|
-
deserialize(
|
|
320
|
+
deserialize(node2, next2) {
|
|
321
|
+
if (node2.nodeType !== 1)
|
|
322
|
+
return;
|
|
323
|
+
const el = node2;
|
|
303
324
|
if (!el.hasChildNodes() || el.getAttribute("data-type") !== "unknown-block-style")
|
|
304
325
|
return;
|
|
305
326
|
const style = el.getAttribute("data-style") ?? "";
|
|
@@ -312,7 +333,10 @@ const defaultStopTypes = [
|
|
|
312
333
|
},
|
|
313
334
|
//handle list items
|
|
314
335
|
{
|
|
315
|
-
deserialize(
|
|
336
|
+
deserialize(node2, next2) {
|
|
337
|
+
if (node2.nodeType !== 1)
|
|
338
|
+
return;
|
|
339
|
+
const el = node2;
|
|
316
340
|
if (!el.hasChildNodes() || el.tagName.toLowerCase() !== "li")
|
|
317
341
|
return;
|
|
318
342
|
const tagsToStyle = {
|
|
@@ -346,7 +370,7 @@ const defaultStopTypes = [
|
|
|
346
370
|
};
|
|
347
371
|
}
|
|
348
372
|
}
|
|
349
|
-
], META_FIELDS$1 = ["_key", "_type", "_id"], languageObjectFieldFilter = (obj, baseLang) => {
|
|
373
|
+
], META_FIELDS$1 = ["_key", "_type", "_id"], isRecord$2 = (value) => typeof value == "object" && value !== null && !Array.isArray(value), languageObjectFieldFilter = (obj, baseLang) => {
|
|
350
374
|
const filterToLangField = (childObj) => {
|
|
351
375
|
const filteredObj = {};
|
|
352
376
|
return filteredObj[baseLang] = childObj[baseLang], META_FIELDS$1.forEach((field) => {
|
|
@@ -360,24 +384,29 @@ const defaultStopTypes = [
|
|
|
360
384
|
for (const key in childObj)
|
|
361
385
|
if (childObj.hasOwnProperty(key)) {
|
|
362
386
|
const value = childObj[key];
|
|
363
|
-
if (value.
|
|
387
|
+
if (isRecord$2(value) && Object.hasOwn(value, baseLang))
|
|
364
388
|
filteredObj[key] = filterToLangField(value);
|
|
365
389
|
else if (Array.isArray(value) && value.length && typeof value[0] == "object") {
|
|
366
|
-
const validLangObjects = value.reduce(
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
390
|
+
const validLangObjects = value.reduce(
|
|
391
|
+
(validArr, objInArray) => {
|
|
392
|
+
if (!isRecord$2(objInArray))
|
|
393
|
+
return validArr;
|
|
394
|
+
if (objInArray._type === "block")
|
|
395
|
+
validArr.push(objInArray);
|
|
396
|
+
else if (Object.hasOwn(objInArray, baseLang))
|
|
397
|
+
validArr.push(filterToLangField(objInArray));
|
|
398
|
+
else {
|
|
399
|
+
const filtered = findBaseLang(objInArray);
|
|
400
|
+
Object.keys(filtered).filter(
|
|
401
|
+
(objInArrayKey) => META_FIELDS$1.indexOf(objInArrayKey) === -1
|
|
402
|
+
).length && validArr.push(filtered);
|
|
403
|
+
}
|
|
404
|
+
return validArr;
|
|
405
|
+
},
|
|
406
|
+
[]
|
|
407
|
+
);
|
|
379
408
|
validLangObjects.length && (filteredObj[key] = validLangObjects);
|
|
380
|
-
} else if (
|
|
409
|
+
} else if (isRecord$2(value)) {
|
|
381
410
|
const nestedLangObj = findBaseLang(value);
|
|
382
411
|
Object.keys(nestedLangObj).filter(
|
|
383
412
|
(nestedObjKey) => META_FIELDS$1.indexOf(nestedObjKey) === -1
|
|
@@ -388,18 +417,24 @@ const defaultStopTypes = [
|
|
|
388
417
|
};
|
|
389
418
|
return findBaseLang(obj);
|
|
390
419
|
}, fieldFilter = (obj, objFields, stopTypes) => {
|
|
391
|
-
const filteredObj = {
|
|
420
|
+
const filteredObj = {
|
|
421
|
+
_type: typeof obj._type == "string" ? obj._type : ""
|
|
422
|
+
}, fieldFilterFunc = (field) => {
|
|
423
|
+
const fieldMetadata = field, fieldType = typeof fieldMetadata.type == "string" ? fieldMetadata.type : fieldMetadata.type?.name;
|
|
424
|
+
return fieldMetadata.localize === !1 ? !1 : fieldType === "string" || fieldType === "text" || Array.isArray(obj[field.name]) ? !0 : !!(fieldType && !stopTypes.includes(fieldType));
|
|
425
|
+
};
|
|
392
426
|
return [
|
|
393
427
|
...META_FIELDS$1,
|
|
394
428
|
...objFields.filter(fieldFilterFunc).map((field) => field.name)
|
|
395
429
|
].forEach((field) => {
|
|
396
430
|
obj[field] && (filteredObj[field] = obj[field]);
|
|
397
431
|
}), filteredObj;
|
|
398
|
-
}, META_FIELDS = ["_key", "_type", "_id", "_weak"], BaseDocumentSerializer = (schemas) => {
|
|
432
|
+
}, META_FIELDS = ["_key", "_type", "_id", "_weak"], isRecord$1 = (value) => typeof value == "object" && value !== null && !Array.isArray(value), BaseDocumentSerializer = (schemas) => {
|
|
399
433
|
const getSchema = (name) => schemas?._original?.types.find((s) => s.name === name), serializeObject = (obj, stopTypes, serializers) => {
|
|
400
434
|
if (stopTypes.includes(obj._type))
|
|
401
435
|
return "";
|
|
402
|
-
|
|
436
|
+
const typeSerializers = isRecord$1(serializers.types) ? serializers.types : {};
|
|
437
|
+
if (Object.keys(typeSerializers).includes(obj._type))
|
|
403
438
|
return toHtml.toHTML([obj], { components: serializers });
|
|
404
439
|
if (obj._type === "span" || obj._type === "block")
|
|
405
440
|
return toHtml.toHTML(obj, { components: serializers });
|
|
@@ -420,9 +455,9 @@ const defaultStopTypes = [
|
|
|
420
455
|
else if (Array.isArray(value))
|
|
421
456
|
htmlField = serializeArray(value, fieldName, stopTypes, {
|
|
422
457
|
...serializers,
|
|
423
|
-
types: { ...
|
|
458
|
+
types: { ...typeSerializers }
|
|
424
459
|
});
|
|
425
|
-
else {
|
|
460
|
+
else if (isRecord$1(value)) {
|
|
426
461
|
const embeddedObject = value, embeddedObjectSchema = getSchema(embeddedObject._type);
|
|
427
462
|
let toTranslate = embeddedObject;
|
|
428
463
|
embeddedObjectSchema && embeddedObjectSchema.fields && (toTranslate = fieldFilter(
|
|
@@ -432,7 +467,7 @@ const defaultStopTypes = [
|
|
|
432
467
|
));
|
|
433
468
|
const objHTML = serializeObject(toTranslate, stopTypes, {
|
|
434
469
|
...serializers,
|
|
435
|
-
types: { ...
|
|
470
|
+
types: { ...typeSerializers }
|
|
436
471
|
});
|
|
437
472
|
htmlField = `<div class="${fieldName}" data-level="field">${objHTML}</div>`;
|
|
438
473
|
}
|
|
@@ -450,7 +485,7 @@ const defaultStopTypes = [
|
|
|
450
485
|
components: {
|
|
451
486
|
...serializers,
|
|
452
487
|
types: {
|
|
453
|
-
...
|
|
488
|
+
...typeSerializers,
|
|
454
489
|
...newSerializationMethods
|
|
455
490
|
}
|
|
456
491
|
}
|
|
@@ -463,9 +498,13 @@ const defaultStopTypes = [
|
|
|
463
498
|
return serializedBlock;
|
|
464
499
|
}, serializeArray = (fieldContent, fieldName, stopTypes, serializers) => {
|
|
465
500
|
const output = fieldContent.filter(
|
|
466
|
-
(block) => !stopTypes.includes(block._type)
|
|
501
|
+
(block) => typeof block == "string" || typeof block._type != "string" || !stopTypes.includes(block._type)
|
|
467
502
|
).map((block) => {
|
|
468
|
-
|
|
503
|
+
if (typeof block == "string")
|
|
504
|
+
return block;
|
|
505
|
+
const schema2 = getSchema(
|
|
506
|
+
typeof block._type == "string" ? block._type : ""
|
|
507
|
+
);
|
|
469
508
|
return schema2 && schema2.fields ? fieldFilter(block, schema2.fields, stopTypes) : block;
|
|
470
509
|
}).map((obj) => typeof obj == "string" ? `<span>${obj}</span>` : serializeObject(obj, stopTypes, serializers));
|
|
471
510
|
return `<div class="${fieldName}" data-type="array">${output.join("")}</div>`;
|
|
@@ -483,12 +522,14 @@ const defaultStopTypes = [
|
|
|
483
522
|
serializedFields[key] = value;
|
|
484
523
|
else if (Array.isArray(value))
|
|
485
524
|
serializedFields[key] = serializeArray(
|
|
486
|
-
value
|
|
525
|
+
value.filter(
|
|
526
|
+
(item) => typeof item == "string" || isRecord$1(item)
|
|
527
|
+
),
|
|
487
528
|
key,
|
|
488
529
|
stopTypes,
|
|
489
530
|
serializers
|
|
490
531
|
);
|
|
491
|
-
else if (value && !stopTypes.find((stopType) => stopType == value?._type)) {
|
|
532
|
+
else if (value && isRecord$1(value) && !stopTypes.find((stopType) => stopType == value?._type)) {
|
|
492
533
|
const serialized = serializeObject(
|
|
493
534
|
value,
|
|
494
535
|
stopTypes,
|
|
@@ -534,13 +575,22 @@ const deserializeArray = (arrayHTML, deserializers = customDeserializers, blockD
|
|
|
534
575
|
return Array.from(arrayHTML.children).forEach((child) => {
|
|
535
576
|
let deserializedObject;
|
|
536
577
|
try {
|
|
537
|
-
child.tagName?.toLowerCase() === "span"
|
|
538
|
-
child
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
578
|
+
if (child.tagName?.toLowerCase() === "span")
|
|
579
|
+
deserializedObject = preprocess(child.innerHTML);
|
|
580
|
+
else if (child.className || child.getAttribute("data-type") === "object")
|
|
581
|
+
deserializedObject = deserializeObject(
|
|
582
|
+
child,
|
|
583
|
+
deserializers,
|
|
584
|
+
blockDeserializers
|
|
585
|
+
), deserializedObject && typeof deserializedObject == "object" && !Array.isArray(deserializedObject) && (deserializedObject._key = child.id);
|
|
586
|
+
else {
|
|
587
|
+
const blocks = blockTools.htmlToBlocks(child.outerHTML, blockContentType, {
|
|
588
|
+
rules: blockDeserializers
|
|
589
|
+
});
|
|
590
|
+
deserializedObject = mergeBlocks(
|
|
591
|
+
blocks
|
|
592
|
+
), deserializedObject._key = child.id;
|
|
593
|
+
}
|
|
544
594
|
} catch (e) {
|
|
545
595
|
console.debug(
|
|
546
596
|
`Tried to deserialize block: ${child.outerHTML} in an array but failed to identify it! Error: ${e}`
|
|
@@ -549,7 +599,7 @@ const deserializeArray = (arrayHTML, deserializers = customDeserializers, blockD
|
|
|
549
599
|
output.push(deserializedObject);
|
|
550
600
|
}), output;
|
|
551
601
|
}, deserializeObject = (objectHTML, deserializers = customDeserializers, blockDeserializers = customBlockDeserializers) => {
|
|
552
|
-
const deserialize = deserializers.types[objectHTML.className];
|
|
602
|
+
const deserialize = deserializers.types?.[objectHTML.className];
|
|
553
603
|
if (deserialize)
|
|
554
604
|
return deserialize(objectHTML);
|
|
555
605
|
const output = {};
|
|
@@ -576,7 +626,7 @@ const deserializeArray = (arrayHTML, deserializers = customDeserializers, blockD
|
|
|
576
626
|
if (HTMLnode?.getAttribute("data-level") === "field" && (HTMLnode = HTMLnode.children[0]), !HTMLnode)
|
|
577
627
|
return {};
|
|
578
628
|
let output;
|
|
579
|
-
const deserialize = deserializers.types[HTMLnode.className];
|
|
629
|
+
const deserialize = deserializers.types?.[HTMLnode.className];
|
|
580
630
|
return deserialize ? output = deserialize(HTMLnode) : HTMLnode.getAttribute("data-type") === "object" ? output = deserializeObject(HTMLnode, deserializers, blockDeserializers) : HTMLnode.getAttribute("data-type") === "array" ? output = deserializeArray(HTMLnode, deserializers, blockDeserializers) : (output = {}, console.debug(
|
|
581
631
|
`Tried to deserialize block ${HTMLnode.outerHTML} but failed to identify it!`
|
|
582
632
|
)), output;
|
|
@@ -615,7 +665,7 @@ function forEachMatchingField(documentId, document2, fields, callback) {
|
|
|
615
665
|
});
|
|
616
666
|
results && results.length > 0 && results.forEach(
|
|
617
667
|
(result) => {
|
|
618
|
-
type !== void 0 ? typeof result.value == "object" && result.value !== null && result.value._type === type && callback(result) : callback(result);
|
|
668
|
+
type !== void 0 ? typeof result.value == "object" && result.value !== null && !Array.isArray(result.value) && result.value._type === type && callback(result) : callback(result);
|
|
619
669
|
}
|
|
620
670
|
);
|
|
621
671
|
} catch (error) {
|
|
@@ -649,10 +699,17 @@ function applyDocuments(documentId, sourceDocument, targetDocument, ignore, skip
|
|
|
649
699
|
}), deleteMatchingFields(documentId, mergedDocument, skip), mergedDocument;
|
|
650
700
|
}
|
|
651
701
|
function dedupeFieldValue(value, localeId) {
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
702
|
+
if (!localeId) return value;
|
|
703
|
+
if (typeof value == "string")
|
|
704
|
+
return appendLocaleSuffix(value, localeId);
|
|
705
|
+
if (value && typeof value == "object" && !Array.isArray(value) && typeof value.current == "string") {
|
|
706
|
+
const slug = value;
|
|
707
|
+
return {
|
|
708
|
+
...slug,
|
|
709
|
+
current: appendLocaleSuffix(slug.current, localeId)
|
|
710
|
+
};
|
|
711
|
+
}
|
|
712
|
+
return value;
|
|
656
713
|
}
|
|
657
714
|
function appendLocaleSuffix(value, localeId) {
|
|
658
715
|
if (!value) return value;
|
|
@@ -976,7 +1033,9 @@ const documentLevelPatch = async (docInfo, translatedFields, localeId, client, l
|
|
|
976
1033
|
baseDoc,
|
|
977
1034
|
client,
|
|
978
1035
|
baseLanguage
|
|
979
|
-
)).translations.find(
|
|
1036
|
+
)).translations.find(
|
|
1037
|
+
(translation) => translation.language === localeId
|
|
1038
|
+
)?.value?._ref;
|
|
980
1039
|
i18nDocId && (i18nDoc = await findLatestDraft(i18nDocId, client)), mergeWithTargetLocale && i18nDoc ? baseDoc = i18nDoc : docInfo.documentId && docInfo.versionId && (baseDoc = await findDocumentAtRevision(
|
|
981
1040
|
docInfo.documentId,
|
|
982
1041
|
docInfo.versionId,
|
|
@@ -1002,7 +1061,9 @@ const documentLevelPatch = async (docInfo, translatedFields, localeId, client, l
|
|
|
1002
1061
|
baseDoc,
|
|
1003
1062
|
client,
|
|
1004
1063
|
baseLanguage
|
|
1005
|
-
), freshI18nDocId = freshTranslationMetadata.translations.find(
|
|
1064
|
+
), freshI18nDocId = freshTranslationMetadata.translations.find(
|
|
1065
|
+
(translation) => translation.language === localeId
|
|
1066
|
+
)?.value?._ref;
|
|
1006
1067
|
if (freshI18nDocId) {
|
|
1007
1068
|
const freshI18nDoc = await findLatestDraft(freshI18nDocId, client);
|
|
1008
1069
|
await patchI18nDoc(
|
|
@@ -1039,6 +1100,7 @@ async function importDocument(docInfo, localeId, document2, context, mergeWithTa
|
|
|
1039
1100
|
mergeWithTargetLocale
|
|
1040
1101
|
);
|
|
1041
1102
|
}
|
|
1103
|
+
const isRecord = (value) => typeof value == "object" && value !== null && !Array.isArray(value), isReference = (value) => isRecord(value) && value._type === "reference" && typeof value._ref == "string";
|
|
1042
1104
|
async function resolveRefs(doc, locale, client) {
|
|
1043
1105
|
const references = findReferences(doc);
|
|
1044
1106
|
if (references.length === 0)
|
|
@@ -1054,9 +1116,9 @@ function findReferences(obj, path = []) {
|
|
|
1054
1116
|
if (!obj || typeof obj != "object")
|
|
1055
1117
|
return [];
|
|
1056
1118
|
const references = [];
|
|
1057
|
-
return obj
|
|
1119
|
+
return isReference(obj) && references.push({ ref: obj, path }), Array.isArray(obj) ? obj.forEach((item, index) => {
|
|
1058
1120
|
references.push(...findReferences(item, [...path, index.toString()]));
|
|
1059
|
-
}) : Object.keys(obj).forEach((key) => {
|
|
1121
|
+
}) : isRecord(obj) && Object.keys(obj).forEach((key) => {
|
|
1060
1122
|
references.push(...findReferences(obj[key], [...path, key]));
|
|
1061
1123
|
}), references;
|
|
1062
1124
|
}
|
|
@@ -1080,7 +1142,7 @@ function updateDocumentReferences(doc, translatedRefs) {
|
|
|
1080
1142
|
function updateReferencesRecursive(obj, translatedRefs) {
|
|
1081
1143
|
if (!obj || typeof obj != "object")
|
|
1082
1144
|
return obj;
|
|
1083
|
-
if (obj
|
|
1145
|
+
if (isReference(obj) && translatedRefs.has(obj._ref))
|
|
1084
1146
|
return {
|
|
1085
1147
|
...obj,
|
|
1086
1148
|
_ref: translatedRefs.get(obj._ref)
|
|
@@ -1089,7 +1151,10 @@ function updateReferencesRecursive(obj, translatedRefs) {
|
|
|
1089
1151
|
return obj.map((item) => updateReferencesRecursive(item, translatedRefs));
|
|
1090
1152
|
const updated = {};
|
|
1091
1153
|
return Object.keys(obj).forEach((key) => {
|
|
1092
|
-
updated[key] = updateReferencesRecursive(
|
|
1154
|
+
updated[key] = updateReferencesRecursive(
|
|
1155
|
+
obj[key],
|
|
1156
|
+
translatedRefs
|
|
1157
|
+
);
|
|
1093
1158
|
}), updated;
|
|
1094
1159
|
}
|
|
1095
1160
|
async function findTranslatedDocumentForLocale(sourceDocumentId, localeId, client) {
|
|
@@ -1202,16 +1267,19 @@ async function getReadyFilesForImport(translationStatuses, options = {}) {
|
|
|
1202
1267
|
async function importTranslations(readyFiles, secrets, translationContext, options = {}) {
|
|
1203
1268
|
if (readyFiles.length === 0)
|
|
1204
1269
|
return { successCount: 0, failureCount: 0, successfulImports: [] };
|
|
1205
|
-
const importItems = (await downloadTranslations(readyFiles, secrets)).map((file) =>
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1270
|
+
const importItems = (await downloadTranslations(readyFiles, secrets)).map((file) => {
|
|
1271
|
+
const data = typeof file.data == "string" ? file.data : JSON.stringify(file.data ?? "");
|
|
1272
|
+
return {
|
|
1273
|
+
docInfo: {
|
|
1274
|
+
documentId: file.fileId,
|
|
1275
|
+
versionId: file.versionId
|
|
1276
|
+
},
|
|
1277
|
+
locale: file.locale,
|
|
1278
|
+
data,
|
|
1279
|
+
translationContext,
|
|
1280
|
+
key: `${file.branchId}:${file.fileId}:${file.versionId}:${file.locale}`
|
|
1281
|
+
};
|
|
1282
|
+
}), result = await processImportBatch(importItems, {
|
|
1215
1283
|
onProgress: options.onProgress,
|
|
1216
1284
|
onItemSuccess: (item, key) => {
|
|
1217
1285
|
options.onImportSuccess?.(key);
|
|
@@ -1297,7 +1365,7 @@ const getLocales = async (_secrets) => pluginConfig.getLocales().map((locale) =>
|
|
|
1297
1365
|
setDocuments(dedupeDocumentsPreferDraft(docs));
|
|
1298
1366
|
} catch {
|
|
1299
1367
|
toast.push({
|
|
1300
|
-
title: "
|
|
1368
|
+
title: "Documents could not be loaded. Check your Sanity connection and try refreshing.",
|
|
1301
1369
|
status: "error",
|
|
1302
1370
|
closable: !0
|
|
1303
1371
|
});
|
|
@@ -1311,7 +1379,7 @@ const getLocales = async (_secrets) => pluginConfig.getLocales().map((locale) =>
|
|
|
1311
1379
|
setLocales(availableLocales);
|
|
1312
1380
|
} catch {
|
|
1313
1381
|
toast.push({
|
|
1314
|
-
title: "
|
|
1382
|
+
title: "Locales could not be loaded. Check your General Translation credentials and try again.",
|
|
1315
1383
|
status: "error",
|
|
1316
1384
|
closable: !0
|
|
1317
1385
|
});
|
|
@@ -1343,7 +1411,7 @@ const getLocales = async (_secrets) => pluginConfig.getLocales().map((locale) =>
|
|
|
1343
1411
|
}), setExistingTranslations(existing);
|
|
1344
1412
|
} catch (error) {
|
|
1345
1413
|
console.error("Error fetching existing translations:", error), toast.push({
|
|
1346
|
-
title: "
|
|
1414
|
+
title: "Existing translations could not be loaded. Try refreshing before importing.",
|
|
1347
1415
|
status: "error",
|
|
1348
1416
|
closable: !0
|
|
1349
1417
|
});
|
|
@@ -1379,7 +1447,7 @@ const getLocales = async (_secrets) => pluginConfig.getLocales().map((locale) =>
|
|
|
1379
1447
|
});
|
|
1380
1448
|
} catch {
|
|
1381
1449
|
toast.push({
|
|
1382
|
-
title: "
|
|
1450
|
+
title: "Translation tasks could not be created. No documents were changed. Try again or check the console for details.",
|
|
1383
1451
|
status: "error",
|
|
1384
1452
|
closable: !0
|
|
1385
1453
|
});
|
|
@@ -1435,7 +1503,7 @@ const getLocales = async (_secrets) => pluginConfig.getLocales().map((locale) =>
|
|
|
1435
1503
|
});
|
|
1436
1504
|
} catch (error) {
|
|
1437
1505
|
console.error("Error importing translations:", error), toast.push({
|
|
1438
|
-
title: "
|
|
1506
|
+
title: "Translations could not be imported. No documents were changed. Try again or check the console for details.",
|
|
1439
1507
|
status: "error",
|
|
1440
1508
|
closable: !0
|
|
1441
1509
|
});
|
|
@@ -1537,7 +1605,7 @@ const getLocales = async (_secrets) => pluginConfig.getLocales().map((locale) =>
|
|
|
1537
1605
|
});
|
|
1538
1606
|
} catch (error) {
|
|
1539
1607
|
console.error("Error importing missing translations:", error), toast.push({
|
|
1540
|
-
title: "
|
|
1608
|
+
title: "Missing translations could not be imported. No documents were changed. Try again or check the console for details.",
|
|
1541
1609
|
status: "error",
|
|
1542
1610
|
closable: !0
|
|
1543
1611
|
});
|
|
@@ -1623,7 +1691,7 @@ const getLocales = async (_secrets) => pluginConfig.getLocales().map((locale) =>
|
|
|
1623
1691
|
});
|
|
1624
1692
|
} catch (error) {
|
|
1625
1693
|
console.error("Error refreshing translation status:", error), toast.push({
|
|
1626
|
-
title: "
|
|
1694
|
+
title: "Translation status could not be refreshed. Try again before importing.",
|
|
1627
1695
|
status: "error",
|
|
1628
1696
|
closable: !0
|
|
1629
1697
|
});
|
|
@@ -1698,7 +1766,7 @@ const getLocales = async (_secrets) => pluginConfig.getLocales().map((locale) =>
|
|
|
1698
1766
|
});
|
|
1699
1767
|
} catch (importError) {
|
|
1700
1768
|
console.error("Failed to import translation:", importError), toast.push({
|
|
1701
|
-
title: `
|
|
1769
|
+
title: `Translation for ${documentId} (${localeId}) could not be imported. This document was not changed.`,
|
|
1702
1770
|
status: "error",
|
|
1703
1771
|
closable: !0
|
|
1704
1772
|
});
|
|
@@ -1711,7 +1779,7 @@ const getLocales = async (_secrets) => pluginConfig.getLocales().map((locale) =>
|
|
|
1711
1779
|
});
|
|
1712
1780
|
} catch (error) {
|
|
1713
1781
|
console.error("Error importing translation:", error), toast.push({
|
|
1714
|
-
title: `
|
|
1782
|
+
title: `Translation for ${documentId} could not be imported. This document was not changed.`,
|
|
1715
1783
|
status: "error",
|
|
1716
1784
|
closable: !0
|
|
1717
1785
|
});
|
|
@@ -1785,7 +1853,7 @@ const getLocales = async (_secrets) => pluginConfig.getLocales().map((locale) =>
|
|
|
1785
1853
|
}), patchedCount;
|
|
1786
1854
|
} catch (error) {
|
|
1787
1855
|
return console.error("Error patching document references:", error), toast.push({
|
|
1788
|
-
title: "
|
|
1856
|
+
title: "Document references could not be updated. Imported translations may need to be linked manually.",
|
|
1789
1857
|
status: "error",
|
|
1790
1858
|
closable: !0
|
|
1791
1859
|
}), 0;
|
|
@@ -1840,7 +1908,7 @@ const getLocales = async (_secrets) => pluginConfig.getLocales().map((locale) =>
|
|
|
1840
1908
|
}), translatedDocumentIds.length;
|
|
1841
1909
|
} catch (error) {
|
|
1842
1910
|
return console.error("Error publishing translations:", error), toast.push({
|
|
1843
|
-
title: "
|
|
1911
|
+
title: "Translations could not be published. No unpublished source documents were changed.",
|
|
1844
1912
|
status: "error",
|
|
1845
1913
|
closable: !0
|
|
1846
1914
|
}), 0;
|