@el-j/google-sheet-translations 2.1.2 → 2.1.4
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 +18 -5
- package/dist/index.js +18 -5
- package/dist/utils/configurationHandler.d.ts +4 -3
- package/dist/utils/configurationHandler.d.ts.map +1 -1
- package/dist/utils/spreadsheetCreator.d.ts.map +1 -1
- package/dist/utils/spreadsheetUpdater.d.ts +12 -4
- package/dist/utils/spreadsheetUpdater.d.ts.map +1 -1
- package/package.json +4 -1
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())
|
|
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())
|
|
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
|
}
|
|
@@ -975,6 +985,9 @@ function colLetter(index) {
|
|
|
975
985
|
} while (i >= 0);
|
|
976
986
|
return result;
|
|
977
987
|
}
|
|
988
|
+
function langCodeFormula2(cellRef) {
|
|
989
|
+
return `LOWER(IFERROR(LEFT(${cellRef},FIND("-",${cellRef})-1),${cellRef}))`;
|
|
990
|
+
}
|
|
978
991
|
var DEFAULT_TARGET_LOCALES = ["de", "fr", "es", "it", "pt", "ja", "zh"];
|
|
979
992
|
var STARTER_KEYS = {
|
|
980
993
|
"app.name": "My App",
|
|
@@ -1059,7 +1072,7 @@ async function createSpreadsheet(authClient, options = {}) {
|
|
|
1059
1072
|
const row = { key, [sourceLocale]: sourceValue };
|
|
1060
1073
|
targetLocales.forEach((locale, idx) => {
|
|
1061
1074
|
const targetColLetter = colLetter(2 + idx);
|
|
1062
|
-
row[locale] = `=GOOGLETRANSLATE(INDIRECT("${sourceColLetter}"&ROW())
|
|
1075
|
+
row[locale] = `=GOOGLETRANSLATE(INDIRECT("${sourceColLetter}"&ROW());${langCodeFormula2(`$${sourceColLetter}$1`)};${langCodeFormula2(`${targetColLetter}$1`)})`;
|
|
1063
1076
|
});
|
|
1064
1077
|
return row;
|
|
1065
1078
|
});
|
|
@@ -1235,10 +1248,10 @@ async function getSpreadSheetData(_docTitle, options = {}, _refreshDepth = 0) {
|
|
|
1235
1248
|
}
|
|
1236
1249
|
|
|
1237
1250
|
// src/utils/wait.ts
|
|
1238
|
-
import { setTimeout as
|
|
1251
|
+
import { setTimeout as delay3 } from "node:timers/promises";
|
|
1239
1252
|
function wait(seconds, reason) {
|
|
1240
1253
|
console.log("wait", seconds, reason);
|
|
1241
|
-
return
|
|
1254
|
+
return delay3(seconds * 1e3);
|
|
1242
1255
|
}
|
|
1243
1256
|
|
|
1244
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())
|
|
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())
|
|
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
|
}
|
|
@@ -1040,6 +1050,9 @@ function colLetter(index) {
|
|
|
1040
1050
|
} while (i >= 0);
|
|
1041
1051
|
return result;
|
|
1042
1052
|
}
|
|
1053
|
+
function langCodeFormula2(cellRef) {
|
|
1054
|
+
return `LOWER(IFERROR(LEFT(${cellRef},FIND("-",${cellRef})-1),${cellRef}))`;
|
|
1055
|
+
}
|
|
1043
1056
|
var DEFAULT_TARGET_LOCALES = ["de", "fr", "es", "it", "pt", "ja", "zh"];
|
|
1044
1057
|
var STARTER_KEYS = {
|
|
1045
1058
|
"app.name": "My App",
|
|
@@ -1124,7 +1137,7 @@ async function createSpreadsheet(authClient, options = {}) {
|
|
|
1124
1137
|
const row = { key, [sourceLocale]: sourceValue };
|
|
1125
1138
|
targetLocales.forEach((locale, idx) => {
|
|
1126
1139
|
const targetColLetter = colLetter(2 + idx);
|
|
1127
|
-
row[locale] = `=GOOGLETRANSLATE(INDIRECT("${sourceColLetter}"&ROW())
|
|
1140
|
+
row[locale] = `=GOOGLETRANSLATE(INDIRECT("${sourceColLetter}"&ROW());${langCodeFormula2(`$${sourceColLetter}$1`)};${langCodeFormula2(`${targetColLetter}$1`)})`;
|
|
1128
1141
|
});
|
|
1129
1142
|
return row;
|
|
1130
1143
|
});
|
|
@@ -1300,10 +1313,10 @@ async function getSpreadSheetData(_docTitle, options = {}, _refreshDepth = 0) {
|
|
|
1300
1313
|
}
|
|
1301
1314
|
|
|
1302
1315
|
// src/utils/wait.ts
|
|
1303
|
-
var
|
|
1316
|
+
var import_promises3 = require("node:timers/promises");
|
|
1304
1317
|
function wait(seconds, reason) {
|
|
1305
1318
|
console.log("wait", seconds, reason);
|
|
1306
|
-
return (0,
|
|
1319
|
+
return (0, import_promises3.setTimeout)(seconds * 1e3);
|
|
1307
1320
|
}
|
|
1308
1321
|
|
|
1309
1322
|
// src/utils/translationHelpers.ts
|
|
@@ -4,9 +4,10 @@
|
|
|
4
4
|
export interface SpreadsheetOptions {
|
|
5
5
|
rowLimit?: number;
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
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
|
|
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":"spreadsheetCreator.d.ts","sourceRoot":"","sources":["../../src/utils/spreadsheetCreator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;
|
|
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
|
|
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
|
-
*
|
|
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 -
|
|
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":"
|
|
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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@el-j/google-sheet-translations",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.4",
|
|
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",
|
|
@@ -100,6 +100,9 @@
|
|
|
100
100
|
},
|
|
101
101
|
"vite": {
|
|
102
102
|
"esbuild": "^0.25.0"
|
|
103
|
+
},
|
|
104
|
+
"@actions/http-client": {
|
|
105
|
+
"undici": "^7.0.0"
|
|
103
106
|
}
|
|
104
107
|
}
|
|
105
108
|
}
|