@el-j/google-sheet-translations 2.1.1 → 2.1.3

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/esm/index.js CHANGED
@@ -521,6 +521,7 @@ function findLocalChanges(localData, spreadsheetData) {
521
521
  }
522
522
 
523
523
  // src/utils/spreadsheetUpdater.ts
524
+ import { setTimeout as delay2 } from "node:timers/promises";
524
525
  function columnIndexToLetter(index) {
525
526
  let result = "";
526
527
  let i = index;
@@ -530,6 +531,9 @@ function columnIndexToLetter(index) {
530
531
  } while (i >= 0);
531
532
  return result;
532
533
  }
534
+ function langCodeFormula(cellRef) {
535
+ return `LOWER(IFERROR(LEFT(${cellRef},FIND("-",${cellRef})-1),${cellRef}))`;
536
+ }
533
537
  async function updateSpreadsheetWithLocalChanges(doc, changes, waitSeconds, autoTranslate = false, localeMapping = {}, override = false) {
534
538
  console.log("Updating spreadsheet with local changes...");
535
539
  const baseDelayMs = waitSeconds * 1e3;
@@ -676,7 +680,7 @@ async function updateSpreadsheetWithLocalChanges(doc, changes, waitSeconds, auto
676
680
  const targetColumnLetter = columnIndexToLetter(targetHeaderIndex);
677
681
  row.set(
678
682
  exactTargetHeader,
679
- `=GOOGLETRANSLATE(INDIRECT("${sourceColumnLetter}"&ROW());$${sourceColumnLetter}$1;${targetColumnLetter}$1)`
683
+ `=GOOGLETRANSLATE(INDIRECT("${sourceColumnLetter}"&ROW());${langCodeFormula(`$${sourceColumnLetter}$1`)};${langCodeFormula(`${targetColumnLetter}$1`)})`
680
684
  );
681
685
  }
682
686
  }
@@ -688,6 +692,9 @@ async function updateSpreadsheetWithLocalChanges(doc, changes, waitSeconds, auto
688
692
  `save row ${rowIndex} in ${sheetTitle}`,
689
693
  baseDelayMs
690
694
  );
695
+ if (baseDelayMs > 0) {
696
+ await delay2(baseDelayMs);
697
+ }
691
698
  } catch (err) {
692
699
  console.error(
693
700
  `Failed to save row for key "${keyLower}" in sheet "${sheetTitle}":`,
@@ -722,7 +729,7 @@ async function updateSpreadsheetWithLocalChanges(doc, changes, waitSeconds, auto
722
729
  }
723
730
  const sourceColumnLetter = columnIndexToLetter(sourceHeaderIndex);
724
731
  const targetColumnLetter = columnIndexToLetter(targetHeaderIndex);
725
- rowData[exactHeaderName] = `=GOOGLETRANSLATE(INDIRECT("${sourceColumnLetter}"&ROW());$${sourceColumnLetter}$1;${targetColumnLetter}$1)`;
732
+ rowData[exactHeaderName] = `=GOOGLETRANSLATE(INDIRECT("${sourceColumnLetter}"&ROW());${langCodeFormula(`$${sourceColumnLetter}$1`)};${langCodeFormula(`${targetColumnLetter}$1`)})`;
726
733
  }
727
734
  }
728
735
  }
@@ -737,6 +744,9 @@ async function updateSpreadsheetWithLocalChanges(doc, changes, waitSeconds, auto
737
744
  `addRows chunk ${Math.floor(i / CHUNK_SIZE) + 1} in ${sheetTitle}`,
738
745
  baseDelayMs
739
746
  );
747
+ if (baseDelayMs > 0 && i + CHUNK_SIZE < newRows.length) {
748
+ await delay2(baseDelayMs);
749
+ }
740
750
  }
741
751
  }
742
752
  }
@@ -773,6 +783,9 @@ function isDataJsonNewer(dataJsonPath, translationsOutputDir) {
773
783
  if (!mostRecentTranslationMtime) return true;
774
784
  return dataJsonMtime > mostRecentTranslationMtime;
775
785
  } catch (error) {
786
+ if (error.code === "ENOENT") {
787
+ return true;
788
+ }
776
789
  console.warn("Error comparing file modification times:", error);
777
790
  return false;
778
791
  }
@@ -830,6 +843,20 @@ function readDataJson(dataJsonPath) {
830
843
  }
831
844
 
832
845
  // src/utils/syncManager.ts
846
+ function hasSheetsMissingFromSpreadsheet(localData, spreadsheetData) {
847
+ const spreadsheetLocales = Object.keys(spreadsheetData);
848
+ for (const locale of Object.keys(localData)) {
849
+ if (!localData[locale]) continue;
850
+ const resolvedLocale = resolveLocaleWithFallback(locale, spreadsheetLocales);
851
+ for (const sheet of Object.keys(localData[locale])) {
852
+ if (sheet === I18N_SHEET_NAME) continue;
853
+ if (!resolvedLocale || !spreadsheetData[resolvedLocale]?.[sheet]) {
854
+ return true;
855
+ }
856
+ }
857
+ }
858
+ return false;
859
+ }
833
860
  async function handleBidirectionalSync(doc, dataJsonPath, translationsOutputDir, syncLocalChanges, autoTranslate, spreadsheetData, waitSeconds, localeMapping = {}, override = false, cleanPush = false) {
834
861
  const result = {
835
862
  shouldRefresh: false,
@@ -837,12 +864,15 @@ async function handleBidirectionalSync(doc, dataJsonPath, translationsOutputDir,
837
864
  };
838
865
  const localData = readDataJson(dataJsonPath);
839
866
  const dataJsonExists = localData !== null;
840
- const shouldSyncToSheet = dataJsonExists && (cleanPush || syncLocalChanges && isDataJsonNewer(dataJsonPath, translationsOutputDir));
867
+ const hasMissingSheets = syncLocalChanges && localData !== null && hasSheetsMissingFromSpreadsheet(localData, spreadsheetData);
868
+ const shouldSyncToSheet = dataJsonExists && (cleanPush || syncLocalChanges && isDataJsonNewer(dataJsonPath, translationsOutputDir) || hasMissingSheets);
841
869
  if (!shouldSyncToSheet || !localData) {
842
870
  return result;
843
871
  }
844
872
  if (cleanPush) {
845
873
  console.log("Clean push enabled \u2013 pushing ALL keys from languageData.json to the spreadsheet...");
874
+ } else if (hasMissingSheets) {
875
+ console.log("Spreadsheet is missing one or more local sheets. Syncing missing sheets...");
846
876
  } else {
847
877
  console.log("Local languageData.json is newer than translation files. Checking for changes...");
848
878
  }
@@ -955,6 +985,9 @@ function colLetter(index) {
955
985
  } while (i >= 0);
956
986
  return result;
957
987
  }
988
+ function langCodeFormula2(cellRef) {
989
+ return `LOWER(IFERROR(LEFT(${cellRef},FIND("-",${cellRef})-1),${cellRef}))`;
990
+ }
958
991
  var DEFAULT_TARGET_LOCALES = ["de", "fr", "es", "it", "pt", "ja", "zh"];
959
992
  var STARTER_KEYS = {
960
993
  "app.name": "My App",
@@ -1039,7 +1072,7 @@ async function createSpreadsheet(authClient, options = {}) {
1039
1072
  const row = { key, [sourceLocale]: sourceValue };
1040
1073
  targetLocales.forEach((locale, idx) => {
1041
1074
  const targetColLetter = colLetter(2 + idx);
1042
- row[locale] = `=GOOGLETRANSLATE(INDIRECT("${sourceColLetter}"&ROW());$${sourceColLetter}$1;${targetColLetter}$1)`;
1075
+ row[locale] = `=GOOGLETRANSLATE(INDIRECT("${sourceColLetter}"&ROW());${langCodeFormula2(`$${sourceColLetter}$1`)};${langCodeFormula2(`${targetColLetter}$1`)})`;
1043
1076
  });
1044
1077
  return row;
1045
1078
  });
@@ -1215,10 +1248,10 @@ async function getSpreadSheetData(_docTitle, options = {}, _refreshDepth = 0) {
1215
1248
  }
1216
1249
 
1217
1250
  // src/utils/wait.ts
1218
- import { setTimeout as delay2 } from "node:timers/promises";
1251
+ import { setTimeout as delay3 } from "node:timers/promises";
1219
1252
  function wait(seconds, reason) {
1220
1253
  console.log("wait", seconds, reason);
1221
- return delay2(seconds * 1e3);
1254
+ return delay3(seconds * 1e3);
1222
1255
  }
1223
1256
 
1224
1257
  // src/utils/translationHelpers.ts
package/dist/index.js CHANGED
@@ -586,6 +586,7 @@ function findLocalChanges(localData, spreadsheetData) {
586
586
  }
587
587
 
588
588
  // src/utils/spreadsheetUpdater.ts
589
+ var import_promises2 = require("node:timers/promises");
589
590
  function columnIndexToLetter(index) {
590
591
  let result = "";
591
592
  let i = index;
@@ -595,6 +596,9 @@ function columnIndexToLetter(index) {
595
596
  } while (i >= 0);
596
597
  return result;
597
598
  }
599
+ function langCodeFormula(cellRef) {
600
+ return `LOWER(IFERROR(LEFT(${cellRef},FIND("-",${cellRef})-1),${cellRef}))`;
601
+ }
598
602
  async function updateSpreadsheetWithLocalChanges(doc, changes, waitSeconds, autoTranslate = false, localeMapping = {}, override = false) {
599
603
  console.log("Updating spreadsheet with local changes...");
600
604
  const baseDelayMs = waitSeconds * 1e3;
@@ -741,7 +745,7 @@ async function updateSpreadsheetWithLocalChanges(doc, changes, waitSeconds, auto
741
745
  const targetColumnLetter = columnIndexToLetter(targetHeaderIndex);
742
746
  row.set(
743
747
  exactTargetHeader,
744
- `=GOOGLETRANSLATE(INDIRECT("${sourceColumnLetter}"&ROW());$${sourceColumnLetter}$1;${targetColumnLetter}$1)`
748
+ `=GOOGLETRANSLATE(INDIRECT("${sourceColumnLetter}"&ROW());${langCodeFormula(`$${sourceColumnLetter}$1`)};${langCodeFormula(`${targetColumnLetter}$1`)})`
745
749
  );
746
750
  }
747
751
  }
@@ -753,6 +757,9 @@ async function updateSpreadsheetWithLocalChanges(doc, changes, waitSeconds, auto
753
757
  `save row ${rowIndex} in ${sheetTitle}`,
754
758
  baseDelayMs
755
759
  );
760
+ if (baseDelayMs > 0) {
761
+ await (0, import_promises2.setTimeout)(baseDelayMs);
762
+ }
756
763
  } catch (err) {
757
764
  console.error(
758
765
  `Failed to save row for key "${keyLower}" in sheet "${sheetTitle}":`,
@@ -787,7 +794,7 @@ async function updateSpreadsheetWithLocalChanges(doc, changes, waitSeconds, auto
787
794
  }
788
795
  const sourceColumnLetter = columnIndexToLetter(sourceHeaderIndex);
789
796
  const targetColumnLetter = columnIndexToLetter(targetHeaderIndex);
790
- rowData[exactHeaderName] = `=GOOGLETRANSLATE(INDIRECT("${sourceColumnLetter}"&ROW());$${sourceColumnLetter}$1;${targetColumnLetter}$1)`;
797
+ rowData[exactHeaderName] = `=GOOGLETRANSLATE(INDIRECT("${sourceColumnLetter}"&ROW());${langCodeFormula(`$${sourceColumnLetter}$1`)};${langCodeFormula(`${targetColumnLetter}$1`)})`;
791
798
  }
792
799
  }
793
800
  }
@@ -802,6 +809,9 @@ async function updateSpreadsheetWithLocalChanges(doc, changes, waitSeconds, auto
802
809
  `addRows chunk ${Math.floor(i / CHUNK_SIZE) + 1} in ${sheetTitle}`,
803
810
  baseDelayMs
804
811
  );
812
+ if (baseDelayMs > 0 && i + CHUNK_SIZE < newRows.length) {
813
+ await (0, import_promises2.setTimeout)(baseDelayMs);
814
+ }
805
815
  }
806
816
  }
807
817
  }
@@ -838,6 +848,9 @@ function isDataJsonNewer(dataJsonPath, translationsOutputDir) {
838
848
  if (!mostRecentTranslationMtime) return true;
839
849
  return dataJsonMtime > mostRecentTranslationMtime;
840
850
  } catch (error) {
851
+ if (error.code === "ENOENT") {
852
+ return true;
853
+ }
841
854
  console.warn("Error comparing file modification times:", error);
842
855
  return false;
843
856
  }
@@ -895,6 +908,20 @@ function readDataJson(dataJsonPath) {
895
908
  }
896
909
 
897
910
  // src/utils/syncManager.ts
911
+ function hasSheetsMissingFromSpreadsheet(localData, spreadsheetData) {
912
+ const spreadsheetLocales = Object.keys(spreadsheetData);
913
+ for (const locale of Object.keys(localData)) {
914
+ if (!localData[locale]) continue;
915
+ const resolvedLocale = resolveLocaleWithFallback(locale, spreadsheetLocales);
916
+ for (const sheet of Object.keys(localData[locale])) {
917
+ if (sheet === I18N_SHEET_NAME) continue;
918
+ if (!resolvedLocale || !spreadsheetData[resolvedLocale]?.[sheet]) {
919
+ return true;
920
+ }
921
+ }
922
+ }
923
+ return false;
924
+ }
898
925
  async function handleBidirectionalSync(doc, dataJsonPath, translationsOutputDir, syncLocalChanges, autoTranslate, spreadsheetData, waitSeconds, localeMapping = {}, override = false, cleanPush = false) {
899
926
  const result = {
900
927
  shouldRefresh: false,
@@ -902,12 +929,15 @@ async function handleBidirectionalSync(doc, dataJsonPath, translationsOutputDir,
902
929
  };
903
930
  const localData = readDataJson(dataJsonPath);
904
931
  const dataJsonExists = localData !== null;
905
- const shouldSyncToSheet = dataJsonExists && (cleanPush || syncLocalChanges && isDataJsonNewer(dataJsonPath, translationsOutputDir));
932
+ const hasMissingSheets = syncLocalChanges && localData !== null && hasSheetsMissingFromSpreadsheet(localData, spreadsheetData);
933
+ const shouldSyncToSheet = dataJsonExists && (cleanPush || syncLocalChanges && isDataJsonNewer(dataJsonPath, translationsOutputDir) || hasMissingSheets);
906
934
  if (!shouldSyncToSheet || !localData) {
907
935
  return result;
908
936
  }
909
937
  if (cleanPush) {
910
938
  console.log("Clean push enabled \u2013 pushing ALL keys from languageData.json to the spreadsheet...");
939
+ } else if (hasMissingSheets) {
940
+ console.log("Spreadsheet is missing one or more local sheets. Syncing missing sheets...");
911
941
  } else {
912
942
  console.log("Local languageData.json is newer than translation files. Checking for changes...");
913
943
  }
@@ -1020,6 +1050,9 @@ function colLetter(index) {
1020
1050
  } while (i >= 0);
1021
1051
  return result;
1022
1052
  }
1053
+ function langCodeFormula2(cellRef) {
1054
+ return `LOWER(IFERROR(LEFT(${cellRef},FIND("-",${cellRef})-1),${cellRef}))`;
1055
+ }
1023
1056
  var DEFAULT_TARGET_LOCALES = ["de", "fr", "es", "it", "pt", "ja", "zh"];
1024
1057
  var STARTER_KEYS = {
1025
1058
  "app.name": "My App",
@@ -1104,7 +1137,7 @@ async function createSpreadsheet(authClient, options = {}) {
1104
1137
  const row = { key, [sourceLocale]: sourceValue };
1105
1138
  targetLocales.forEach((locale, idx) => {
1106
1139
  const targetColLetter = colLetter(2 + idx);
1107
- row[locale] = `=GOOGLETRANSLATE(INDIRECT("${sourceColLetter}"&ROW());$${sourceColLetter}$1;${targetColLetter}$1)`;
1140
+ row[locale] = `=GOOGLETRANSLATE(INDIRECT("${sourceColLetter}"&ROW());${langCodeFormula2(`$${sourceColLetter}$1`)};${langCodeFormula2(`${targetColLetter}$1`)})`;
1108
1141
  });
1109
1142
  return row;
1110
1143
  });
@@ -1280,10 +1313,10 @@ async function getSpreadSheetData(_docTitle, options = {}, _refreshDepth = 0) {
1280
1313
  }
1281
1314
 
1282
1315
  // src/utils/wait.ts
1283
- var import_promises2 = require("node:timers/promises");
1316
+ var import_promises3 = require("node:timers/promises");
1284
1317
  function wait(seconds, reason) {
1285
1318
  console.log("wait", seconds, reason);
1286
- return (0, import_promises2.setTimeout)(seconds * 1e3);
1319
+ return (0, import_promises3.setTimeout)(seconds * 1e3);
1287
1320
  }
1288
1321
 
1289
1322
  // src/utils/translationHelpers.ts
@@ -4,9 +4,10 @@
4
4
  export interface SpreadsheetOptions {
5
5
  rowLimit?: number;
6
6
  /**
7
- * Base back-off delay in seconds used when retrying Google Sheets API
8
- * calls that fail with a rate-limit response (HTTP 429 / 503).
9
- * The actual delay for each retry attempt is `waitSeconds * 2^attempt`,
7
+ * Seconds to wait between consecutive Google Sheets write API calls
8
+ * (proactive throttle) and as the base back-off delay when retrying calls
9
+ * that fail with a rate-limit response (HTTP 429 / 503).
10
+ * The actual retry delay for each attempt is `waitSeconds * 2^attempt`,
10
11
  * capped at 30 seconds. Defaults to 1.
11
12
  */
12
13
  waitSeconds?: number;
@@ -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;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
+ {"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;;;;;;OAMG;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":"isDataJsonNewer.d.ts","sourceRoot":"","sources":["../../src/utils/isDataJsonNewer.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,EAAE,qBAAqB,EAAE,MAAM,GAAG,OAAO,CA2B5F"}
1
+ {"version":3,"file":"isDataJsonNewer.d.ts","sourceRoot":"","sources":["../../src/utils/isDataJsonNewer.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,EAAE,qBAAqB,EAAE,MAAM,GAAG,OAAO,CAgC5F"}
@@ -1 +1 @@
1
- {"version":3,"file":"spreadsheetCreator.d.ts","sourceRoot":"","sources":["../../src/utils/spreadsheetCreator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAiB/C,MAAM,WAAW,wBAAwB;IACxC,+DAA+D;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8FAA8F;IAC9F,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mGAAmG;IACnG,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,mFAAmF;IACnF,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,sBAAsB;IACtC,aAAa,EAAE,MAAM,CAAC;IACtB,GAAG,EAAE,MAAM,CAAC;CACZ;AAiBD;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACtC,UAAU,EAAE,GAAG,EACf,OAAO,GAAE,wBAA6B,GACpC,OAAO,CAAC,sBAAsB,CAAC,CA8GjC"}
1
+ {"version":3,"file":"spreadsheetCreator.d.ts","sourceRoot":"","sources":["../../src/utils/spreadsheetCreator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AA8B/C,MAAM,WAAW,wBAAwB;IACxC,+DAA+D;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8FAA8F;IAC9F,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mGAAmG;IACnG,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,mFAAmF;IACnF,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,sBAAsB;IACtC,aAAa,EAAE,MAAM,CAAC;IACtB,GAAG,EAAE,MAAM,CAAC;CACZ;AAiBD;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACtC,UAAU,EAAE,GAAG,EACf,OAAO,GAAE,wBAA6B,GACpC,OAAO,CAAC,sBAAsB,CAAC,CAgHjC"}
@@ -6,11 +6,18 @@ import type { TranslationData } from "../types";
6
6
  * When autoTranslate is enabled:
7
7
  * - For each new key added to the spreadsheet, the system checks which languages have translations
8
8
  * - For languages missing translations, it automatically adds Google Translate formulas
9
- * - The formula format is: =GOOGLETRANSLATE(INDIRECT(sourceColumn&ROW());$sourceColumn$1;targetColumn$1)
9
+ * - The formula extracts the language prefix from the header cell (e.g. "tr-TR" → "tr") because
10
+ * GOOGLETRANSLATE only accepts ISO 639-1 codes for most languages
11
+ * - The formula format is:
12
+ * =GOOGLETRANSLATE(INDIRECT(sourceColumn&ROW());LOWER(IFERROR(LEFT($sourceColumn$1,FIND("-",$sourceColumn$1)-1),$sourceColumn$1));LOWER(IFERROR(LEFT(targetColumn$1,FIND("-",targetColumn$1)-1),targetColumn$1)))
10
13
  * - This dynamic formula uses cell references for language codes and automatically adapts to the correct row
11
14
  * - For **existing** keys the same logic applies: empty cells in other language columns receive a
12
15
  * formula; cells that already contain a translation are only overwritten when `override` is true.
13
16
  *
17
+ * A proactive inter-request delay of `waitSeconds` seconds is inserted between each
18
+ * individual row save and between each addRows chunk to avoid exceeding Google's
19
+ * "Write requests per minute per user" quota before a 429 is even returned.
20
+ *
14
21
  * If a sheet named `sheetTitle` does not yet exist in the document and `localeMapping` is
15
22
  * non-empty, the sheet is **created automatically** with "key" as the first column followed by
16
23
  * the original locale-header names from `localeMapping`. This ensures that new feature sheets
@@ -18,12 +25,13 @@ import type { TranslationData } from "../types";
18
25
  *
19
26
  * Example:
20
27
  * If a new key "welcome" has an English translation in column B but no German translation in column C,
21
- * and autoTranslate is enabled, the system will add:
22
- * =GOOGLETRANSLATE(INDIRECT("B"&ROW());$B$1;C$1) to the German column
28
+ * and autoTranslate is enabled, the system will add a formula that translates from English ("en")
29
+ * to the language code extracted from the German column header to the German column.
23
30
  *
24
31
  * @param doc - The Google Spreadsheet instance
25
32
  * @param changes - Object containing new keys to add to the spreadsheet
26
- * @param waitSeconds - Base back-off delay in seconds for retrying rate-limited API calls
33
+ * @param waitSeconds - Seconds to wait between consecutive write API calls (throttle) and as the
34
+ * base back-off delay when retrying rate-limited calls (HTTP 429/503). Must be ≥ 1.
27
35
  * @param autoTranslate - Whether to add Google Translate formulas for missing translations (default: false)
28
36
  * @param localeMapping - Mapping from normalized locale codes to original spreadsheet headers
29
37
  * @param override - When true AND autoTranslate is true, existing translations in other language
@@ -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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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"}
1
+ {"version":3,"file":"spreadsheetUpdater.d.ts","sourceRoot":"","sources":["../../src/utils/spreadsheetUpdater.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAA8B,MAAM,oBAAoB,CAAC;AACxF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAiChD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;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,CAiVf"}
@@ -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;;;;;;;;;;;;;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"}
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;AAQhD;;GAEG;AACH,MAAM,WAAW,UAAU;IAC1B,aAAa,EAAE,OAAO,CAAC;IACvB,UAAU,EAAE,OAAO,CAAC;CACpB;AA2BD;;;;;;;;;;;;;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,CA2ErB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@el-j/google-sheet-translations",
3
- "version": "2.1.1",
3
+ "version": "2.1.3",
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",
@@ -97,6 +97,9 @@
97
97
  "overrides": {
98
98
  "google-spreadsheet": {
99
99
  "google-auth-library": "^10.6.1"
100
+ },
101
+ "vite": {
102
+ "esbuild": "^0.25.0"
100
103
  }
101
104
  }
102
105
  }