gt-sanity 2.0.7 → 2.0.8

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.mjs CHANGED
@@ -46,6 +46,7 @@ class GTConfig {
46
46
  singletons;
47
47
  singletonMapping;
48
48
  ignoreFields;
49
+ dedupeFields;
49
50
  skipFields;
50
51
  translateDocuments;
51
52
  additionalStopTypes;
@@ -53,8 +54,8 @@ class GTConfig {
53
54
  additionalDeserializers;
54
55
  additionalBlockDeserializers;
55
56
  static instance;
56
- constructor(secretsNamespace, languageField, sourceLocale, locales, singletons, singletonMapping, ignoreFields, skipFields, translateDocuments, additionalStopTypes = [], additionalSerializers = {}, additionalDeserializers = {}, additionalBlockDeserializers = []) {
57
- this.secretsNamespace = secretsNamespace, this.languageField = languageField, this.sourceLocale = sourceLocale, this.locales = locales, this.singletons = singletons, this.singletonMapping = singletonMapping, this.ignoreFields = ignoreFields, this.skipFields = skipFields, this.translateDocuments = translateDocuments, this.additionalStopTypes = additionalStopTypes, this.additionalSerializers = additionalSerializers, this.additionalDeserializers = additionalDeserializers, this.additionalBlockDeserializers = additionalBlockDeserializers;
57
+ constructor(secretsNamespace, languageField, sourceLocale, locales, singletons, singletonMapping, ignoreFields, dedupeFields, skipFields, translateDocuments, additionalStopTypes = [], additionalSerializers = {}, additionalDeserializers = {}, additionalBlockDeserializers = []) {
58
+ 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;
58
59
  }
59
60
  static getInstance() {
60
61
  return this.instance || (this.instance = new GTConfig(
@@ -68,13 +69,14 @@ class GTConfig {
68
69
  [],
69
70
  [],
70
71
  [],
72
+ [],
71
73
  {},
72
74
  {},
73
75
  []
74
76
  )), this.instance;
75
77
  }
76
- init(secretsNamespace, languageField, sourceLocale, locales, singletons, singletonMapping, ignoreFields, skipFields, translateDocuments, additionalStopTypes = [], additionalSerializers = {}, additionalDeserializers = {}, additionalBlockDeserializers = []) {
77
- this.secretsNamespace = secretsNamespace, this.languageField = languageField, this.sourceLocale = sourceLocale, this.locales = locales, this.singletons = singletons, this.singletonMapping = singletonMapping, this.ignoreFields = ignoreFields, this.skipFields = skipFields, this.translateDocuments = translateDocuments, this.additionalStopTypes = additionalStopTypes, this.additionalSerializers = additionalSerializers, this.additionalDeserializers = additionalDeserializers, this.additionalBlockDeserializers = additionalBlockDeserializers;
78
+ init(secretsNamespace, languageField, sourceLocale, locales, singletons, singletonMapping, ignoreFields, dedupeFields, skipFields, translateDocuments, additionalStopTypes = [], additionalSerializers = {}, additionalDeserializers = {}, additionalBlockDeserializers = []) {
79
+ 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;
78
80
  }
79
81
  getSecretsNamespace() {
80
82
  return this.secretsNamespace;
@@ -97,6 +99,9 @@ class GTConfig {
97
99
  getIgnoreFields() {
98
100
  return this.ignoreFields;
99
101
  }
102
+ getDedupeFields() {
103
+ return this.dedupeFields;
104
+ }
100
105
  getSkipFields() {
101
106
  return this.skipFields;
102
107
  }
@@ -640,14 +645,35 @@ function deleteMatchingFields(documentId, document2, fields) {
640
645
  for (const { parent, index } of arrayRemovals)
641
646
  parent.splice(index, 1);
642
647
  }
643
- function applyDocuments(documentId, sourceDocument, targetDocument, ignore, skip = []) {
648
+ function applyDocuments(documentId, sourceDocument, targetDocument, ignore, skip = [], dedupe = [], localeId) {
644
649
  const mergedDocument = JSON.parse(JSON.stringify(sourceDocument)), clonedTarget = JSON.parse(JSON.stringify(targetDocument));
645
650
  for (const [key, value] of Object.entries(clonedTarget))
646
651
  mergedDocument[key] = value;
647
652
  return forEachMatchingField(documentId, sourceDocument, ignore, (result) => {
648
653
  JSONPointer.set(mergedDocument, result.pointer, result.value);
654
+ }), forEachMatchingField(documentId, sourceDocument, dedupe, (result) => {
655
+ JSONPointer.set(
656
+ mergedDocument,
657
+ result.pointer,
658
+ dedupeFieldValue(result.value, localeId)
659
+ );
649
660
  }), deleteMatchingFields(documentId, mergedDocument, skip), mergedDocument;
650
661
  }
662
+ function dedupeFieldValue(value, localeId) {
663
+ return localeId ? typeof value == "string" ? appendLocaleSuffix(value, localeId) : value && typeof value == "object" && !Array.isArray(value) && typeof value.current == "string" ? {
664
+ ...value,
665
+ current: appendLocaleSuffix(value.current, localeId)
666
+ } : value : value;
667
+ }
668
+ function appendLocaleSuffix(value, localeId) {
669
+ if (!value) return value;
670
+ const suffix = createLocaleSuffix(localeId);
671
+ return !suffix || value.endsWith(suffix) ? value : `${value}${suffix}`;
672
+ }
673
+ function createLocaleSuffix(localeId) {
674
+ const normalized = localeId.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
675
+ return normalized ? `-${normalized}` : "";
676
+ }
651
677
  function deserializeDocument(document2) {
652
678
  const deserializers = merge(
653
679
  { types: {} },
@@ -671,7 +697,8 @@ function serializeDocument(document2, schema, baseLanguage) {
671
697
  pluginConfig.getAdditionalSerializers()
672
698
  ), docToSerialize = stripIgnoredFields(
673
699
  document2,
674
- pluginConfig.getIgnoreFields()
700
+ pluginConfig.getIgnoreFields(),
701
+ pluginConfig.getDedupeFields()
675
702
  );
676
703
  return BaseDocumentSerializer(schema).serializeDocument(
677
704
  docToSerialize,
@@ -681,13 +708,14 @@ function serializeDocument(document2, schema, baseLanguage) {
681
708
  serializers
682
709
  );
683
710
  }
684
- function stripIgnoredFields(document2, ignoreFields) {
685
- if (ignoreFields.length === 0) return document2;
711
+ function stripIgnoredFields(document2, ignoreFields, dedupeFields) {
712
+ const fieldsToStrip = [...ignoreFields, ...dedupeFields];
713
+ if (fieldsToStrip.length === 0) return document2;
686
714
  const strippedDoc = JSON.parse(JSON.stringify(document2));
687
715
  return deleteMatchingFields(
688
716
  document2._id.replace("drafts.", ""),
689
717
  strippedDoc,
690
- ignoreFields
718
+ fieldsToStrip
691
719
  ), strippedDoc;
692
720
  }
693
721
  async function uploadFiles(documents, secrets) {
@@ -799,7 +827,9 @@ async function createI18nDocAndPatchMetadata(sourceDocument, translatedDoc, loca
799
827
  sourceDocument,
800
828
  rest,
801
829
  pluginConfig.getIgnoreFields(),
802
- pluginConfig.getSkipFields()
830
+ pluginConfig.getSkipFields(),
831
+ pluginConfig.getDedupeFields(),
832
+ localeId
803
833
  ), isSingleton = pluginConfig.getSingletons().includes(sourceDocumentId);
804
834
  let createDocumentPromise;
805
835
  if (isSingleton) {
@@ -882,7 +912,7 @@ const getOrCreateTranslationMetadata = async (documentId, baseDocument, client,
882
912
  throw error;
883
913
  }
884
914
  }, SYSTEM_FIELDS = ["_id", "_rev", "_updatedAt", "language"], isSystemField = (field) => SYSTEM_FIELDS.includes(field);
885
- async function patchI18nDoc(sourceDocumentId, i18nDocId, sourceDocument, mergedDocument, translatedFields, client) {
915
+ async function patchI18nDoc(sourceDocumentId, i18nDocId, sourceDocument, mergedDocument, translatedFields, client, existingDocument) {
886
916
  const cleanedMerge = {};
887
917
  Object.entries(mergedDocument).forEach(([key, value]) => {
888
918
  key in translatedFields && //don't overwrite any existing system values on the i18n doc
@@ -898,8 +928,15 @@ async function patchI18nDoc(sourceDocumentId, i18nDocId, sourceDocument, mergedD
898
928
  cleanedMerge,
899
929
  pluginConfig.getIgnoreFields(),
900
930
  pluginConfig.getSkipFields()
901
- );
902
- await client.patch(i18nDocId, { set: appliedDocument }).commit();
931
+ ), dedupeFields = pluginConfig.getDedupeFields();
932
+ deleteMatchingFields(sourceDocumentId, appliedDocument, dedupeFields), existingDocument && forEachMatchingField(
933
+ sourceDocumentId,
934
+ existingDocument,
935
+ dedupeFields,
936
+ (result) => {
937
+ JSONPointer.set(appliedDocument, result.pointer, result.value);
938
+ }
939
+ ), await client.patch(i18nDocId, { set: appliedDocument }).commit();
903
940
  }
904
941
  const documentLevelPatch = async (docInfo, translatedFields, localeId, client, languageField = "language", mergeWithTargetLocale = !1) => {
905
942
  const baseLanguage = pluginConfig.getSourceLocale();
@@ -930,7 +967,8 @@ const documentLevelPatch = async (docInfo, translatedFields, localeId, client, l
930
967
  baseDoc,
931
968
  merged,
932
969
  translatedFields,
933
- client
970
+ client,
971
+ i18nDoc
934
972
  ) : await createI18nDocAndPatchMetadata(
935
973
  baseDoc,
936
974
  merged,
@@ -3708,6 +3746,7 @@ const WrapText = dt(Box)`
3708
3746
  singletons,
3709
3747
  singletonMapping,
3710
3748
  ignoreFields,
3749
+ dedupeFields,
3711
3750
  skipFields,
3712
3751
  translateDocuments,
3713
3752
  secretsNamespace = SECRETS_NAMESPACE,
@@ -3728,6 +3767,7 @@ const WrapText = dt(Box)`
3728
3767
  // singletons is a string array of singleton document ids
3729
3768
  singletonMapping || ((sourceDocumentId, locale) => `${sourceDocumentId}-${locale}`),
3730
3769
  ignoreFields || [],
3770
+ dedupeFields || [],
3731
3771
  skipFields || [],
3732
3772
  normalizedTranslateDocuments || [],
3733
3773
  additionalStopTypes,