@el-j/google-sheet-translations 2.0.1 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/action-entrypoint.d.ts.map +1 -1
- package/dist/esm/index.js +71 -13
- package/dist/getSpreadSheetData.d.ts.map +1 -1
- package/dist/index.js +71 -13
- package/dist/utils/configurationHandler.d.ts +19 -0
- package/dist/utils/configurationHandler.d.ts.map +1 -1
- package/dist/utils/dataConverter/convertToDataJsonFormat.d.ts.map +1 -1
- package/dist/utils/spreadsheetUpdater.d.ts +6 -1
- package/dist/utils/spreadsheetUpdater.d.ts.map +1 -1
- package/dist/utils/syncManager.d.ts +3 -1
- package/dist/utils/syncManager.d.ts.map +1 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"action-entrypoint.d.ts","sourceRoot":"","sources":["../src/action-entrypoint.ts"],"names":[],"mappings":"AAKA,wBAAsB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"action-entrypoint.d.ts","sourceRoot":"","sources":["../src/action-entrypoint.ts"],"names":[],"mappings":"AAKA,wBAAsB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CA+DzC"}
|
package/dist/esm/index.js
CHANGED
|
@@ -80,7 +80,11 @@ function normalizeConfig(options = {}) {
|
|
|
80
80
|
// Default to true
|
|
81
81
|
spreadsheetTitle: options.spreadsheetTitle ?? "google-sheet-translations",
|
|
82
82
|
sourceLocale: options.sourceLocale ?? "en",
|
|
83
|
-
targetLocales: options.targetLocales ?? ["de", "fr", "es", "it", "pt", "ja", "zh"]
|
|
83
|
+
targetLocales: options.targetLocales ?? ["de", "fr", "es", "it", "pt", "ja", "zh"],
|
|
84
|
+
override: options.override === true,
|
|
85
|
+
// Default to false
|
|
86
|
+
cleanPush: options.cleanPush === true
|
|
87
|
+
// Default to false
|
|
84
88
|
};
|
|
85
89
|
}
|
|
86
90
|
|
|
@@ -390,11 +394,8 @@ function convertToDataJsonFormat(translationObj, locales) {
|
|
|
390
394
|
projectData[sheetTitle] = {};
|
|
391
395
|
for (const locale of locales) {
|
|
392
396
|
if (translationObj?.[locale]?.[sheetTitle]) {
|
|
393
|
-
projectData[sheetTitle][locale] = {};
|
|
394
397
|
const translations = translationObj[locale][sheetTitle];
|
|
395
|
-
|
|
396
|
-
projectData[sheetTitle][locale][key] = translations[key];
|
|
397
|
-
}
|
|
398
|
+
projectData[sheetTitle][locale] = { ...translations };
|
|
398
399
|
console.log(
|
|
399
400
|
`Found ${Object.keys(translations).length} keys for locale ${locale} in sheet ${sheetTitle}`
|
|
400
401
|
);
|
|
@@ -529,7 +530,7 @@ function columnIndexToLetter(index) {
|
|
|
529
530
|
} while (i >= 0);
|
|
530
531
|
return result;
|
|
531
532
|
}
|
|
532
|
-
async function updateSpreadsheetWithLocalChanges(doc, changes, waitSeconds, autoTranslate = false, localeMapping = {}) {
|
|
533
|
+
async function updateSpreadsheetWithLocalChanges(doc, changes, waitSeconds, autoTranslate = false, localeMapping = {}, override = false) {
|
|
533
534
|
console.log("Updating spreadsheet with local changes...");
|
|
534
535
|
const baseDelayMs = waitSeconds * 1e3;
|
|
535
536
|
for (const sheetTitle of new Set(
|
|
@@ -589,6 +590,27 @@ async function updateSpreadsheetWithLocalChanges(doc, changes, waitSeconds, auto
|
|
|
589
590
|
});
|
|
590
591
|
const newKeys = /* @__PURE__ */ new Map();
|
|
591
592
|
const keyLocalesMap = /* @__PURE__ */ new Map();
|
|
593
|
+
const pushedLocaleHeadersPerKey = /* @__PURE__ */ new Map();
|
|
594
|
+
if (autoTranslate) {
|
|
595
|
+
for (const pushedLocale of Object.keys(changes)) {
|
|
596
|
+
if (!changes[pushedLocale]?.[sheetTitle]) continue;
|
|
597
|
+
for (const pushedKey of Object.keys(changes[pushedLocale][sheetTitle])) {
|
|
598
|
+
const pushedKeyLower = pushedKey.toLowerCase();
|
|
599
|
+
if (!existingKeys.has(pushedKeyLower)) continue;
|
|
600
|
+
let pushedHeader = getOriginalHeaderForLocale(pushedLocale, localeMapping);
|
|
601
|
+
if (!pushedHeader) {
|
|
602
|
+
const prefix = getLanguagePrefix(pushedLocale);
|
|
603
|
+
pushedHeader = originalHeaders.find((h) => getLanguagePrefix(h) === prefix);
|
|
604
|
+
}
|
|
605
|
+
if (pushedHeader) {
|
|
606
|
+
if (!pushedLocaleHeadersPerKey.has(pushedKeyLower)) {
|
|
607
|
+
pushedLocaleHeadersPerKey.set(pushedKeyLower, /* @__PURE__ */ new Set());
|
|
608
|
+
}
|
|
609
|
+
pushedLocaleHeadersPerKey.get(pushedKeyLower).add(pushedHeader.toLowerCase());
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
}
|
|
592
614
|
for (const locale of Object.keys(changes)) {
|
|
593
615
|
if (!changes[locale]?.[sheetTitle]) continue;
|
|
594
616
|
const localeData = changes[locale][sheetTitle];
|
|
@@ -631,6 +653,35 @@ async function updateSpreadsheetWithLocalChanges(doc, changes, waitSeconds, auto
|
|
|
631
653
|
}
|
|
632
654
|
if (localeHeader) {
|
|
633
655
|
row.set(localeHeader, String(localeData[key]));
|
|
656
|
+
if (autoTranslate) {
|
|
657
|
+
const sourceHeaderLower = localeHeader.toLowerCase();
|
|
658
|
+
const sourceHeaderIndex = headerRow.indexOf(sourceHeaderLower);
|
|
659
|
+
if (sourceHeaderIndex >= 0) {
|
|
660
|
+
const sourceColumnLetter = columnIndexToLetter(sourceHeaderIndex);
|
|
661
|
+
const rowObj = row.toObject();
|
|
662
|
+
const pushedHeaders = pushedLocaleHeadersPerKey.get(keyLower) ?? /* @__PURE__ */ new Set();
|
|
663
|
+
for (const targetLocaleHeader of locales) {
|
|
664
|
+
const targetLower = targetLocaleHeader.toLowerCase();
|
|
665
|
+
if (targetLower === sourceHeaderLower) continue;
|
|
666
|
+
if (pushedHeaders.has(targetLower)) continue;
|
|
667
|
+
const targetHeaderIndex = headerRow.indexOf(targetLower);
|
|
668
|
+
if (targetHeaderIndex < 0) continue;
|
|
669
|
+
const exactTargetHeader = originalHeaders.find(
|
|
670
|
+
(h) => h.toLowerCase() === targetLower
|
|
671
|
+
);
|
|
672
|
+
if (!exactTargetHeader) continue;
|
|
673
|
+
const existingValue = rowObj[exactTargetHeader];
|
|
674
|
+
const isEmpty = !existingValue || existingValue.toString().trim() === "";
|
|
675
|
+
if (isEmpty || override) {
|
|
676
|
+
const targetColumnLetter = columnIndexToLetter(targetHeaderIndex);
|
|
677
|
+
row.set(
|
|
678
|
+
exactTargetHeader,
|
|
679
|
+
`=GOOGLETRANSLATE(INDIRECT("${sourceColumnLetter}"&ROW());$${sourceColumnLetter}$1;${targetColumnLetter}$1)`
|
|
680
|
+
);
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
}
|
|
634
685
|
try {
|
|
635
686
|
await withRetry(
|
|
636
687
|
() => row.save(),
|
|
@@ -779,19 +830,23 @@ function readDataJson(dataJsonPath) {
|
|
|
779
830
|
}
|
|
780
831
|
|
|
781
832
|
// src/utils/syncManager.ts
|
|
782
|
-
async function handleBidirectionalSync(doc, dataJsonPath, translationsOutputDir, syncLocalChanges, autoTranslate, spreadsheetData, waitSeconds, localeMapping = {}) {
|
|
833
|
+
async function handleBidirectionalSync(doc, dataJsonPath, translationsOutputDir, syncLocalChanges, autoTranslate, spreadsheetData, waitSeconds, localeMapping = {}, override = false, cleanPush = false) {
|
|
783
834
|
const result = {
|
|
784
835
|
shouldRefresh: false,
|
|
785
836
|
hasChanges: false
|
|
786
837
|
};
|
|
787
838
|
const localData = readDataJson(dataJsonPath);
|
|
788
839
|
const dataJsonExists = localData !== null;
|
|
789
|
-
const shouldSyncToSheet =
|
|
840
|
+
const shouldSyncToSheet = dataJsonExists && (cleanPush || syncLocalChanges && isDataJsonNewer(dataJsonPath, translationsOutputDir));
|
|
790
841
|
if (!shouldSyncToSheet || !localData) {
|
|
791
842
|
return result;
|
|
792
843
|
}
|
|
793
|
-
|
|
794
|
-
|
|
844
|
+
if (cleanPush) {
|
|
845
|
+
console.log("Clean push enabled \u2013 pushing ALL keys from languageData.json to the spreadsheet...");
|
|
846
|
+
} else {
|
|
847
|
+
console.log("Local languageData.json is newer than translation files. Checking for changes...");
|
|
848
|
+
}
|
|
849
|
+
const changes = cleanPush ? localData : findLocalChanges(localData, spreadsheetData);
|
|
795
850
|
const hasChanges = Object.keys(changes).length > 0 && Object.keys(changes).some(
|
|
796
851
|
(locale) => Object.keys(changes[locale]).length > 0
|
|
797
852
|
);
|
|
@@ -801,9 +856,10 @@ async function handleBidirectionalSync(doc, dataJsonPath, translationsOutputDir,
|
|
|
801
856
|
}
|
|
802
857
|
const localesCount = Object.keys(changes).length;
|
|
803
858
|
const keysCount = Object.values(changes).flatMap((l) => Object.values(l)).flatMap((s) => Object.keys(s)).length;
|
|
804
|
-
|
|
859
|
+
const pushMode = cleanPush ? "clean push" : "incremental sync";
|
|
860
|
+
console.log(`Found local changes (${pushMode}): ${localesCount} locale(s), ~${keysCount} key(s) to sync to the spreadsheet.`);
|
|
805
861
|
try {
|
|
806
|
-
await updateSpreadsheetWithLocalChanges(doc, changes, waitSeconds, autoTranslate, localeMapping);
|
|
862
|
+
await updateSpreadsheetWithLocalChanges(doc, changes, waitSeconds, autoTranslate, localeMapping, override);
|
|
807
863
|
result.shouldRefresh = true;
|
|
808
864
|
result.hasChanges = true;
|
|
809
865
|
} catch (err) {
|
|
@@ -1132,7 +1188,9 @@ async function getSpreadSheetData(_docTitle, options = {}, _refreshDepth = 0) {
|
|
|
1132
1188
|
config.autoTranslate,
|
|
1133
1189
|
finalTranslations,
|
|
1134
1190
|
config.waitSeconds,
|
|
1135
|
-
globalLocaleMapping
|
|
1191
|
+
globalLocaleMapping,
|
|
1192
|
+
config.override,
|
|
1193
|
+
config.cleanPush
|
|
1136
1194
|
);
|
|
1137
1195
|
if (syncResult.shouldRefresh && _refreshDepth < MAX_SYNC_REFRESH_DEPTH) {
|
|
1138
1196
|
return getSpreadSheetData(
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getSpreadSheetData.d.ts","sourceRoot":"","sources":["../src/getSpreadSheetData.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,OAAO,EAAmB,KAAK,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAOxF,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,CAAC;AAsChC,wBAAsB,kBAAkB,CACvC,SAAS,CAAC,EAAE,MAAM,EAAE,EACpB,OAAO,GAAE,kBAAuB,EAChC,aAAa,SAAI,GACf,OAAO,CAAC,eAAe,CAAC,
|
|
1
|
+
{"version":3,"file":"getSpreadSheetData.d.ts","sourceRoot":"","sources":["../src/getSpreadSheetData.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,OAAO,EAAmB,KAAK,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAOxF,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,CAAC;AAsChC,wBAAsB,kBAAkB,CACvC,SAAS,CAAC,EAAE,MAAM,EAAE,EACpB,OAAO,GAAE,kBAAuB,EAChC,aAAa,SAAI,GACf,OAAO,CAAC,eAAe,CAAC,CA2J1B;AAED,eAAe,kBAAkB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -145,7 +145,11 @@ function normalizeConfig(options = {}) {
|
|
|
145
145
|
// Default to true
|
|
146
146
|
spreadsheetTitle: options.spreadsheetTitle ?? "google-sheet-translations",
|
|
147
147
|
sourceLocale: options.sourceLocale ?? "en",
|
|
148
|
-
targetLocales: options.targetLocales ?? ["de", "fr", "es", "it", "pt", "ja", "zh"]
|
|
148
|
+
targetLocales: options.targetLocales ?? ["de", "fr", "es", "it", "pt", "ja", "zh"],
|
|
149
|
+
override: options.override === true,
|
|
150
|
+
// Default to false
|
|
151
|
+
cleanPush: options.cleanPush === true
|
|
152
|
+
// Default to false
|
|
149
153
|
};
|
|
150
154
|
}
|
|
151
155
|
|
|
@@ -455,11 +459,8 @@ function convertToDataJsonFormat(translationObj, locales) {
|
|
|
455
459
|
projectData[sheetTitle] = {};
|
|
456
460
|
for (const locale of locales) {
|
|
457
461
|
if (translationObj?.[locale]?.[sheetTitle]) {
|
|
458
|
-
projectData[sheetTitle][locale] = {};
|
|
459
462
|
const translations = translationObj[locale][sheetTitle];
|
|
460
|
-
|
|
461
|
-
projectData[sheetTitle][locale][key] = translations[key];
|
|
462
|
-
}
|
|
463
|
+
projectData[sheetTitle][locale] = { ...translations };
|
|
463
464
|
console.log(
|
|
464
465
|
`Found ${Object.keys(translations).length} keys for locale ${locale} in sheet ${sheetTitle}`
|
|
465
466
|
);
|
|
@@ -594,7 +595,7 @@ function columnIndexToLetter(index) {
|
|
|
594
595
|
} while (i >= 0);
|
|
595
596
|
return result;
|
|
596
597
|
}
|
|
597
|
-
async function updateSpreadsheetWithLocalChanges(doc, changes, waitSeconds, autoTranslate = false, localeMapping = {}) {
|
|
598
|
+
async function updateSpreadsheetWithLocalChanges(doc, changes, waitSeconds, autoTranslate = false, localeMapping = {}, override = false) {
|
|
598
599
|
console.log("Updating spreadsheet with local changes...");
|
|
599
600
|
const baseDelayMs = waitSeconds * 1e3;
|
|
600
601
|
for (const sheetTitle of new Set(
|
|
@@ -654,6 +655,27 @@ async function updateSpreadsheetWithLocalChanges(doc, changes, waitSeconds, auto
|
|
|
654
655
|
});
|
|
655
656
|
const newKeys = /* @__PURE__ */ new Map();
|
|
656
657
|
const keyLocalesMap = /* @__PURE__ */ new Map();
|
|
658
|
+
const pushedLocaleHeadersPerKey = /* @__PURE__ */ new Map();
|
|
659
|
+
if (autoTranslate) {
|
|
660
|
+
for (const pushedLocale of Object.keys(changes)) {
|
|
661
|
+
if (!changes[pushedLocale]?.[sheetTitle]) continue;
|
|
662
|
+
for (const pushedKey of Object.keys(changes[pushedLocale][sheetTitle])) {
|
|
663
|
+
const pushedKeyLower = pushedKey.toLowerCase();
|
|
664
|
+
if (!existingKeys.has(pushedKeyLower)) continue;
|
|
665
|
+
let pushedHeader = getOriginalHeaderForLocale(pushedLocale, localeMapping);
|
|
666
|
+
if (!pushedHeader) {
|
|
667
|
+
const prefix = getLanguagePrefix(pushedLocale);
|
|
668
|
+
pushedHeader = originalHeaders.find((h) => getLanguagePrefix(h) === prefix);
|
|
669
|
+
}
|
|
670
|
+
if (pushedHeader) {
|
|
671
|
+
if (!pushedLocaleHeadersPerKey.has(pushedKeyLower)) {
|
|
672
|
+
pushedLocaleHeadersPerKey.set(pushedKeyLower, /* @__PURE__ */ new Set());
|
|
673
|
+
}
|
|
674
|
+
pushedLocaleHeadersPerKey.get(pushedKeyLower).add(pushedHeader.toLowerCase());
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
}
|
|
657
679
|
for (const locale of Object.keys(changes)) {
|
|
658
680
|
if (!changes[locale]?.[sheetTitle]) continue;
|
|
659
681
|
const localeData = changes[locale][sheetTitle];
|
|
@@ -696,6 +718,35 @@ async function updateSpreadsheetWithLocalChanges(doc, changes, waitSeconds, auto
|
|
|
696
718
|
}
|
|
697
719
|
if (localeHeader) {
|
|
698
720
|
row.set(localeHeader, String(localeData[key]));
|
|
721
|
+
if (autoTranslate) {
|
|
722
|
+
const sourceHeaderLower = localeHeader.toLowerCase();
|
|
723
|
+
const sourceHeaderIndex = headerRow.indexOf(sourceHeaderLower);
|
|
724
|
+
if (sourceHeaderIndex >= 0) {
|
|
725
|
+
const sourceColumnLetter = columnIndexToLetter(sourceHeaderIndex);
|
|
726
|
+
const rowObj = row.toObject();
|
|
727
|
+
const pushedHeaders = pushedLocaleHeadersPerKey.get(keyLower) ?? /* @__PURE__ */ new Set();
|
|
728
|
+
for (const targetLocaleHeader of locales) {
|
|
729
|
+
const targetLower = targetLocaleHeader.toLowerCase();
|
|
730
|
+
if (targetLower === sourceHeaderLower) continue;
|
|
731
|
+
if (pushedHeaders.has(targetLower)) continue;
|
|
732
|
+
const targetHeaderIndex = headerRow.indexOf(targetLower);
|
|
733
|
+
if (targetHeaderIndex < 0) continue;
|
|
734
|
+
const exactTargetHeader = originalHeaders.find(
|
|
735
|
+
(h) => h.toLowerCase() === targetLower
|
|
736
|
+
);
|
|
737
|
+
if (!exactTargetHeader) continue;
|
|
738
|
+
const existingValue = rowObj[exactTargetHeader];
|
|
739
|
+
const isEmpty = !existingValue || existingValue.toString().trim() === "";
|
|
740
|
+
if (isEmpty || override) {
|
|
741
|
+
const targetColumnLetter = columnIndexToLetter(targetHeaderIndex);
|
|
742
|
+
row.set(
|
|
743
|
+
exactTargetHeader,
|
|
744
|
+
`=GOOGLETRANSLATE(INDIRECT("${sourceColumnLetter}"&ROW());$${sourceColumnLetter}$1;${targetColumnLetter}$1)`
|
|
745
|
+
);
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
}
|
|
699
750
|
try {
|
|
700
751
|
await withRetry(
|
|
701
752
|
() => row.save(),
|
|
@@ -844,19 +895,23 @@ function readDataJson(dataJsonPath) {
|
|
|
844
895
|
}
|
|
845
896
|
|
|
846
897
|
// src/utils/syncManager.ts
|
|
847
|
-
async function handleBidirectionalSync(doc, dataJsonPath, translationsOutputDir, syncLocalChanges, autoTranslate, spreadsheetData, waitSeconds, localeMapping = {}) {
|
|
898
|
+
async function handleBidirectionalSync(doc, dataJsonPath, translationsOutputDir, syncLocalChanges, autoTranslate, spreadsheetData, waitSeconds, localeMapping = {}, override = false, cleanPush = false) {
|
|
848
899
|
const result = {
|
|
849
900
|
shouldRefresh: false,
|
|
850
901
|
hasChanges: false
|
|
851
902
|
};
|
|
852
903
|
const localData = readDataJson(dataJsonPath);
|
|
853
904
|
const dataJsonExists = localData !== null;
|
|
854
|
-
const shouldSyncToSheet =
|
|
905
|
+
const shouldSyncToSheet = dataJsonExists && (cleanPush || syncLocalChanges && isDataJsonNewer(dataJsonPath, translationsOutputDir));
|
|
855
906
|
if (!shouldSyncToSheet || !localData) {
|
|
856
907
|
return result;
|
|
857
908
|
}
|
|
858
|
-
|
|
859
|
-
|
|
909
|
+
if (cleanPush) {
|
|
910
|
+
console.log("Clean push enabled \u2013 pushing ALL keys from languageData.json to the spreadsheet...");
|
|
911
|
+
} else {
|
|
912
|
+
console.log("Local languageData.json is newer than translation files. Checking for changes...");
|
|
913
|
+
}
|
|
914
|
+
const changes = cleanPush ? localData : findLocalChanges(localData, spreadsheetData);
|
|
860
915
|
const hasChanges = Object.keys(changes).length > 0 && Object.keys(changes).some(
|
|
861
916
|
(locale) => Object.keys(changes[locale]).length > 0
|
|
862
917
|
);
|
|
@@ -866,9 +921,10 @@ async function handleBidirectionalSync(doc, dataJsonPath, translationsOutputDir,
|
|
|
866
921
|
}
|
|
867
922
|
const localesCount = Object.keys(changes).length;
|
|
868
923
|
const keysCount = Object.values(changes).flatMap((l) => Object.values(l)).flatMap((s) => Object.keys(s)).length;
|
|
869
|
-
|
|
924
|
+
const pushMode = cleanPush ? "clean push" : "incremental sync";
|
|
925
|
+
console.log(`Found local changes (${pushMode}): ${localesCount} locale(s), ~${keysCount} key(s) to sync to the spreadsheet.`);
|
|
870
926
|
try {
|
|
871
|
-
await updateSpreadsheetWithLocalChanges(doc, changes, waitSeconds, autoTranslate, localeMapping);
|
|
927
|
+
await updateSpreadsheetWithLocalChanges(doc, changes, waitSeconds, autoTranslate, localeMapping, override);
|
|
872
928
|
result.shouldRefresh = true;
|
|
873
929
|
result.hasChanges = true;
|
|
874
930
|
} catch (err) {
|
|
@@ -1197,7 +1253,9 @@ async function getSpreadSheetData(_docTitle, options = {}, _refreshDepth = 0) {
|
|
|
1197
1253
|
config.autoTranslate,
|
|
1198
1254
|
finalTranslations,
|
|
1199
1255
|
config.waitSeconds,
|
|
1200
|
-
globalLocaleMapping
|
|
1256
|
+
globalLocaleMapping,
|
|
1257
|
+
config.override,
|
|
1258
|
+
config.cleanPush
|
|
1201
1259
|
);
|
|
1202
1260
|
if (syncResult.shouldRefresh && _refreshDepth < MAX_SYNC_REFRESH_DEPTH) {
|
|
1203
1261
|
return getSpreadSheetData(
|
|
@@ -47,6 +47,23 @@ export interface SpreadsheetOptions {
|
|
|
47
47
|
* Default: ['de', 'fr', 'es', 'it', 'pt', 'ja', 'zh'].
|
|
48
48
|
*/
|
|
49
49
|
targetLocales?: string[];
|
|
50
|
+
/**
|
|
51
|
+
* When `true`, existing translations in other language columns are overwritten
|
|
52
|
+
* with GOOGLETRANSLATE formulas when `autoTranslate` is also enabled and keys
|
|
53
|
+
* are pushed. When `false` (the default), only **empty** cells receive a
|
|
54
|
+
* formula – cells that already contain a translation are left untouched.
|
|
55
|
+
*/
|
|
56
|
+
override?: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* When `true`, **all** keys from the local `languageData.json` are pushed to
|
|
59
|
+
* the spreadsheet – including keys that already exist there. This is useful
|
|
60
|
+
* when the file has been copied from another project and the spreadsheet needs
|
|
61
|
+
* a complete refresh. The file-timestamp guard (`isDataJsonNewer`) is
|
|
62
|
+
* bypassed. Whether existing cell values are overwritten depends on the usual
|
|
63
|
+
* `override` + `autoTranslate` flags. Implies `syncLocalChanges`.
|
|
64
|
+
* Default: `false`.
|
|
65
|
+
*/
|
|
66
|
+
cleanPush?: boolean;
|
|
50
67
|
}
|
|
51
68
|
/**
|
|
52
69
|
* Normalized configuration with all defaults applied
|
|
@@ -65,6 +82,8 @@ export interface NormalizedConfig {
|
|
|
65
82
|
spreadsheetTitle: string;
|
|
66
83
|
sourceLocale: string;
|
|
67
84
|
targetLocales: string[];
|
|
85
|
+
override: boolean;
|
|
86
|
+
cleanPush: boolean;
|
|
68
87
|
}
|
|
69
88
|
/**
|
|
70
89
|
* Normalizes configuration options by applying defaults
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configurationHandler.d.ts","sourceRoot":"","sources":["../../src/utils/configurationHandler.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,qFAAqF;IACrF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"configurationHandler.d.ts","sourceRoot":"","sources":["../../src/utils/configurationHandler.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,qFAAqF;IACrF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,GAAE,kBAAuB,GAAG,gBAAgB,CAkBlF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"convertToDataJsonFormat.d.ts","sourceRoot":"","sources":["../../../src/utils/dataConverter/convertToDataJsonFormat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAoB,MAAM,aAAa,CAAC;AAErE;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACtC,cAAc,EAAE,eAAe,EAC/B,OAAO,EAAE,MAAM,EAAE,GACf,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,
|
|
1
|
+
{"version":3,"file":"convertToDataJsonFormat.d.ts","sourceRoot":"","sources":["../../../src/utils/dataConverter/convertToDataJsonFormat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAoB,MAAM,aAAa,CAAC;AAErE;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACtC,cAAc,EAAE,eAAe,EAC/B,OAAO,EAAE,MAAM,EAAE,GACf,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAmD3B;AAED,eAAe,uBAAuB,CAAC"}
|
|
@@ -8,6 +8,8 @@ import type { TranslationData } from "../types";
|
|
|
8
8
|
* - For languages missing translations, it automatically adds Google Translate formulas
|
|
9
9
|
* - The formula format is: =GOOGLETRANSLATE(INDIRECT(sourceColumn&ROW());$sourceColumn$1;targetColumn$1)
|
|
10
10
|
* - This dynamic formula uses cell references for language codes and automatically adapts to the correct row
|
|
11
|
+
* - For **existing** keys the same logic applies: empty cells in other language columns receive a
|
|
12
|
+
* formula; cells that already contain a translation are only overwritten when `override` is true.
|
|
11
13
|
*
|
|
12
14
|
* If a sheet named `sheetTitle` does not yet exist in the document and `localeMapping` is
|
|
13
15
|
* non-empty, the sheet is **created automatically** with "key" as the first column followed by
|
|
@@ -24,7 +26,10 @@ import type { TranslationData } from "../types";
|
|
|
24
26
|
* @param waitSeconds - Base back-off delay in seconds for retrying rate-limited API calls
|
|
25
27
|
* @param autoTranslate - Whether to add Google Translate formulas for missing translations (default: false)
|
|
26
28
|
* @param localeMapping - Mapping from normalized locale codes to original spreadsheet headers
|
|
29
|
+
* @param override - When true AND autoTranslate is true, existing translations in other language
|
|
30
|
+
* columns are overwritten with GOOGLETRANSLATE formulas. When false (default) only empty cells
|
|
31
|
+
* receive a formula.
|
|
27
32
|
* @returns Promise that resolves when the update is complete
|
|
28
33
|
*/
|
|
29
|
-
export declare function updateSpreadsheetWithLocalChanges(doc: GoogleSpreadsheet, changes: TranslationData, waitSeconds: number, autoTranslate?: boolean, localeMapping?: Record<string, string
|
|
34
|
+
export declare function updateSpreadsheetWithLocalChanges(doc: GoogleSpreadsheet, changes: TranslationData, waitSeconds: number, autoTranslate?: boolean, localeMapping?: Record<string, string>, override?: boolean): Promise<void>;
|
|
30
35
|
//# sourceMappingURL=spreadsheetUpdater.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spreadsheetUpdater.d.ts","sourceRoot":"","sources":["../../src/utils/spreadsheetUpdater.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAA8B,MAAM,oBAAoB,CAAC;AACxF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAgBhD
|
|
1
|
+
{"version":3,"file":"spreadsheetUpdater.d.ts","sourceRoot":"","sources":["../../src/utils/spreadsheetUpdater.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAA8B,MAAM,oBAAoB,CAAC;AACxF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAgBhD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAsB,iCAAiC,CACnD,GAAG,EAAE,iBAAiB,EACtB,OAAO,EAAE,eAAe,EACxB,WAAW,EAAE,MAAM,EACnB,aAAa,UAAQ,EACrB,aAAa,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,EAC1C,QAAQ,UAAQ,GACjB,OAAO,CAAC,IAAI,CAAC,CAsUf"}
|
|
@@ -17,7 +17,9 @@ export interface SyncResult {
|
|
|
17
17
|
* @param spreadsheetData Current data from the spreadsheet
|
|
18
18
|
* @param waitSeconds Time to wait between API calls
|
|
19
19
|
* @param localeMapping Mapping from normalized locale codes to original spreadsheet headers
|
|
20
|
+
* @param override When true AND autoTranslate is true, overwrite existing translations with formulas
|
|
21
|
+
* @param cleanPush When true, push ALL keys from localData (bypasses timestamp guard and diff)
|
|
20
22
|
* @returns Sync operation result
|
|
21
23
|
*/
|
|
22
|
-
export declare function handleBidirectionalSync(doc: GoogleSpreadsheet, dataJsonPath: string, translationsOutputDir: string, syncLocalChanges: boolean, autoTranslate: boolean, spreadsheetData: TranslationData, waitSeconds: number, localeMapping?: Record<string, string
|
|
24
|
+
export declare function handleBidirectionalSync(doc: GoogleSpreadsheet, dataJsonPath: string, translationsOutputDir: string, syncLocalChanges: boolean, autoTranslate: boolean, spreadsheetData: TranslationData, waitSeconds: number, localeMapping?: Record<string, string>, override?: boolean, cleanPush?: boolean): Promise<SyncResult>;
|
|
23
25
|
//# sourceMappingURL=syncManager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"syncManager.d.ts","sourceRoot":"","sources":["../../src/utils/syncManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAMhD;;GAEG;AACH,MAAM,WAAW,UAAU;IAC1B,aAAa,EAAE,OAAO,CAAC;IACvB,UAAU,EAAE,OAAO,CAAC;CACpB;AAED
|
|
1
|
+
{"version":3,"file":"syncManager.d.ts","sourceRoot":"","sources":["../../src/utils/syncManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAMhD;;GAEG;AACH,MAAM,WAAW,UAAU;IAC1B,aAAa,EAAE,OAAO,CAAC;IACvB,UAAU,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,uBAAuB,CAC5C,GAAG,EAAE,iBAAiB,EACtB,YAAY,EAAE,MAAM,EACpB,qBAAqB,EAAE,MAAM,EAC7B,gBAAgB,EAAE,OAAO,EACzB,aAAa,EAAE,OAAO,EACtB,eAAe,EAAE,eAAe,EAChC,WAAW,EAAE,MAAM,EACnB,aAAa,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,EAC1C,QAAQ,UAAQ,EAChB,SAAS,UAAQ,GACf,OAAO,CAAC,UAAU,CAAC,CA4DrB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@el-j/google-sheet-translations",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.1",
|
|
4
4
|
"description": "A package to manage translations stored in Google Spreadsheets",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -75,10 +75,10 @@
|
|
|
75
75
|
"@semantic-release/npm": "^13.1.5",
|
|
76
76
|
"@semantic-release/release-notes-generator": "^14.1.0",
|
|
77
77
|
"@types/jest": "^30.0.0",
|
|
78
|
-
"@types/node": "^25.
|
|
78
|
+
"@types/node": "^25.5.0",
|
|
79
79
|
"@typescript-eslint/eslint-plugin": "^8.57.0",
|
|
80
80
|
"@typescript-eslint/parser": "^8.57.0",
|
|
81
|
-
"esbuild": "^0.
|
|
81
|
+
"esbuild": "^0.27.4",
|
|
82
82
|
"conventional-changelog-conventionalcommits": "^9.3.0",
|
|
83
83
|
"dotenv": "17.3.1",
|
|
84
84
|
"eslint": "^10.0.3",
|