@el-j/google-sheet-translations 3.0.0-beta.2 → 3.0.0-beta.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 CHANGED
@@ -10,6 +10,7 @@ import { Readable } from "node:stream";
10
10
  import fs$1 from "node:fs/promises";
11
11
  import { parse } from "csv-parse/sync";
12
12
  import crypto from "node:crypto";
13
+ import nacl from "tweetnacl";
13
14
  //#region src/utils/validateEnv.ts
14
15
  /**
15
16
  * Validates that Google service-account credentials are present.
@@ -3260,6 +3261,448 @@ function createCryptPadCsvInputProvider(options, depsOverrides = {}) {
3260
3261
  };
3261
3262
  }
3262
3263
  //#endregion
3264
+ //#region src/providers/cryptpad/crypto.ts
3265
+ /** Decodes CryptPad base64 string (which may have '-' instead of '/' and no padding). */
3266
+ function b64Decode(str) {
3267
+ let s = str.replace(/-/g, "/");
3268
+ const pad = s.length % 4;
3269
+ if (pad) s += "=".repeat(4 - pad);
3270
+ return new Uint8Array(Buffer.from(s, "base64"));
3271
+ }
3272
+ /** Decodes UTF-8 string to Uint8Array. */
3273
+ function decodeUTF8(str) {
3274
+ return new Uint8Array(Buffer.from(str, "utf8"));
3275
+ }
3276
+ /** Encodes Uint8Array to UTF-8 string. */
3277
+ function encodeUTF8(bytes) {
3278
+ return Buffer.from(bytes).toString("utf8");
3279
+ }
3280
+ /**
3281
+ * Parses a CryptPad URL and extracts the app type, mode, seed, and whether it requires a password.
3282
+ * Format: https://{host}/{app}/#/{version}/{app}/{mode}/{seed}[/p/]
3283
+ */
3284
+ function parsePadUrl(url) {
3285
+ let urlObj;
3286
+ try {
3287
+ urlObj = new URL(url);
3288
+ } catch {
3289
+ throw new Error(`Invalid CryptPad URL: "${url}"`);
3290
+ }
3291
+ const match = urlObj.hash.match(/#\/(\d+)\/([^/]+)\/([^/]+)\/([^/]+)(\/p\/)?/);
3292
+ if (!match) throw new Error(`Unsupported CryptPad URL format: "${url}". Expected "#/<version>/<app>/<mode>/<seed>[/p/]"`);
3293
+ const [, versionStr, app, modeRaw, seed, passwordFlag] = match;
3294
+ const mode = modeRaw === "edit" ? "edit" : "view";
3295
+ const isPasswordProtected = Boolean(passwordFlag);
3296
+ return {
3297
+ origin: urlObj.origin,
3298
+ version: parseInt(versionStr, 10),
3299
+ app,
3300
+ mode,
3301
+ seed,
3302
+ isPasswordProtected,
3303
+ cleanUrl: `${urlObj.origin}/${app}/#/${versionStr}/${app}/${mode}/${seed}${isPasswordProtected ? "/p/" : ""}`
3304
+ };
3305
+ }
3306
+ /**
3307
+ * Derives the Netflux channel ID (hex string) and symmetric encryption key (32 bytes)
3308
+ * from a CryptPad pad seed and optional password according to CryptPad's createEditCryptor2 / createViewCryptor2 protocol.
3309
+ */
3310
+ function deriveCryptPadKeys(seedStr, password) {
3311
+ const seed = b64Decode(seedStr);
3312
+ if (!password) {
3313
+ const seed2 = crypto.createHash("sha512").update(seed).digest().subarray(32, 64);
3314
+ const hash2 = crypto.createHash("sha512").update(seed2).digest();
3315
+ return {
3316
+ channelHex: hash2.subarray(0, 16).toString("hex"),
3317
+ cryptKey: new Uint8Array(hash2.subarray(16, 48))
3318
+ };
3319
+ }
3320
+ const pwBytes = decodeUTF8(password);
3321
+ const superSeed1 = Buffer.concat([Buffer.from(pwBytes), Buffer.from(seed)]);
3322
+ const seed2 = crypto.createHash("sha512").update(superSeed1).digest().subarray(32, 64);
3323
+ const superSeed2 = Buffer.concat([Buffer.from(pwBytes), Buffer.from(seed2)]);
3324
+ const hash2 = crypto.createHash("sha512").update(superSeed2).digest();
3325
+ return {
3326
+ channelHex: hash2.subarray(0, 16).toString("hex"),
3327
+ cryptKey: new Uint8Array(hash2.subarray(16, 48))
3328
+ };
3329
+ }
3330
+ /**
3331
+ * Decrypts an encrypted CryptPad message payload formatted as `nonce|ciphertext`
3332
+ * (or optionally prefixed with a 64-byte Ed25519 signature from historyKeeper).
3333
+ */
3334
+ function decryptCryptPadPayload(payload, cryptKey) {
3335
+ if (!payload || typeof payload !== "string") return null;
3336
+ const candidates = [];
3337
+ if (payload.includes("|")) candidates.push(payload);
3338
+ const rawBytes = b64Decode(payload);
3339
+ if (rawBytes.length > 64) {
3340
+ const strWithoutSig = encodeUTF8(rawBytes.subarray(64));
3341
+ if (strWithoutSig.includes("|")) candidates.push(strWithoutSig);
3342
+ }
3343
+ for (const cand of candidates) {
3344
+ const parts = cand.split("|");
3345
+ if (parts.length === 2) try {
3346
+ const nonce = b64Decode(parts[0]);
3347
+ const cipher = b64Decode(parts[1]);
3348
+ if (nonce.length === 24) {
3349
+ const opened = nacl.secretbox.open(cipher, nonce, cryptKey);
3350
+ if (opened) return encodeUTF8(opened);
3351
+ }
3352
+ } catch {}
3353
+ }
3354
+ return null;
3355
+ }
3356
+ //#endregion
3357
+ //#region src/providers/cryptpad/netflux.ts
3358
+ /**
3359
+ * Discovers the real WebSocket URL for a CryptPad instance by querying its `/api/config` endpoint.
3360
+ */
3361
+ async function resolveCryptPadWebsocketUrl(origin, signal) {
3362
+ try {
3363
+ const configUrl = `${origin.replace(/\/$/, "")}/api/config`;
3364
+ const res = await fetch(configUrl, { signal });
3365
+ if (res.ok) {
3366
+ const match = (await res.text()).match(/"websocketPath":\s*"([^"]+)"/);
3367
+ if (match && match[1]) return match[1];
3368
+ }
3369
+ } catch {}
3370
+ const urlObj = new URL(origin);
3371
+ return `${urlObj.protocol === "https:" ? "wss:" : "ws:"}//${urlObj.host}/cryptpad_websocket`;
3372
+ }
3373
+ /**
3374
+ * Connects to the CryptPad Netflux WebSocket server, joins a channel,
3375
+ * requests its complete history from the historyKeeper peer, decrypts all messages,
3376
+ * and returns the decrypted message strings.
3377
+ */
3378
+ function fetchChannelHistory(wsUrl, channelHex, cryptKey, options = {}) {
3379
+ const { timeoutMs = 8e3, quietPeriodMs = 1200, signal } = options;
3380
+ return new Promise((resolve, reject) => {
3381
+ if (signal?.aborted) return reject(/* @__PURE__ */ new Error("Operation aborted"));
3382
+ const ws = new WebSocket(wsUrl);
3383
+ let seq = 1;
3384
+ const decryptedMessages = [];
3385
+ let quietTimer = null;
3386
+ let overallTimeout = null;
3387
+ let requestedHistory = false;
3388
+ const cleanup = () => {
3389
+ if (quietTimer) clearTimeout(quietTimer);
3390
+ if (overallTimeout) clearTimeout(overallTimeout);
3391
+ try {
3392
+ ws.close();
3393
+ } catch {}
3394
+ };
3395
+ const finish = () => {
3396
+ cleanup();
3397
+ resolve(decryptedMessages);
3398
+ };
3399
+ const resetQuietTimer = () => {
3400
+ if (quietTimer) clearTimeout(quietTimer);
3401
+ quietTimer = setTimeout(finish, quietPeriodMs);
3402
+ };
3403
+ overallTimeout = setTimeout(() => {
3404
+ cleanup();
3405
+ if (decryptedMessages.length > 0) resolve(decryptedMessages);
3406
+ else reject(/* @__PURE__ */ new Error(`Timeout after ${timeoutMs}ms waiting for CryptPad channel "${channelHex}" history.`));
3407
+ }, timeoutMs);
3408
+ if (signal) signal.addEventListener("abort", () => {
3409
+ cleanup();
3410
+ reject(/* @__PURE__ */ new Error("Operation aborted"));
3411
+ });
3412
+ ws.onopen = () => {
3413
+ ws.send(JSON.stringify([
3414
+ seq++,
3415
+ "JOIN",
3416
+ channelHex
3417
+ ]));
3418
+ };
3419
+ ws.onmessage = (event) => {
3420
+ try {
3421
+ const raw = typeof event.data === "string" ? event.data : event.data.toString();
3422
+ const msg = JSON.parse(raw);
3423
+ if (!Array.isArray(msg)) return;
3424
+ const [, peerId, cmd, , payload] = msg;
3425
+ if (cmd === "JOIN" && typeof peerId === "string" && peerId.length === 16) {
3426
+ if (!requestedHistory) {
3427
+ requestedHistory = true;
3428
+ ws.send(JSON.stringify([
3429
+ seq++,
3430
+ "MSG",
3431
+ peerId,
3432
+ JSON.stringify([
3433
+ "GET_HISTORY",
3434
+ channelHex,
3435
+ {}
3436
+ ])
3437
+ ]));
3438
+ resetQuietTimer();
3439
+ }
3440
+ }
3441
+ if (cmd === "MSG") {
3442
+ let encStr = payload;
3443
+ if (!encStr && typeof msg[3] === "string" && msg[3].length > 50) encStr = msg[3];
3444
+ try {
3445
+ const parsed = JSON.parse(encStr);
3446
+ if (Array.isArray(parsed) && parsed[2] === "MSG" && typeof parsed[4] === "string") encStr = parsed[4];
3447
+ } catch {}
3448
+ if (typeof encStr === "string" && encStr.length > 30) {
3449
+ const decrypted = decryptCryptPadPayload(encStr, cryptKey);
3450
+ if (decrypted) {
3451
+ decryptedMessages.push(decrypted);
3452
+ resetQuietTimer();
3453
+ }
3454
+ }
3455
+ }
3456
+ } catch {}
3457
+ };
3458
+ ws.onerror = (err) => {
3459
+ cleanup();
3460
+ reject(/* @__PURE__ */ new Error(`CryptPad WebSocket error: ${String(err)}`));
3461
+ };
3462
+ });
3463
+ }
3464
+ //#endregion
3465
+ //#region src/providers/cryptpad/sheetParser.ts
3466
+ /** Converts column index (0-based) to letter: 0 -> 'A', 25 -> 'Z', 26 -> 'AA'. */
3467
+ function colIndexToLetter(colIndex) {
3468
+ let temp = colIndex;
3469
+ let letter = "";
3470
+ while (temp >= 0) {
3471
+ letter = String.fromCharCode(temp % 26 + 65) + letter;
3472
+ temp = Math.floor(temp / 26) - 1;
3473
+ }
3474
+ return letter;
3475
+ }
3476
+ /**
3477
+ * Parses cell coordinates from a reference like "A1", "Sheet1!B2", or "$C$5".
3478
+ */
3479
+ function parseCellRef(ref) {
3480
+ const match = ref.match(/^(?:([^!]+)!)?\$?([A-Z]+)\$?(\d+)$/i);
3481
+ if (!match) return null;
3482
+ return {
3483
+ sheet: match[1],
3484
+ col: match[2].toUpperCase(),
3485
+ row: parseInt(match[3], 10)
3486
+ };
3487
+ }
3488
+ /**
3489
+ * Extracts the OnlyOffice real-time collaboration channel ID from decrypted pad metadata messages.
3490
+ */
3491
+ function extractOnlyOfficeChannelId(metadataMessages) {
3492
+ for (const raw of metadataMessages) try {
3493
+ const parsed = JSON.parse(raw);
3494
+ if (Array.isArray(parsed) && Array.isArray(parsed[1])) {
3495
+ for (const edit of parsed[1]) if (Array.isArray(edit) && typeof edit[2] === "string") try {
3496
+ const inner = JSON.parse(edit[2]);
3497
+ if (inner?.content?.channel && typeof inner.content.channel === "string") return inner.content.channel;
3498
+ } catch {}
3499
+ }
3500
+ if (parsed?.content?.channel && typeof parsed.content.channel === "string") return parsed.content.channel;
3501
+ } catch {}
3502
+ return null;
3503
+ }
3504
+ /**
3505
+ * Parses OnlyOffice incremental binary change records into cell coordinates and text values.
3506
+ */
3507
+ function parseOnlyOfficeChanges(rtMessages) {
3508
+ const cells = {};
3509
+ for (const raw of rtMessages) try {
3510
+ const data = JSON.parse(raw);
3511
+ if (!Array.isArray(data.changes)) continue;
3512
+ for (const ch of data.changes) {
3513
+ if (!ch?.change) continue;
3514
+ let changeStr = ch.change;
3515
+ if (typeof changeStr !== "string") continue;
3516
+ try {
3517
+ changeStr = JSON.parse(changeStr);
3518
+ } catch {}
3519
+ const parts = changeStr.split(";");
3520
+ if (parts.length < 2) continue;
3521
+ const b64 = parts[1];
3522
+ const buf = Buffer.from(b64, "base64");
3523
+ if (buf.length === 0) continue;
3524
+ for (let i = 0; i < buf.length - 5; i++) if (buf[i] === 8) {
3525
+ const strLen = buf.readUInt32LE(i + 1);
3526
+ if (strLen > 0 && strLen < 4e3 && i + 5 + strLen <= buf.length) {
3527
+ const str = buf.subarray(i + 5, i + 5 + strLen).toString("utf16le");
3528
+ const cellMatch = str.match(/^(?:Sheet\d+!)?([A-Z]+)(\d+)$/);
3529
+ if (cellMatch) {
3530
+ const cellRef = `${cellMatch[1]}${cellMatch[2]}`;
3531
+ const searchStart = i + 5 + strLen;
3532
+ for (let j = searchStart; j < Math.min(searchStart + 30, buf.length - 5); j++) if (buf[j] === 8) {
3533
+ const nextLen = buf.readUInt32LE(j + 1);
3534
+ if (nextLen > 0 && nextLen < 1e4 && j + 5 + nextLen <= buf.length) cells[cellRef] = buf.subarray(j + 5, j + 5 + nextLen).toString("utf16le");
3535
+ break;
3536
+ }
3537
+ }
3538
+ if (buf.length >= 30 && i >= 40) try {
3539
+ const c1 = buf.readUInt32LE(14);
3540
+ const r1 = buf.readUInt32LE(18);
3541
+ if (r1 < 1e5 && c1 < 200) {
3542
+ const cellRef = `${colIndexToLetter(c1)}${r1 + 1}`;
3543
+ if (!cells[cellRef] && str.trim().length > 0 && !str.includes("!")) cells[cellRef] = str;
3544
+ }
3545
+ } catch {}
3546
+ }
3547
+ }
3548
+ }
3549
+ } catch {}
3550
+ return cells;
3551
+ }
3552
+ /**
3553
+ * Converts a grid of cell references (e.g. { A1: 'key', B1: 'en', A2: 'btn.save', B2: 'Save' })
3554
+ * into structured `SheetRow[]` objects using row 1 as the header column keys.
3555
+ */
3556
+ function convertCellsToSheetRows(cells) {
3557
+ const rowMap = /* @__PURE__ */ new Map();
3558
+ for (const [cellRef, val] of Object.entries(cells)) {
3559
+ const parsed = parseCellRef(cellRef);
3560
+ if (!parsed) continue;
3561
+ const { col, row } = parsed;
3562
+ if (!rowMap.has(row)) rowMap.set(row, /* @__PURE__ */ new Map());
3563
+ rowMap.get(row).set(col, val);
3564
+ }
3565
+ if (rowMap.size === 0) return [];
3566
+ const sortedRowIndices = Array.from(rowMap.keys()).sort((a, b) => a - b);
3567
+ const headerRowIdx = sortedRowIndices[0];
3568
+ const headerCols = rowMap.get(headerRowIdx);
3569
+ const colToHeaderName = /* @__PURE__ */ new Map();
3570
+ for (const [col, colName] of headerCols.entries()) {
3571
+ const trimmed = colName.trim();
3572
+ if (trimmed.length > 0) colToHeaderName.set(col, trimmed);
3573
+ }
3574
+ const resultRows = [];
3575
+ for (const rowIdx of sortedRowIndices) {
3576
+ if (rowIdx === headerRowIdx) continue;
3577
+ const rowCells = rowMap.get(rowIdx);
3578
+ const sheetRow = {};
3579
+ for (const [col, headerName] of colToHeaderName.entries()) sheetRow[headerName] = rowCells.get(col) ?? "";
3580
+ if (Object.values(sheetRow).some((v) => typeof v === "string" && v.trim().length > 0)) resultRows.push(sheetRow);
3581
+ }
3582
+ return resultRows;
3583
+ }
3584
+ //#endregion
3585
+ //#region src/providers/cryptpad/client.ts
3586
+ /**
3587
+ * Headless programmatic client for interacting with CryptPad documents (spreadsheets)
3588
+ * over end-to-end encrypted Netflux WebSockets without requiring a browser or user interaction.
3589
+ */
3590
+ var CryptPadClient = class {
3591
+ constructor(options) {
3592
+ if (!options.url || typeof options.url !== "string") throw new Error("CryptPadClient requires a valid \"url\" option.");
3593
+ this.parsedUrl = parsePadUrl(options.url);
3594
+ this.password = options.password ?? process.env.CRYPTPAD_PASSWORD;
3595
+ this.websocketUrl = options.websocketUrl;
3596
+ this.timeoutMs = options.timeoutMs ?? 1e4;
3597
+ if (this.parsedUrl.isPasswordProtected && !this.password) throw new Error(`CryptPad pad "${this.parsedUrl.cleanUrl}" is password protected, but no password was provided. Set "password" option or CRYPTPAD_PASSWORD environment variable.`);
3598
+ }
3599
+ /** Gets or derives the symmetric key and primary Netflux channel ID. */
3600
+ getKeys() {
3601
+ if (!this.derivedKeys) this.derivedKeys = deriveCryptPadKeys(this.parsedUrl.seed, this.password);
3602
+ return this.derivedKeys;
3603
+ }
3604
+ /** Resolves the Netflux WebSocket endpoint to connect to. */
3605
+ async getWebsocketUrl(signal) {
3606
+ if (this.websocketUrl) return this.websocketUrl;
3607
+ return resolveCryptPadWebsocketUrl(this.parsedUrl.origin, signal);
3608
+ }
3609
+ /**
3610
+ * Fetches the complete sheet data, including raw cell coordinate mappings
3611
+ * and structured rows formatted for translation ingestion.
3612
+ */
3613
+ async fetchSheetData(signal) {
3614
+ const wsUrl = await this.getWebsocketUrl(signal);
3615
+ const { channelHex, cryptKey } = this.getKeys();
3616
+ const rtChannel = extractOnlyOfficeChannelId(await fetchChannelHistory(wsUrl, channelHex, cryptKey, {
3617
+ timeoutMs: this.timeoutMs,
3618
+ signal
3619
+ }));
3620
+ let cells = {};
3621
+ if (rtChannel) cells = parseOnlyOfficeChanges(await fetchChannelHistory(wsUrl, rtChannel, cryptKey, {
3622
+ timeoutMs: this.timeoutMs,
3623
+ signal
3624
+ }));
3625
+ const rows = convertCellsToSheetRows(cells);
3626
+ return {
3627
+ url: this.parsedUrl.cleanUrl,
3628
+ cells,
3629
+ rows,
3630
+ metadata: {
3631
+ app: this.parsedUrl.app,
3632
+ mode: this.parsedUrl.mode,
3633
+ channelId: channelHex,
3634
+ rtChannelId: rtChannel ?? void 0
3635
+ }
3636
+ };
3637
+ }
3638
+ /**
3639
+ * Directly fetches tabular translation rows `[ { key: '...', en: '...', de: '...' } ]`.
3640
+ */
3641
+ async fetchSheetRows(signal) {
3642
+ return (await this.fetchSheetData(signal)).rows;
3643
+ }
3644
+ };
3645
+ //#endregion
3646
+ //#region src/providers/cryptpad/sheetProvider.ts
3647
+ const CRYPTPAD_SHEET_INPUT_CAPABILITIES = createCapabilitySet({
3648
+ readTables: true,
3649
+ publicReadNoAuth: false
3650
+ });
3651
+ /**
3652
+ * Creates a read-only {@link TranslationInputProvider} that retrieves translation tables
3653
+ * directly from password-protected or public CryptPad spreadsheets (OnlyOffice sheets)
3654
+ * using end-to-end encrypted Netflux WebSockets without requiring a browser or bot.
3655
+ */
3656
+ function createCryptPadSheetInputProvider(options) {
3657
+ let sources = options.sources ? [...options.sources] : [];
3658
+ if (sources.length === 0) {
3659
+ const singleUrl = options.url ?? process.env.CRYPTPAD_URL;
3660
+ if (singleUrl) sources.push({
3661
+ tableName: options.tableName ?? "translations",
3662
+ url: singleUrl,
3663
+ password: options.password ?? process.env.CRYPTPAD_PASSWORD
3664
+ });
3665
+ }
3666
+ if (sources.length === 0) throw new Error("CryptPad Sheet provider requires at least one source (either \"sources\" array or \"url\" option/CRYPTPAD_URL).");
3667
+ return {
3668
+ kind: "input",
3669
+ providerId: options.providerId ?? "cryptpad-sheet",
3670
+ displayName: options.displayName ?? "CryptPad Sheet Input (E2EE)",
3671
+ capabilities: CRYPTPAD_SHEET_INPUT_CAPABILITIES,
3672
+ async readTables(request) {
3673
+ const requested = new Set((request.tableNames ?? []).filter(Boolean));
3674
+ const selectedSources = requested.size === 0 ? sources : sources.filter((source) => requested.has(source.tableName));
3675
+ return {
3676
+ tables: await Promise.all(selectedSources.map(async (source) => {
3677
+ const url = source.url ?? options.url ?? process.env.CRYPTPAD_URL;
3678
+ if (!url) throw new Error(`CryptPad sheet source "${source.tableName}" does not define a URL.`);
3679
+ const sheetData = await new CryptPadClient({
3680
+ url,
3681
+ password: source.password ?? options.password ?? process.env.CRYPTPAD_PASSWORD,
3682
+ timeoutMs: options.timeoutMs
3683
+ }).fetchSheetData(request.signal);
3684
+ return {
3685
+ tableId: source.tableId ?? url,
3686
+ tableName: source.tableName,
3687
+ rows: sheetData.rows,
3688
+ sourcePath: url,
3689
+ metadata: {
3690
+ provider: "cryptpad-sheet",
3691
+ channelId: sheetData.metadata.channelId,
3692
+ rtChannelId: sheetData.metadata.rtChannelId,
3693
+ cellCount: Object.keys(sheetData.cells).length
3694
+ }
3695
+ };
3696
+ })),
3697
+ metadata: {
3698
+ provider: "cryptpad-sheet",
3699
+ sourceCount: selectedSources.length
3700
+ }
3701
+ };
3702
+ }
3703
+ };
3704
+ }
3705
+ //#endregion
3263
3706
  //#region src/providers/syncEngine.ts
3264
3707
  function pathKey(locale, sheet, key) {
3265
3708
  return `${locale}::${sheet}::${key}`;
@@ -3735,6 +4178,16 @@ function createDefaultProviderCatalog() {
3735
4178
  name: "Google Drive Folder Discovery",
3736
4179
  metadata: { authRequired: true }
3737
4180
  },
4181
+ {
4182
+ providerId: "cryptpad-sheet",
4183
+ sourceId: "cryptpad-sheet-url",
4184
+ kind: "table",
4185
+ name: "CryptPad Sheet (E2EE OnlyOffice)",
4186
+ metadata: {
4187
+ authRequired: false,
4188
+ passwordSupported: true
4189
+ }
4190
+ },
3738
4191
  {
3739
4192
  providerId: "cryptpad-csv",
3740
4193
  sourceId: "cryptpad-csv-url",
@@ -3948,6 +4401,16 @@ function createInputProvider(providerId, options) {
3948
4401
  displayName: typeof options.displayName === "string" ? options.displayName : void 0
3949
4402
  });
3950
4403
  }
4404
+ case "cryptpad-sheet":
4405
+ case "cryptpad": return createCryptPadSheetInputProvider({
4406
+ sources: Array.isArray(options.sources) ? options.sources : void 0,
4407
+ url: typeof options.url === "string" ? options.url : void 0,
4408
+ password: typeof options.password === "string" ? options.password : void 0,
4409
+ tableName: typeof options.tableName === "string" ? options.tableName : void 0,
4410
+ providerId: typeof options.providerId === "string" ? options.providerId : void 0,
4411
+ displayName: typeof options.displayName === "string" ? options.displayName : void 0,
4412
+ timeoutMs: typeof options.timeoutMs === "number" ? options.timeoutMs : void 0
4413
+ });
3951
4414
  default: throw new Error(`Unsupported input provider: "${providerId}"`);
3952
4415
  }
3953
4416
  }
@@ -4307,4 +4770,4 @@ function migrateProjectToV3(options = {}) {
4307
4770
  //#region src/index.ts
4308
4771
  var src_default = getSpreadSheetData;
4309
4772
  //#endregion
4310
- export { CRYPTPAD_ASSET_SYNC_CAPABILITIES, CRYPTPAD_CSV_INPUT_CAPABILITIES, CRYPTPAD_WORKSPACE_OUTPUT_CAPABILITIES, CRYPTPAD_WORKSPACE_SYNC_CAPABILITIES, DEFAULT_IMAGE_EXTENSIONS, DEFAULT_WAIT_SECONDS, EMPTY_PROVIDER_CAPABILITIES, GOOGLE_SHEETS_PROVIDER_CAPABILITIES, GcpApiError, OPERATION_CAPABILITY_REQUIREMENTS, PROVIDER_CAPABILITIES, assertOperationCapabilities, assertRequiredCapabilities, assertValidProviderRuntimeConfig, buildGoogleAuth, buildManifest, buildSyncPlan, columnIndexToLetter, convertFromDataJsonFormat, convertToDataJsonFormat, createAuthClient, createCapabilitySet, createCryptPadAssetSyncProvider, createCryptPadCsvInputProvider, createCryptPadWorkspaceOutputProvider, createCryptPadWorkspaceSyncProvider, createDefaultProviderCatalog, createGoogleSheetsInputProvider, createGoogleSheetsOutputProvider, createGoogleSheetsSyncProvider, createInMemoryProviderCatalogProvider, createLocaleMapping, createProvidersFromRuntimeConfig, createSpreadsheet, src_default as default, entriesToSeedKeys, entriesToTranslationData, exportDoc, filterValidLocales, findLocalChanges, getGoogleTranslateCode, getLanguagePrefix, getLocaleDisplayName, getMultipleSpreadSheetsData, getNormalizedLocaleForHeader, getOriginalHeaderForLocale, getSpreadSheetData, getTranslationSummary, grantDrivePermissions, handleBidirectionalSync, hasRequiredCapabilities, inferLocaleFromDocName, ingestDoc, isValidLocale, manageDriveTranslations, mapLegacyGoogleOptionsToProviderConfig, mergeMultipleTranslationData, mergeSheets, migrateProjectToV3, missingCapabilities, moveSpreadsheetToFolder, normalizeExtension, normalizeLocaleCode, normalizePrivateKey, parseDocContent, processRawRows, readManifest, readPublicSheet, requiresGoogleAuthForRuntimeConfig, resolveLocaleWithFallback, resolveSyncPlan, runProviderPipeline, sanitizeFolderName, scanDriveFolderForDocs, scanDriveFolderForSpreadsheets, setupWIF, slugifyKey, syncDriveImages, updateSpreadsheetWithLocalChanges, validateCredentials, validateEnv, validateImageDirectory, validateProviderRuntimeConfig, wait, walkDirectory, withRetry, writeLanguageDataFile, writeLocalesFile, writeManifest, writeTranslationFiles };
4773
+ export { CRYPTPAD_ASSET_SYNC_CAPABILITIES, CRYPTPAD_CSV_INPUT_CAPABILITIES, CRYPTPAD_SHEET_INPUT_CAPABILITIES, CRYPTPAD_WORKSPACE_OUTPUT_CAPABILITIES, CRYPTPAD_WORKSPACE_SYNC_CAPABILITIES, CryptPadClient, DEFAULT_IMAGE_EXTENSIONS, DEFAULT_WAIT_SECONDS, EMPTY_PROVIDER_CAPABILITIES, GOOGLE_SHEETS_PROVIDER_CAPABILITIES, GcpApiError, OPERATION_CAPABILITY_REQUIREMENTS, PROVIDER_CAPABILITIES, assertOperationCapabilities, assertRequiredCapabilities, assertValidProviderRuntimeConfig, buildGoogleAuth, buildManifest, buildSyncPlan, columnIndexToLetter, convertCellsToSheetRows, convertFromDataJsonFormat, convertToDataJsonFormat, createAuthClient, createCapabilitySet, createCryptPadAssetSyncProvider, createCryptPadCsvInputProvider, createCryptPadSheetInputProvider, createCryptPadWorkspaceOutputProvider, createCryptPadWorkspaceSyncProvider, createDefaultProviderCatalog, createGoogleSheetsInputProvider, createGoogleSheetsOutputProvider, createGoogleSheetsSyncProvider, createInMemoryProviderCatalogProvider, createLocaleMapping, createProvidersFromRuntimeConfig, createSpreadsheet, decryptCryptPadPayload, src_default as default, deriveCryptPadKeys, entriesToSeedKeys, entriesToTranslationData, exportDoc, extractOnlyOfficeChannelId, fetchChannelHistory, filterValidLocales, findLocalChanges, getGoogleTranslateCode, getLanguagePrefix, getLocaleDisplayName, getMultipleSpreadSheetsData, getNormalizedLocaleForHeader, getOriginalHeaderForLocale, getSpreadSheetData, getTranslationSummary, grantDrivePermissions, handleBidirectionalSync, hasRequiredCapabilities, inferLocaleFromDocName, ingestDoc, isValidLocale, manageDriveTranslations, mapLegacyGoogleOptionsToProviderConfig, mergeMultipleTranslationData, mergeSheets, migrateProjectToV3, missingCapabilities, moveSpreadsheetToFolder, normalizeExtension, normalizeLocaleCode, normalizePrivateKey, parseDocContent, parseOnlyOfficeChanges, parsePadUrl, processRawRows, readManifest, readPublicSheet, requiresGoogleAuthForRuntimeConfig, resolveCryptPadWebsocketUrl, resolveLocaleWithFallback, resolveSyncPlan, runProviderPipeline, sanitizeFolderName, scanDriveFolderForDocs, scanDriveFolderForSpreadsheets, setupWIF, slugifyKey, syncDriveImages, updateSpreadsheetWithLocalChanges, validateCredentials, validateEnv, validateImageDirectory, validateProviderRuntimeConfig, wait, walkDirectory, withRetry, writeLanguageDataFile, writeLocalesFile, writeManifest, writeTranslationFiles };
package/dist/index.d.ts CHANGED
@@ -47,8 +47,8 @@ export type { DocIngesterOptions, DocIngestResult, DocUpdateMode } from './utils
47
47
  export { setupWIF, grantDrivePermissions, GcpApiError } from './setup/wifSetup';
48
48
  export type { WifSetupOptions, WifSetupResult, GrantDrivePermissionsOptions, } from './setup/wifSetup';
49
49
  export { PROVIDER_CAPABILITIES, EMPTY_PROVIDER_CAPABILITIES, OPERATION_CAPABILITY_REQUIREMENTS, createCapabilitySet, missingCapabilities, hasRequiredCapabilities, assertRequiredCapabilities, assertOperationCapabilities, } from './providers';
50
- export type { ProviderCapability, ProviderCapabilitySet, ProviderOperation, ProviderKind, ProviderMetadata, CanonicalTableInput, TranslationInputRequest, TranslationInputResult, TranslationOutputPayload, TranslationOutputResult, TranslationSyncPayload, TranslationSyncResult, TranslationInputProvider, TranslationOutputProvider, TranslationSyncProvider, AnyTranslationProvider, ProviderRegistry, SegmentedProviderRegistry, AssetProviderKind, CanonicalAssetEntry, AssetManifestResult, AssetSyncRequest, AssetSyncResult, AssetInputProvider, AssetOutputProvider, AssetSyncProvider, ProviderSourceKind, ProviderSourceDescriptor, ProviderDiscoveryRequest, ProviderDiscoveryResult, ProviderCatalogProvider, InMemoryProviderCatalogOptions, GoogleSheetsInputProviderOptions, GoogleSheetsOutputProviderOptions, GoogleSheetsSyncProviderOptions, CryptPadCsvSource, CryptPadCsvInputProviderOptions, CryptPadWorkspaceProviderOptions, CryptPadAssetSyncProviderOptions, SyncConflictPolicy, SyncChangeType, SyncEntryChange, SyncConflict, SyncPlan, ResolveSyncPlanResult, BuildSyncPlanInput, ProviderPipelineOptions, ProviderPipelineResult, ProviderReferenceConfig, ProviderRuntimeConfig, ProviderConfigValidationResult, LegacyConfigMappingResult, ProviderRuntimeSelection, } from './providers';
51
- export { createGoogleSheetsInputProvider, createGoogleSheetsOutputProvider, createGoogleSheetsSyncProvider, GOOGLE_SHEETS_PROVIDER_CAPABILITIES, createCryptPadCsvInputProvider, createCryptPadWorkspaceOutputProvider, createCryptPadWorkspaceSyncProvider, createCryptPadAssetSyncProvider, CRYPTPAD_CSV_INPUT_CAPABILITIES, CRYPTPAD_WORKSPACE_OUTPUT_CAPABILITIES, CRYPTPAD_WORKSPACE_SYNC_CAPABILITIES, CRYPTPAD_ASSET_SYNC_CAPABILITIES, createInMemoryProviderCatalogProvider, createDefaultProviderCatalog, buildSyncPlan, resolveSyncPlan, runProviderPipeline, validateProviderRuntimeConfig, assertValidProviderRuntimeConfig, mapLegacyGoogleOptionsToProviderConfig, createProvidersFromRuntimeConfig, requiresGoogleAuthForRuntimeConfig, } from './providers';
50
+ export type { ProviderCapability, ProviderCapabilitySet, ProviderOperation, ProviderKind, ProviderMetadata, CanonicalTableInput, TranslationInputRequest, TranslationInputResult, TranslationOutputPayload, TranslationOutputResult, TranslationSyncPayload, TranslationSyncResult, TranslationInputProvider, TranslationOutputProvider, TranslationSyncProvider, AnyTranslationProvider, ProviderRegistry, SegmentedProviderRegistry, AssetProviderKind, CanonicalAssetEntry, AssetManifestResult, AssetSyncRequest, AssetSyncResult, AssetInputProvider, AssetOutputProvider, AssetSyncProvider, ProviderSourceKind, ProviderSourceDescriptor, ProviderDiscoveryRequest, ProviderDiscoveryResult, ProviderCatalogProvider, InMemoryProviderCatalogOptions, GoogleSheetsInputProviderOptions, GoogleSheetsOutputProviderOptions, GoogleSheetsSyncProviderOptions, CryptPadCsvSource, CryptPadCsvInputProviderOptions, CryptPadSheetSource, CryptPadSheetInputProviderOptions, CryptPadClientOptions, CryptPadSheetResult, ParsedCryptPadUrl, DerivedCryptPadKeys, CryptPadSheetGrid, ReconstructedSheet, CryptPadWorkspaceProviderOptions, CryptPadAssetSyncProviderOptions, SyncConflictPolicy, SyncChangeType, SyncEntryChange, SyncConflict, SyncPlan, ResolveSyncPlanResult, BuildSyncPlanInput, ProviderPipelineOptions, ProviderPipelineResult, ProviderReferenceConfig, ProviderRuntimeConfig, ProviderConfigValidationResult, LegacyConfigMappingResult, ProviderRuntimeSelection, } from './providers';
51
+ export { createGoogleSheetsInputProvider, createGoogleSheetsOutputProvider, createGoogleSheetsSyncProvider, GOOGLE_SHEETS_PROVIDER_CAPABILITIES, createCryptPadCsvInputProvider, createCryptPadSheetInputProvider, createCryptPadWorkspaceOutputProvider, createCryptPadWorkspaceSyncProvider, createCryptPadAssetSyncProvider, CryptPadClient, parsePadUrl, deriveCryptPadKeys, decryptCryptPadPayload, resolveCryptPadWebsocketUrl, fetchChannelHistory, extractOnlyOfficeChannelId, parseOnlyOfficeChanges, convertCellsToSheetRows, CRYPTPAD_CSV_INPUT_CAPABILITIES, CRYPTPAD_SHEET_INPUT_CAPABILITIES, CRYPTPAD_WORKSPACE_OUTPUT_CAPABILITIES, CRYPTPAD_WORKSPACE_SYNC_CAPABILITIES, CRYPTPAD_ASSET_SYNC_CAPABILITIES, createInMemoryProviderCatalogProvider, createDefaultProviderCatalog, buildSyncPlan, resolveSyncPlan, runProviderPipeline, validateProviderRuntimeConfig, assertValidProviderRuntimeConfig, mapLegacyGoogleOptionsToProviderConfig, createProvidersFromRuntimeConfig, requiresGoogleAuthForRuntimeConfig, } from './providers';
52
52
  export { migrateProjectToV3 } from './migration/migrateV3';
53
53
  export type { MigrateV3Options, MigrateV3Result } from './migration/migrateV3';
54
54
  import { getSpreadSheetData } from './getSpreadSheetData';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}