@el-j/google-sheet-translations 2.2.0-beta.2 → 2.2.0-beta.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
@@ -4,17 +4,24 @@ import path4 from "node:path";
4
4
  import { GoogleSpreadsheet as GoogleSpreadsheet2 } from "google-spreadsheet";
5
5
 
6
6
  // src/utils/auth.ts
7
- import { JWT } from "google-auth-library";
7
+ import { GoogleAuth } from "google-auth-library";
8
8
 
9
9
  // src/utils/validateEnv.ts
10
10
  function validateCredentials() {
11
+ if (process.env.GOOGLE_APPLICATION_CREDENTIALS) {
12
+ return {
13
+ GOOGLE_CLIENT_EMAIL: process.env.GOOGLE_CLIENT_EMAIL ?? "",
14
+ GOOGLE_PRIVATE_KEY: process.env.GOOGLE_PRIVATE_KEY ?? ""
15
+ };
16
+ }
11
17
  const requiredVars = ["GOOGLE_CLIENT_EMAIL", "GOOGLE_PRIVATE_KEY"];
12
18
  const missing = requiredVars.filter((v) => !process.env[v]);
13
19
  if (missing.length > 0) {
14
20
  throw new Error(
15
21
  `Missing required environment variables: ${missing.join(", ")}
16
22
 
17
- Make sure these are set in your .env file or environment.`
23
+ Make sure these are set in your .env file or environment.
24
+ Alternatively, set GOOGLE_APPLICATION_CREDENTIALS for Workload Identity Federation.`
18
25
  );
19
26
  }
20
27
  return {
@@ -23,6 +30,21 @@ Make sure these are set in your .env file or environment.`
23
30
  };
24
31
  }
25
32
  function validateEnv() {
33
+ const spreadsheetId = process.env.GOOGLE_SPREADSHEET_ID;
34
+ if (!spreadsheetId) {
35
+ throw new Error(
36
+ `Missing required environment variable: GOOGLE_SPREADSHEET_ID
37
+
38
+ Make sure this is set in your .env file or environment.`
39
+ );
40
+ }
41
+ if (process.env.GOOGLE_APPLICATION_CREDENTIALS) {
42
+ return {
43
+ GOOGLE_CLIENT_EMAIL: process.env.GOOGLE_CLIENT_EMAIL ?? "",
44
+ GOOGLE_PRIVATE_KEY: process.env.GOOGLE_PRIVATE_KEY ?? "",
45
+ GOOGLE_SPREADSHEET_ID: spreadsheetId
46
+ };
47
+ }
26
48
  const requiredVars = [
27
49
  "GOOGLE_CLIENT_EMAIL",
28
50
  "GOOGLE_PRIVATE_KEY",
@@ -33,24 +55,43 @@ function validateEnv() {
33
55
  throw new Error(
34
56
  `Missing required environment variables: ${missingVars.join(", ")}
35
57
 
36
- Make sure these are set in your .env file or environment.`
58
+ Make sure these are set in your .env file or environment.
59
+ Alternatively, set GOOGLE_APPLICATION_CREDENTIALS for Workload Identity Federation.`
37
60
  );
38
61
  }
39
62
  return {
40
63
  GOOGLE_CLIENT_EMAIL: process.env.GOOGLE_CLIENT_EMAIL,
41
64
  GOOGLE_PRIVATE_KEY: process.env.GOOGLE_PRIVATE_KEY,
42
- GOOGLE_SPREADSHEET_ID: process.env.GOOGLE_SPREADSHEET_ID
65
+ GOOGLE_SPREADSHEET_ID: spreadsheetId
43
66
  };
44
67
  }
45
68
 
46
69
  // src/utils/auth.ts
70
+ function normalizePrivateKey(key) {
71
+ let normalized = key;
72
+ const outer = key.trim();
73
+ if (outer.startsWith('"') && outer.endsWith('"') || outer.startsWith("'") && outer.endsWith("'")) {
74
+ normalized = outer.slice(1, -1);
75
+ }
76
+ normalized = normalized.replace(/\\n/g, "\n");
77
+ normalized = normalized.replace(/\r\n/g, "\n");
78
+ return normalized;
79
+ }
80
+ function buildGoogleAuth(scopes, credentials) {
81
+ if (credentials) {
82
+ return new GoogleAuth({ credentials, scopes });
83
+ }
84
+ return new GoogleAuth({ scopes });
85
+ }
47
86
  function createAuthClient() {
87
+ if (process.env.GOOGLE_APPLICATION_CREDENTIALS) {
88
+ return buildGoogleAuth(["https://www.googleapis.com/auth/spreadsheets"]);
89
+ }
48
90
  const { GOOGLE_CLIENT_EMAIL, GOOGLE_PRIVATE_KEY } = validateCredentials();
49
- const normalizedKey = GOOGLE_PRIVATE_KEY.replace(/\\n/g, "\n");
50
- return new JWT({
51
- email: GOOGLE_CLIENT_EMAIL,
52
- key: normalizedKey,
53
- scopes: ["https://www.googleapis.com/auth/spreadsheets"]
91
+ const normalizedKey = normalizePrivateKey(GOOGLE_PRIVATE_KEY);
92
+ return buildGoogleAuth(["https://www.googleapis.com/auth/spreadsheets"], {
93
+ client_email: GOOGLE_CLIENT_EMAIL,
94
+ private_key: normalizedKey
54
95
  });
55
96
  }
56
97
 
@@ -1037,7 +1078,6 @@ async function createSpreadsheet(authClient, options = {}) {
1037
1078
  targetLocales = DEFAULT_TARGET_LOCALES,
1038
1079
  seedKeys = STARTER_KEYS
1039
1080
  } = options;
1040
- await authClient.authorize();
1041
1081
  const createRes = await withRetry(
1042
1082
  () => authClient.request({
1043
1083
  url: "https://sheets.googleapis.com/v4/spreadsheets",
@@ -1359,23 +1399,22 @@ async function getMultipleSpreadSheetsData(docTitles, options = {}) {
1359
1399
  }
1360
1400
 
1361
1401
  // src/utils/driveFolderScanner.ts
1362
- import { GoogleAuth } from "google-auth-library";
1363
1402
  var SPREADSHEET_MIME = "application/vnd.google-apps.spreadsheet";
1364
1403
  var FOLDER_MIME = "application/vnd.google-apps.folder";
1365
1404
  var DRIVE_FILES_URL = "https://www.googleapis.com/drive/v3/files";
1405
+ var DRIVE_SCOPES = ["https://www.googleapis.com/auth/drive.readonly"];
1366
1406
  async function getAccessToken(credentials) {
1367
1407
  const clientEmail = credentials?.GOOGLE_CLIENT_EMAIL ?? process.env.GOOGLE_CLIENT_EMAIL;
1368
1408
  const privateKey = credentials?.GOOGLE_PRIVATE_KEY ?? process.env.GOOGLE_PRIVATE_KEY;
1369
- if (!clientEmail || !privateKey) {
1409
+ let driveCredentials;
1410
+ if (clientEmail && privateKey) {
1411
+ driveCredentials = { client_email: clientEmail, private_key: normalizePrivateKey(privateKey) };
1412
+ } else if (!process.env.GOOGLE_APPLICATION_CREDENTIALS) {
1370
1413
  throw new Error(
1371
- "Google Drive credentials required: GOOGLE_CLIENT_EMAIL and GOOGLE_PRIVATE_KEY"
1414
+ "Google Drive credentials required: set GOOGLE_CLIENT_EMAIL and GOOGLE_PRIVATE_KEY, or set GOOGLE_APPLICATION_CREDENTIALS for Workload Identity Federation."
1372
1415
  );
1373
1416
  }
1374
- const normalizedKey = privateKey.replace(/\\n/g, "\n");
1375
- const auth = new GoogleAuth({
1376
- credentials: { client_email: clientEmail, private_key: normalizedKey },
1377
- scopes: ["https://www.googleapis.com/auth/drive.readonly"]
1378
- });
1417
+ const auth = buildGoogleAuth(DRIVE_SCOPES, driveCredentials);
1379
1418
  const client = await auth.getClient();
1380
1419
  const tokenResponse = await client.getAccessToken();
1381
1420
  return tokenResponse.token;
@@ -1450,7 +1489,6 @@ import { createWriteStream, mkdirSync, existsSync, readdirSync, unlinkSync, stat
1450
1489
  import { join, dirname } from "node:path";
1451
1490
  import { pipeline } from "node:stream/promises";
1452
1491
  import { Readable } from "node:stream";
1453
- import { GoogleAuth as GoogleAuth2 } from "google-auth-library";
1454
1492
  var DEFAULT_IMAGE_MIME_TYPES = [
1455
1493
  "image/jpeg",
1456
1494
  "image/jpg",
@@ -1474,19 +1512,19 @@ function normalizeExtension(name) {
1474
1512
  if (ext === "jpeg") ext = "jpg";
1475
1513
  return `${base}.${ext}`;
1476
1514
  }
1515
+ var DRIVE_SCOPES2 = ["https://www.googleapis.com/auth/drive.readonly"];
1477
1516
  async function getAccessToken2(credentials) {
1478
1517
  const clientEmail = credentials?.GOOGLE_CLIENT_EMAIL ?? process.env.GOOGLE_CLIENT_EMAIL;
1479
1518
  const privateKey = credentials?.GOOGLE_PRIVATE_KEY ?? process.env.GOOGLE_PRIVATE_KEY;
1480
- if (!clientEmail || !privateKey) {
1519
+ let driveCredentials;
1520
+ if (clientEmail && privateKey) {
1521
+ driveCredentials = { client_email: clientEmail, private_key: normalizePrivateKey(privateKey) };
1522
+ } else if (!process.env.GOOGLE_APPLICATION_CREDENTIALS) {
1481
1523
  throw new Error(
1482
- "Google Drive credentials required: GOOGLE_CLIENT_EMAIL and GOOGLE_PRIVATE_KEY"
1524
+ "Google Drive credentials required: set GOOGLE_CLIENT_EMAIL and GOOGLE_PRIVATE_KEY, or set GOOGLE_APPLICATION_CREDENTIALS for Workload Identity Federation."
1483
1525
  );
1484
1526
  }
1485
- const normalizedKey = privateKey.replace(/\\n/g, "\n");
1486
- const auth = new GoogleAuth2({
1487
- credentials: { client_email: clientEmail, private_key: normalizedKey },
1488
- scopes: ["https://www.googleapis.com/auth/drive.readonly"]
1489
- });
1527
+ const auth = buildGoogleAuth(DRIVE_SCOPES2, driveCredentials);
1490
1528
  const client = await auth.getClient();
1491
1529
  const tokenResponse = await client.getAccessToken();
1492
1530
  return tokenResponse.token;
@@ -1912,6 +1950,7 @@ var index_default = getSpreadSheetData;
1912
1950
  export {
1913
1951
  DEFAULT_IMAGE_EXTENSIONS,
1914
1952
  DEFAULT_WAIT_SECONDS,
1953
+ buildGoogleAuth,
1915
1954
  buildManifest,
1916
1955
  convertFromDataJsonFormat,
1917
1956
  convertToDataJsonFormat,
@@ -1936,6 +1975,7 @@ export {
1936
1975
  mergeSheets,
1937
1976
  normalizeExtension,
1938
1977
  normalizeLocaleCode,
1978
+ normalizePrivateKey,
1939
1979
  processRawRows,
1940
1980
  readPublicSheet,
1941
1981
  resolveLocaleWithFallback,
package/dist/index.d.ts CHANGED
@@ -7,7 +7,7 @@ export type { SpreadsheetOptions } from './utils/configurationHandler';
7
7
  export { wait } from './utils/wait';
8
8
  export { withRetry } from './utils/rateLimiter';
9
9
  export { validateEnv } from './utils/validateEnv';
10
- export { createAuthClient } from './utils/auth';
10
+ export { createAuthClient, buildGoogleAuth, normalizePrivateKey } from './utils/auth';
11
11
  export { convertToDataJsonFormat } from './utils/dataConverter/convertToDataJsonFormat';
12
12
  export { convertFromDataJsonFormat } from './utils/dataConverter/convertFromDataJsonFormat';
13
13
  export { findLocalChanges } from './utils/dataConverter/findLocalChanges';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAGhF,YAAY,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAGvE,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,uBAAuB,EAAE,MAAM,+CAA+C,CAAC;AACxF,OAAO,EAAE,yBAAyB,EAAE,MAAM,iDAAiD,CAAC;AAC5F,OAAO,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAC;AAC1E,OAAO,EAAE,iCAAiC,EAAE,MAAM,4BAA4B,CAAC;AAG/E,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAG5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAG1D,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAGzE,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,mBAAmB,EACnB,mBAAmB,EACnB,0BAA0B,EAC1B,4BAA4B,EAC5B,yBAAyB,GAC1B,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,YAAY,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAGpE,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACtG,YAAY,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAGnF,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAGpG,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,YAAY,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGtD,YAAY,EACV,eAAe,EACf,gBAAgB,EAChB,QAAQ,EACR,aAAa,GACd,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,2BAA2B,EAAE,MAAM,+BAA+B,CAAC;AAC5E,YAAY,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AAC7E,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAG9E,OAAO,EAAE,8BAA8B,EAAE,MAAM,4BAA4B,CAAC;AAC5E,YAAY,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AAG/F,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC7E,YAAY,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC1F,OAAO,EAAE,aAAa,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAC1G,YAAY,EACV,oBAAoB,EACpB,+BAA+B,EAC/B,8BAA8B,GAC/B,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,YAAY,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AAGxG,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AACzE,YAAY,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAGtH,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,eAAe,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -32,6 +32,7 @@ var index_exports = {};
32
32
  __export(index_exports, {
33
33
  DEFAULT_IMAGE_EXTENSIONS: () => DEFAULT_IMAGE_EXTENSIONS,
34
34
  DEFAULT_WAIT_SECONDS: () => DEFAULT_WAIT_SECONDS,
35
+ buildGoogleAuth: () => buildGoogleAuth,
35
36
  buildManifest: () => buildManifest,
36
37
  convertFromDataJsonFormat: () => convertFromDataJsonFormat,
37
38
  convertToDataJsonFormat: () => convertToDataJsonFormat,
@@ -56,6 +57,7 @@ __export(index_exports, {
56
57
  mergeSheets: () => mergeSheets,
57
58
  normalizeExtension: () => normalizeExtension,
58
59
  normalizeLocaleCode: () => normalizeLocaleCode,
60
+ normalizePrivateKey: () => normalizePrivateKey,
59
61
  processRawRows: () => processRawRows,
60
62
  readPublicSheet: () => readPublicSheet,
61
63
  resolveLocaleWithFallback: () => resolveLocaleWithFallback,
@@ -85,13 +87,20 @@ var import_google_auth_library = require("google-auth-library");
85
87
 
86
88
  // src/utils/validateEnv.ts
87
89
  function validateCredentials() {
90
+ if (process.env.GOOGLE_APPLICATION_CREDENTIALS) {
91
+ return {
92
+ GOOGLE_CLIENT_EMAIL: process.env.GOOGLE_CLIENT_EMAIL ?? "",
93
+ GOOGLE_PRIVATE_KEY: process.env.GOOGLE_PRIVATE_KEY ?? ""
94
+ };
95
+ }
88
96
  const requiredVars = ["GOOGLE_CLIENT_EMAIL", "GOOGLE_PRIVATE_KEY"];
89
97
  const missing = requiredVars.filter((v) => !process.env[v]);
90
98
  if (missing.length > 0) {
91
99
  throw new Error(
92
100
  `Missing required environment variables: ${missing.join(", ")}
93
101
 
94
- Make sure these are set in your .env file or environment.`
102
+ Make sure these are set in your .env file or environment.
103
+ Alternatively, set GOOGLE_APPLICATION_CREDENTIALS for Workload Identity Federation.`
95
104
  );
96
105
  }
97
106
  return {
@@ -100,6 +109,21 @@ Make sure these are set in your .env file or environment.`
100
109
  };
101
110
  }
102
111
  function validateEnv() {
112
+ const spreadsheetId = process.env.GOOGLE_SPREADSHEET_ID;
113
+ if (!spreadsheetId) {
114
+ throw new Error(
115
+ `Missing required environment variable: GOOGLE_SPREADSHEET_ID
116
+
117
+ Make sure this is set in your .env file or environment.`
118
+ );
119
+ }
120
+ if (process.env.GOOGLE_APPLICATION_CREDENTIALS) {
121
+ return {
122
+ GOOGLE_CLIENT_EMAIL: process.env.GOOGLE_CLIENT_EMAIL ?? "",
123
+ GOOGLE_PRIVATE_KEY: process.env.GOOGLE_PRIVATE_KEY ?? "",
124
+ GOOGLE_SPREADSHEET_ID: spreadsheetId
125
+ };
126
+ }
103
127
  const requiredVars = [
104
128
  "GOOGLE_CLIENT_EMAIL",
105
129
  "GOOGLE_PRIVATE_KEY",
@@ -110,24 +134,43 @@ function validateEnv() {
110
134
  throw new Error(
111
135
  `Missing required environment variables: ${missingVars.join(", ")}
112
136
 
113
- Make sure these are set in your .env file or environment.`
137
+ Make sure these are set in your .env file or environment.
138
+ Alternatively, set GOOGLE_APPLICATION_CREDENTIALS for Workload Identity Federation.`
114
139
  );
115
140
  }
116
141
  return {
117
142
  GOOGLE_CLIENT_EMAIL: process.env.GOOGLE_CLIENT_EMAIL,
118
143
  GOOGLE_PRIVATE_KEY: process.env.GOOGLE_PRIVATE_KEY,
119
- GOOGLE_SPREADSHEET_ID: process.env.GOOGLE_SPREADSHEET_ID
144
+ GOOGLE_SPREADSHEET_ID: spreadsheetId
120
145
  };
121
146
  }
122
147
 
123
148
  // src/utils/auth.ts
149
+ function normalizePrivateKey(key) {
150
+ let normalized = key;
151
+ const outer = key.trim();
152
+ if (outer.startsWith('"') && outer.endsWith('"') || outer.startsWith("'") && outer.endsWith("'")) {
153
+ normalized = outer.slice(1, -1);
154
+ }
155
+ normalized = normalized.replace(/\\n/g, "\n");
156
+ normalized = normalized.replace(/\r\n/g, "\n");
157
+ return normalized;
158
+ }
159
+ function buildGoogleAuth(scopes, credentials) {
160
+ if (credentials) {
161
+ return new import_google_auth_library.GoogleAuth({ credentials, scopes });
162
+ }
163
+ return new import_google_auth_library.GoogleAuth({ scopes });
164
+ }
124
165
  function createAuthClient() {
166
+ if (process.env.GOOGLE_APPLICATION_CREDENTIALS) {
167
+ return buildGoogleAuth(["https://www.googleapis.com/auth/spreadsheets"]);
168
+ }
125
169
  const { GOOGLE_CLIENT_EMAIL, GOOGLE_PRIVATE_KEY } = validateCredentials();
126
- const normalizedKey = GOOGLE_PRIVATE_KEY.replace(/\\n/g, "\n");
127
- return new import_google_auth_library.JWT({
128
- email: GOOGLE_CLIENT_EMAIL,
129
- key: normalizedKey,
130
- scopes: ["https://www.googleapis.com/auth/spreadsheets"]
170
+ const normalizedKey = normalizePrivateKey(GOOGLE_PRIVATE_KEY);
171
+ return buildGoogleAuth(["https://www.googleapis.com/auth/spreadsheets"], {
172
+ client_email: GOOGLE_CLIENT_EMAIL,
173
+ private_key: normalizedKey
131
174
  });
132
175
  }
133
176
 
@@ -1114,7 +1157,6 @@ async function createSpreadsheet(authClient, options = {}) {
1114
1157
  targetLocales = DEFAULT_TARGET_LOCALES,
1115
1158
  seedKeys = STARTER_KEYS
1116
1159
  } = options;
1117
- await authClient.authorize();
1118
1160
  const createRes = await withRetry(
1119
1161
  () => authClient.request({
1120
1162
  url: "https://sheets.googleapis.com/v4/spreadsheets",
@@ -1436,23 +1478,22 @@ async function getMultipleSpreadSheetsData(docTitles, options = {}) {
1436
1478
  }
1437
1479
 
1438
1480
  // src/utils/driveFolderScanner.ts
1439
- var import_google_auth_library2 = require("google-auth-library");
1440
1481
  var SPREADSHEET_MIME = "application/vnd.google-apps.spreadsheet";
1441
1482
  var FOLDER_MIME = "application/vnd.google-apps.folder";
1442
1483
  var DRIVE_FILES_URL = "https://www.googleapis.com/drive/v3/files";
1484
+ var DRIVE_SCOPES = ["https://www.googleapis.com/auth/drive.readonly"];
1443
1485
  async function getAccessToken(credentials) {
1444
1486
  const clientEmail = credentials?.GOOGLE_CLIENT_EMAIL ?? process.env.GOOGLE_CLIENT_EMAIL;
1445
1487
  const privateKey = credentials?.GOOGLE_PRIVATE_KEY ?? process.env.GOOGLE_PRIVATE_KEY;
1446
- if (!clientEmail || !privateKey) {
1488
+ let driveCredentials;
1489
+ if (clientEmail && privateKey) {
1490
+ driveCredentials = { client_email: clientEmail, private_key: normalizePrivateKey(privateKey) };
1491
+ } else if (!process.env.GOOGLE_APPLICATION_CREDENTIALS) {
1447
1492
  throw new Error(
1448
- "Google Drive credentials required: GOOGLE_CLIENT_EMAIL and GOOGLE_PRIVATE_KEY"
1493
+ "Google Drive credentials required: set GOOGLE_CLIENT_EMAIL and GOOGLE_PRIVATE_KEY, or set GOOGLE_APPLICATION_CREDENTIALS for Workload Identity Federation."
1449
1494
  );
1450
1495
  }
1451
- const normalizedKey = privateKey.replace(/\\n/g, "\n");
1452
- const auth = new import_google_auth_library2.GoogleAuth({
1453
- credentials: { client_email: clientEmail, private_key: normalizedKey },
1454
- scopes: ["https://www.googleapis.com/auth/drive.readonly"]
1455
- });
1496
+ const auth = buildGoogleAuth(DRIVE_SCOPES, driveCredentials);
1456
1497
  const client = await auth.getClient();
1457
1498
  const tokenResponse = await client.getAccessToken();
1458
1499
  return tokenResponse.token;
@@ -1527,7 +1568,6 @@ var import_node_fs6 = require("node:fs");
1527
1568
  var import_node_path5 = require("node:path");
1528
1569
  var import_promises4 = require("node:stream/promises");
1529
1570
  var import_node_stream = require("node:stream");
1530
- var import_google_auth_library3 = require("google-auth-library");
1531
1571
  var DEFAULT_IMAGE_MIME_TYPES = [
1532
1572
  "image/jpeg",
1533
1573
  "image/jpg",
@@ -1551,19 +1591,19 @@ function normalizeExtension(name) {
1551
1591
  if (ext === "jpeg") ext = "jpg";
1552
1592
  return `${base}.${ext}`;
1553
1593
  }
1594
+ var DRIVE_SCOPES2 = ["https://www.googleapis.com/auth/drive.readonly"];
1554
1595
  async function getAccessToken2(credentials) {
1555
1596
  const clientEmail = credentials?.GOOGLE_CLIENT_EMAIL ?? process.env.GOOGLE_CLIENT_EMAIL;
1556
1597
  const privateKey = credentials?.GOOGLE_PRIVATE_KEY ?? process.env.GOOGLE_PRIVATE_KEY;
1557
- if (!clientEmail || !privateKey) {
1598
+ let driveCredentials;
1599
+ if (clientEmail && privateKey) {
1600
+ driveCredentials = { client_email: clientEmail, private_key: normalizePrivateKey(privateKey) };
1601
+ } else if (!process.env.GOOGLE_APPLICATION_CREDENTIALS) {
1558
1602
  throw new Error(
1559
- "Google Drive credentials required: GOOGLE_CLIENT_EMAIL and GOOGLE_PRIVATE_KEY"
1603
+ "Google Drive credentials required: set GOOGLE_CLIENT_EMAIL and GOOGLE_PRIVATE_KEY, or set GOOGLE_APPLICATION_CREDENTIALS for Workload Identity Federation."
1560
1604
  );
1561
1605
  }
1562
- const normalizedKey = privateKey.replace(/\\n/g, "\n");
1563
- const auth = new import_google_auth_library3.GoogleAuth({
1564
- credentials: { client_email: clientEmail, private_key: normalizedKey },
1565
- scopes: ["https://www.googleapis.com/auth/drive.readonly"]
1566
- });
1606
+ const auth = buildGoogleAuth(DRIVE_SCOPES2, driveCredentials);
1567
1607
  const client = await auth.getClient();
1568
1608
  const tokenResponse = await client.getAccessToken();
1569
1609
  return tokenResponse.token;
@@ -1990,6 +2030,7 @@ var index_default = getSpreadSheetData;
1990
2030
  0 && (module.exports = {
1991
2031
  DEFAULT_IMAGE_EXTENSIONS,
1992
2032
  DEFAULT_WAIT_SECONDS,
2033
+ buildGoogleAuth,
1993
2034
  buildManifest,
1994
2035
  convertFromDataJsonFormat,
1995
2036
  convertToDataJsonFormat,
@@ -2013,6 +2054,7 @@ var index_default = getSpreadSheetData;
2013
2054
  mergeSheets,
2014
2055
  normalizeExtension,
2015
2056
  normalizeLocaleCode,
2057
+ normalizePrivateKey,
2016
2058
  processRawRows,
2017
2059
  readPublicSheet,
2018
2060
  resolveLocaleWithFallback,
@@ -1,8 +1,48 @@
1
- import { JWT } from "google-auth-library";
1
+ import { GoogleAuth } from "google-auth-library";
2
2
  /**
3
- * Creates and returns a JWT auth client for Google Sheets API
4
- * @returns JWT authentication client
3
+ * Normalizes a private key string from the many different ways secret-storage
4
+ * systems (GitHub Secrets, CI env vars, secret managers) encode it.
5
+ *
6
+ * Handles all of the following formats so the caller doesn't need to care
7
+ * whether the value came from a GitHub Secret, a plain env var, a `.env` file
8
+ * or any other source:
9
+ *
10
+ * - Real newlines → left as-is
11
+ * - Literal `\n` two-char sequences → converted to real newlines
12
+ * - Surrounding double or single quotes added by some tools → stripped
13
+ * (leading/trailing whitespace outside the quotes is also stripped)
14
+ * - Windows-style `\r\n` line endings → normalised to `\n`
5
15
  */
6
- export declare function createAuthClient(): JWT;
16
+ export declare function normalizePrivateKey(key: string): string;
17
+ /**
18
+ * Low-level factory: creates a `GoogleAuth` instance for a given set of scopes.
19
+ *
20
+ * - When `credentials` are supplied, uses them directly (service-account key mode).
21
+ * - When `credentials` is omitted, the instance relies on Application Default
22
+ * Credentials, i.e. the file pointed to by `GOOGLE_APPLICATION_CREDENTIALS`
23
+ * (Workload Identity Federation, `gcloud auth application-default login`, etc.).
24
+ *
25
+ * @internal Shared by Drive utilities and `createAuthClient()`. Import
26
+ * `createAuthClient()` for the standard Sheets use-case.
27
+ */
28
+ export declare function buildGoogleAuth(scopes: string[], credentials?: {
29
+ client_email: string;
30
+ private_key: string;
31
+ }): GoogleAuth;
32
+ /**
33
+ * Creates and returns a GoogleAuth client for Google Sheets API.
34
+ *
35
+ * Supports two authentication modes (checked in order):
36
+ *
37
+ * 1. **Workload Identity Federation / Application Default Credentials (ADC)**:
38
+ * Set `GOOGLE_APPLICATION_CREDENTIALS` to the path of a credential JSON file
39
+ * (e.g. written by `google-github-actions/auth`). No service-account key needed.
40
+ *
41
+ * 2. **Service account key** (classic):
42
+ * Set `GOOGLE_CLIENT_EMAIL` and `GOOGLE_PRIVATE_KEY` environment variables.
43
+ *
44
+ * @returns GoogleAuth client usable with google-spreadsheet and other Google APIs
45
+ */
46
+ export declare function createAuthClient(): GoogleAuth;
7
47
  export default createAuthClient;
8
48
  //# sourceMappingURL=auth.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/utils/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAG1C;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,GAAG,CAatC;AAED,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/utils/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGjD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAuBvD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC9B,MAAM,EAAE,MAAM,EAAE,EAChB,WAAW,CAAC,EAAE;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GACzD,UAAU,CAKZ;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,IAAI,UAAU,CAmB7C;AAED,eAAe,gBAAgB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"driveFolderScanner.d.ts","sourceRoot":"","sources":["../../src/utils/driveFolderScanner.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,sBAAsB;IACrC,qCAAqC;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,2EAA2E;IAC3E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kEAAkE;IAClE,WAAW,CAAC,EAAE,aAAa,CAAC;CAC7B;AA8HD;;;;GAIG;AACH,wBAAsB,8BAA8B,CAClD,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAKjC"}
1
+ {"version":3,"file":"driveFolderScanner.d.ts","sourceRoot":"","sources":["../../src/utils/driveFolderScanner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAG9C,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,sBAAsB;IACrC,qCAAqC;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,2EAA2E;IAC3E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kEAAkE;IAClE,WAAW,CAAC,EAAE,aAAa,CAAC;CAC7B;AAgID;;;;GAIG;AACH,wBAAsB,8BAA8B,CAClD,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAKjC"}
@@ -1 +1 @@
1
- {"version":3,"file":"driveImageSync.d.ts","sourceRoot":"","sources":["../../src/utils/driveImageSync.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,MAAM,WAAW,qBAAqB;IACpC,sDAAsD;IACtD,QAAQ,EAAE,MAAM,CAAC;IACjB,2EAA2E;IAC3E,UAAU,EAAE,MAAM,CAAC;IACnB,+EAA+E;IAC/E,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,6DAA6D;IAC7D,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kEAAkE;IAClE,WAAW,CAAC,EAAE,aAAa,CAAC;IAC5B,iFAAiF;IACjF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,4CAA4C;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;;;OAMG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAwCD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAOvD;AAyJD;;;;;;;;;;;GAWG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,oBAAoB,CAAC,CA4F/B"}
1
+ {"version":3,"file":"driveImageSync.d.ts","sourceRoot":"","sources":["../../src/utils/driveImageSync.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAG9C,MAAM,WAAW,qBAAqB;IACpC,sDAAsD;IACtD,QAAQ,EAAE,MAAM,CAAC;IACjB,2EAA2E;IAC3E,UAAU,EAAE,MAAM,CAAC;IACnB,+EAA+E;IAC/E,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,6DAA6D;IAC7D,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kEAAkE;IAClE,WAAW,CAAC,EAAE,aAAa,CAAC;IAC5B,iFAAiF;IACjF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,4CAA4C;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;;;OAMG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAwCD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAOvD;AA2JD;;;;;;;;;;;GAWG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,oBAAoB,CAAC,CA4F/B"}
@@ -1,4 +1,4 @@
1
- import type { JWT } from "google-auth-library";
1
+ import type { GoogleAuth } from "google-auth-library";
2
2
  export interface CreateSpreadsheetOptions {
3
3
  /** Spreadsheet title (default: "google-sheet-translations") */
4
4
  title?: string;
@@ -19,5 +19,5 @@ export interface CreatedSpreadsheetInfo {
19
19
  *
20
20
  * Returns the spreadsheet ID and URL.
21
21
  */
22
- export declare function createSpreadsheet(authClient: JWT, options?: CreateSpreadsheetOptions): Promise<CreatedSpreadsheetInfo>;
22
+ export declare function createSpreadsheet(authClient: GoogleAuth, options?: CreateSpreadsheetOptions): Promise<CreatedSpreadsheetInfo>;
23
23
  //# sourceMappingURL=spreadsheetCreator.d.ts.map
@@ -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;AA2C/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,CAmHjC"}
1
+ {"version":3,"file":"spreadsheetCreator.d.ts","sourceRoot":"","sources":["../../src/utils/spreadsheetCreator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AA2CtD,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,UAAU,EACtB,OAAO,GAAE,wBAA6B,GACpC,OAAO,CAAC,sBAAsB,CAAC,CAkHjC"}
@@ -1,12 +1,16 @@
1
1
  import type { GoogleEnvVars } from "../types";
2
2
  /**
3
- * Validates that the Google service-account credentials are present.
3
+ * Validates that Google service-account credentials are present.
4
4
  * Does NOT require GOOGLE_SPREADSHEET_ID — the caller may create one on first run.
5
+ *
6
+ * When `GOOGLE_APPLICATION_CREDENTIALS` is set (Workload Identity Federation / ADC),
7
+ * `GOOGLE_CLIENT_EMAIL` and `GOOGLE_PRIVATE_KEY` are not required.
5
8
  */
6
9
  export declare function validateCredentials(): Pick<GoogleEnvVars, 'GOOGLE_CLIENT_EMAIL' | 'GOOGLE_PRIVATE_KEY'>;
7
10
  /**
8
- * Validates all three required Google Sheets environment variables.
9
- * Throws if any are missing.
11
+ * Validates all Google Sheets environment variables, including the spreadsheet ID.
12
+ * Throws if GOOGLE_SPREADSHEET_ID is missing, or if neither service-account key
13
+ * credentials nor GOOGLE_APPLICATION_CREDENTIALS (WIF/ADC) are set.
10
14
  */
11
15
  export declare function validateEnv(): GoogleEnvVars;
12
16
  export default validateEnv;
@@ -1 +1 @@
1
- {"version":3,"file":"validateEnv.d.ts","sourceRoot":"","sources":["../../src/utils/validateEnv.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAAC,aAAa,EAAE,qBAAqB,GAAG,oBAAoB,CAAC,CAYvG;AAED;;;GAGG;AACH,wBAAgB,WAAW,IAAI,aAAa,CAiB3C;AAED,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"validateEnv.d.ts","sourceRoot":"","sources":["../../src/utils/validateEnv.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C;;;;;;GAMG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAAC,aAAa,EAAE,qBAAqB,GAAG,oBAAoB,CAAC,CAoBvG;AAED;;;;GAIG;AACH,wBAAgB,WAAW,IAAI,aAAa,CAiC3C;AAED,eAAe,WAAW,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@el-j/google-sheet-translations",
3
- "version": "2.2.0-beta.2",
3
+ "version": "2.2.0-beta.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",
@@ -30,7 +30,7 @@
30
30
  "clean": "rimraf dist",
31
31
  "prebuild": "npm run clean",
32
32
  "prepare": "npm run build",
33
- "test": "jest",
33
+ "test": "vitest run --coverage",
34
34
  "lint": "eslint src/ --ext .ts --max-warnings 0",
35
35
  "dev": "tsc --watch",
36
36
  "release": "semantic-release",
@@ -38,7 +38,7 @@
38
38
  "docs:dev": "vitepress dev website",
39
39
  "docs:build": "vitepress build website",
40
40
  "docs:preview": "vitepress preview website",
41
- "test:integration": "INTEGRATION=true jest --testPathPatterns=integration --testTimeout=60000 --coverage=false",
41
+ "test:integration": "INTEGRATION=true vitest run tests/integration --testTimeout=60000",
42
42
  "sync:translations": "node scripts/sync-demo-translations.mjs",
43
43
  "changelog:preview": "node scripts/changelog-preview.mjs"
44
44
  },
@@ -61,7 +61,7 @@
61
61
  "license": "MIT",
62
62
  "dependencies": {
63
63
  "@actions/core": "^3.0.0",
64
- "google-auth-library": "^10.6.1",
64
+ "google-auth-library": "^10.6.2",
65
65
  "google-spreadsheet": "^5.2.0"
66
66
  },
67
67
  "peerDependencies": {
@@ -75,29 +75,29 @@
75
75
  "@semantic-release/github": "^12.0.6",
76
76
  "@semantic-release/npm": "^13.1.5",
77
77
  "@semantic-release/release-notes-generator": "^14.1.0",
78
- "@types/jest": "^30.0.0",
79
- "@types/node": "^25.5.0",
80
- "@typescript-eslint/eslint-plugin": "^8.57.0",
81
- "@typescript-eslint/parser": "^8.57.0",
82
- "esbuild": "^0.27.4",
83
- "conventional-changelog-conventionalcommits": "^9.3.0",
84
- "dotenv": "17.3.1",
85
- "eslint": "^10.0.3",
86
- "jest": "^30.3.0",
87
- "jest-mock-extended": "^4.0.0",
78
+ "@types/node": "^25.5.1",
79
+ "@typescript-eslint/eslint-plugin": "^8.58.0",
80
+ "@typescript-eslint/parser": "^8.58.0",
81
+ "@vitest/coverage-v8": "^4.1.2",
82
+ "conventional-changelog-conventionalcommits": "^9.3.1",
83
+ "dotenv": "17.4.0",
84
+ "esbuild": "^0.28.0",
85
+ "eslint": "^10.1.0",
86
+ "npm-check-updates": "^20.0.0",
88
87
  "rimraf": "^6.1.3",
89
88
  "semantic-release": "^25.0.3",
90
- "ts-jest": "^29.4.6",
91
89
  "ts-node": "^10.9.2",
92
- "typescript": "^5.9.3",
93
- "vitepress": "^1.6.4"
90
+ "typescript": "^6.0.2",
91
+ "vitepress": "^1.6.4",
92
+ "vitest": "^4.1.2",
93
+ "vitest-mock-extended": "^3.1.1"
94
94
  },
95
95
  "engines": {
96
96
  "node": ">=18.0.0"
97
97
  },
98
98
  "overrides": {
99
99
  "google-spreadsheet": {
100
- "google-auth-library": "^10.6.1"
100
+ "google-auth-library": "^10.6.2"
101
101
  },
102
102
  "vite": {
103
103
  "esbuild": "^0.25.0"