@saptools/sharepoint-excel 0.1.0 → 0.1.2
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/README.md +1 -77
- package/dist/cli.js +8 -3
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +8 -3
- package/dist/index.js.map +1 -1
- package/package.json +11 -11
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ Create `.xlsx` files, read workbook content, append records, update cells, and a
|
|
|
11
11
|
[](https://packagephobia.com/result?p=@saptools/sharepoint-excel)
|
|
12
12
|
[](https://www.typescriptlang.org)
|
|
13
13
|
|
|
14
|
-
[Install](#-install) • [Quick Start](#-quick-start) • [CLI](#-cli) • [Security](#-credential-security)
|
|
14
|
+
[Install](#-install) • [Quick Start](#-quick-start) • [CLI](#-cli) • [Security](#-credential-security)
|
|
15
15
|
|
|
16
16
|
</div>
|
|
17
17
|
|
|
@@ -29,21 +29,10 @@ Create `.xlsx` files, read workbook content, append records, update cells, and a
|
|
|
29
29
|
- 🧪 **Fake-backed e2e tests**: package tests do not call real Microsoft Graph or SharePoint
|
|
30
30
|
- 🧰 **CLI and typed API**: every CLI action is backed by exported TypeScript functions
|
|
31
31
|
|
|
32
|
-
> [!NOTE]
|
|
33
|
-
> Microsoft Graph's direct Excel workbook APIs are excellent for delegated user flows, but several workbook mutation endpoints do not support application permissions. This package intentionally treats SharePoint as file storage, edits the workbook locally, and uploads the changed `.xlsx` with conflict protection.
|
|
34
|
-
|
|
35
|
-
---
|
|
36
|
-
|
|
37
32
|
## 📦 Install
|
|
38
33
|
|
|
39
34
|
```bash
|
|
40
|
-
# Global CLI
|
|
41
35
|
npm install -g @saptools/sharepoint-excel
|
|
42
|
-
|
|
43
|
-
# Or as a dependency
|
|
44
|
-
npm install @saptools/sharepoint-excel
|
|
45
|
-
# pnpm add @saptools/sharepoint-excel
|
|
46
|
-
# yarn add @saptools/sharepoint-excel
|
|
47
36
|
```
|
|
48
37
|
|
|
49
38
|
Requires **Node.js >= 20**. The CLI binary is `saptools-sharepoint-excel`.
|
|
@@ -250,71 +239,6 @@ Required Graph application permissions depend on your tenant model. Typical setu
|
|
|
250
239
|
|
|
251
240
|
---
|
|
252
241
|
|
|
253
|
-
## 🧑💻 Programmatic Usage
|
|
254
|
-
|
|
255
|
-
```ts
|
|
256
|
-
import {
|
|
257
|
-
appendRemoteWorkbookRows,
|
|
258
|
-
createRemoteWorkbook,
|
|
259
|
-
openSession,
|
|
260
|
-
parseSiteRef,
|
|
261
|
-
} from "@saptools/sharepoint-excel";
|
|
262
|
-
|
|
263
|
-
const session = await openSession({
|
|
264
|
-
credentials: {
|
|
265
|
-
tenantId: process.env.SHAREPOINT_EXCEL_TENANT_ID ?? "",
|
|
266
|
-
clientId: process.env.SHAREPOINT_EXCEL_CLIENT_ID ?? "",
|
|
267
|
-
clientSecret: process.env.SHAREPOINT_EXCEL_CLIENT_SECRET ?? "",
|
|
268
|
-
},
|
|
269
|
-
site: parseSiteRef("contoso.sharepoint.com/sites/demo"),
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
await createRemoteWorkbook(
|
|
273
|
-
{ session, driveHint: "Documents" },
|
|
274
|
-
"Reports/orders.xlsx",
|
|
275
|
-
{
|
|
276
|
-
sheetName: "Orders",
|
|
277
|
-
headers: ["Name", "Amount"],
|
|
278
|
-
rows: [{ Name: "Coffee", Amount: 3 }],
|
|
279
|
-
},
|
|
280
|
-
);
|
|
281
|
-
|
|
282
|
-
await appendRemoteWorkbookRows(
|
|
283
|
-
{ session, driveHint: "Documents" },
|
|
284
|
-
"Reports/orders.xlsx",
|
|
285
|
-
"Orders",
|
|
286
|
-
[{ Name: "Tea", Amount: 8 }],
|
|
287
|
-
true,
|
|
288
|
-
);
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
<details>
|
|
292
|
-
<summary><b>📚 Main exports</b></summary>
|
|
293
|
-
|
|
294
|
-
| Export | Description |
|
|
295
|
-
| --- | --- |
|
|
296
|
-
| `resolveRuntime()` | Resolve flags/env/profile into a SharePoint target |
|
|
297
|
-
| `createProfileStore()` | Read/write redacted local profile metadata |
|
|
298
|
-
| `createKeyringSecretVault()` | OS credential vault adapter |
|
|
299
|
-
| `acquireAppToken()` | Request an app-only Graph token |
|
|
300
|
-
| `createGraphClient()` | Minimal Graph JSON/binary client |
|
|
301
|
-
| `parseSiteRef()` / `resolveSite()` | Parse and resolve SharePoint site references |
|
|
302
|
-
| `listDrives()` / `selectDrive()` | Discover and select document libraries |
|
|
303
|
-
| `createWorkbookBytes()` | Build a local `.xlsx` workbook |
|
|
304
|
-
| `readWorkbookBytes()` | Read sheet rows from workbook bytes |
|
|
305
|
-
| `appendWorkbookRows()` | Append rows in workbook bytes |
|
|
306
|
-
| `updateWorkbookCell()` | Update an A1 cell in workbook bytes |
|
|
307
|
-
| `addWorkbookSheet()` | Add a new worksheet |
|
|
308
|
-
| `createRemoteWorkbook()` | Create SharePoint workbook without overwriting |
|
|
309
|
-
| `readRemoteWorkbook()` | Download and read SharePoint workbook |
|
|
310
|
-
| `appendRemoteWorkbookRows()` | Append rows and upload with ETag protection |
|
|
311
|
-
| `updateRemoteWorkbookCell()` | Update one cell and upload with ETag protection |
|
|
312
|
-
| `addRemoteWorkbookSheet()` | Add a worksheet and upload with ETag protection |
|
|
313
|
-
|
|
314
|
-
</details>
|
|
315
|
-
|
|
316
|
-
---
|
|
317
|
-
|
|
318
242
|
## 🛠️ Development
|
|
319
243
|
|
|
320
244
|
From the monorepo root:
|
package/dist/cli.js
CHANGED
|
@@ -282,8 +282,11 @@ function resolveBaseUrl(options) {
|
|
|
282
282
|
const fromEnv = (options.env ?? process2.env)[ENV_GRAPH_BASE];
|
|
283
283
|
return fromEnv === void 0 || fromEnv.length === 0 ? DEFAULT_GRAPH_BASE : fromEnv.replace(/\/+$/, "");
|
|
284
284
|
}
|
|
285
|
-
function resolveUrl(base, path) {
|
|
285
|
+
function resolveUrl(base, path, includeAuthorization) {
|
|
286
286
|
if (/^https?:\/\//i.test(path)) {
|
|
287
|
+
if (includeAuthorization && new URL(path).origin !== new URL(base).origin) {
|
|
288
|
+
throw new Error("Refusing to send a Graph bearer token to a different origin");
|
|
289
|
+
}
|
|
287
290
|
return path;
|
|
288
291
|
}
|
|
289
292
|
return `${base}${path.startsWith("/") ? path : `/${path}`}`;
|
|
@@ -318,8 +321,8 @@ async function extractErrorDetail(response) {
|
|
|
318
321
|
}
|
|
319
322
|
function buildInit(accessToken, options) {
|
|
320
323
|
const headers = {
|
|
321
|
-
Authorization: `Bearer ${accessToken}`,
|
|
322
324
|
Accept: "application/json",
|
|
325
|
+
...options.includeAuthorization === false ? {} : { Authorization: `Bearer ${accessToken}` },
|
|
323
326
|
...options.headers
|
|
324
327
|
};
|
|
325
328
|
const init = { method: options.method ?? "GET", headers };
|
|
@@ -355,7 +358,8 @@ function createGraphClient(options) {
|
|
|
355
358
|
const baseDelayMs = options.retry?.baseDelayMs ?? DEFAULT_BASE_DELAY_MS;
|
|
356
359
|
const sleepFn = options.retry?.sleepFn ?? defaultSleep;
|
|
357
360
|
async function execute(path, requestOptions) {
|
|
358
|
-
const
|
|
361
|
+
const includeAuthorization = requestOptions.includeAuthorization !== false;
|
|
362
|
+
const url = resolveUrl(baseUrl, path, includeAuthorization);
|
|
359
363
|
const init = buildInit(options.accessToken, requestOptions);
|
|
360
364
|
let attempt = 0;
|
|
361
365
|
let response = await fetchFn(url, init);
|
|
@@ -755,6 +759,7 @@ async function uploadNewDriveFile(client, driveId, relativePath, bytes) {
|
|
|
755
759
|
const raw = await client.requestJson(uploadUrl, {
|
|
756
760
|
method: "PUT",
|
|
757
761
|
rawBody: bytes,
|
|
762
|
+
includeAuthorization: false,
|
|
758
763
|
headers: {
|
|
759
764
|
"Content-Length": bytes.byteLength.toString(),
|
|
760
765
|
"Content-Range": `bytes 0-${lastByte.toString()}/${bytes.byteLength.toString()}`,
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/index.ts","../src/cli/commands.ts","../src/config/resolve.ts","../src/credentials/profile-store.ts","../src/config/paths.ts","../src/types.ts","../src/credentials/secret-vault.ts","../src/graph/client.ts","../src/graph/site.ts","../src/output/format.ts","../src/auth/token.ts","../src/graph/drive.ts","../src/session.ts","../src/workbook/json.ts","../src/workbook/excel.ts","../src/workbook/a1.ts","../src/workbook/service.ts","../src/cli/options.ts"],"sourcesContent":["import process from \"node:process\";\n\nimport { Command } from \"commander\";\n\nimport { registerCommands } from \"./commands.js\";\n\nexport async function main(argv: readonly string[]): Promise<void> {\n const program = new Command();\n program\n .name(\"saptools-sharepoint-excel\")\n .description(\"Create, read, and update SharePoint-hosted Excel workbooks\");\n registerCommands(program);\n await program.parseAsync([...argv]);\n}\n\ntry {\n await main(process.argv);\n} catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n process.stderr.write(`Error: ${message}\\n`);\n process.exit(1);\n}\n","import process from \"node:process\";\n\nimport type { Command } from \"commander\";\n\nimport { parseSecretStoreKind, resolveRuntime } from \"../config/resolve.js\";\nimport type { ResolvedRuntime } from \"../config/resolve.js\";\nimport { createProfileStore, findProfile, redactProfile, removeProfile, upsertProfile } from \"../credentials/profile-store.js\";\nimport type { SecretVault } from \"../credentials/secret-vault.js\";\nimport { createFileSecretVault, createKeyringSecretVault } from \"../credentials/secret-vault.js\";\nimport { formatCreateResult, formatDriveList, formatMutationResult, formatProfile, formatTestResult, formatWorkbookRead } from \"../output/format.js\";\nimport { openSession } from \"../session.js\";\nimport type { SharePointExcelSession } from \"../session.js\";\nimport { DEFAULT_PROFILE_NAME, ENV_ALLOW_PLAINTEXT } from \"../types.js\";\nimport type { WorkbookReadOptions } from \"../types.js\";\nimport { parseCellValue, parseHeaders, parseWorkbookRows } from \"../workbook/json.js\";\nimport { addRemoteWorkbookSheet, appendRemoteWorkbookRows, createRemoteWorkbook, readRemoteWorkbook, updateRemoteWorkbookCell } from \"../workbook/service.js\";\nimport type { WorkbookServiceTarget } from \"../workbook/service.js\";\n\nimport {\n addCommonOptions,\n requireFlag,\n toRuntimeOverrides,\n} from \"./options.js\";\nimport type {\n AddSheetFlags,\n AppendFlags,\n CommonFlags,\n ConfigGetFlags,\n ConfigSetFlags,\n CreateFlags,\n ReadFlags,\n UpdateCellFlags,\n} from \"./options.js\";\n\nfunction writeJson(value: unknown): void {\n process.stdout.write(`${JSON.stringify(value, null, 2)}\\n`);\n}\n\nfunction writeOutput(json: boolean | undefined, jsonValue: unknown, textValue: string): void {\n if (json === true) {\n writeJson(jsonValue);\n return;\n }\n process.stdout.write(`${textValue}\\n`);\n}\n\nfunction getSecretVault(storeKind: \"keyring\" | \"file\"): SecretVault {\n return storeKind === \"keyring\" ? createKeyringSecretVault() : createFileSecretVault();\n}\n\ninterface OpenRuntimeResult {\n readonly runtime: ResolvedRuntime;\n readonly session: SharePointExcelSession;\n}\n\nasync function openRuntime(flags: CommonFlags): Promise<OpenRuntimeResult> {\n const runtime = await resolveRuntime({ overrides: toRuntimeOverrides(flags) });\n const session = await openSession(runtime.target);\n return { runtime, session };\n}\n\nfunction toServiceTarget(\n session: SharePointExcelSession,\n runtime: ResolvedRuntime,\n flags: CommonFlags,\n): WorkbookServiceTarget {\n const driveHint = flags.drive ?? runtime.drive;\n return driveHint === undefined ? { session } : { session, driveHint };\n}\n\nfunction toReadOptions(flags: ReadFlags): WorkbookReadOptions {\n return {\n ...(flags.sheet === undefined ? {} : { sheetName: flags.sheet }),\n ...(flags.range === undefined ? {} : { range: flags.range }),\n };\n}\n\nfunction assertPlaintextAllowed(flags: ConfigSetFlags): void {\n if (flags.store !== \"file\") {\n return;\n }\n if (flags.allowPlaintextSecret === true || process.env[ENV_ALLOW_PLAINTEXT] === \"1\") {\n return;\n }\n throw new Error(\n `Plaintext secret file store requires --allow-plaintext-secret or ${ENV_ALLOW_PLAINTEXT}=1`,\n );\n}\n\nasync function handleConfigSet(flags: ConfigSetFlags): Promise<void> {\n assertPlaintextAllowed(flags);\n const secretStore = parseSecretStoreKind(flags.store);\n const input = {\n name: flags.profile ?? DEFAULT_PROFILE_NAME,\n tenantId: requireFlag(flags.tenant, \"--tenant\"),\n clientId: requireFlag(flags.clientId, \"--client-id\"),\n clientSecret: requireFlag(flags.clientSecret, \"--client-secret\"),\n site: requireFlag(flags.site, \"--site\"),\n secretStore,\n ...(flags.drive === undefined ? {} : { drive: flags.drive }),\n };\n const profile = await upsertProfile(createProfileStore(), getSecretVault(secretStore), input);\n const redacted = await redactProfile(profile, getSecretVault(secretStore));\n writeOutput(flags.json, redacted, formatProfile(redacted));\n}\n\nasync function handleConfigGet(flags: ConfigGetFlags): Promise<void> {\n const name = flags.profile ?? DEFAULT_PROFILE_NAME;\n const profile = findProfile(await createProfileStore().readProfiles(), name);\n if (profile === undefined) {\n throw new Error(`Profile \"${name}\" not found`);\n }\n const redacted = await redactProfile(profile, getSecretVault(profile.secretStore));\n writeOutput(flags.json, redacted, formatProfile(redacted));\n}\n\nasync function handleConfigRemove(flags: ConfigGetFlags): Promise<void> {\n const name = flags.profile ?? DEFAULT_PROFILE_NAME;\n const profile = findProfile(await createProfileStore().readProfiles(), name);\n const secretStore = profile?.secretStore ?? \"keyring\";\n const removed = await removeProfile(createProfileStore(), getSecretVault(secretStore), name);\n const output = { profile: name, removed };\n writeOutput(flags.json, output, `Removed profile ${name}: ${String(removed)}`);\n}\n\nasync function handleTest(flags: CommonFlags): Promise<void> {\n const { session } = await openRuntime(flags);\n const output = { site: session.site, drives: session.drives, tokenType: session.token.tokenType };\n writeOutput(flags.json, output, formatTestResult(session.site, session.drives));\n}\n\nasync function handleDrives(flags: CommonFlags): Promise<void> {\n const { session } = await openRuntime(flags);\n writeOutput(flags.json, session.drives, formatDriveList(session.drives));\n}\n\nasync function handleCreate(flags: CreateFlags): Promise<void> {\n const { runtime, session } = await openRuntime(flags);\n const result = await createRemoteWorkbook(\n toServiceTarget(session, runtime, flags),\n requireFlag(flags.path, \"--path\"),\n {\n sheetName: requireFlag(flags.sheet, \"--sheet\"),\n headers: parseHeaders(flags.headers),\n rows: parseWorkbookRows(flags.rows),\n ...(flags.table === undefined ? {} : { tableName: flags.table }),\n },\n );\n writeOutput(flags.json, result, formatCreateResult(result));\n}\n\nasync function handleRead(flags: ReadFlags): Promise<void> {\n const { runtime, session } = await openRuntime(flags);\n const result = await readRemoteWorkbook(\n toServiceTarget(session, runtime, flags),\n requireFlag(flags.path, \"--path\"),\n toReadOptions(flags),\n );\n writeOutput(flags.json, result, formatWorkbookRead(result));\n}\n\nasync function handleAppend(flags: AppendFlags): Promise<void> {\n const { runtime, session } = await openRuntime(flags);\n const result = await appendRemoteWorkbookRows(\n toServiceTarget(session, runtime, flags),\n requireFlag(flags.path, \"--path\"),\n requireFlag(flags.sheet, \"--sheet\"),\n parseWorkbookRows(requireFlag(flags.record, \"--record\")),\n flags.matchHeader !== false,\n );\n writeOutput(flags.json, result, formatMutationResult(\"Updated\", result));\n}\n\nasync function handleUpdateCell(flags: UpdateCellFlags): Promise<void> {\n const { runtime, session } = await openRuntime(flags);\n const result = await updateRemoteWorkbookCell(\n toServiceTarget(session, runtime, flags),\n requireFlag(flags.path, \"--path\"),\n requireFlag(flags.sheet, \"--sheet\"),\n requireFlag(flags.cell, \"--cell\"),\n parseCellValue(requireFlag(flags.value, \"--value\")),\n );\n writeOutput(flags.json, result, formatMutationResult(\"Updated\", result));\n}\n\nasync function handleAddSheet(flags: AddSheetFlags): Promise<void> {\n const { runtime, session } = await openRuntime(flags);\n const result = await addRemoteWorkbookSheet(\n toServiceTarget(session, runtime, flags),\n requireFlag(flags.path, \"--path\"),\n requireFlag(flags.sheet, \"--sheet\"),\n parseHeaders(flags.headers),\n );\n writeOutput(flags.json, result, formatMutationResult(\"Updated\", result));\n}\n\nfunction registerConfigCommands(program: Command): void {\n const config = program.command(\"config\").description(\"Manage local SharePoint Excel profiles\");\n config.command(\"set\")\n .description(\"Store a SharePoint app-only profile\")\n .option(\"--profile <name>\", \"Profile name\", DEFAULT_PROFILE_NAME)\n .requiredOption(\"--tenant <id>\", \"Azure AD tenant ID\")\n .requiredOption(\"--client-id <id>\", \"App registration client ID\")\n .requiredOption(\"--client-secret <secret>\", \"App registration client secret\")\n .requiredOption(\"--site <ref>\", \"SharePoint site\")\n .option(\"--drive <nameOrId>\", \"Default document library\")\n .option(\"--store <keyring|file>\", \"Secret store\", \"keyring\")\n .option(\"--allow-plaintext-secret\", \"Allow plaintext file secret storage\", false)\n .option(\"--json\", \"Emit JSON output\", false)\n .action(handleConfigSet);\n config.command(\"get\")\n .description(\"Read a stored profile without printing secrets\")\n .option(\"--profile <name>\", \"Profile name\", DEFAULT_PROFILE_NAME)\n .option(\"--json\", \"Emit JSON output\", false)\n .action(handleConfigGet);\n config.command(\"remove\")\n .description(\"Remove a stored profile\")\n .option(\"--profile <name>\", \"Profile name\", DEFAULT_PROFILE_NAME)\n .option(\"--json\", \"Emit JSON output\", false)\n .action(handleConfigRemove);\n}\n\nexport function registerCommands(program: Command): void {\n registerConfigCommands(program);\n addCommonOptions(program.command(\"test\").description(\"Authenticate, resolve site, and list drives\"))\n .action(handleTest);\n addCommonOptions(program.command(\"drives\").description(\"List SharePoint document libraries\"))\n .action(handleDrives);\n addCommonOptions(program.command(\"create\").description(\"Create a new .xlsx file without overwriting\"))\n .requiredOption(\"--path <xlsxPath>\", \"SharePoint path for the new workbook\")\n .requiredOption(\"--sheet <name>\", \"Initial sheet name\")\n .option(\"--headers <csv>\", \"Comma-separated header row\")\n .option(\"--rows <json>\", \"JSON row/object or array of rows/objects\")\n .option(\"--table <name>\", \"Optional Excel table name\")\n .action(handleCreate);\n addCommonOptions(program.command(\"read\").description(\"Read workbook sheets or a range\"))\n .requiredOption(\"--path <xlsxPath>\", \"SharePoint workbook path\")\n .option(\"--sheet <name>\", \"Sheet to read\")\n .option(\"--range <a1Range>\", \"A1 range, e.g. A1:C10\")\n .action(handleRead);\n addCommonOptions(program.command(\"append\").description(\"Append one or more records to a sheet\"))\n .requiredOption(\"--path <xlsxPath>\", \"SharePoint workbook path\")\n .requiredOption(\"--sheet <name>\", \"Sheet to append\")\n .requiredOption(\"--record <json>\", \"JSON row/object or array of rows/objects\")\n .option(\"--no-match-header\", \"Append object values by key order instead of row 1 headers\")\n .action(handleAppend);\n addCommonOptions(program.command(\"update-cell\").description(\"Update one cell in a workbook\"))\n .requiredOption(\"--path <xlsxPath>\", \"SharePoint workbook path\")\n .requiredOption(\"--sheet <name>\", \"Sheet name\")\n .requiredOption(\"--cell <a1Cell>\", \"A1 cell reference, e.g. B2\")\n .requiredOption(\"--value <jsonOrString>\", \"JSON scalar or raw string\")\n .action(handleUpdateCell);\n addCommonOptions(program.command(\"add-sheet\").description(\"Add a new sheet to an existing workbook\"))\n .requiredOption(\"--path <xlsxPath>\", \"SharePoint workbook path\")\n .requiredOption(\"--sheet <name>\", \"New sheet name\")\n .option(\"--headers <csv>\", \"Optional comma-separated header row\")\n .action(handleAddSheet);\n}\n","import process from \"node:process\";\n\nimport type { ProfileStore } from \"../credentials/profile-store.js\";\nimport { createProfileStore, findProfile } from \"../credentials/profile-store.js\";\nimport type { SecretVault } from \"../credentials/secret-vault.js\";\nimport { createFileSecretVault, createKeyringSecretVault } from \"../credentials/secret-vault.js\";\nimport { parseSiteRef } from \"../graph/site.js\";\nimport type { SecretStoreKind, SharePointTarget, StoredProfile } from \"../types.js\";\nimport {\n DEFAULT_PROFILE_NAME,\n ENV_CLIENT_ID,\n ENV_CLIENT_SECRET,\n ENV_DRIVE,\n ENV_PROFILE,\n ENV_SITE,\n ENV_TENANT,\n FALLBACK_ENV_CLIENT_ID,\n FALLBACK_ENV_CLIENT_SECRET,\n FALLBACK_ENV_DRIVE,\n FALLBACK_ENV_SITE,\n FALLBACK_ENV_TENANT,\n} from \"../types.js\";\n\nexport interface RuntimeOverrides {\n readonly profile?: string | undefined;\n readonly tenant?: string | undefined;\n readonly clientId?: string | undefined;\n readonly clientSecret?: string | undefined;\n readonly site?: string | undefined;\n readonly drive?: string | undefined;\n}\n\nexport interface ResolveRuntimeOptions {\n readonly env?: NodeJS.ProcessEnv;\n readonly overrides?: RuntimeOverrides;\n readonly profileStore?: ProfileStore;\n readonly keyringVault?: SecretVault;\n readonly fileVault?: SecretVault;\n}\n\nexport interface ResolvedRuntime {\n readonly target: SharePointTarget;\n readonly drive?: string;\n readonly profileName: string;\n readonly source: \"profile\" | \"env\";\n}\n\nfunction pickEnv(env: NodeJS.ProcessEnv, primary: string, fallback: string): string | undefined {\n const value = env[primary] ?? env[fallback];\n return value === undefined || value.length === 0 ? undefined : value;\n}\n\nfunction pickValue(\n override: string | undefined,\n envValue: string | undefined,\n profileValue: string | undefined,\n): string | undefined {\n if (override !== undefined && override.length > 0) {\n return override;\n }\n return envValue ?? profileValue;\n}\n\nfunction vaultForProfile(\n profile: StoredProfile | undefined,\n options: ResolveRuntimeOptions,\n): SecretVault {\n if (profile?.secretStore === \"file\") {\n return options.fileVault ?? createFileSecretVault();\n }\n return options.keyringVault ?? createKeyringSecretVault();\n}\n\nasync function resolveClientSecret(\n override: string | undefined,\n envValue: string | undefined,\n profile: StoredProfile | undefined,\n options: ResolveRuntimeOptions,\n): Promise<string | undefined> {\n if (override !== undefined && override.length > 0) {\n return override;\n }\n if (envValue !== undefined) {\n return envValue;\n }\n return profile === undefined ? undefined : await vaultForProfile(profile, options).getSecret(profile.name);\n}\n\nfunction requireValue(value: string | undefined, humanName: string): string {\n if (value === undefined || value.length === 0) {\n throw new Error(`${humanName} is required (pass a flag, set env, or run config set)`);\n }\n return value;\n}\n\nexport async function resolveRuntime(options: ResolveRuntimeOptions = {}): Promise<ResolvedRuntime> {\n const env = options.env ?? process.env;\n const overrides = options.overrides ?? {};\n const profileName =\n overrides.profile ?? env[ENV_PROFILE] ?? DEFAULT_PROFILE_NAME;\n const store = options.profileStore ?? createProfileStore();\n const profile = findProfile(await store.readProfiles(), profileName);\n\n const tenantId = pickValue(\n overrides.tenant,\n pickEnv(env, ENV_TENANT, FALLBACK_ENV_TENANT),\n profile?.tenantId,\n );\n const clientId = pickValue(\n overrides.clientId,\n pickEnv(env, ENV_CLIENT_ID, FALLBACK_ENV_CLIENT_ID),\n profile?.clientId,\n );\n const site = pickValue(overrides.site, pickEnv(env, ENV_SITE, FALLBACK_ENV_SITE), profile?.site);\n const drive = pickValue(overrides.drive, pickEnv(env, ENV_DRIVE, FALLBACK_ENV_DRIVE), profile?.drive);\n const clientSecret = await resolveClientSecret(\n overrides.clientSecret,\n pickEnv(env, ENV_CLIENT_SECRET, FALLBACK_ENV_CLIENT_SECRET),\n profile,\n options,\n );\n\n return {\n target: {\n credentials: {\n tenantId: requireValue(tenantId, \"Tenant ID\"),\n clientId: requireValue(clientId, \"Client ID\"),\n clientSecret: requireValue(clientSecret, \"Client secret\"),\n },\n site: parseSiteRef(requireValue(site, \"SharePoint site\")),\n },\n ...(drive === undefined ? {} : { drive }),\n profileName,\n source: profile === undefined ? \"env\" : \"profile\",\n };\n}\n\nexport function parseSecretStoreKind(value: string | undefined): SecretStoreKind {\n if (value === undefined || value === \"keyring\") {\n return \"keyring\";\n }\n if (value === \"file\") {\n return \"file\";\n }\n throw new Error(`Invalid secret store \"${value}\". Expected keyring or file`);\n}\n","import { chmod, mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\nimport { profilesPath } from \"../config/paths.js\";\nimport type { RedactedProfile, SecretStoreKind, StoredProfile } from \"../types.js\";\nimport { DEFAULT_PROFILE_NAME } from \"../types.js\";\n\nimport type { SecretVault } from \"./secret-vault.js\";\n\ninterface ProfileFile {\n readonly version: 1;\n readonly profiles: readonly StoredProfile[];\n}\n\nexport interface ProfileStore {\n readProfiles: () => Promise<readonly StoredProfile[]>;\n writeProfiles: (profiles: readonly StoredProfile[]) => Promise<void>;\n}\n\nexport interface UpsertProfileInput {\n readonly name?: string;\n readonly tenantId: string;\n readonly clientId: string;\n readonly clientSecret: string;\n readonly site: string;\n readonly drive?: string;\n readonly secretStore: SecretStoreKind;\n readonly updatedAt?: Date;\n}\n\nconst PROFILE_FILE_MODE = 0o600;\nconst EMPTY_PROFILE_FILE: ProfileFile = { version: 1, profiles: [] };\n\nfunction isMissingFileError(err: unknown): boolean {\n return err instanceof Error && \"code\" in err && err.code === \"ENOENT\";\n}\n\nfunction isSecretStoreKind(value: unknown): value is SecretStoreKind {\n return value === \"keyring\" || value === \"file\";\n}\n\nfunction toStoredProfile(value: unknown): StoredProfile | undefined {\n if (typeof value !== \"object\" || value === null) {\n return undefined;\n }\n const raw = value as Record<string, unknown>;\n const name = raw[\"name\"];\n const tenantId = raw[\"tenantId\"];\n const clientId = raw[\"clientId\"];\n const site = raw[\"site\"];\n const drive = raw[\"drive\"];\n const secretStore = raw[\"secretStore\"];\n const updatedAt = raw[\"updatedAt\"];\n if (\n typeof name !== \"string\" ||\n typeof tenantId !== \"string\" ||\n typeof clientId !== \"string\" ||\n typeof site !== \"string\" ||\n typeof updatedAt !== \"string\" ||\n !isSecretStoreKind(secretStore)\n ) {\n return undefined;\n }\n return {\n name,\n tenantId,\n clientId,\n site,\n ...(typeof drive === \"string\" ? { drive } : {}),\n secretStore,\n updatedAt,\n };\n}\n\nfunction isStoredProfile(value: StoredProfile | undefined): value is StoredProfile {\n return value !== undefined;\n}\n\nasync function readProfileFile(path: string): Promise<ProfileFile> {\n try {\n const raw = await readFile(path, \"utf8\");\n const parsed = JSON.parse(raw) as { readonly version?: unknown; readonly profiles?: unknown };\n if (parsed.version !== 1 || !Array.isArray(parsed.profiles)) {\n return EMPTY_PROFILE_FILE;\n }\n return { version: 1, profiles: parsed.profiles.map(toStoredProfile).filter(isStoredProfile) };\n } catch (err) {\n if (isMissingFileError(err)) {\n return EMPTY_PROFILE_FILE;\n }\n throw err;\n }\n}\n\nasync function writeProfileFile(path: string, value: ProfileFile): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, `${JSON.stringify(value, null, 2)}\\n`, {\n encoding: \"utf8\",\n mode: PROFILE_FILE_MODE,\n });\n await chmod(path, PROFILE_FILE_MODE);\n}\n\nexport function createProfileStore(path = profilesPath()): ProfileStore {\n return {\n async readProfiles(): Promise<readonly StoredProfile[]> {\n return (await readProfileFile(path)).profiles;\n },\n async writeProfiles(profiles: readonly StoredProfile[]): Promise<void> {\n await writeProfileFile(path, { version: 1, profiles });\n },\n };\n}\n\nexport function findProfile(\n profiles: readonly StoredProfile[],\n name = DEFAULT_PROFILE_NAME,\n): StoredProfile | undefined {\n return profiles.find((profile) => profile.name === name);\n}\n\nexport async function upsertProfile(\n store: ProfileStore,\n vault: SecretVault,\n input: UpsertProfileInput,\n): Promise<StoredProfile> {\n const name = input.name ?? DEFAULT_PROFILE_NAME;\n const stored: StoredProfile = {\n name,\n tenantId: input.tenantId,\n clientId: input.clientId,\n site: input.site,\n ...(input.drive === undefined || input.drive.length === 0 ? {} : { drive: input.drive }),\n secretStore: input.secretStore,\n updatedAt: (input.updatedAt ?? new Date()).toISOString(),\n };\n const profiles = await store.readProfiles();\n const nextProfiles = profiles.some((profile) => profile.name === name)\n ? profiles.map((profile) => (profile.name === name ? stored : profile))\n : [...profiles, stored];\n await vault.setSecret(name, input.clientSecret);\n await store.writeProfiles(nextProfiles);\n return stored;\n}\n\nexport async function removeProfile(\n store: ProfileStore,\n vault: SecretVault,\n name = DEFAULT_PROFILE_NAME,\n): Promise<boolean> {\n const profiles = await store.readProfiles();\n const nextProfiles = profiles.filter((profile) => profile.name !== name);\n await vault.deleteSecret(name);\n if (nextProfiles.length === profiles.length) {\n return false;\n }\n await store.writeProfiles(nextProfiles);\n return true;\n}\n\nexport async function redactProfile(\n profile: StoredProfile,\n vault: SecretVault,\n): Promise<RedactedProfile> {\n const secret = await vault.getSecret(profile.name);\n return {\n ...profile,\n clientId: `${profile.clientId.slice(0, 4)}...${profile.clientId.slice(-4)}`,\n hasClientSecret: secret !== undefined,\n };\n}\n","import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport process from \"node:process\";\n\nimport { ENV_HOME } from \"../types.js\";\n\nexport const SAPTOOLS_DIR_NAME = \".saptools\";\nexport const PACKAGE_DIR_NAME = \"sharepoint-excel\";\nexport const PROFILES_FILENAME = \"profiles.json\";\nexport const FILE_SECRETS_FILENAME = \"secrets.json\";\n\nexport function packageDataDir(env: NodeJS.ProcessEnv = process.env): string {\n const override = env[ENV_HOME];\n if (override !== undefined && override.length > 0) {\n return override;\n }\n return join(homedir(), SAPTOOLS_DIR_NAME, PACKAGE_DIR_NAME);\n}\n\nexport function profilesPath(env: NodeJS.ProcessEnv = process.env): string {\n return join(packageDataDir(env), PROFILES_FILENAME);\n}\n\nexport function fileSecretsPath(env: NodeJS.ProcessEnv = process.env): string {\n return join(packageDataDir(env), FILE_SECRETS_FILENAME);\n}\n","export type SecretStoreKind = \"keyring\" | \"file\";\n\nexport interface SharePointCredentials {\n readonly tenantId: string;\n readonly clientId: string;\n readonly clientSecret: string;\n}\n\nexport interface SharePointSiteRef {\n readonly hostname: string;\n readonly sitePath: string;\n}\n\nexport interface SharePointTarget {\n readonly credentials: SharePointCredentials;\n readonly site: SharePointSiteRef;\n}\n\nexport interface AccessTokenInfo {\n readonly accessToken: string;\n readonly expiresOn: number;\n readonly tokenType: string;\n readonly scope?: string;\n}\n\nexport interface SharePointSite {\n readonly id: string;\n readonly name: string;\n readonly displayName: string;\n readonly webUrl: string;\n}\n\nexport interface SharePointDrive {\n readonly id: string;\n readonly name: string;\n readonly driveType: string;\n readonly webUrl: string;\n}\n\nexport interface DriveItemSummary {\n readonly id: string;\n readonly name: string;\n readonly isFolder: boolean;\n readonly size: number;\n readonly eTag?: string;\n readonly cTag?: string;\n readonly webUrl?: string;\n}\n\nexport interface StoredProfile {\n readonly name: string;\n readonly tenantId: string;\n readonly clientId: string;\n readonly site: string;\n readonly drive?: string;\n readonly secretStore: SecretStoreKind;\n readonly updatedAt: string;\n}\n\nexport interface RedactedProfile extends Omit<StoredProfile, \"clientId\"> {\n readonly clientId: string;\n readonly hasClientSecret: boolean;\n}\n\nexport type JsonCellValue = string | number | boolean | null;\nexport type JsonRow = readonly JsonCellValue[];\nexport type JsonRecord = Readonly<Record<string, JsonCellValue>>;\nexport type WorkbookInputRow = JsonRow | JsonRecord;\n\nexport interface WorkbookCreateInput {\n readonly sheetName: string;\n readonly headers: readonly string[];\n readonly rows: readonly WorkbookInputRow[];\n readonly tableName?: string;\n}\n\nexport interface WorkbookReadOptions {\n readonly sheetName?: string;\n readonly range?: string;\n}\n\nexport interface WorkbookSheetReadResult {\n readonly name: string;\n readonly rowCount: number;\n readonly columnCount: number;\n readonly rows: readonly JsonRow[];\n}\n\nexport interface WorkbookReadResult {\n readonly sheets: readonly WorkbookSheetReadResult[];\n}\n\nexport interface WorkbookMutationResult {\n readonly bytes: Uint8Array;\n readonly sheetName: string;\n readonly rowCount: number;\n readonly columnCount: number;\n}\n\nexport const DEFAULT_PROFILE_NAME = \"default\";\nexport const DEFAULT_AUTH_BASE = \"https://login.microsoftonline.com\";\nexport const DEFAULT_GRAPH_BASE = \"https://graph.microsoft.com/v1.0\";\n\nexport const ENV_TENANT = \"SHAREPOINT_EXCEL_TENANT_ID\";\nexport const ENV_CLIENT_ID = \"SHAREPOINT_EXCEL_CLIENT_ID\";\nexport const ENV_CLIENT_SECRET = \"SHAREPOINT_EXCEL_CLIENT_SECRET\";\nexport const ENV_SITE = \"SHAREPOINT_EXCEL_SITE\";\nexport const ENV_DRIVE = \"SHAREPOINT_EXCEL_DRIVE\";\nexport const ENV_PROFILE = \"SHAREPOINT_EXCEL_PROFILE\";\nexport const ENV_AUTH_BASE = \"SHAREPOINT_EXCEL_AUTH_BASE\";\nexport const ENV_GRAPH_BASE = \"SHAREPOINT_EXCEL_GRAPH_BASE\";\nexport const ENV_HOME = \"SAPTOOLS_SHAREPOINT_EXCEL_HOME\";\nexport const ENV_ALLOW_PLAINTEXT = \"SAPTOOLS_SHAREPOINT_EXCEL_ALLOW_PLAINTEXT\";\n\nexport const FALLBACK_ENV_TENANT = \"SHAREPOINT_TENANT_ID\";\nexport const FALLBACK_ENV_CLIENT_ID = \"SHAREPOINT_CLIENT_ID\";\nexport const FALLBACK_ENV_CLIENT_SECRET = \"SHAREPOINT_CLIENT_SECRET\";\nexport const FALLBACK_ENV_SITE = \"SHAREPOINT_SITE\";\nexport const FALLBACK_ENV_DRIVE = \"SHAREPOINT_DRIVE\";\n","import { chmod, mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\nimport { Entry } from \"@napi-rs/keyring\";\n\nimport { fileSecretsPath } from \"../config/paths.js\";\n\nexport interface SecretVault {\n getSecret: (profileName: string) => Promise<string | undefined>;\n setSecret: (profileName: string, secret: string) => Promise<void>;\n deleteSecret: (profileName: string) => Promise<void>;\n}\n\ninterface SecretFile {\n readonly version: 1;\n readonly entries: Readonly<Record<string, string>>;\n}\n\nconst SERVICE_NAME = \"saptools-sharepoint-excel\";\nconst SECRET_FILE_MODE = 0o600;\nconst EMPTY_SECRET_FILE: SecretFile = { version: 1, entries: {} };\n\nfunction isMissingFileError(err: unknown): boolean {\n return err instanceof Error && \"code\" in err && err.code === \"ENOENT\";\n}\n\nasync function readSecretFile(path: string): Promise<SecretFile> {\n try {\n const raw = await readFile(path, \"utf8\");\n const parsed = JSON.parse(raw) as { readonly version?: unknown; readonly entries?: unknown };\n if (parsed.version !== 1 || typeof parsed.entries !== \"object\" || parsed.entries === null) {\n return EMPTY_SECRET_FILE;\n }\n const entries: Record<string, string> = {};\n for (const [key, value] of Object.entries(parsed.entries)) {\n if (typeof value === \"string\") {\n entries[key] = value;\n }\n }\n return { version: 1, entries };\n } catch (err) {\n if (isMissingFileError(err)) {\n return EMPTY_SECRET_FILE;\n }\n throw err;\n }\n}\n\nasync function writeSecretFile(path: string, value: SecretFile): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, `${JSON.stringify(value, null, 2)}\\n`, {\n encoding: \"utf8\",\n mode: SECRET_FILE_MODE,\n });\n await chmod(path, SECRET_FILE_MODE);\n}\n\nexport function createKeyringSecretVault(serviceName = SERVICE_NAME): SecretVault {\n return {\n getSecret(profileName: string): Promise<string | undefined> {\n const password = new Entry(serviceName, profileName).getPassword();\n return Promise.resolve(password === null || password.length === 0 ? undefined : password);\n },\n setSecret(profileName: string, secret: string): Promise<void> {\n new Entry(serviceName, profileName).setPassword(secret);\n return Promise.resolve();\n },\n deleteSecret(profileName: string): Promise<void> {\n try {\n new Entry(serviceName, profileName).deletePassword();\n } catch (err) {\n if (err instanceof Error && /not found|no entry|missing/i.test(err.message)) {\n return Promise.resolve();\n }\n return Promise.reject(err instanceof Error ? err : new Error(String(err)));\n }\n return Promise.resolve();\n },\n };\n}\n\nexport function createFileSecretVault(path = fileSecretsPath()): SecretVault {\n return {\n async getSecret(profileName: string): Promise<string | undefined> {\n const file = await readSecretFile(path);\n return file.entries[profileName];\n },\n async setSecret(profileName: string, secret: string): Promise<void> {\n const file = await readSecretFile(path);\n await writeSecretFile(path, {\n version: 1,\n entries: { ...file.entries, [profileName]: secret },\n });\n },\n async deleteSecret(profileName: string): Promise<void> {\n const file = await readSecretFile(path);\n const remaining = Object.fromEntries(\n Object.entries(file.entries).filter(([entryName]) => entryName !== profileName),\n );\n await writeSecretFile(path, { version: 1, entries: remaining });\n },\n };\n}\n","import process from \"node:process\";\n\nimport { DEFAULT_GRAPH_BASE, ENV_GRAPH_BASE } from \"../types.js\";\n\nexport type FetchLike = typeof fetch;\n\nexport interface GraphRetryOptions {\n readonly maxRetries?: number;\n readonly baseDelayMs?: number;\n readonly sleepFn?: (ms: number) => Promise<void>;\n}\n\nexport interface GraphClientOptions {\n readonly accessToken: string;\n readonly baseUrl?: string;\n readonly fetchFn?: FetchLike;\n readonly retry?: GraphRetryOptions;\n readonly env?: NodeJS.ProcessEnv;\n}\n\nexport interface GraphRequestOptions {\n readonly method?: string;\n readonly body?: unknown;\n readonly rawBody?: Uint8Array | string;\n readonly headers?: Readonly<Record<string, string>>;\n}\n\nexport interface GraphClient {\n readonly baseUrl: string;\n requestJson: <T>(path: string, options?: GraphRequestOptions) => Promise<T>;\n requestBytes: (path: string, options?: GraphRequestOptions) => Promise<Uint8Array>;\n requestNoContent: (path: string, options?: GraphRequestOptions) => Promise<void>;\n}\n\ninterface GraphErrorBody {\n readonly error?: {\n readonly code?: unknown;\n readonly message?: unknown;\n };\n}\n\nconst RETRYABLE_STATUSES = new Set<number>([429, 503]);\nconst DEFAULT_MAX_RETRIES = 2;\nconst DEFAULT_BASE_DELAY_MS = 500;\n\nfunction defaultSleep(ms: number): Promise<void> {\n return new Promise((resolve) => {\n setTimeout(resolve, ms);\n });\n}\n\nfunction parseRetryAfter(header: string | null): number | undefined {\n if (header === null || header.length === 0) {\n return undefined;\n }\n const seconds = Number.parseFloat(header);\n if (Number.isFinite(seconds) && seconds >= 0) {\n return Math.ceil(seconds * 1000);\n }\n const dateMs = Date.parse(header);\n return Number.isNaN(dateMs) ? undefined : Math.max(0, dateMs - Date.now());\n}\n\nfunction resolveBaseUrl(options: GraphClientOptions): string {\n if (options.baseUrl !== undefined && options.baseUrl.length > 0) {\n return options.baseUrl.replace(/\\/+$/, \"\");\n }\n const fromEnv = (options.env ?? process.env)[ENV_GRAPH_BASE];\n return fromEnv === undefined || fromEnv.length === 0\n ? DEFAULT_GRAPH_BASE\n : fromEnv.replace(/\\/+$/, \"\");\n}\n\nfunction resolveUrl(base: string, path: string): string {\n if (/^https?:\\/\\//i.test(path)) {\n return path;\n }\n return `${base}${path.startsWith(\"/\") ? path : `/${path}`}`;\n}\n\nexport class GraphHttpError extends Error {\n public readonly status: number;\n public readonly code: string | undefined;\n public readonly detail: string;\n\n public constructor(status: number, code: string | undefined, detail: string) {\n super(\n `Microsoft Graph request failed (${status.toString()}${\n code === undefined ? \"\" : ` ${code}`\n }): ${detail}`,\n );\n this.name = \"GraphHttpError\";\n this.status = status;\n this.code = code;\n this.detail = detail;\n }\n}\n\nasync function extractErrorDetail(response: Response): Promise<{ code: string | undefined; detail: string }> {\n const text = await response.text().catch(() => \"\");\n if (text.length === 0) {\n return { code: undefined, detail: response.statusText };\n }\n try {\n const body = JSON.parse(text) as GraphErrorBody;\n const code = typeof body.error?.code === \"string\" ? body.error.code : undefined;\n const detail =\n typeof body.error?.message === \"string\" && body.error.message.length > 0\n ? body.error.message\n : response.statusText;\n return { code, detail };\n } catch {\n return { code: undefined, detail: text };\n }\n}\n\nfunction buildInit(accessToken: string, options: GraphRequestOptions): RequestInit {\n const headers: Record<string, string> = {\n Authorization: `Bearer ${accessToken}`,\n Accept: \"application/json\",\n ...options.headers,\n };\n const init: RequestInit = { method: options.method ?? \"GET\", headers };\n if (options.rawBody !== undefined) {\n init.body = rawBodyToBodyInit(options.rawBody);\n return init;\n }\n if (options.body !== undefined) {\n headers[\"Content-Type\"] = headers[\"Content-Type\"] ?? \"application/json\";\n init.body = typeof options.body === \"string\" ? options.body : JSON.stringify(options.body);\n }\n return init;\n}\n\ntype RequestBody = NonNullable<RequestInit[\"body\"]>;\n\nfunction rawBodyToBodyInit(rawBody: Uint8Array | string): RequestBody {\n if (typeof rawBody === \"string\") {\n return rawBody;\n }\n const copy = new ArrayBuffer(rawBody.byteLength);\n new Uint8Array(copy).set(rawBody);\n return copy;\n}\n\nasync function discardBody(response: Response): Promise<void> {\n if (response.body === null) {\n return;\n }\n await response.body.cancel().catch(() => {\n /* ignore */\n });\n}\n\nexport function createGraphClient(options: GraphClientOptions): GraphClient {\n const baseUrl = resolveBaseUrl(options);\n const fetchFn = options.fetchFn ?? fetch;\n const maxRetries = options.retry?.maxRetries ?? DEFAULT_MAX_RETRIES;\n const baseDelayMs = options.retry?.baseDelayMs ?? DEFAULT_BASE_DELAY_MS;\n const sleepFn = options.retry?.sleepFn ?? defaultSleep;\n\n async function execute(path: string, requestOptions: GraphRequestOptions): Promise<Response> {\n const url = resolveUrl(baseUrl, path);\n const init = buildInit(options.accessToken, requestOptions);\n let attempt = 0;\n let response = await fetchFn(url, init);\n while (!response.ok && RETRYABLE_STATUSES.has(response.status) && attempt < maxRetries) {\n const retryAfterMs =\n parseRetryAfter(response.headers.get(\"retry-after\")) ?? baseDelayMs * 2 ** attempt;\n await discardBody(response);\n await sleepFn(retryAfterMs);\n attempt += 1;\n response = await fetchFn(url, init);\n }\n if (!response.ok) {\n const { code, detail } = await extractErrorDetail(response);\n throw new GraphHttpError(response.status, code, detail);\n }\n return response;\n }\n\n async function requestJson<T>(path: string, requestOptions: GraphRequestOptions = {}): Promise<T> {\n const response = await execute(path, requestOptions);\n if (response.status === 204) {\n return undefined as T;\n }\n const contentType = response.headers.get(\"content-type\")?.toLowerCase() ?? \"\";\n if (!contentType.includes(\"application/json\")) {\n return undefined as T;\n }\n return (await response.json()) as T;\n }\n\n async function requestBytes(path: string, requestOptions: GraphRequestOptions = {}): Promise<Uint8Array> {\n const response = await execute(path, requestOptions);\n return new Uint8Array(await response.arrayBuffer());\n }\n\n async function requestNoContent(path: string, requestOptions: GraphRequestOptions = {}): Promise<void> {\n await execute(path, requestOptions);\n }\n\n return { baseUrl, requestJson, requestBytes, requestNoContent };\n}\n","import type { SharePointSite, SharePointSiteRef } from \"../types.js\";\n\nimport type { GraphClient } from \"./client.js\";\nimport { GraphHttpError } from \"./client.js\";\n\ninterface RawSiteResponse {\n readonly id?: unknown;\n readonly name?: unknown;\n readonly displayName?: unknown;\n readonly webUrl?: unknown;\n}\n\nfunction asString(value: unknown, fallback = \"\"): string {\n return typeof value === \"string\" ? value : fallback;\n}\n\nfunction stripQueryAndHash(value: string): string {\n const markerIndex = value.search(/[?#]/);\n return markerIndex === -1 ? value : value.slice(0, markerIndex);\n}\n\nfunction decodeSitePath(sitePath: string, input: string): string {\n return sitePath\n .split(\"/\")\n .map((segment) => {\n try {\n return decodeURIComponent(segment);\n } catch (err) {\n throw new Error(`Invalid site reference \"${input}\". Site path has invalid encoding`, {\n cause: err,\n });\n }\n })\n .join(\"/\");\n}\n\nfunction parseSiteInput(trimmed: string): { readonly hostname: string; readonly rawPath: string } {\n if (/^https?:\\/\\//i.test(trimmed)) {\n const url = new URL(trimmed);\n return { hostname: url.hostname, rawPath: url.pathname };\n }\n const withoutQuery = stripQueryAndHash(trimmed);\n const firstSlash = withoutQuery.indexOf(\"/\");\n if (firstSlash === -1) {\n throw new Error(`Invalid site reference \"${trimmed}\". Expected host/sites/<name> or full URL`);\n }\n return { hostname: withoutQuery.slice(0, firstSlash), rawPath: withoutQuery.slice(firstSlash + 1) };\n}\n\nexport function parseSiteRef(input: string): SharePointSiteRef {\n const trimmed = input.trim();\n if (trimmed.length === 0) {\n throw new Error(\"Site reference is empty\");\n }\n const { hostname, rawPath } = parseSiteInput(trimmed);\n const sitePath = decodeSitePath(rawPath.replace(/^\\/+|\\/+$/g, \"\"), trimmed);\n if (hostname.length === 0 || sitePath.length === 0) {\n throw new Error(`Invalid site reference \"${trimmed}\". Missing hostname or site path`);\n }\n return { hostname, sitePath };\n}\n\nfunction encodeSitePath(sitePath: string): string {\n return sitePath.split(\"/\").map((segment) => encodeURIComponent(segment)).join(\"/\");\n}\n\nexport async function resolveSite(\n client: GraphClient,\n ref: SharePointSiteRef,\n): Promise<SharePointSite> {\n const path = `/sites/${encodeURIComponent(ref.hostname)}:/${encodeSitePath(ref.sitePath)}`;\n let raw: RawSiteResponse;\n try {\n raw = await client.requestJson<RawSiteResponse>(path);\n } catch (err) {\n if (err instanceof GraphHttpError && err.status === 404) {\n throw new Error(`SharePoint site not found at ${ref.hostname}/${ref.sitePath}`, {\n cause: err,\n });\n }\n throw err;\n }\n const id = asString(raw.id);\n if (id.length === 0) {\n throw new Error(`Site response missing id for ${ref.hostname}/${ref.sitePath}`);\n }\n return {\n id,\n name: asString(raw.name, ref.sitePath),\n displayName: asString(raw.displayName, asString(raw.name, ref.sitePath)),\n webUrl: asString(raw.webUrl),\n };\n}\n","import type { RedactedProfile, SharePointDrive, SharePointSite, WorkbookReadResult } from \"../types.js\";\nimport type {\n RemoteMutationResult,\n RemoteReadResult,\n RemoteWorkbookResult,\n} from \"../workbook/service.js\";\n\nexport function formatDriveList(drives: readonly SharePointDrive[]): string {\n if (drives.length === 0) {\n return \"(no drives found)\";\n }\n return drives.map((drive) => `- ${drive.name} [${drive.driveType}] (${drive.id})`).join(\"\\n\");\n}\n\nexport function formatTestResult(site: SharePointSite, drives: readonly SharePointDrive[]): string {\n return [\n `Authenticated and resolved site: ${site.displayName} (${site.id})`,\n `Document libraries: ${drives.length.toString()}`,\n formatDriveList(drives),\n ].join(\"\\n\");\n}\n\nexport function formatProfile(profile: RedactedProfile): string {\n return [\n `Profile: ${profile.name}`,\n `Tenant: ${profile.tenantId}`,\n `Client: ${profile.clientId}`,\n `Site: ${profile.site}`,\n `Drive: ${profile.drive ?? \"(first available)\"}`,\n `Secret store: ${profile.secretStore}`,\n `Client secret: ${profile.hasClientSecret ? \"stored\" : \"missing\"}`,\n ].join(\"\\n\");\n}\n\nexport function formatCreateResult(result: RemoteWorkbookResult): string {\n return `Created ${result.path} in ${result.driveName} (${result.item.id})`;\n}\n\nexport function formatMutationResult(action: string, result: RemoteMutationResult): string {\n return `${action} ${result.path} in ${result.driveName}; sheet ${result.mutation.sheetName} now has ${result.mutation.rowCount.toString()} row(s)`;\n}\n\nexport function formatWorkbookRead(result: RemoteReadResult): string {\n return formatWorkbookSheets(result.workbook);\n}\n\nexport function formatWorkbookSheets(workbook: WorkbookReadResult): string {\n return workbook.sheets\n .map((sheet) => `${sheet.name}: ${sheet.rowCount.toString()} row(s), ${sheet.columnCount.toString()} column(s)`)\n .join(\"\\n\");\n}\n","import process from \"node:process\";\n\nimport type { FetchLike } from \"../graph/client.js\";\nimport type { AccessTokenInfo, SharePointCredentials } from \"../types.js\";\nimport { DEFAULT_AUTH_BASE, ENV_AUTH_BASE } from \"../types.js\";\n\nexport interface AcquireTokenOptions {\n readonly authBase?: string;\n readonly scope?: string;\n readonly fetchFn?: FetchLike;\n readonly env?: NodeJS.ProcessEnv;\n}\n\ninterface TokenResponse {\n readonly access_token?: unknown;\n readonly token_type?: unknown;\n readonly expires_in?: unknown;\n readonly scope?: unknown;\n readonly error?: unknown;\n readonly error_description?: unknown;\n}\n\nconst DEFAULT_SCOPE = \"https://graph.microsoft.com/.default\";\n\nfunction resolveAuthBase(options: AcquireTokenOptions): string {\n if (options.authBase !== undefined && options.authBase.length > 0) {\n return options.authBase.replace(/\\/+$/, \"\");\n }\n const fromEnv = (options.env ?? process.env)[ENV_AUTH_BASE];\n return fromEnv === undefined || fromEnv.length === 0\n ? DEFAULT_AUTH_BASE\n : fromEnv.replace(/\\/+$/, \"\");\n}\n\nfunction assertString(value: unknown, field: string): string {\n if (typeof value !== \"string\" || value.length === 0) {\n throw new Error(`Token response missing field: ${field}`);\n }\n return value;\n}\n\nfunction assertNumber(value: unknown, field: string): number {\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n throw new Error(`Token response missing numeric field: ${field}`);\n }\n return value;\n}\n\nfunction parseTokenResponse(text: string, status: number): TokenResponse {\n try {\n return JSON.parse(text) as TokenResponse;\n } catch (err) {\n throw new Error(`Failed to parse token response (HTTP ${status.toString()})`, { cause: err });\n }\n}\n\nfunction throwIfTokenError(response: Response, parsed: TokenResponse): void {\n if (response.ok && typeof parsed.error !== \"string\") {\n return;\n }\n const code = typeof parsed.error === \"string\" ? parsed.error : \"unknown_error\";\n const description =\n typeof parsed.error_description === \"string\" && parsed.error_description.length > 0\n ? parsed.error_description\n : response.statusText;\n throw new Error(\n `Azure AD token request failed (HTTP ${response.status.toString()} ${code}): ${description}`,\n );\n}\n\nexport async function acquireAppToken(\n credentials: SharePointCredentials,\n options: AcquireTokenOptions = {},\n): Promise<AccessTokenInfo> {\n if (credentials.tenantId.length === 0) {\n throw new Error(\"tenantId is required\");\n }\n if (credentials.clientId.length === 0) {\n throw new Error(\"clientId is required\");\n }\n if (credentials.clientSecret.length === 0) {\n throw new Error(\"clientSecret is required\");\n }\n\n const authBase = resolveAuthBase(options);\n const fetchFn = options.fetchFn ?? fetch;\n const url = `${authBase}/${encodeURIComponent(credentials.tenantId)}/oauth2/v2.0/token`;\n const form = new URLSearchParams({\n grant_type: \"client_credentials\",\n client_id: credentials.clientId,\n client_secret: credentials.clientSecret,\n scope: options.scope ?? DEFAULT_SCOPE,\n });\n\n const response = await fetchFn(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\", Accept: \"application/json\" },\n body: form.toString(),\n });\n const parsed = parseTokenResponse(await response.text(), response.status);\n throwIfTokenError(response, parsed);\n\n const scopeValue = typeof parsed.scope === \"string\" ? parsed.scope : undefined;\n const base = {\n accessToken: assertString(parsed.access_token, \"access_token\"),\n tokenType: assertString(parsed.token_type, \"token_type\"),\n expiresOn: Math.floor(Date.now() / 1000) + assertNumber(parsed.expires_in, \"expires_in\"),\n };\n return scopeValue === undefined ? base : { ...base, scope: scopeValue };\n}\n","import type { DriveItemSummary, SharePointDrive } from \"../types.js\";\n\nimport type { GraphClient } from \"./client.js\";\nimport { GraphHttpError } from \"./client.js\";\n\ninterface RawDriveResponse {\n readonly id?: unknown;\n readonly name?: unknown;\n readonly driveType?: unknown;\n readonly webUrl?: unknown;\n}\n\ninterface RawDriveListResponse {\n readonly value?: unknown;\n}\n\ninterface RawDriveItem {\n readonly id?: unknown;\n readonly name?: unknown;\n readonly size?: unknown;\n readonly eTag?: unknown;\n readonly cTag?: unknown;\n readonly webUrl?: unknown;\n readonly folder?: unknown;\n readonly file?: unknown;\n}\n\ninterface UploadSessionResponse {\n readonly uploadUrl?: unknown;\n}\n\nconst XLSX_CONTENT_TYPE = \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\";\n\nfunction asString(value: unknown, fallback = \"\"): string {\n return typeof value === \"string\" ? value : fallback;\n}\n\nfunction asNumber(value: unknown, fallback = 0): number {\n return typeof value === \"number\" && Number.isFinite(value) ? value : fallback;\n}\n\nexport function encodeDrivePath(relativePath: string): string {\n return relativePath\n .split(\"/\")\n .filter((segment) => segment.length > 0)\n .map((segment) => encodeURIComponent(segment))\n .join(\"/\");\n}\n\nfunction toDrive(raw: RawDriveResponse): SharePointDrive {\n return {\n id: asString(raw.id),\n name: asString(raw.name),\n driveType: asString(raw.driveType, \"documentLibrary\"),\n webUrl: asString(raw.webUrl),\n };\n}\n\nfunction toDriveItem(raw: RawDriveItem): DriveItemSummary {\n const base = {\n id: asString(raw.id),\n name: asString(raw.name),\n isFolder: raw.folder !== undefined && raw.folder !== null,\n size: asNumber(raw.size),\n };\n return {\n ...base,\n ...(typeof raw.eTag === \"string\" ? { eTag: raw.eTag } : {}),\n ...(typeof raw.cTag === \"string\" ? { cTag: raw.cTag } : {}),\n ...(typeof raw.webUrl === \"string\" ? { webUrl: raw.webUrl } : {}),\n };\n}\n\nexport async function listDrives(\n client: GraphClient,\n siteId: string,\n): Promise<readonly SharePointDrive[]> {\n const response = await client.requestJson<RawDriveListResponse>(`/sites/${encodeURIComponent(siteId)}/drives`);\n if (!Array.isArray(response.value)) {\n return [];\n }\n return response.value\n .filter((entry): entry is RawDriveResponse => typeof entry === \"object\" && entry !== null)\n .map(toDrive);\n}\n\nexport function selectDrive(\n drives: readonly SharePointDrive[],\n driveHint: string | undefined,\n): SharePointDrive {\n if (drives.length === 0) {\n throw new Error(\"SharePoint site has no drives (document libraries)\");\n }\n if (driveHint === undefined || driveHint.length === 0) {\n const first = drives[0];\n if (first === undefined) {\n throw new Error(\"No drives available\");\n }\n return first;\n }\n const match = drives.find((drive) => drive.id === driveHint || drive.name === driveHint);\n if (match === undefined) {\n throw new Error(`Drive \"${driveHint}\" not found. Available: ${drives.map((d) => d.name).join(\", \")}`);\n }\n return match;\n}\n\nexport async function getDriveItemByPath(\n client: GraphClient,\n driveId: string,\n relativePath: string,\n): Promise<DriveItemSummary | null> {\n const normalized = relativePath.replace(/^\\/+|\\/+$/g, \"\");\n const path =\n normalized.length === 0\n ? `/drives/${encodeURIComponent(driveId)}/root`\n : `/drives/${encodeURIComponent(driveId)}/root:/${encodeDrivePath(normalized)}`;\n try {\n return toDriveItem(await client.requestJson<RawDriveItem>(path));\n } catch (err) {\n if (err instanceof GraphHttpError && err.status === 404) {\n return null;\n }\n throw err;\n }\n}\n\nexport async function downloadDriveFile(\n client: GraphClient,\n driveId: string,\n relativePath: string,\n): Promise<Uint8Array> {\n const encodedPath = encodeDrivePath(relativePath.replace(/^\\/+|\\/+$/g, \"\"));\n return await client.requestBytes(`/drives/${encodeURIComponent(driveId)}/root:/${encodedPath}:/content`, {\n headers: { Accept: XLSX_CONTENT_TYPE },\n });\n}\n\nasync function createUploadSession(\n client: GraphClient,\n driveId: string,\n relativePath: string,\n): Promise<string> {\n const encodedPath = encodeDrivePath(relativePath.replace(/^\\/+|\\/+$/g, \"\"));\n const response = await client.requestJson<UploadSessionResponse>(\n `/drives/${encodeURIComponent(driveId)}/root:/${encodedPath}:/createUploadSession`,\n {\n method: \"POST\",\n body: { item: { \"@microsoft.graph.conflictBehavior\": \"fail\" } },\n },\n );\n if (typeof response.uploadUrl !== \"string\" || response.uploadUrl.length === 0) {\n throw new Error(\"Graph upload session response missing uploadUrl\");\n }\n return response.uploadUrl;\n}\n\nexport async function uploadNewDriveFile(\n client: GraphClient,\n driveId: string,\n relativePath: string,\n bytes: Uint8Array,\n): Promise<DriveItemSummary> {\n const existing = await getDriveItemByPath(client, driveId, relativePath);\n if (existing !== null) {\n throw new Error(`Refusing to overwrite existing SharePoint file: ${relativePath}`);\n }\n const uploadUrl = await createUploadSession(client, driveId, relativePath);\n const lastByte = bytes.byteLength - 1;\n const raw = await client.requestJson<RawDriveItem>(uploadUrl, {\n method: \"PUT\",\n rawBody: bytes,\n headers: {\n \"Content-Length\": bytes.byteLength.toString(),\n \"Content-Range\": `bytes 0-${lastByte.toString()}/${bytes.byteLength.toString()}`,\n \"Content-Type\": XLSX_CONTENT_TYPE,\n },\n });\n return toDriveItem(raw);\n}\n\nexport async function replaceDriveFile(\n client: GraphClient,\n driveId: string,\n relativePath: string,\n eTag: string,\n bytes: Uint8Array,\n): Promise<DriveItemSummary> {\n const encodedPath = encodeDrivePath(relativePath.replace(/^\\/+|\\/+$/g, \"\"));\n const raw = await client.requestJson<RawDriveItem>(\n `/drives/${encodeURIComponent(driveId)}/root:/${encodedPath}:/content`,\n {\n method: \"PUT\",\n rawBody: bytes,\n headers: {\n \"Content-Type\": XLSX_CONTENT_TYPE,\n \"If-Match\": eTag,\n },\n },\n );\n return toDriveItem(raw);\n}\n","import { acquireAppToken } from \"./auth/token.js\";\nimport type { AcquireTokenOptions } from \"./auth/token.js\";\nimport { createGraphClient } from \"./graph/client.js\";\nimport type { FetchLike, GraphClient, GraphRetryOptions } from \"./graph/client.js\";\nimport { listDrives } from \"./graph/drive.js\";\nimport { resolveSite } from \"./graph/site.js\";\nimport type { AccessTokenInfo, SharePointDrive, SharePointSite, SharePointTarget } from \"./types.js\";\n\nexport interface SessionOptions {\n readonly fetchFn?: FetchLike;\n readonly authBase?: string;\n readonly graphBase?: string;\n readonly retry?: GraphRetryOptions;\n}\n\nexport interface SharePointExcelSession {\n readonly token: AccessTokenInfo;\n readonly client: GraphClient;\n readonly site: SharePointSite;\n readonly drives: readonly SharePointDrive[];\n}\n\nexport async function openSession(\n target: SharePointTarget,\n options: SessionOptions = {},\n): Promise<SharePointExcelSession> {\n const tokenOptions: AcquireTokenOptions = {\n ...(options.authBase === undefined ? {} : { authBase: options.authBase }),\n ...(options.fetchFn === undefined ? {} : { fetchFn: options.fetchFn }),\n };\n const token = await acquireAppToken(target.credentials, tokenOptions);\n const client = createGraphClient({\n accessToken: token.accessToken,\n ...(options.graphBase === undefined ? {} : { baseUrl: options.graphBase }),\n ...(options.fetchFn === undefined ? {} : { fetchFn: options.fetchFn }),\n ...(options.retry === undefined ? {} : { retry: options.retry }),\n });\n const site = await resolveSite(client, target.site);\n const drives = await listDrives(client, site.id);\n return { token, client, site, drives };\n}\n","import { z } from \"zod\";\n\nimport type { JsonCellValue, WorkbookInputRow } from \"../types.js\";\n\nconst JsonCellValueSchema = z.union([z.string(), z.number(), z.boolean(), z.null()]);\nconst JsonRowSchema = z.array(JsonCellValueSchema);\nconst JsonRecordSchema = z.record(z.string(), JsonCellValueSchema);\n\nexport function parseHeaders(input: string | undefined): readonly string[] {\n if (input === undefined || input.trim().length === 0) {\n return [];\n }\n return input\n .split(\",\")\n .map((entry) => entry.trim())\n .filter((entry) => entry.length > 0);\n}\n\nfunction parseJson(input: string, label: string): unknown {\n try {\n return JSON.parse(input) as unknown;\n } catch (err) {\n throw new Error(`Invalid JSON for ${label}`, { cause: err });\n }\n}\n\nexport function parseCellValue(input: string): JsonCellValue {\n const trimmed = input.trim();\n if (trimmed.length === 0) {\n return \"\";\n }\n let parsed: unknown;\n try {\n parsed = parseJson(trimmed, \"cell value\");\n } catch {\n return input;\n }\n const result = JsonCellValueSchema.safeParse(parsed);\n if (!result.success) {\n return input;\n }\n return result.data;\n}\n\nexport function parseWorkbookRows(input: string | undefined): readonly WorkbookInputRow[] {\n if (input === undefined || input.trim().length === 0) {\n return [];\n }\n const parsed = parseJson(input, \"rows\");\n const rowResult = JsonRowSchema.safeParse(parsed);\n if (rowResult.success) {\n return [rowResult.data];\n }\n const recordResult = JsonRecordSchema.safeParse(parsed);\n if (recordResult.success) {\n return [recordResult.data];\n }\n if (Array.isArray(parsed)) {\n return parsed.map(parseWorkbookRow);\n }\n throw new Error(`Rows JSON must be an object, row array, or array of rows/objects`);\n}\n\nfunction parseWorkbookRow(value: unknown): WorkbookInputRow {\n const rowResult = JsonRowSchema.safeParse(value);\n if (rowResult.success) {\n return rowResult.data;\n }\n const recordResult = JsonRecordSchema.safeParse(value);\n if (recordResult.success) {\n return recordResult.data;\n }\n throw new Error(`Rows JSON must be an object, row array, or array of rows/objects`);\n}\n","import ExcelJS from \"exceljs\";\nimport type { CellValue, Worksheet } from \"exceljs\";\n\nimport type {\n JsonCellValue,\n JsonRecord,\n JsonRow,\n WorkbookCreateInput,\n WorkbookInputRow,\n WorkbookMutationResult,\n WorkbookReadOptions,\n WorkbookReadResult,\n WorkbookSheetReadResult,\n} from \"../types.js\";\n\nimport { parseA1Cell, parseA1Range } from \"./a1.js\";\n\nconst INVALID_SHEET_CHARS = /[\\][:*?/\\\\]/;\n\nfunction validateSheetName(sheetName: string): string {\n const trimmed = sheetName.trim();\n if (trimmed.length === 0 || trimmed.length > 31 || INVALID_SHEET_CHARS.test(trimmed)) {\n throw new Error(`Invalid Excel sheet name \"${sheetName}\"`);\n }\n return trimmed;\n}\n\nfunction isRecord(row: WorkbookInputRow): row is JsonRecord {\n return !Array.isArray(row);\n}\n\nfunction deriveHeaders(headers: readonly string[], rows: readonly WorkbookInputRow[]): readonly string[] {\n if (headers.length > 0) {\n return headers;\n }\n const firstRecord = rows.find(isRecord);\n return firstRecord === undefined ? [] : Object.keys(firstRecord);\n}\n\nfunction rowToValues(row: WorkbookInputRow, headers: readonly string[]): JsonRow {\n if (!isRecord(row)) {\n return [...row];\n }\n const record = row;\n if (headers.length === 0) {\n return Object.keys(record).map((key) => record[key] ?? null);\n }\n return headers.map((header) => record[header] ?? null);\n}\n\nfunction addRows(sheet: Worksheet, headers: readonly string[], rows: readonly WorkbookInputRow[]): void {\n if (headers.length > 0) {\n sheet.addRow([...headers]);\n }\n for (const row of rows) {\n sheet.addRow([...rowToValues(row, headers)]);\n }\n}\n\nfunction addTable(sheet: Worksheet, tableName: string, headers: readonly string[], rows: readonly WorkbookInputRow[]): void {\n sheet.addTable({\n name: tableName,\n ref: \"A1\",\n headerRow: true,\n totalsRow: false,\n style: { theme: \"TableStyleMedium2\", showRowStripes: true },\n columns: headers.map((name) => ({ name })),\n rows: rows.map((row) => [...rowToValues(row, headers)]),\n });\n}\n\nasync function workbookToBytes(workbook: ExcelJS.Workbook): Promise<Uint8Array> {\n const buffer = await workbook.xlsx.writeBuffer();\n return new Uint8Array(buffer);\n}\n\nasync function loadWorkbook(bytes: Uint8Array): Promise<ExcelJS.Workbook> {\n const workbook = new ExcelJS.Workbook();\n await workbook.xlsx.load(uint8ArrayToArrayBuffer(bytes));\n return workbook;\n}\n\nfunction uint8ArrayToArrayBuffer(bytes: Uint8Array): ArrayBuffer {\n const copy = new ArrayBuffer(bytes.byteLength);\n new Uint8Array(copy).set(bytes);\n return copy;\n}\n\nfunction getWorksheet(workbook: ExcelJS.Workbook, sheetName: string): Worksheet {\n const sheet = workbook.getWorksheet(sheetName);\n if (sheet === undefined) {\n throw new Error(`Sheet \"${sheetName}\" not found`);\n }\n return sheet;\n}\n\nfunction serializeCellValue(value: unknown): JsonCellValue {\n if (value === null || value === undefined) {\n return null;\n }\n if (typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\") {\n return value;\n }\n if (value instanceof Date) {\n return value.toISOString();\n }\n if (typeof value === \"object\" && \"result\" in value) {\n return serializeCellValue((value as { readonly result?: unknown }).result);\n }\n return JSON.stringify(value);\n}\n\nfunction readRow(sheet: Worksheet, rowNumber: number, startColumn: number, endColumn: number): JsonRow {\n const row = sheet.getRow(rowNumber);\n const columnCount = endColumn - startColumn + 1;\n return Array.from({ length: columnCount }, (_value, index) =>\n serializeCellValue(row.getCell(startColumn + index).value),\n );\n}\n\nfunction readHeaderRow(sheet: Worksheet): readonly string[] {\n if (sheet.actualRowCount === 0) {\n return [];\n }\n return readRow(sheet, 1, 1, Math.max(1, sheet.actualColumnCount)).map((value) => String(value ?? \"\"));\n}\n\nfunction readSheet(sheet: Worksheet, options: WorkbookReadOptions): WorkbookSheetReadResult {\n const range = options.range === undefined ? undefined : parseA1Range(options.range);\n const startRow = range?.start.row ?? 1;\n const endRow = range?.end.row ?? Math.max(1, sheet.actualRowCount);\n const startColumn = range?.start.column ?? 1;\n const endColumn = range?.end.column ?? Math.max(1, sheet.actualColumnCount);\n const rows: JsonRow[] = [];\n for (let row = startRow; row <= endRow; row += 1) {\n rows.push(readRow(sheet, row, startColumn, endColumn));\n }\n return { name: sheet.name, rowCount: rows.length, columnCount: endColumn - startColumn + 1, rows };\n}\n\nexport async function createWorkbookBytes(input: WorkbookCreateInput): Promise<Uint8Array> {\n const workbook = new ExcelJS.Workbook();\n const sheet = workbook.addWorksheet(validateSheetName(input.sheetName));\n const headers = deriveHeaders(input.headers, input.rows);\n if (input.tableName !== undefined && input.tableName.length > 0 && headers.length > 0) {\n addTable(sheet, input.tableName, headers, input.rows);\n } else {\n addRows(sheet, headers, input.rows);\n }\n return await workbookToBytes(workbook);\n}\n\nexport async function readWorkbookBytes(\n bytes: Uint8Array,\n options: WorkbookReadOptions = {},\n): Promise<WorkbookReadResult> {\n const workbook = await loadWorkbook(bytes);\n const sheets =\n options.sheetName === undefined\n ? workbook.worksheets\n : [getWorksheet(workbook, validateSheetName(options.sheetName))];\n return { sheets: sheets.map((sheet) => readSheet(sheet, options)) };\n}\n\nexport async function appendWorkbookRows(\n bytes: Uint8Array,\n sheetName: string,\n rows: readonly WorkbookInputRow[],\n matchHeader: boolean,\n): Promise<WorkbookMutationResult> {\n const workbook = await loadWorkbook(bytes);\n const sheet = getWorksheet(workbook, validateSheetName(sheetName));\n const headers = matchHeader ? readHeaderRow(sheet) : deriveHeaders([], rows);\n for (const row of rows) {\n sheet.addRow([...rowToValues(row, headers)]);\n }\n return {\n bytes: await workbookToBytes(workbook),\n sheetName: sheet.name,\n rowCount: sheet.actualRowCount,\n columnCount: sheet.actualColumnCount,\n };\n}\n\nexport async function updateWorkbookCell(\n bytes: Uint8Array,\n sheetName: string,\n cellRef: string,\n value: CellValue,\n): Promise<WorkbookMutationResult> {\n const workbook = await loadWorkbook(bytes);\n const sheet = getWorksheet(workbook, validateSheetName(sheetName));\n const cell = parseA1Cell(cellRef);\n sheet.getCell(cell.row, cell.column).value = value;\n return {\n bytes: await workbookToBytes(workbook),\n sheetName: sheet.name,\n rowCount: sheet.actualRowCount,\n columnCount: sheet.actualColumnCount,\n };\n}\n\nexport async function addWorkbookSheet(\n bytes: Uint8Array,\n sheetName: string,\n headers: readonly string[],\n): Promise<WorkbookMutationResult> {\n const workbook = await loadWorkbook(bytes);\n const normalized = validateSheetName(sheetName);\n if (workbook.getWorksheet(normalized) !== undefined) {\n throw new Error(`Sheet \"${normalized}\" already exists`);\n }\n const sheet = workbook.addWorksheet(normalized);\n if (headers.length > 0) {\n sheet.addRow([...headers]);\n }\n return {\n bytes: await workbookToBytes(workbook),\n sheetName: sheet.name,\n rowCount: sheet.actualRowCount,\n columnCount: sheet.actualColumnCount,\n };\n}\n","export interface A1CellRef {\n readonly row: number;\n readonly column: number;\n}\n\nexport interface A1RangeRef {\n readonly start: A1CellRef;\n readonly end: A1CellRef;\n}\n\nconst CELL_REF_PATTERN = /^([A-Za-z]+)([1-9]\\d*)$/;\n\nexport function columnNameToNumber(columnName: string): number {\n const normalized = columnName.trim().toUpperCase();\n if (!/^[A-Z]+$/.test(normalized)) {\n throw new Error(`Invalid column name \"${columnName}\"`);\n }\n let total = 0;\n for (const char of normalized) {\n total = total * 26 + char.charCodeAt(0) - 64;\n }\n return total;\n}\n\nexport function parseA1Cell(input: string): A1CellRef {\n const trimmed = input.trim();\n const match = CELL_REF_PATTERN.exec(trimmed);\n if (match === null) {\n throw new Error(`Invalid A1 cell reference \"${input}\"`);\n }\n const columnName = match[1];\n const rowValue = match[2];\n if (columnName === undefined || rowValue === undefined) {\n throw new Error(`Invalid A1 cell reference \"${input}\"`);\n }\n return {\n row: Number.parseInt(rowValue, 10),\n column: columnNameToNumber(columnName),\n };\n}\n\nfunction orderRange(start: A1CellRef, end: A1CellRef): A1RangeRef {\n return {\n start: {\n row: Math.min(start.row, end.row),\n column: Math.min(start.column, end.column),\n },\n end: {\n row: Math.max(start.row, end.row),\n column: Math.max(start.column, end.column),\n },\n };\n}\n\nexport function parseA1Range(input: string): A1RangeRef {\n const parts = input.split(\":\").map((part) => part.trim());\n if (parts.length === 1) {\n const cell = parseA1Cell(parts[0] ?? \"\");\n return { start: cell, end: cell };\n }\n if (parts.length !== 2) {\n throw new Error(`Invalid A1 range \"${input}\"`);\n }\n return orderRange(parseA1Cell(parts[0] ?? \"\"), parseA1Cell(parts[1] ?? \"\"));\n}\n","import {\n downloadDriveFile,\n getDriveItemByPath,\n replaceDriveFile,\n selectDrive,\n uploadNewDriveFile,\n} from \"../graph/drive.js\";\nimport type { SharePointExcelSession } from \"../session.js\";\nimport type {\n DriveItemSummary,\n WorkbookCreateInput,\n WorkbookInputRow,\n WorkbookMutationResult,\n WorkbookReadOptions,\n WorkbookReadResult,\n} from \"../types.js\";\n\nimport {\n addWorkbookSheet,\n appendWorkbookRows,\n createWorkbookBytes,\n readWorkbookBytes,\n updateWorkbookCell,\n} from \"./excel.js\";\n\nexport interface WorkbookServiceTarget {\n readonly session: SharePointExcelSession;\n readonly driveHint?: string;\n}\n\nexport interface RemoteWorkbookResult {\n readonly driveId: string;\n readonly driveName: string;\n readonly path: string;\n readonly item: DriveItemSummary;\n}\n\nexport interface RemoteReadResult extends RemoteWorkbookResult {\n readonly workbook: WorkbookReadResult;\n}\n\nexport interface RemoteMutationResult extends RemoteWorkbookResult {\n readonly mutation: WorkbookMutationResult;\n}\n\nfunction normalizeWorkbookPath(path: string): string {\n const normalized = path.trim().replace(/^\\/+|\\/+$/g, \"\");\n if (normalized.length === 0) {\n throw new Error(\"Workbook path is required\");\n }\n if (!normalized.toLowerCase().endsWith(\".xlsx\")) {\n throw new Error(`Workbook path must end with .xlsx: ${path}`);\n }\n return normalized;\n}\n\nfunction requireEtag(item: DriveItemSummary, path: string): string {\n if (item.eTag === undefined || item.eTag.length === 0) {\n throw new Error(`Cannot update ${path}: SharePoint item is missing an ETag`);\n }\n return item.eTag;\n}\n\nasync function downloadExistingWorkbook(\n target: WorkbookServiceTarget,\n path: string,\n): Promise<{ readonly bytes: Uint8Array; readonly item: DriveItemSummary; readonly driveId: string; readonly driveName: string }> {\n const drive = selectDrive(target.session.drives, target.driveHint);\n const item = await getDriveItemByPath(target.session.client, drive.id, path);\n if (item === null || item.isFolder) {\n throw new Error(`Workbook not found: ${path}`);\n }\n const bytes = await downloadDriveFile(target.session.client, drive.id, path);\n return { bytes, item, driveId: drive.id, driveName: drive.name };\n}\n\nexport async function createRemoteWorkbook(\n target: WorkbookServiceTarget,\n path: string,\n input: WorkbookCreateInput,\n): Promise<RemoteWorkbookResult> {\n const normalizedPath = normalizeWorkbookPath(path);\n const drive = selectDrive(target.session.drives, target.driveHint);\n const bytes = await createWorkbookBytes(input);\n const item = await uploadNewDriveFile(target.session.client, drive.id, normalizedPath, bytes);\n return { driveId: drive.id, driveName: drive.name, path: normalizedPath, item };\n}\n\nexport async function readRemoteWorkbook(\n target: WorkbookServiceTarget,\n path: string,\n options: WorkbookReadOptions = {},\n): Promise<RemoteReadResult> {\n const normalizedPath = normalizeWorkbookPath(path);\n const downloaded = await downloadExistingWorkbook(target, normalizedPath);\n const workbook = await readWorkbookBytes(downloaded.bytes, options);\n return { ...downloaded, path: normalizedPath, workbook };\n}\n\nexport async function appendRemoteWorkbookRows(\n target: WorkbookServiceTarget,\n path: string,\n sheetName: string,\n rows: readonly WorkbookInputRow[],\n matchHeader: boolean,\n): Promise<RemoteMutationResult> {\n const normalizedPath = normalizeWorkbookPath(path);\n const downloaded = await downloadExistingWorkbook(target, normalizedPath);\n const mutation = await appendWorkbookRows(downloaded.bytes, sheetName, rows, matchHeader);\n const item = await replaceDriveFile(\n target.session.client,\n downloaded.driveId,\n normalizedPath,\n requireEtag(downloaded.item, normalizedPath),\n mutation.bytes,\n );\n return { ...downloaded, item, path: normalizedPath, mutation };\n}\n\nexport async function updateRemoteWorkbookCell(\n target: WorkbookServiceTarget,\n path: string,\n sheetName: string,\n cellRef: string,\n value: string | number | boolean | null,\n): Promise<RemoteMutationResult> {\n const normalizedPath = normalizeWorkbookPath(path);\n const downloaded = await downloadExistingWorkbook(target, normalizedPath);\n const mutation = await updateWorkbookCell(downloaded.bytes, sheetName, cellRef, value);\n const item = await replaceDriveFile(\n target.session.client,\n downloaded.driveId,\n normalizedPath,\n requireEtag(downloaded.item, normalizedPath),\n mutation.bytes,\n );\n return { ...downloaded, item, path: normalizedPath, mutation };\n}\n\nexport async function addRemoteWorkbookSheet(\n target: WorkbookServiceTarget,\n path: string,\n sheetName: string,\n headers: readonly string[],\n): Promise<RemoteMutationResult> {\n const normalizedPath = normalizeWorkbookPath(path);\n const downloaded = await downloadExistingWorkbook(target, normalizedPath);\n const mutation = await addWorkbookSheet(downloaded.bytes, sheetName, headers);\n const item = await replaceDriveFile(\n target.session.client,\n downloaded.driveId,\n normalizedPath,\n requireEtag(downloaded.item, normalizedPath),\n mutation.bytes,\n );\n return { ...downloaded, item, path: normalizedPath, mutation };\n}\n","import type { Command } from \"commander\";\n\nimport type { RuntimeOverrides } from \"../config/resolve.js\";\n\nexport interface CommonFlags extends RuntimeOverrides {\n readonly json?: boolean;\n}\n\nexport interface ConfigSetFlags {\n readonly profile?: string;\n readonly tenant?: string;\n readonly clientId?: string;\n readonly clientSecret?: string;\n readonly site?: string;\n readonly drive?: string;\n readonly store?: string;\n readonly allowPlaintextSecret?: boolean;\n readonly json?: boolean;\n}\n\nexport interface ConfigGetFlags {\n readonly profile?: string;\n readonly json?: boolean;\n}\n\nexport interface CreateFlags extends CommonFlags {\n readonly drive?: string;\n readonly path?: string;\n readonly sheet?: string;\n readonly headers?: string;\n readonly rows?: string;\n readonly table?: string;\n}\n\nexport interface ReadFlags extends CommonFlags {\n readonly drive?: string;\n readonly path?: string;\n readonly sheet?: string;\n readonly range?: string;\n}\n\nexport interface AppendFlags extends CommonFlags {\n readonly drive?: string;\n readonly path?: string;\n readonly sheet?: string;\n readonly record?: string;\n readonly matchHeader?: boolean;\n}\n\nexport interface UpdateCellFlags extends CommonFlags {\n readonly drive?: string;\n readonly path?: string;\n readonly sheet?: string;\n readonly cell?: string;\n readonly value?: string;\n}\n\nexport interface AddSheetFlags extends CommonFlags {\n readonly drive?: string;\n readonly path?: string;\n readonly sheet?: string;\n readonly headers?: string;\n}\n\nexport function addCommonOptions(cmd: Command): Command {\n return cmd\n .option(\"--profile <name>\", \"Stored profile name\")\n .option(\"--tenant <id>\", \"Azure AD tenant ID\")\n .option(\"--client-id <id>\", \"App registration client ID\")\n .option(\"--client-secret <secret>\", \"App registration client secret\")\n .option(\"--site <ref>\", \"SharePoint site, e.g. contoso.sharepoint.com/sites/demo\")\n .option(\"--drive <nameOrId>\", \"Document library name or ID\")\n .option(\"--json\", \"Emit JSON output\", false);\n}\n\nexport function toRuntimeOverrides(flags: CommonFlags): RuntimeOverrides {\n return {\n profile: flags.profile,\n tenant: flags.tenant,\n clientId: flags.clientId,\n clientSecret: flags.clientSecret,\n site: flags.site,\n drive: flags.drive,\n };\n}\n\nexport function requireFlag(value: string | undefined, flagName: string): string {\n if (value === undefined || value.trim().length === 0) {\n throw new Error(`${flagName} is required`);\n }\n return value;\n}\n"],"mappings":"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","names":["process","process","process","chmod","mkdir","readFile","writeFile","dirname","isMissingFileError","readFile","mkdir","dirname","writeFile","chmod","process","process","process","process","process","asString","process","process"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli/index.ts","../src/cli/commands.ts","../src/config/resolve.ts","../src/credentials/profile-store.ts","../src/config/paths.ts","../src/types.ts","../src/credentials/secret-vault.ts","../src/graph/client.ts","../src/graph/site.ts","../src/output/format.ts","../src/auth/token.ts","../src/graph/drive.ts","../src/session.ts","../src/workbook/json.ts","../src/workbook/excel.ts","../src/workbook/a1.ts","../src/workbook/service.ts","../src/cli/options.ts"],"sourcesContent":["import process from \"node:process\";\n\nimport { Command } from \"commander\";\n\nimport { registerCommands } from \"./commands.js\";\n\nexport async function main(argv: readonly string[]): Promise<void> {\n const program = new Command();\n program\n .name(\"saptools-sharepoint-excel\")\n .description(\"Create, read, and update SharePoint-hosted Excel workbooks\");\n registerCommands(program);\n await program.parseAsync([...argv]);\n}\n\ntry {\n await main(process.argv);\n} catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n process.stderr.write(`Error: ${message}\\n`);\n process.exit(1);\n}\n","import process from \"node:process\";\n\nimport type { Command } from \"commander\";\n\nimport { parseSecretStoreKind, resolveRuntime } from \"../config/resolve.js\";\nimport type { ResolvedRuntime } from \"../config/resolve.js\";\nimport { createProfileStore, findProfile, redactProfile, removeProfile, upsertProfile } from \"../credentials/profile-store.js\";\nimport type { SecretVault } from \"../credentials/secret-vault.js\";\nimport { createFileSecretVault, createKeyringSecretVault } from \"../credentials/secret-vault.js\";\nimport { formatCreateResult, formatDriveList, formatMutationResult, formatProfile, formatTestResult, formatWorkbookRead } from \"../output/format.js\";\nimport { openSession } from \"../session.js\";\nimport type { SharePointExcelSession } from \"../session.js\";\nimport { DEFAULT_PROFILE_NAME, ENV_ALLOW_PLAINTEXT } from \"../types.js\";\nimport type { WorkbookReadOptions } from \"../types.js\";\nimport { parseCellValue, parseHeaders, parseWorkbookRows } from \"../workbook/json.js\";\nimport { addRemoteWorkbookSheet, appendRemoteWorkbookRows, createRemoteWorkbook, readRemoteWorkbook, updateRemoteWorkbookCell } from \"../workbook/service.js\";\nimport type { WorkbookServiceTarget } from \"../workbook/service.js\";\n\nimport {\n addCommonOptions,\n requireFlag,\n toRuntimeOverrides,\n} from \"./options.js\";\nimport type {\n AddSheetFlags,\n AppendFlags,\n CommonFlags,\n ConfigGetFlags,\n ConfigSetFlags,\n CreateFlags,\n ReadFlags,\n UpdateCellFlags,\n} from \"./options.js\";\n\nfunction writeJson(value: unknown): void {\n process.stdout.write(`${JSON.stringify(value, null, 2)}\\n`);\n}\n\nfunction writeOutput(json: boolean | undefined, jsonValue: unknown, textValue: string): void {\n if (json === true) {\n writeJson(jsonValue);\n return;\n }\n process.stdout.write(`${textValue}\\n`);\n}\n\nfunction getSecretVault(storeKind: \"keyring\" | \"file\"): SecretVault {\n return storeKind === \"keyring\" ? createKeyringSecretVault() : createFileSecretVault();\n}\n\ninterface OpenRuntimeResult {\n readonly runtime: ResolvedRuntime;\n readonly session: SharePointExcelSession;\n}\n\nasync function openRuntime(flags: CommonFlags): Promise<OpenRuntimeResult> {\n const runtime = await resolveRuntime({ overrides: toRuntimeOverrides(flags) });\n const session = await openSession(runtime.target);\n return { runtime, session };\n}\n\nfunction toServiceTarget(\n session: SharePointExcelSession,\n runtime: ResolvedRuntime,\n flags: CommonFlags,\n): WorkbookServiceTarget {\n const driveHint = flags.drive ?? runtime.drive;\n return driveHint === undefined ? { session } : { session, driveHint };\n}\n\nfunction toReadOptions(flags: ReadFlags): WorkbookReadOptions {\n return {\n ...(flags.sheet === undefined ? {} : { sheetName: flags.sheet }),\n ...(flags.range === undefined ? {} : { range: flags.range }),\n };\n}\n\nfunction assertPlaintextAllowed(flags: ConfigSetFlags): void {\n if (flags.store !== \"file\") {\n return;\n }\n if (flags.allowPlaintextSecret === true || process.env[ENV_ALLOW_PLAINTEXT] === \"1\") {\n return;\n }\n throw new Error(\n `Plaintext secret file store requires --allow-plaintext-secret or ${ENV_ALLOW_PLAINTEXT}=1`,\n );\n}\n\nasync function handleConfigSet(flags: ConfigSetFlags): Promise<void> {\n assertPlaintextAllowed(flags);\n const secretStore = parseSecretStoreKind(flags.store);\n const input = {\n name: flags.profile ?? DEFAULT_PROFILE_NAME,\n tenantId: requireFlag(flags.tenant, \"--tenant\"),\n clientId: requireFlag(flags.clientId, \"--client-id\"),\n clientSecret: requireFlag(flags.clientSecret, \"--client-secret\"),\n site: requireFlag(flags.site, \"--site\"),\n secretStore,\n ...(flags.drive === undefined ? {} : { drive: flags.drive }),\n };\n const profile = await upsertProfile(createProfileStore(), getSecretVault(secretStore), input);\n const redacted = await redactProfile(profile, getSecretVault(secretStore));\n writeOutput(flags.json, redacted, formatProfile(redacted));\n}\n\nasync function handleConfigGet(flags: ConfigGetFlags): Promise<void> {\n const name = flags.profile ?? DEFAULT_PROFILE_NAME;\n const profile = findProfile(await createProfileStore().readProfiles(), name);\n if (profile === undefined) {\n throw new Error(`Profile \"${name}\" not found`);\n }\n const redacted = await redactProfile(profile, getSecretVault(profile.secretStore));\n writeOutput(flags.json, redacted, formatProfile(redacted));\n}\n\nasync function handleConfigRemove(flags: ConfigGetFlags): Promise<void> {\n const name = flags.profile ?? DEFAULT_PROFILE_NAME;\n const profile = findProfile(await createProfileStore().readProfiles(), name);\n const secretStore = profile?.secretStore ?? \"keyring\";\n const removed = await removeProfile(createProfileStore(), getSecretVault(secretStore), name);\n const output = { profile: name, removed };\n writeOutput(flags.json, output, `Removed profile ${name}: ${String(removed)}`);\n}\n\nasync function handleTest(flags: CommonFlags): Promise<void> {\n const { session } = await openRuntime(flags);\n const output = { site: session.site, drives: session.drives, tokenType: session.token.tokenType };\n writeOutput(flags.json, output, formatTestResult(session.site, session.drives));\n}\n\nasync function handleDrives(flags: CommonFlags): Promise<void> {\n const { session } = await openRuntime(flags);\n writeOutput(flags.json, session.drives, formatDriveList(session.drives));\n}\n\nasync function handleCreate(flags: CreateFlags): Promise<void> {\n const { runtime, session } = await openRuntime(flags);\n const result = await createRemoteWorkbook(\n toServiceTarget(session, runtime, flags),\n requireFlag(flags.path, \"--path\"),\n {\n sheetName: requireFlag(flags.sheet, \"--sheet\"),\n headers: parseHeaders(flags.headers),\n rows: parseWorkbookRows(flags.rows),\n ...(flags.table === undefined ? {} : { tableName: flags.table }),\n },\n );\n writeOutput(flags.json, result, formatCreateResult(result));\n}\n\nasync function handleRead(flags: ReadFlags): Promise<void> {\n const { runtime, session } = await openRuntime(flags);\n const result = await readRemoteWorkbook(\n toServiceTarget(session, runtime, flags),\n requireFlag(flags.path, \"--path\"),\n toReadOptions(flags),\n );\n writeOutput(flags.json, result, formatWorkbookRead(result));\n}\n\nasync function handleAppend(flags: AppendFlags): Promise<void> {\n const { runtime, session } = await openRuntime(flags);\n const result = await appendRemoteWorkbookRows(\n toServiceTarget(session, runtime, flags),\n requireFlag(flags.path, \"--path\"),\n requireFlag(flags.sheet, \"--sheet\"),\n parseWorkbookRows(requireFlag(flags.record, \"--record\")),\n flags.matchHeader !== false,\n );\n writeOutput(flags.json, result, formatMutationResult(\"Updated\", result));\n}\n\nasync function handleUpdateCell(flags: UpdateCellFlags): Promise<void> {\n const { runtime, session } = await openRuntime(flags);\n const result = await updateRemoteWorkbookCell(\n toServiceTarget(session, runtime, flags),\n requireFlag(flags.path, \"--path\"),\n requireFlag(flags.sheet, \"--sheet\"),\n requireFlag(flags.cell, \"--cell\"),\n parseCellValue(requireFlag(flags.value, \"--value\")),\n );\n writeOutput(flags.json, result, formatMutationResult(\"Updated\", result));\n}\n\nasync function handleAddSheet(flags: AddSheetFlags): Promise<void> {\n const { runtime, session } = await openRuntime(flags);\n const result = await addRemoteWorkbookSheet(\n toServiceTarget(session, runtime, flags),\n requireFlag(flags.path, \"--path\"),\n requireFlag(flags.sheet, \"--sheet\"),\n parseHeaders(flags.headers),\n );\n writeOutput(flags.json, result, formatMutationResult(\"Updated\", result));\n}\n\nfunction registerConfigCommands(program: Command): void {\n const config = program.command(\"config\").description(\"Manage local SharePoint Excel profiles\");\n config.command(\"set\")\n .description(\"Store a SharePoint app-only profile\")\n .option(\"--profile <name>\", \"Profile name\", DEFAULT_PROFILE_NAME)\n .requiredOption(\"--tenant <id>\", \"Azure AD tenant ID\")\n .requiredOption(\"--client-id <id>\", \"App registration client ID\")\n .requiredOption(\"--client-secret <secret>\", \"App registration client secret\")\n .requiredOption(\"--site <ref>\", \"SharePoint site\")\n .option(\"--drive <nameOrId>\", \"Default document library\")\n .option(\"--store <keyring|file>\", \"Secret store\", \"keyring\")\n .option(\"--allow-plaintext-secret\", \"Allow plaintext file secret storage\", false)\n .option(\"--json\", \"Emit JSON output\", false)\n .action(handleConfigSet);\n config.command(\"get\")\n .description(\"Read a stored profile without printing secrets\")\n .option(\"--profile <name>\", \"Profile name\", DEFAULT_PROFILE_NAME)\n .option(\"--json\", \"Emit JSON output\", false)\n .action(handleConfigGet);\n config.command(\"remove\")\n .description(\"Remove a stored profile\")\n .option(\"--profile <name>\", \"Profile name\", DEFAULT_PROFILE_NAME)\n .option(\"--json\", \"Emit JSON output\", false)\n .action(handleConfigRemove);\n}\n\nexport function registerCommands(program: Command): void {\n registerConfigCommands(program);\n addCommonOptions(program.command(\"test\").description(\"Authenticate, resolve site, and list drives\"))\n .action(handleTest);\n addCommonOptions(program.command(\"drives\").description(\"List SharePoint document libraries\"))\n .action(handleDrives);\n addCommonOptions(program.command(\"create\").description(\"Create a new .xlsx file without overwriting\"))\n .requiredOption(\"--path <xlsxPath>\", \"SharePoint path for the new workbook\")\n .requiredOption(\"--sheet <name>\", \"Initial sheet name\")\n .option(\"--headers <csv>\", \"Comma-separated header row\")\n .option(\"--rows <json>\", \"JSON row/object or array of rows/objects\")\n .option(\"--table <name>\", \"Optional Excel table name\")\n .action(handleCreate);\n addCommonOptions(program.command(\"read\").description(\"Read workbook sheets or a range\"))\n .requiredOption(\"--path <xlsxPath>\", \"SharePoint workbook path\")\n .option(\"--sheet <name>\", \"Sheet to read\")\n .option(\"--range <a1Range>\", \"A1 range, e.g. A1:C10\")\n .action(handleRead);\n addCommonOptions(program.command(\"append\").description(\"Append one or more records to a sheet\"))\n .requiredOption(\"--path <xlsxPath>\", \"SharePoint workbook path\")\n .requiredOption(\"--sheet <name>\", \"Sheet to append\")\n .requiredOption(\"--record <json>\", \"JSON row/object or array of rows/objects\")\n .option(\"--no-match-header\", \"Append object values by key order instead of row 1 headers\")\n .action(handleAppend);\n addCommonOptions(program.command(\"update-cell\").description(\"Update one cell in a workbook\"))\n .requiredOption(\"--path <xlsxPath>\", \"SharePoint workbook path\")\n .requiredOption(\"--sheet <name>\", \"Sheet name\")\n .requiredOption(\"--cell <a1Cell>\", \"A1 cell reference, e.g. B2\")\n .requiredOption(\"--value <jsonOrString>\", \"JSON scalar or raw string\")\n .action(handleUpdateCell);\n addCommonOptions(program.command(\"add-sheet\").description(\"Add a new sheet to an existing workbook\"))\n .requiredOption(\"--path <xlsxPath>\", \"SharePoint workbook path\")\n .requiredOption(\"--sheet <name>\", \"New sheet name\")\n .option(\"--headers <csv>\", \"Optional comma-separated header row\")\n .action(handleAddSheet);\n}\n","import process from \"node:process\";\n\nimport type { ProfileStore } from \"../credentials/profile-store.js\";\nimport { createProfileStore, findProfile } from \"../credentials/profile-store.js\";\nimport type { SecretVault } from \"../credentials/secret-vault.js\";\nimport { createFileSecretVault, createKeyringSecretVault } from \"../credentials/secret-vault.js\";\nimport { parseSiteRef } from \"../graph/site.js\";\nimport type { SecretStoreKind, SharePointTarget, StoredProfile } from \"../types.js\";\nimport {\n DEFAULT_PROFILE_NAME,\n ENV_CLIENT_ID,\n ENV_CLIENT_SECRET,\n ENV_DRIVE,\n ENV_PROFILE,\n ENV_SITE,\n ENV_TENANT,\n FALLBACK_ENV_CLIENT_ID,\n FALLBACK_ENV_CLIENT_SECRET,\n FALLBACK_ENV_DRIVE,\n FALLBACK_ENV_SITE,\n FALLBACK_ENV_TENANT,\n} from \"../types.js\";\n\nexport interface RuntimeOverrides {\n readonly profile?: string | undefined;\n readonly tenant?: string | undefined;\n readonly clientId?: string | undefined;\n readonly clientSecret?: string | undefined;\n readonly site?: string | undefined;\n readonly drive?: string | undefined;\n}\n\nexport interface ResolveRuntimeOptions {\n readonly env?: NodeJS.ProcessEnv;\n readonly overrides?: RuntimeOverrides;\n readonly profileStore?: ProfileStore;\n readonly keyringVault?: SecretVault;\n readonly fileVault?: SecretVault;\n}\n\nexport interface ResolvedRuntime {\n readonly target: SharePointTarget;\n readonly drive?: string;\n readonly profileName: string;\n readonly source: \"profile\" | \"env\";\n}\n\nfunction pickEnv(env: NodeJS.ProcessEnv, primary: string, fallback: string): string | undefined {\n const value = env[primary] ?? env[fallback];\n return value === undefined || value.length === 0 ? undefined : value;\n}\n\nfunction pickValue(\n override: string | undefined,\n envValue: string | undefined,\n profileValue: string | undefined,\n): string | undefined {\n if (override !== undefined && override.length > 0) {\n return override;\n }\n return envValue ?? profileValue;\n}\n\nfunction vaultForProfile(\n profile: StoredProfile | undefined,\n options: ResolveRuntimeOptions,\n): SecretVault {\n if (profile?.secretStore === \"file\") {\n return options.fileVault ?? createFileSecretVault();\n }\n return options.keyringVault ?? createKeyringSecretVault();\n}\n\nasync function resolveClientSecret(\n override: string | undefined,\n envValue: string | undefined,\n profile: StoredProfile | undefined,\n options: ResolveRuntimeOptions,\n): Promise<string | undefined> {\n if (override !== undefined && override.length > 0) {\n return override;\n }\n if (envValue !== undefined) {\n return envValue;\n }\n return profile === undefined ? undefined : await vaultForProfile(profile, options).getSecret(profile.name);\n}\n\nfunction requireValue(value: string | undefined, humanName: string): string {\n if (value === undefined || value.length === 0) {\n throw new Error(`${humanName} is required (pass a flag, set env, or run config set)`);\n }\n return value;\n}\n\nexport async function resolveRuntime(options: ResolveRuntimeOptions = {}): Promise<ResolvedRuntime> {\n const env = options.env ?? process.env;\n const overrides = options.overrides ?? {};\n const profileName =\n overrides.profile ?? env[ENV_PROFILE] ?? DEFAULT_PROFILE_NAME;\n const store = options.profileStore ?? createProfileStore();\n const profile = findProfile(await store.readProfiles(), profileName);\n\n const tenantId = pickValue(\n overrides.tenant,\n pickEnv(env, ENV_TENANT, FALLBACK_ENV_TENANT),\n profile?.tenantId,\n );\n const clientId = pickValue(\n overrides.clientId,\n pickEnv(env, ENV_CLIENT_ID, FALLBACK_ENV_CLIENT_ID),\n profile?.clientId,\n );\n const site = pickValue(overrides.site, pickEnv(env, ENV_SITE, FALLBACK_ENV_SITE), profile?.site);\n const drive = pickValue(overrides.drive, pickEnv(env, ENV_DRIVE, FALLBACK_ENV_DRIVE), profile?.drive);\n const clientSecret = await resolveClientSecret(\n overrides.clientSecret,\n pickEnv(env, ENV_CLIENT_SECRET, FALLBACK_ENV_CLIENT_SECRET),\n profile,\n options,\n );\n\n return {\n target: {\n credentials: {\n tenantId: requireValue(tenantId, \"Tenant ID\"),\n clientId: requireValue(clientId, \"Client ID\"),\n clientSecret: requireValue(clientSecret, \"Client secret\"),\n },\n site: parseSiteRef(requireValue(site, \"SharePoint site\")),\n },\n ...(drive === undefined ? {} : { drive }),\n profileName,\n source: profile === undefined ? \"env\" : \"profile\",\n };\n}\n\nexport function parseSecretStoreKind(value: string | undefined): SecretStoreKind {\n if (value === undefined || value === \"keyring\") {\n return \"keyring\";\n }\n if (value === \"file\") {\n return \"file\";\n }\n throw new Error(`Invalid secret store \"${value}\". Expected keyring or file`);\n}\n","import { chmod, mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\nimport { profilesPath } from \"../config/paths.js\";\nimport type { RedactedProfile, SecretStoreKind, StoredProfile } from \"../types.js\";\nimport { DEFAULT_PROFILE_NAME } from \"../types.js\";\n\nimport type { SecretVault } from \"./secret-vault.js\";\n\ninterface ProfileFile {\n readonly version: 1;\n readonly profiles: readonly StoredProfile[];\n}\n\nexport interface ProfileStore {\n readProfiles: () => Promise<readonly StoredProfile[]>;\n writeProfiles: (profiles: readonly StoredProfile[]) => Promise<void>;\n}\n\nexport interface UpsertProfileInput {\n readonly name?: string;\n readonly tenantId: string;\n readonly clientId: string;\n readonly clientSecret: string;\n readonly site: string;\n readonly drive?: string;\n readonly secretStore: SecretStoreKind;\n readonly updatedAt?: Date;\n}\n\nconst PROFILE_FILE_MODE = 0o600;\nconst EMPTY_PROFILE_FILE: ProfileFile = { version: 1, profiles: [] };\n\nfunction isMissingFileError(err: unknown): boolean {\n return err instanceof Error && \"code\" in err && err.code === \"ENOENT\";\n}\n\nfunction isSecretStoreKind(value: unknown): value is SecretStoreKind {\n return value === \"keyring\" || value === \"file\";\n}\n\nfunction toStoredProfile(value: unknown): StoredProfile | undefined {\n if (typeof value !== \"object\" || value === null) {\n return undefined;\n }\n const raw = value as Record<string, unknown>;\n const name = raw[\"name\"];\n const tenantId = raw[\"tenantId\"];\n const clientId = raw[\"clientId\"];\n const site = raw[\"site\"];\n const drive = raw[\"drive\"];\n const secretStore = raw[\"secretStore\"];\n const updatedAt = raw[\"updatedAt\"];\n if (\n typeof name !== \"string\" ||\n typeof tenantId !== \"string\" ||\n typeof clientId !== \"string\" ||\n typeof site !== \"string\" ||\n typeof updatedAt !== \"string\" ||\n !isSecretStoreKind(secretStore)\n ) {\n return undefined;\n }\n return {\n name,\n tenantId,\n clientId,\n site,\n ...(typeof drive === \"string\" ? { drive } : {}),\n secretStore,\n updatedAt,\n };\n}\n\nfunction isStoredProfile(value: StoredProfile | undefined): value is StoredProfile {\n return value !== undefined;\n}\n\nasync function readProfileFile(path: string): Promise<ProfileFile> {\n try {\n const raw = await readFile(path, \"utf8\");\n const parsed = JSON.parse(raw) as { readonly version?: unknown; readonly profiles?: unknown };\n if (parsed.version !== 1 || !Array.isArray(parsed.profiles)) {\n return EMPTY_PROFILE_FILE;\n }\n return { version: 1, profiles: parsed.profiles.map(toStoredProfile).filter(isStoredProfile) };\n } catch (err) {\n if (isMissingFileError(err)) {\n return EMPTY_PROFILE_FILE;\n }\n throw err;\n }\n}\n\nasync function writeProfileFile(path: string, value: ProfileFile): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, `${JSON.stringify(value, null, 2)}\\n`, {\n encoding: \"utf8\",\n mode: PROFILE_FILE_MODE,\n });\n await chmod(path, PROFILE_FILE_MODE);\n}\n\nexport function createProfileStore(path = profilesPath()): ProfileStore {\n return {\n async readProfiles(): Promise<readonly StoredProfile[]> {\n return (await readProfileFile(path)).profiles;\n },\n async writeProfiles(profiles: readonly StoredProfile[]): Promise<void> {\n await writeProfileFile(path, { version: 1, profiles });\n },\n };\n}\n\nexport function findProfile(\n profiles: readonly StoredProfile[],\n name = DEFAULT_PROFILE_NAME,\n): StoredProfile | undefined {\n return profiles.find((profile) => profile.name === name);\n}\n\nexport async function upsertProfile(\n store: ProfileStore,\n vault: SecretVault,\n input: UpsertProfileInput,\n): Promise<StoredProfile> {\n const name = input.name ?? DEFAULT_PROFILE_NAME;\n const stored: StoredProfile = {\n name,\n tenantId: input.tenantId,\n clientId: input.clientId,\n site: input.site,\n ...(input.drive === undefined || input.drive.length === 0 ? {} : { drive: input.drive }),\n secretStore: input.secretStore,\n updatedAt: (input.updatedAt ?? new Date()).toISOString(),\n };\n const profiles = await store.readProfiles();\n const nextProfiles = profiles.some((profile) => profile.name === name)\n ? profiles.map((profile) => (profile.name === name ? stored : profile))\n : [...profiles, stored];\n await vault.setSecret(name, input.clientSecret);\n await store.writeProfiles(nextProfiles);\n return stored;\n}\n\nexport async function removeProfile(\n store: ProfileStore,\n vault: SecretVault,\n name = DEFAULT_PROFILE_NAME,\n): Promise<boolean> {\n const profiles = await store.readProfiles();\n const nextProfiles = profiles.filter((profile) => profile.name !== name);\n await vault.deleteSecret(name);\n if (nextProfiles.length === profiles.length) {\n return false;\n }\n await store.writeProfiles(nextProfiles);\n return true;\n}\n\nexport async function redactProfile(\n profile: StoredProfile,\n vault: SecretVault,\n): Promise<RedactedProfile> {\n const secret = await vault.getSecret(profile.name);\n return {\n ...profile,\n clientId: `${profile.clientId.slice(0, 4)}...${profile.clientId.slice(-4)}`,\n hasClientSecret: secret !== undefined,\n };\n}\n","import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport process from \"node:process\";\n\nimport { ENV_HOME } from \"../types.js\";\n\nexport const SAPTOOLS_DIR_NAME = \".saptools\";\nexport const PACKAGE_DIR_NAME = \"sharepoint-excel\";\nexport const PROFILES_FILENAME = \"profiles.json\";\nexport const FILE_SECRETS_FILENAME = \"secrets.json\";\n\nexport function packageDataDir(env: NodeJS.ProcessEnv = process.env): string {\n const override = env[ENV_HOME];\n if (override !== undefined && override.length > 0) {\n return override;\n }\n return join(homedir(), SAPTOOLS_DIR_NAME, PACKAGE_DIR_NAME);\n}\n\nexport function profilesPath(env: NodeJS.ProcessEnv = process.env): string {\n return join(packageDataDir(env), PROFILES_FILENAME);\n}\n\nexport function fileSecretsPath(env: NodeJS.ProcessEnv = process.env): string {\n return join(packageDataDir(env), FILE_SECRETS_FILENAME);\n}\n","export type SecretStoreKind = \"keyring\" | \"file\";\n\nexport interface SharePointCredentials {\n readonly tenantId: string;\n readonly clientId: string;\n readonly clientSecret: string;\n}\n\nexport interface SharePointSiteRef {\n readonly hostname: string;\n readonly sitePath: string;\n}\n\nexport interface SharePointTarget {\n readonly credentials: SharePointCredentials;\n readonly site: SharePointSiteRef;\n}\n\nexport interface AccessTokenInfo {\n readonly accessToken: string;\n readonly expiresOn: number;\n readonly tokenType: string;\n readonly scope?: string;\n}\n\nexport interface SharePointSite {\n readonly id: string;\n readonly name: string;\n readonly displayName: string;\n readonly webUrl: string;\n}\n\nexport interface SharePointDrive {\n readonly id: string;\n readonly name: string;\n readonly driveType: string;\n readonly webUrl: string;\n}\n\nexport interface DriveItemSummary {\n readonly id: string;\n readonly name: string;\n readonly isFolder: boolean;\n readonly size: number;\n readonly eTag?: string;\n readonly cTag?: string;\n readonly webUrl?: string;\n}\n\nexport interface StoredProfile {\n readonly name: string;\n readonly tenantId: string;\n readonly clientId: string;\n readonly site: string;\n readonly drive?: string;\n readonly secretStore: SecretStoreKind;\n readonly updatedAt: string;\n}\n\nexport interface RedactedProfile extends Omit<StoredProfile, \"clientId\"> {\n readonly clientId: string;\n readonly hasClientSecret: boolean;\n}\n\nexport type JsonCellValue = string | number | boolean | null;\nexport type JsonRow = readonly JsonCellValue[];\nexport type JsonRecord = Readonly<Record<string, JsonCellValue>>;\nexport type WorkbookInputRow = JsonRow | JsonRecord;\n\nexport interface WorkbookCreateInput {\n readonly sheetName: string;\n readonly headers: readonly string[];\n readonly rows: readonly WorkbookInputRow[];\n readonly tableName?: string;\n}\n\nexport interface WorkbookReadOptions {\n readonly sheetName?: string;\n readonly range?: string;\n}\n\nexport interface WorkbookSheetReadResult {\n readonly name: string;\n readonly rowCount: number;\n readonly columnCount: number;\n readonly rows: readonly JsonRow[];\n}\n\nexport interface WorkbookReadResult {\n readonly sheets: readonly WorkbookSheetReadResult[];\n}\n\nexport interface WorkbookMutationResult {\n readonly bytes: Uint8Array;\n readonly sheetName: string;\n readonly rowCount: number;\n readonly columnCount: number;\n}\n\nexport const DEFAULT_PROFILE_NAME = \"default\";\nexport const DEFAULT_AUTH_BASE = \"https://login.microsoftonline.com\";\nexport const DEFAULT_GRAPH_BASE = \"https://graph.microsoft.com/v1.0\";\n\nexport const ENV_TENANT = \"SHAREPOINT_EXCEL_TENANT_ID\";\nexport const ENV_CLIENT_ID = \"SHAREPOINT_EXCEL_CLIENT_ID\";\nexport const ENV_CLIENT_SECRET = \"SHAREPOINT_EXCEL_CLIENT_SECRET\";\nexport const ENV_SITE = \"SHAREPOINT_EXCEL_SITE\";\nexport const ENV_DRIVE = \"SHAREPOINT_EXCEL_DRIVE\";\nexport const ENV_PROFILE = \"SHAREPOINT_EXCEL_PROFILE\";\nexport const ENV_AUTH_BASE = \"SHAREPOINT_EXCEL_AUTH_BASE\";\nexport const ENV_GRAPH_BASE = \"SHAREPOINT_EXCEL_GRAPH_BASE\";\nexport const ENV_HOME = \"SAPTOOLS_SHAREPOINT_EXCEL_HOME\";\nexport const ENV_ALLOW_PLAINTEXT = \"SAPTOOLS_SHAREPOINT_EXCEL_ALLOW_PLAINTEXT\";\n\nexport const FALLBACK_ENV_TENANT = \"SHAREPOINT_TENANT_ID\";\nexport const FALLBACK_ENV_CLIENT_ID = \"SHAREPOINT_CLIENT_ID\";\nexport const FALLBACK_ENV_CLIENT_SECRET = \"SHAREPOINT_CLIENT_SECRET\";\nexport const FALLBACK_ENV_SITE = \"SHAREPOINT_SITE\";\nexport const FALLBACK_ENV_DRIVE = \"SHAREPOINT_DRIVE\";\n","import { chmod, mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\nimport { Entry } from \"@napi-rs/keyring\";\n\nimport { fileSecretsPath } from \"../config/paths.js\";\n\nexport interface SecretVault {\n getSecret: (profileName: string) => Promise<string | undefined>;\n setSecret: (profileName: string, secret: string) => Promise<void>;\n deleteSecret: (profileName: string) => Promise<void>;\n}\n\ninterface SecretFile {\n readonly version: 1;\n readonly entries: Readonly<Record<string, string>>;\n}\n\nconst SERVICE_NAME = \"saptools-sharepoint-excel\";\nconst SECRET_FILE_MODE = 0o600;\nconst EMPTY_SECRET_FILE: SecretFile = { version: 1, entries: {} };\n\nfunction isMissingFileError(err: unknown): boolean {\n return err instanceof Error && \"code\" in err && err.code === \"ENOENT\";\n}\n\nasync function readSecretFile(path: string): Promise<SecretFile> {\n try {\n const raw = await readFile(path, \"utf8\");\n const parsed = JSON.parse(raw) as { readonly version?: unknown; readonly entries?: unknown };\n if (parsed.version !== 1 || typeof parsed.entries !== \"object\" || parsed.entries === null) {\n return EMPTY_SECRET_FILE;\n }\n const entries: Record<string, string> = {};\n for (const [key, value] of Object.entries(parsed.entries)) {\n if (typeof value === \"string\") {\n entries[key] = value;\n }\n }\n return { version: 1, entries };\n } catch (err) {\n if (isMissingFileError(err)) {\n return EMPTY_SECRET_FILE;\n }\n throw err;\n }\n}\n\nasync function writeSecretFile(path: string, value: SecretFile): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, `${JSON.stringify(value, null, 2)}\\n`, {\n encoding: \"utf8\",\n mode: SECRET_FILE_MODE,\n });\n await chmod(path, SECRET_FILE_MODE);\n}\n\nexport function createKeyringSecretVault(serviceName = SERVICE_NAME): SecretVault {\n return {\n getSecret(profileName: string): Promise<string | undefined> {\n const password = new Entry(serviceName, profileName).getPassword();\n return Promise.resolve(password === null || password.length === 0 ? undefined : password);\n },\n setSecret(profileName: string, secret: string): Promise<void> {\n new Entry(serviceName, profileName).setPassword(secret);\n return Promise.resolve();\n },\n deleteSecret(profileName: string): Promise<void> {\n try {\n new Entry(serviceName, profileName).deletePassword();\n } catch (err) {\n if (err instanceof Error && /not found|no entry|missing/i.test(err.message)) {\n return Promise.resolve();\n }\n return Promise.reject(err instanceof Error ? err : new Error(String(err)));\n }\n return Promise.resolve();\n },\n };\n}\n\nexport function createFileSecretVault(path = fileSecretsPath()): SecretVault {\n return {\n async getSecret(profileName: string): Promise<string | undefined> {\n const file = await readSecretFile(path);\n return file.entries[profileName];\n },\n async setSecret(profileName: string, secret: string): Promise<void> {\n const file = await readSecretFile(path);\n await writeSecretFile(path, {\n version: 1,\n entries: { ...file.entries, [profileName]: secret },\n });\n },\n async deleteSecret(profileName: string): Promise<void> {\n const file = await readSecretFile(path);\n const remaining = Object.fromEntries(\n Object.entries(file.entries).filter(([entryName]) => entryName !== profileName),\n );\n await writeSecretFile(path, { version: 1, entries: remaining });\n },\n };\n}\n","import process from \"node:process\";\n\nimport { DEFAULT_GRAPH_BASE, ENV_GRAPH_BASE } from \"../types.js\";\n\nexport type FetchLike = typeof fetch;\n\nexport interface GraphRetryOptions {\n readonly maxRetries?: number;\n readonly baseDelayMs?: number;\n readonly sleepFn?: (ms: number) => Promise<void>;\n}\n\nexport interface GraphClientOptions {\n readonly accessToken: string;\n readonly baseUrl?: string;\n readonly fetchFn?: FetchLike;\n readonly retry?: GraphRetryOptions;\n readonly env?: NodeJS.ProcessEnv;\n}\n\nexport interface GraphRequestOptions {\n readonly method?: string;\n readonly body?: unknown;\n readonly rawBody?: Uint8Array | string;\n readonly headers?: Readonly<Record<string, string>>;\n readonly includeAuthorization?: boolean;\n}\n\nexport interface GraphClient {\n readonly baseUrl: string;\n requestJson: <T>(path: string, options?: GraphRequestOptions) => Promise<T>;\n requestBytes: (path: string, options?: GraphRequestOptions) => Promise<Uint8Array>;\n requestNoContent: (path: string, options?: GraphRequestOptions) => Promise<void>;\n}\n\ninterface GraphErrorBody {\n readonly error?: {\n readonly code?: unknown;\n readonly message?: unknown;\n };\n}\n\nconst RETRYABLE_STATUSES = new Set<number>([429, 503]);\nconst DEFAULT_MAX_RETRIES = 2;\nconst DEFAULT_BASE_DELAY_MS = 500;\n\nfunction defaultSleep(ms: number): Promise<void> {\n return new Promise((resolve) => {\n setTimeout(resolve, ms);\n });\n}\n\nfunction parseRetryAfter(header: string | null): number | undefined {\n if (header === null || header.length === 0) {\n return undefined;\n }\n const seconds = Number.parseFloat(header);\n if (Number.isFinite(seconds) && seconds >= 0) {\n return Math.ceil(seconds * 1000);\n }\n const dateMs = Date.parse(header);\n return Number.isNaN(dateMs) ? undefined : Math.max(0, dateMs - Date.now());\n}\n\nfunction resolveBaseUrl(options: GraphClientOptions): string {\n if (options.baseUrl !== undefined && options.baseUrl.length > 0) {\n return options.baseUrl.replace(/\\/+$/, \"\");\n }\n const fromEnv = (options.env ?? process.env)[ENV_GRAPH_BASE];\n return fromEnv === undefined || fromEnv.length === 0\n ? DEFAULT_GRAPH_BASE\n : fromEnv.replace(/\\/+$/, \"\");\n}\n\nfunction resolveUrl(base: string, path: string, includeAuthorization: boolean): string {\n if (/^https?:\\/\\//i.test(path)) {\n if (includeAuthorization && new URL(path).origin !== new URL(base).origin) {\n throw new Error(\"Refusing to send a Graph bearer token to a different origin\");\n }\n return path;\n }\n return `${base}${path.startsWith(\"/\") ? path : `/${path}`}`;\n}\n\nexport class GraphHttpError extends Error {\n public readonly status: number;\n public readonly code: string | undefined;\n public readonly detail: string;\n\n public constructor(status: number, code: string | undefined, detail: string) {\n super(\n `Microsoft Graph request failed (${status.toString()}${\n code === undefined ? \"\" : ` ${code}`\n }): ${detail}`,\n );\n this.name = \"GraphHttpError\";\n this.status = status;\n this.code = code;\n this.detail = detail;\n }\n}\n\nasync function extractErrorDetail(response: Response): Promise<{ code: string | undefined; detail: string }> {\n const text = await response.text().catch(() => \"\");\n if (text.length === 0) {\n return { code: undefined, detail: response.statusText };\n }\n try {\n const body = JSON.parse(text) as GraphErrorBody;\n const code = typeof body.error?.code === \"string\" ? body.error.code : undefined;\n const detail =\n typeof body.error?.message === \"string\" && body.error.message.length > 0\n ? body.error.message\n : response.statusText;\n return { code, detail };\n } catch {\n return { code: undefined, detail: text };\n }\n}\n\nfunction buildInit(accessToken: string, options: GraphRequestOptions): RequestInit {\n const headers: Record<string, string> = {\n Accept: \"application/json\",\n ...(options.includeAuthorization === false ? {} : { Authorization: `Bearer ${accessToken}` }),\n ...options.headers,\n };\n const init: RequestInit = { method: options.method ?? \"GET\", headers };\n if (options.rawBody !== undefined) {\n init.body = rawBodyToBodyInit(options.rawBody);\n return init;\n }\n if (options.body !== undefined) {\n headers[\"Content-Type\"] = headers[\"Content-Type\"] ?? \"application/json\";\n init.body = typeof options.body === \"string\" ? options.body : JSON.stringify(options.body);\n }\n return init;\n}\n\ntype RequestBody = NonNullable<RequestInit[\"body\"]>;\n\nfunction rawBodyToBodyInit(rawBody: Uint8Array | string): RequestBody {\n if (typeof rawBody === \"string\") {\n return rawBody;\n }\n const copy = new ArrayBuffer(rawBody.byteLength);\n new Uint8Array(copy).set(rawBody);\n return copy;\n}\n\nasync function discardBody(response: Response): Promise<void> {\n if (response.body === null) {\n return;\n }\n await response.body.cancel().catch(() => {\n /* ignore */\n });\n}\n\nexport function createGraphClient(options: GraphClientOptions): GraphClient {\n const baseUrl = resolveBaseUrl(options);\n const fetchFn = options.fetchFn ?? fetch;\n const maxRetries = options.retry?.maxRetries ?? DEFAULT_MAX_RETRIES;\n const baseDelayMs = options.retry?.baseDelayMs ?? DEFAULT_BASE_DELAY_MS;\n const sleepFn = options.retry?.sleepFn ?? defaultSleep;\n\n async function execute(path: string, requestOptions: GraphRequestOptions): Promise<Response> {\n const includeAuthorization = requestOptions.includeAuthorization !== false;\n const url = resolveUrl(baseUrl, path, includeAuthorization);\n const init = buildInit(options.accessToken, requestOptions);\n let attempt = 0;\n let response = await fetchFn(url, init);\n while (!response.ok && RETRYABLE_STATUSES.has(response.status) && attempt < maxRetries) {\n const retryAfterMs =\n parseRetryAfter(response.headers.get(\"retry-after\")) ?? baseDelayMs * 2 ** attempt;\n await discardBody(response);\n await sleepFn(retryAfterMs);\n attempt += 1;\n response = await fetchFn(url, init);\n }\n if (!response.ok) {\n const { code, detail } = await extractErrorDetail(response);\n throw new GraphHttpError(response.status, code, detail);\n }\n return response;\n }\n\n async function requestJson<T>(path: string, requestOptions: GraphRequestOptions = {}): Promise<T> {\n const response = await execute(path, requestOptions);\n if (response.status === 204) {\n return undefined as T;\n }\n const contentType = response.headers.get(\"content-type\")?.toLowerCase() ?? \"\";\n if (!contentType.includes(\"application/json\")) {\n return undefined as T;\n }\n return (await response.json()) as T;\n }\n\n async function requestBytes(path: string, requestOptions: GraphRequestOptions = {}): Promise<Uint8Array> {\n const response = await execute(path, requestOptions);\n return new Uint8Array(await response.arrayBuffer());\n }\n\n async function requestNoContent(path: string, requestOptions: GraphRequestOptions = {}): Promise<void> {\n await execute(path, requestOptions);\n }\n\n return { baseUrl, requestJson, requestBytes, requestNoContent };\n}\n","import type { SharePointSite, SharePointSiteRef } from \"../types.js\";\n\nimport type { GraphClient } from \"./client.js\";\nimport { GraphHttpError } from \"./client.js\";\n\ninterface RawSiteResponse {\n readonly id?: unknown;\n readonly name?: unknown;\n readonly displayName?: unknown;\n readonly webUrl?: unknown;\n}\n\nfunction asString(value: unknown, fallback = \"\"): string {\n return typeof value === \"string\" ? value : fallback;\n}\n\nfunction stripQueryAndHash(value: string): string {\n const markerIndex = value.search(/[?#]/);\n return markerIndex === -1 ? value : value.slice(0, markerIndex);\n}\n\nfunction decodeSitePath(sitePath: string, input: string): string {\n return sitePath\n .split(\"/\")\n .map((segment) => {\n try {\n return decodeURIComponent(segment);\n } catch (err) {\n throw new Error(`Invalid site reference \"${input}\". Site path has invalid encoding`, {\n cause: err,\n });\n }\n })\n .join(\"/\");\n}\n\nfunction parseSiteInput(trimmed: string): { readonly hostname: string; readonly rawPath: string } {\n if (/^https?:\\/\\//i.test(trimmed)) {\n const url = new URL(trimmed);\n return { hostname: url.hostname, rawPath: url.pathname };\n }\n const withoutQuery = stripQueryAndHash(trimmed);\n const firstSlash = withoutQuery.indexOf(\"/\");\n if (firstSlash === -1) {\n throw new Error(`Invalid site reference \"${trimmed}\". Expected host/sites/<name> or full URL`);\n }\n return { hostname: withoutQuery.slice(0, firstSlash), rawPath: withoutQuery.slice(firstSlash + 1) };\n}\n\nexport function parseSiteRef(input: string): SharePointSiteRef {\n const trimmed = input.trim();\n if (trimmed.length === 0) {\n throw new Error(\"Site reference is empty\");\n }\n const { hostname, rawPath } = parseSiteInput(trimmed);\n const sitePath = decodeSitePath(rawPath.replace(/^\\/+|\\/+$/g, \"\"), trimmed);\n if (hostname.length === 0 || sitePath.length === 0) {\n throw new Error(`Invalid site reference \"${trimmed}\". Missing hostname or site path`);\n }\n return { hostname, sitePath };\n}\n\nfunction encodeSitePath(sitePath: string): string {\n return sitePath.split(\"/\").map((segment) => encodeURIComponent(segment)).join(\"/\");\n}\n\nexport async function resolveSite(\n client: GraphClient,\n ref: SharePointSiteRef,\n): Promise<SharePointSite> {\n const path = `/sites/${encodeURIComponent(ref.hostname)}:/${encodeSitePath(ref.sitePath)}`;\n let raw: RawSiteResponse;\n try {\n raw = await client.requestJson<RawSiteResponse>(path);\n } catch (err) {\n if (err instanceof GraphHttpError && err.status === 404) {\n throw new Error(`SharePoint site not found at ${ref.hostname}/${ref.sitePath}`, {\n cause: err,\n });\n }\n throw err;\n }\n const id = asString(raw.id);\n if (id.length === 0) {\n throw new Error(`Site response missing id for ${ref.hostname}/${ref.sitePath}`);\n }\n return {\n id,\n name: asString(raw.name, ref.sitePath),\n displayName: asString(raw.displayName, asString(raw.name, ref.sitePath)),\n webUrl: asString(raw.webUrl),\n };\n}\n","import type { RedactedProfile, SharePointDrive, SharePointSite, WorkbookReadResult } from \"../types.js\";\nimport type {\n RemoteMutationResult,\n RemoteReadResult,\n RemoteWorkbookResult,\n} from \"../workbook/service.js\";\n\nexport function formatDriveList(drives: readonly SharePointDrive[]): string {\n if (drives.length === 0) {\n return \"(no drives found)\";\n }\n return drives.map((drive) => `- ${drive.name} [${drive.driveType}] (${drive.id})`).join(\"\\n\");\n}\n\nexport function formatTestResult(site: SharePointSite, drives: readonly SharePointDrive[]): string {\n return [\n `Authenticated and resolved site: ${site.displayName} (${site.id})`,\n `Document libraries: ${drives.length.toString()}`,\n formatDriveList(drives),\n ].join(\"\\n\");\n}\n\nexport function formatProfile(profile: RedactedProfile): string {\n return [\n `Profile: ${profile.name}`,\n `Tenant: ${profile.tenantId}`,\n `Client: ${profile.clientId}`,\n `Site: ${profile.site}`,\n `Drive: ${profile.drive ?? \"(first available)\"}`,\n `Secret store: ${profile.secretStore}`,\n `Client secret: ${profile.hasClientSecret ? \"stored\" : \"missing\"}`,\n ].join(\"\\n\");\n}\n\nexport function formatCreateResult(result: RemoteWorkbookResult): string {\n return `Created ${result.path} in ${result.driveName} (${result.item.id})`;\n}\n\nexport function formatMutationResult(action: string, result: RemoteMutationResult): string {\n return `${action} ${result.path} in ${result.driveName}; sheet ${result.mutation.sheetName} now has ${result.mutation.rowCount.toString()} row(s)`;\n}\n\nexport function formatWorkbookRead(result: RemoteReadResult): string {\n return formatWorkbookSheets(result.workbook);\n}\n\nexport function formatWorkbookSheets(workbook: WorkbookReadResult): string {\n return workbook.sheets\n .map((sheet) => `${sheet.name}: ${sheet.rowCount.toString()} row(s), ${sheet.columnCount.toString()} column(s)`)\n .join(\"\\n\");\n}\n","import process from \"node:process\";\n\nimport type { FetchLike } from \"../graph/client.js\";\nimport type { AccessTokenInfo, SharePointCredentials } from \"../types.js\";\nimport { DEFAULT_AUTH_BASE, ENV_AUTH_BASE } from \"../types.js\";\n\nexport interface AcquireTokenOptions {\n readonly authBase?: string;\n readonly scope?: string;\n readonly fetchFn?: FetchLike;\n readonly env?: NodeJS.ProcessEnv;\n}\n\ninterface TokenResponse {\n readonly access_token?: unknown;\n readonly token_type?: unknown;\n readonly expires_in?: unknown;\n readonly scope?: unknown;\n readonly error?: unknown;\n readonly error_description?: unknown;\n}\n\nconst DEFAULT_SCOPE = \"https://graph.microsoft.com/.default\";\n\nfunction resolveAuthBase(options: AcquireTokenOptions): string {\n if (options.authBase !== undefined && options.authBase.length > 0) {\n return options.authBase.replace(/\\/+$/, \"\");\n }\n const fromEnv = (options.env ?? process.env)[ENV_AUTH_BASE];\n return fromEnv === undefined || fromEnv.length === 0\n ? DEFAULT_AUTH_BASE\n : fromEnv.replace(/\\/+$/, \"\");\n}\n\nfunction assertString(value: unknown, field: string): string {\n if (typeof value !== \"string\" || value.length === 0) {\n throw new Error(`Token response missing field: ${field}`);\n }\n return value;\n}\n\nfunction assertNumber(value: unknown, field: string): number {\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n throw new Error(`Token response missing numeric field: ${field}`);\n }\n return value;\n}\n\nfunction parseTokenResponse(text: string, status: number): TokenResponse {\n try {\n return JSON.parse(text) as TokenResponse;\n } catch (err) {\n throw new Error(`Failed to parse token response (HTTP ${status.toString()})`, { cause: err });\n }\n}\n\nfunction throwIfTokenError(response: Response, parsed: TokenResponse): void {\n if (response.ok && typeof parsed.error !== \"string\") {\n return;\n }\n const code = typeof parsed.error === \"string\" ? parsed.error : \"unknown_error\";\n const description =\n typeof parsed.error_description === \"string\" && parsed.error_description.length > 0\n ? parsed.error_description\n : response.statusText;\n throw new Error(\n `Azure AD token request failed (HTTP ${response.status.toString()} ${code}): ${description}`,\n );\n}\n\nexport async function acquireAppToken(\n credentials: SharePointCredentials,\n options: AcquireTokenOptions = {},\n): Promise<AccessTokenInfo> {\n if (credentials.tenantId.length === 0) {\n throw new Error(\"tenantId is required\");\n }\n if (credentials.clientId.length === 0) {\n throw new Error(\"clientId is required\");\n }\n if (credentials.clientSecret.length === 0) {\n throw new Error(\"clientSecret is required\");\n }\n\n const authBase = resolveAuthBase(options);\n const fetchFn = options.fetchFn ?? fetch;\n const url = `${authBase}/${encodeURIComponent(credentials.tenantId)}/oauth2/v2.0/token`;\n const form = new URLSearchParams({\n grant_type: \"client_credentials\",\n client_id: credentials.clientId,\n client_secret: credentials.clientSecret,\n scope: options.scope ?? DEFAULT_SCOPE,\n });\n\n const response = await fetchFn(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\", Accept: \"application/json\" },\n body: form.toString(),\n });\n const parsed = parseTokenResponse(await response.text(), response.status);\n throwIfTokenError(response, parsed);\n\n const scopeValue = typeof parsed.scope === \"string\" ? parsed.scope : undefined;\n const base = {\n accessToken: assertString(parsed.access_token, \"access_token\"),\n tokenType: assertString(parsed.token_type, \"token_type\"),\n expiresOn: Math.floor(Date.now() / 1000) + assertNumber(parsed.expires_in, \"expires_in\"),\n };\n return scopeValue === undefined ? base : { ...base, scope: scopeValue };\n}\n","import type { DriveItemSummary, SharePointDrive } from \"../types.js\";\n\nimport type { GraphClient } from \"./client.js\";\nimport { GraphHttpError } from \"./client.js\";\n\ninterface RawDriveResponse {\n readonly id?: unknown;\n readonly name?: unknown;\n readonly driveType?: unknown;\n readonly webUrl?: unknown;\n}\n\ninterface RawDriveListResponse {\n readonly value?: unknown;\n}\n\ninterface RawDriveItem {\n readonly id?: unknown;\n readonly name?: unknown;\n readonly size?: unknown;\n readonly eTag?: unknown;\n readonly cTag?: unknown;\n readonly webUrl?: unknown;\n readonly folder?: unknown;\n readonly file?: unknown;\n}\n\ninterface UploadSessionResponse {\n readonly uploadUrl?: unknown;\n}\n\nconst XLSX_CONTENT_TYPE = \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\";\n\nfunction asString(value: unknown, fallback = \"\"): string {\n return typeof value === \"string\" ? value : fallback;\n}\n\nfunction asNumber(value: unknown, fallback = 0): number {\n return typeof value === \"number\" && Number.isFinite(value) ? value : fallback;\n}\n\nexport function encodeDrivePath(relativePath: string): string {\n return relativePath\n .split(\"/\")\n .filter((segment) => segment.length > 0)\n .map((segment) => encodeURIComponent(segment))\n .join(\"/\");\n}\n\nfunction toDrive(raw: RawDriveResponse): SharePointDrive {\n return {\n id: asString(raw.id),\n name: asString(raw.name),\n driveType: asString(raw.driveType, \"documentLibrary\"),\n webUrl: asString(raw.webUrl),\n };\n}\n\nfunction toDriveItem(raw: RawDriveItem): DriveItemSummary {\n const base = {\n id: asString(raw.id),\n name: asString(raw.name),\n isFolder: raw.folder !== undefined && raw.folder !== null,\n size: asNumber(raw.size),\n };\n return {\n ...base,\n ...(typeof raw.eTag === \"string\" ? { eTag: raw.eTag } : {}),\n ...(typeof raw.cTag === \"string\" ? { cTag: raw.cTag } : {}),\n ...(typeof raw.webUrl === \"string\" ? { webUrl: raw.webUrl } : {}),\n };\n}\n\nexport async function listDrives(\n client: GraphClient,\n siteId: string,\n): Promise<readonly SharePointDrive[]> {\n const response = await client.requestJson<RawDriveListResponse>(`/sites/${encodeURIComponent(siteId)}/drives`);\n if (!Array.isArray(response.value)) {\n return [];\n }\n return response.value\n .filter((entry): entry is RawDriveResponse => typeof entry === \"object\" && entry !== null)\n .map(toDrive);\n}\n\nexport function selectDrive(\n drives: readonly SharePointDrive[],\n driveHint: string | undefined,\n): SharePointDrive {\n if (drives.length === 0) {\n throw new Error(\"SharePoint site has no drives (document libraries)\");\n }\n if (driveHint === undefined || driveHint.length === 0) {\n const first = drives[0];\n if (first === undefined) {\n throw new Error(\"No drives available\");\n }\n return first;\n }\n const match = drives.find((drive) => drive.id === driveHint || drive.name === driveHint);\n if (match === undefined) {\n throw new Error(`Drive \"${driveHint}\" not found. Available: ${drives.map((d) => d.name).join(\", \")}`);\n }\n return match;\n}\n\nexport async function getDriveItemByPath(\n client: GraphClient,\n driveId: string,\n relativePath: string,\n): Promise<DriveItemSummary | null> {\n const normalized = relativePath.replace(/^\\/+|\\/+$/g, \"\");\n const path =\n normalized.length === 0\n ? `/drives/${encodeURIComponent(driveId)}/root`\n : `/drives/${encodeURIComponent(driveId)}/root:/${encodeDrivePath(normalized)}`;\n try {\n return toDriveItem(await client.requestJson<RawDriveItem>(path));\n } catch (err) {\n if (err instanceof GraphHttpError && err.status === 404) {\n return null;\n }\n throw err;\n }\n}\n\nexport async function downloadDriveFile(\n client: GraphClient,\n driveId: string,\n relativePath: string,\n): Promise<Uint8Array> {\n const encodedPath = encodeDrivePath(relativePath.replace(/^\\/+|\\/+$/g, \"\"));\n return await client.requestBytes(`/drives/${encodeURIComponent(driveId)}/root:/${encodedPath}:/content`, {\n headers: { Accept: XLSX_CONTENT_TYPE },\n });\n}\n\nasync function createUploadSession(\n client: GraphClient,\n driveId: string,\n relativePath: string,\n): Promise<string> {\n const encodedPath = encodeDrivePath(relativePath.replace(/^\\/+|\\/+$/g, \"\"));\n const response = await client.requestJson<UploadSessionResponse>(\n `/drives/${encodeURIComponent(driveId)}/root:/${encodedPath}:/createUploadSession`,\n {\n method: \"POST\",\n body: { item: { \"@microsoft.graph.conflictBehavior\": \"fail\" } },\n },\n );\n if (typeof response.uploadUrl !== \"string\" || response.uploadUrl.length === 0) {\n throw new Error(\"Graph upload session response missing uploadUrl\");\n }\n return response.uploadUrl;\n}\n\nexport async function uploadNewDriveFile(\n client: GraphClient,\n driveId: string,\n relativePath: string,\n bytes: Uint8Array,\n): Promise<DriveItemSummary> {\n const existing = await getDriveItemByPath(client, driveId, relativePath);\n if (existing !== null) {\n throw new Error(`Refusing to overwrite existing SharePoint file: ${relativePath}`);\n }\n const uploadUrl = await createUploadSession(client, driveId, relativePath);\n const lastByte = bytes.byteLength - 1;\n const raw = await client.requestJson<RawDriveItem>(uploadUrl, {\n method: \"PUT\",\n rawBody: bytes,\n includeAuthorization: false,\n headers: {\n \"Content-Length\": bytes.byteLength.toString(),\n \"Content-Range\": `bytes 0-${lastByte.toString()}/${bytes.byteLength.toString()}`,\n \"Content-Type\": XLSX_CONTENT_TYPE,\n },\n });\n return toDriveItem(raw);\n}\n\nexport async function replaceDriveFile(\n client: GraphClient,\n driveId: string,\n relativePath: string,\n eTag: string,\n bytes: Uint8Array,\n): Promise<DriveItemSummary> {\n const encodedPath = encodeDrivePath(relativePath.replace(/^\\/+|\\/+$/g, \"\"));\n const raw = await client.requestJson<RawDriveItem>(\n `/drives/${encodeURIComponent(driveId)}/root:/${encodedPath}:/content`,\n {\n method: \"PUT\",\n rawBody: bytes,\n headers: {\n \"Content-Type\": XLSX_CONTENT_TYPE,\n \"If-Match\": eTag,\n },\n },\n );\n return toDriveItem(raw);\n}\n","import { acquireAppToken } from \"./auth/token.js\";\nimport type { AcquireTokenOptions } from \"./auth/token.js\";\nimport { createGraphClient } from \"./graph/client.js\";\nimport type { FetchLike, GraphClient, GraphRetryOptions } from \"./graph/client.js\";\nimport { listDrives } from \"./graph/drive.js\";\nimport { resolveSite } from \"./graph/site.js\";\nimport type { AccessTokenInfo, SharePointDrive, SharePointSite, SharePointTarget } from \"./types.js\";\n\nexport interface SessionOptions {\n readonly fetchFn?: FetchLike;\n readonly authBase?: string;\n readonly graphBase?: string;\n readonly retry?: GraphRetryOptions;\n}\n\nexport interface SharePointExcelSession {\n readonly token: AccessTokenInfo;\n readonly client: GraphClient;\n readonly site: SharePointSite;\n readonly drives: readonly SharePointDrive[];\n}\n\nexport async function openSession(\n target: SharePointTarget,\n options: SessionOptions = {},\n): Promise<SharePointExcelSession> {\n const tokenOptions: AcquireTokenOptions = {\n ...(options.authBase === undefined ? {} : { authBase: options.authBase }),\n ...(options.fetchFn === undefined ? {} : { fetchFn: options.fetchFn }),\n };\n const token = await acquireAppToken(target.credentials, tokenOptions);\n const client = createGraphClient({\n accessToken: token.accessToken,\n ...(options.graphBase === undefined ? {} : { baseUrl: options.graphBase }),\n ...(options.fetchFn === undefined ? {} : { fetchFn: options.fetchFn }),\n ...(options.retry === undefined ? {} : { retry: options.retry }),\n });\n const site = await resolveSite(client, target.site);\n const drives = await listDrives(client, site.id);\n return { token, client, site, drives };\n}\n","import { z } from \"zod\";\n\nimport type { JsonCellValue, WorkbookInputRow } from \"../types.js\";\n\nconst JsonCellValueSchema = z.union([z.string(), z.number(), z.boolean(), z.null()]);\nconst JsonRowSchema = z.array(JsonCellValueSchema);\nconst JsonRecordSchema = z.record(z.string(), JsonCellValueSchema);\n\nexport function parseHeaders(input: string | undefined): readonly string[] {\n if (input === undefined || input.trim().length === 0) {\n return [];\n }\n return input\n .split(\",\")\n .map((entry) => entry.trim())\n .filter((entry) => entry.length > 0);\n}\n\nfunction parseJson(input: string, label: string): unknown {\n try {\n return JSON.parse(input) as unknown;\n } catch (err) {\n throw new Error(`Invalid JSON for ${label}`, { cause: err });\n }\n}\n\nexport function parseCellValue(input: string): JsonCellValue {\n const trimmed = input.trim();\n if (trimmed.length === 0) {\n return \"\";\n }\n let parsed: unknown;\n try {\n parsed = parseJson(trimmed, \"cell value\");\n } catch {\n return input;\n }\n const result = JsonCellValueSchema.safeParse(parsed);\n if (!result.success) {\n return input;\n }\n return result.data;\n}\n\nexport function parseWorkbookRows(input: string | undefined): readonly WorkbookInputRow[] {\n if (input === undefined || input.trim().length === 0) {\n return [];\n }\n const parsed = parseJson(input, \"rows\");\n const rowResult = JsonRowSchema.safeParse(parsed);\n if (rowResult.success) {\n return [rowResult.data];\n }\n const recordResult = JsonRecordSchema.safeParse(parsed);\n if (recordResult.success) {\n return [recordResult.data];\n }\n if (Array.isArray(parsed)) {\n return parsed.map(parseWorkbookRow);\n }\n throw new Error(`Rows JSON must be an object, row array, or array of rows/objects`);\n}\n\nfunction parseWorkbookRow(value: unknown): WorkbookInputRow {\n const rowResult = JsonRowSchema.safeParse(value);\n if (rowResult.success) {\n return rowResult.data;\n }\n const recordResult = JsonRecordSchema.safeParse(value);\n if (recordResult.success) {\n return recordResult.data;\n }\n throw new Error(`Rows JSON must be an object, row array, or array of rows/objects`);\n}\n","import ExcelJS from \"exceljs\";\nimport type { CellValue, Worksheet } from \"exceljs\";\n\nimport type {\n JsonCellValue,\n JsonRecord,\n JsonRow,\n WorkbookCreateInput,\n WorkbookInputRow,\n WorkbookMutationResult,\n WorkbookReadOptions,\n WorkbookReadResult,\n WorkbookSheetReadResult,\n} from \"../types.js\";\n\nimport { parseA1Cell, parseA1Range } from \"./a1.js\";\n\nconst INVALID_SHEET_CHARS = /[\\][:*?/\\\\]/;\n\nfunction validateSheetName(sheetName: string): string {\n const trimmed = sheetName.trim();\n if (trimmed.length === 0 || trimmed.length > 31 || INVALID_SHEET_CHARS.test(trimmed)) {\n throw new Error(`Invalid Excel sheet name \"${sheetName}\"`);\n }\n return trimmed;\n}\n\nfunction isRecord(row: WorkbookInputRow): row is JsonRecord {\n return !Array.isArray(row);\n}\n\nfunction deriveHeaders(headers: readonly string[], rows: readonly WorkbookInputRow[]): readonly string[] {\n if (headers.length > 0) {\n return headers;\n }\n const firstRecord = rows.find(isRecord);\n return firstRecord === undefined ? [] : Object.keys(firstRecord);\n}\n\nfunction rowToValues(row: WorkbookInputRow, headers: readonly string[]): JsonRow {\n if (!isRecord(row)) {\n return [...row];\n }\n const record = row;\n if (headers.length === 0) {\n return Object.keys(record).map((key) => record[key] ?? null);\n }\n return headers.map((header) => record[header] ?? null);\n}\n\nfunction addRows(sheet: Worksheet, headers: readonly string[], rows: readonly WorkbookInputRow[]): void {\n if (headers.length > 0) {\n sheet.addRow([...headers]);\n }\n for (const row of rows) {\n sheet.addRow([...rowToValues(row, headers)]);\n }\n}\n\nfunction addTable(sheet: Worksheet, tableName: string, headers: readonly string[], rows: readonly WorkbookInputRow[]): void {\n sheet.addTable({\n name: tableName,\n ref: \"A1\",\n headerRow: true,\n totalsRow: false,\n style: { theme: \"TableStyleMedium2\", showRowStripes: true },\n columns: headers.map((name) => ({ name })),\n rows: rows.map((row) => [...rowToValues(row, headers)]),\n });\n}\n\nasync function workbookToBytes(workbook: ExcelJS.Workbook): Promise<Uint8Array> {\n const buffer = await workbook.xlsx.writeBuffer();\n return new Uint8Array(buffer);\n}\n\nasync function loadWorkbook(bytes: Uint8Array): Promise<ExcelJS.Workbook> {\n const workbook = new ExcelJS.Workbook();\n await workbook.xlsx.load(uint8ArrayToArrayBuffer(bytes));\n return workbook;\n}\n\nfunction uint8ArrayToArrayBuffer(bytes: Uint8Array): ArrayBuffer {\n const copy = new ArrayBuffer(bytes.byteLength);\n new Uint8Array(copy).set(bytes);\n return copy;\n}\n\nfunction getWorksheet(workbook: ExcelJS.Workbook, sheetName: string): Worksheet {\n const sheet = workbook.getWorksheet(sheetName);\n if (sheet === undefined) {\n throw new Error(`Sheet \"${sheetName}\" not found`);\n }\n return sheet;\n}\n\nfunction serializeCellValue(value: unknown): JsonCellValue {\n if (value === null || value === undefined) {\n return null;\n }\n if (typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\") {\n return value;\n }\n if (value instanceof Date) {\n return value.toISOString();\n }\n if (typeof value === \"object\" && \"result\" in value) {\n return serializeCellValue((value as { readonly result?: unknown }).result);\n }\n return JSON.stringify(value);\n}\n\nfunction readRow(sheet: Worksheet, rowNumber: number, startColumn: number, endColumn: number): JsonRow {\n const row = sheet.getRow(rowNumber);\n const columnCount = endColumn - startColumn + 1;\n return Array.from({ length: columnCount }, (_value, index) =>\n serializeCellValue(row.getCell(startColumn + index).value),\n );\n}\n\nfunction readHeaderRow(sheet: Worksheet): readonly string[] {\n if (sheet.actualRowCount === 0) {\n return [];\n }\n return readRow(sheet, 1, 1, Math.max(1, sheet.actualColumnCount)).map((value) => String(value ?? \"\"));\n}\n\nfunction readSheet(sheet: Worksheet, options: WorkbookReadOptions): WorkbookSheetReadResult {\n const range = options.range === undefined ? undefined : parseA1Range(options.range);\n const startRow = range?.start.row ?? 1;\n const endRow = range?.end.row ?? Math.max(1, sheet.actualRowCount);\n const startColumn = range?.start.column ?? 1;\n const endColumn = range?.end.column ?? Math.max(1, sheet.actualColumnCount);\n const rows: JsonRow[] = [];\n for (let row = startRow; row <= endRow; row += 1) {\n rows.push(readRow(sheet, row, startColumn, endColumn));\n }\n return { name: sheet.name, rowCount: rows.length, columnCount: endColumn - startColumn + 1, rows };\n}\n\nexport async function createWorkbookBytes(input: WorkbookCreateInput): Promise<Uint8Array> {\n const workbook = new ExcelJS.Workbook();\n const sheet = workbook.addWorksheet(validateSheetName(input.sheetName));\n const headers = deriveHeaders(input.headers, input.rows);\n if (input.tableName !== undefined && input.tableName.length > 0 && headers.length > 0) {\n addTable(sheet, input.tableName, headers, input.rows);\n } else {\n addRows(sheet, headers, input.rows);\n }\n return await workbookToBytes(workbook);\n}\n\nexport async function readWorkbookBytes(\n bytes: Uint8Array,\n options: WorkbookReadOptions = {},\n): Promise<WorkbookReadResult> {\n const workbook = await loadWorkbook(bytes);\n const sheets =\n options.sheetName === undefined\n ? workbook.worksheets\n : [getWorksheet(workbook, validateSheetName(options.sheetName))];\n return { sheets: sheets.map((sheet) => readSheet(sheet, options)) };\n}\n\nexport async function appendWorkbookRows(\n bytes: Uint8Array,\n sheetName: string,\n rows: readonly WorkbookInputRow[],\n matchHeader: boolean,\n): Promise<WorkbookMutationResult> {\n const workbook = await loadWorkbook(bytes);\n const sheet = getWorksheet(workbook, validateSheetName(sheetName));\n const headers = matchHeader ? readHeaderRow(sheet) : deriveHeaders([], rows);\n for (const row of rows) {\n sheet.addRow([...rowToValues(row, headers)]);\n }\n return {\n bytes: await workbookToBytes(workbook),\n sheetName: sheet.name,\n rowCount: sheet.actualRowCount,\n columnCount: sheet.actualColumnCount,\n };\n}\n\nexport async function updateWorkbookCell(\n bytes: Uint8Array,\n sheetName: string,\n cellRef: string,\n value: CellValue,\n): Promise<WorkbookMutationResult> {\n const workbook = await loadWorkbook(bytes);\n const sheet = getWorksheet(workbook, validateSheetName(sheetName));\n const cell = parseA1Cell(cellRef);\n sheet.getCell(cell.row, cell.column).value = value;\n return {\n bytes: await workbookToBytes(workbook),\n sheetName: sheet.name,\n rowCount: sheet.actualRowCount,\n columnCount: sheet.actualColumnCount,\n };\n}\n\nexport async function addWorkbookSheet(\n bytes: Uint8Array,\n sheetName: string,\n headers: readonly string[],\n): Promise<WorkbookMutationResult> {\n const workbook = await loadWorkbook(bytes);\n const normalized = validateSheetName(sheetName);\n if (workbook.getWorksheet(normalized) !== undefined) {\n throw new Error(`Sheet \"${normalized}\" already exists`);\n }\n const sheet = workbook.addWorksheet(normalized);\n if (headers.length > 0) {\n sheet.addRow([...headers]);\n }\n return {\n bytes: await workbookToBytes(workbook),\n sheetName: sheet.name,\n rowCount: sheet.actualRowCount,\n columnCount: sheet.actualColumnCount,\n };\n}\n","export interface A1CellRef {\n readonly row: number;\n readonly column: number;\n}\n\nexport interface A1RangeRef {\n readonly start: A1CellRef;\n readonly end: A1CellRef;\n}\n\nconst CELL_REF_PATTERN = /^([A-Za-z]+)([1-9]\\d*)$/;\n\nexport function columnNameToNumber(columnName: string): number {\n const normalized = columnName.trim().toUpperCase();\n if (!/^[A-Z]+$/.test(normalized)) {\n throw new Error(`Invalid column name \"${columnName}\"`);\n }\n let total = 0;\n for (const char of normalized) {\n total = total * 26 + char.charCodeAt(0) - 64;\n }\n return total;\n}\n\nexport function parseA1Cell(input: string): A1CellRef {\n const trimmed = input.trim();\n const match = CELL_REF_PATTERN.exec(trimmed);\n if (match === null) {\n throw new Error(`Invalid A1 cell reference \"${input}\"`);\n }\n const columnName = match[1];\n const rowValue = match[2];\n if (columnName === undefined || rowValue === undefined) {\n throw new Error(`Invalid A1 cell reference \"${input}\"`);\n }\n return {\n row: Number.parseInt(rowValue, 10),\n column: columnNameToNumber(columnName),\n };\n}\n\nfunction orderRange(start: A1CellRef, end: A1CellRef): A1RangeRef {\n return {\n start: {\n row: Math.min(start.row, end.row),\n column: Math.min(start.column, end.column),\n },\n end: {\n row: Math.max(start.row, end.row),\n column: Math.max(start.column, end.column),\n },\n };\n}\n\nexport function parseA1Range(input: string): A1RangeRef {\n const parts = input.split(\":\").map((part) => part.trim());\n if (parts.length === 1) {\n const cell = parseA1Cell(parts[0] ?? \"\");\n return { start: cell, end: cell };\n }\n if (parts.length !== 2) {\n throw new Error(`Invalid A1 range \"${input}\"`);\n }\n return orderRange(parseA1Cell(parts[0] ?? \"\"), parseA1Cell(parts[1] ?? \"\"));\n}\n","import {\n downloadDriveFile,\n getDriveItemByPath,\n replaceDriveFile,\n selectDrive,\n uploadNewDriveFile,\n} from \"../graph/drive.js\";\nimport type { SharePointExcelSession } from \"../session.js\";\nimport type {\n DriveItemSummary,\n WorkbookCreateInput,\n WorkbookInputRow,\n WorkbookMutationResult,\n WorkbookReadOptions,\n WorkbookReadResult,\n} from \"../types.js\";\n\nimport {\n addWorkbookSheet,\n appendWorkbookRows,\n createWorkbookBytes,\n readWorkbookBytes,\n updateWorkbookCell,\n} from \"./excel.js\";\n\nexport interface WorkbookServiceTarget {\n readonly session: SharePointExcelSession;\n readonly driveHint?: string;\n}\n\nexport interface RemoteWorkbookResult {\n readonly driveId: string;\n readonly driveName: string;\n readonly path: string;\n readonly item: DriveItemSummary;\n}\n\nexport interface RemoteReadResult extends RemoteWorkbookResult {\n readonly workbook: WorkbookReadResult;\n}\n\nexport interface RemoteMutationResult extends RemoteWorkbookResult {\n readonly mutation: WorkbookMutationResult;\n}\n\nfunction normalizeWorkbookPath(path: string): string {\n const normalized = path.trim().replace(/^\\/+|\\/+$/g, \"\");\n if (normalized.length === 0) {\n throw new Error(\"Workbook path is required\");\n }\n if (!normalized.toLowerCase().endsWith(\".xlsx\")) {\n throw new Error(`Workbook path must end with .xlsx: ${path}`);\n }\n return normalized;\n}\n\nfunction requireEtag(item: DriveItemSummary, path: string): string {\n if (item.eTag === undefined || item.eTag.length === 0) {\n throw new Error(`Cannot update ${path}: SharePoint item is missing an ETag`);\n }\n return item.eTag;\n}\n\nasync function downloadExistingWorkbook(\n target: WorkbookServiceTarget,\n path: string,\n): Promise<{ readonly bytes: Uint8Array; readonly item: DriveItemSummary; readonly driveId: string; readonly driveName: string }> {\n const drive = selectDrive(target.session.drives, target.driveHint);\n const item = await getDriveItemByPath(target.session.client, drive.id, path);\n if (item === null || item.isFolder) {\n throw new Error(`Workbook not found: ${path}`);\n }\n const bytes = await downloadDriveFile(target.session.client, drive.id, path);\n return { bytes, item, driveId: drive.id, driveName: drive.name };\n}\n\nexport async function createRemoteWorkbook(\n target: WorkbookServiceTarget,\n path: string,\n input: WorkbookCreateInput,\n): Promise<RemoteWorkbookResult> {\n const normalizedPath = normalizeWorkbookPath(path);\n const drive = selectDrive(target.session.drives, target.driveHint);\n const bytes = await createWorkbookBytes(input);\n const item = await uploadNewDriveFile(target.session.client, drive.id, normalizedPath, bytes);\n return { driveId: drive.id, driveName: drive.name, path: normalizedPath, item };\n}\n\nexport async function readRemoteWorkbook(\n target: WorkbookServiceTarget,\n path: string,\n options: WorkbookReadOptions = {},\n): Promise<RemoteReadResult> {\n const normalizedPath = normalizeWorkbookPath(path);\n const downloaded = await downloadExistingWorkbook(target, normalizedPath);\n const workbook = await readWorkbookBytes(downloaded.bytes, options);\n return { ...downloaded, path: normalizedPath, workbook };\n}\n\nexport async function appendRemoteWorkbookRows(\n target: WorkbookServiceTarget,\n path: string,\n sheetName: string,\n rows: readonly WorkbookInputRow[],\n matchHeader: boolean,\n): Promise<RemoteMutationResult> {\n const normalizedPath = normalizeWorkbookPath(path);\n const downloaded = await downloadExistingWorkbook(target, normalizedPath);\n const mutation = await appendWorkbookRows(downloaded.bytes, sheetName, rows, matchHeader);\n const item = await replaceDriveFile(\n target.session.client,\n downloaded.driveId,\n normalizedPath,\n requireEtag(downloaded.item, normalizedPath),\n mutation.bytes,\n );\n return { ...downloaded, item, path: normalizedPath, mutation };\n}\n\nexport async function updateRemoteWorkbookCell(\n target: WorkbookServiceTarget,\n path: string,\n sheetName: string,\n cellRef: string,\n value: string | number | boolean | null,\n): Promise<RemoteMutationResult> {\n const normalizedPath = normalizeWorkbookPath(path);\n const downloaded = await downloadExistingWorkbook(target, normalizedPath);\n const mutation = await updateWorkbookCell(downloaded.bytes, sheetName, cellRef, value);\n const item = await replaceDriveFile(\n target.session.client,\n downloaded.driveId,\n normalizedPath,\n requireEtag(downloaded.item, normalizedPath),\n mutation.bytes,\n );\n return { ...downloaded, item, path: normalizedPath, mutation };\n}\n\nexport async function addRemoteWorkbookSheet(\n target: WorkbookServiceTarget,\n path: string,\n sheetName: string,\n headers: readonly string[],\n): Promise<RemoteMutationResult> {\n const normalizedPath = normalizeWorkbookPath(path);\n const downloaded = await downloadExistingWorkbook(target, normalizedPath);\n const mutation = await addWorkbookSheet(downloaded.bytes, sheetName, headers);\n const item = await replaceDriveFile(\n target.session.client,\n downloaded.driveId,\n normalizedPath,\n requireEtag(downloaded.item, normalizedPath),\n mutation.bytes,\n );\n return { ...downloaded, item, path: normalizedPath, mutation };\n}\n","import type { Command } from \"commander\";\n\nimport type { RuntimeOverrides } from \"../config/resolve.js\";\n\nexport interface CommonFlags extends RuntimeOverrides {\n readonly json?: boolean;\n}\n\nexport interface ConfigSetFlags {\n readonly profile?: string;\n readonly tenant?: string;\n readonly clientId?: string;\n readonly clientSecret?: string;\n readonly site?: string;\n readonly drive?: string;\n readonly store?: string;\n readonly allowPlaintextSecret?: boolean;\n readonly json?: boolean;\n}\n\nexport interface ConfigGetFlags {\n readonly profile?: string;\n readonly json?: boolean;\n}\n\nexport interface CreateFlags extends CommonFlags {\n readonly drive?: string;\n readonly path?: string;\n readonly sheet?: string;\n readonly headers?: string;\n readonly rows?: string;\n readonly table?: string;\n}\n\nexport interface ReadFlags extends CommonFlags {\n readonly drive?: string;\n readonly path?: string;\n readonly sheet?: string;\n readonly range?: string;\n}\n\nexport interface AppendFlags extends CommonFlags {\n readonly drive?: string;\n readonly path?: string;\n readonly sheet?: string;\n readonly record?: string;\n readonly matchHeader?: boolean;\n}\n\nexport interface UpdateCellFlags extends CommonFlags {\n readonly drive?: string;\n readonly path?: string;\n readonly sheet?: string;\n readonly cell?: string;\n readonly value?: string;\n}\n\nexport interface AddSheetFlags extends CommonFlags {\n readonly drive?: string;\n readonly path?: string;\n readonly sheet?: string;\n readonly headers?: string;\n}\n\nexport function addCommonOptions(cmd: Command): Command {\n return cmd\n .option(\"--profile <name>\", \"Stored profile name\")\n .option(\"--tenant <id>\", \"Azure AD tenant ID\")\n .option(\"--client-id <id>\", \"App registration client ID\")\n .option(\"--client-secret <secret>\", \"App registration client secret\")\n .option(\"--site <ref>\", \"SharePoint site, e.g. contoso.sharepoint.com/sites/demo\")\n .option(\"--drive <nameOrId>\", \"Document library name or ID\")\n .option(\"--json\", \"Emit JSON output\", false);\n}\n\nexport function toRuntimeOverrides(flags: CommonFlags): RuntimeOverrides {\n return {\n profile: flags.profile,\n tenant: flags.tenant,\n clientId: flags.clientId,\n clientSecret: flags.clientSecret,\n site: flags.site,\n drive: flags.drive,\n };\n}\n\nexport function requireFlag(value: string | undefined, flagName: string): string {\n if (value === undefined || value.trim().length === 0) {\n throw new Error(`${flagName} is required`);\n }\n return value;\n}\n"],"mappings":"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","names":["process","process","process","chmod","mkdir","readFile","writeFile","dirname","isMissingFileError","readFile","mkdir","dirname","writeFile","chmod","process","process","process","process","process","asString","process","process"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -120,6 +120,7 @@ interface GraphRequestOptions {
|
|
|
120
120
|
readonly body?: unknown;
|
|
121
121
|
readonly rawBody?: Uint8Array | string;
|
|
122
122
|
readonly headers?: Readonly<Record<string, string>>;
|
|
123
|
+
readonly includeAuthorization?: boolean;
|
|
123
124
|
}
|
|
124
125
|
interface GraphClient {
|
|
125
126
|
readonly baseUrl: string;
|
package/dist/index.js
CHANGED
|
@@ -345,8 +345,11 @@ function resolveBaseUrl(options) {
|
|
|
345
345
|
const fromEnv = (options.env ?? process3.env)[ENV_GRAPH_BASE];
|
|
346
346
|
return fromEnv === void 0 || fromEnv.length === 0 ? DEFAULT_GRAPH_BASE : fromEnv.replace(/\/+$/, "");
|
|
347
347
|
}
|
|
348
|
-
function resolveUrl(base, path) {
|
|
348
|
+
function resolveUrl(base, path, includeAuthorization) {
|
|
349
349
|
if (/^https?:\/\//i.test(path)) {
|
|
350
|
+
if (includeAuthorization && new URL(path).origin !== new URL(base).origin) {
|
|
351
|
+
throw new Error("Refusing to send a Graph bearer token to a different origin");
|
|
352
|
+
}
|
|
350
353
|
return path;
|
|
351
354
|
}
|
|
352
355
|
return `${base}${path.startsWith("/") ? path : `/${path}`}`;
|
|
@@ -381,8 +384,8 @@ async function extractErrorDetail(response) {
|
|
|
381
384
|
}
|
|
382
385
|
function buildInit(accessToken, options) {
|
|
383
386
|
const headers = {
|
|
384
|
-
Authorization: `Bearer ${accessToken}`,
|
|
385
387
|
Accept: "application/json",
|
|
388
|
+
...options.includeAuthorization === false ? {} : { Authorization: `Bearer ${accessToken}` },
|
|
386
389
|
...options.headers
|
|
387
390
|
};
|
|
388
391
|
const init = { method: options.method ?? "GET", headers };
|
|
@@ -418,7 +421,8 @@ function createGraphClient(options) {
|
|
|
418
421
|
const baseDelayMs = options.retry?.baseDelayMs ?? DEFAULT_BASE_DELAY_MS;
|
|
419
422
|
const sleepFn = options.retry?.sleepFn ?? defaultSleep;
|
|
420
423
|
async function execute(path, requestOptions) {
|
|
421
|
-
const
|
|
424
|
+
const includeAuthorization = requestOptions.includeAuthorization !== false;
|
|
425
|
+
const url = resolveUrl(baseUrl, path, includeAuthorization);
|
|
422
426
|
const init = buildInit(options.accessToken, requestOptions);
|
|
423
427
|
let attempt = 0;
|
|
424
428
|
let response = await fetchFn(url, init);
|
|
@@ -706,6 +710,7 @@ async function uploadNewDriveFile(client, driveId, relativePath, bytes) {
|
|
|
706
710
|
const raw = await client.requestJson(uploadUrl, {
|
|
707
711
|
method: "PUT",
|
|
708
712
|
rawBody: bytes,
|
|
713
|
+
includeAuthorization: false,
|
|
709
714
|
headers: {
|
|
710
715
|
"Content-Length": bytes.byteLength.toString(),
|
|
711
716
|
"Content-Range": `bytes 0-${lastByte.toString()}/${bytes.byteLength.toString()}`,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts","../src/auth/token.ts","../src/config/paths.ts","../src/config/resolve.ts","../src/credentials/profile-store.ts","../src/credentials/secret-vault.ts","../src/graph/client.ts","../src/graph/site.ts","../src/graph/drive.ts","../src/session.ts","../src/workbook/a1.ts","../src/workbook/excel.ts","../src/workbook/json.ts","../src/workbook/service.ts"],"sourcesContent":["export type SecretStoreKind = \"keyring\" | \"file\";\n\nexport interface SharePointCredentials {\n readonly tenantId: string;\n readonly clientId: string;\n readonly clientSecret: string;\n}\n\nexport interface SharePointSiteRef {\n readonly hostname: string;\n readonly sitePath: string;\n}\n\nexport interface SharePointTarget {\n readonly credentials: SharePointCredentials;\n readonly site: SharePointSiteRef;\n}\n\nexport interface AccessTokenInfo {\n readonly accessToken: string;\n readonly expiresOn: number;\n readonly tokenType: string;\n readonly scope?: string;\n}\n\nexport interface SharePointSite {\n readonly id: string;\n readonly name: string;\n readonly displayName: string;\n readonly webUrl: string;\n}\n\nexport interface SharePointDrive {\n readonly id: string;\n readonly name: string;\n readonly driveType: string;\n readonly webUrl: string;\n}\n\nexport interface DriveItemSummary {\n readonly id: string;\n readonly name: string;\n readonly isFolder: boolean;\n readonly size: number;\n readonly eTag?: string;\n readonly cTag?: string;\n readonly webUrl?: string;\n}\n\nexport interface StoredProfile {\n readonly name: string;\n readonly tenantId: string;\n readonly clientId: string;\n readonly site: string;\n readonly drive?: string;\n readonly secretStore: SecretStoreKind;\n readonly updatedAt: string;\n}\n\nexport interface RedactedProfile extends Omit<StoredProfile, \"clientId\"> {\n readonly clientId: string;\n readonly hasClientSecret: boolean;\n}\n\nexport type JsonCellValue = string | number | boolean | null;\nexport type JsonRow = readonly JsonCellValue[];\nexport type JsonRecord = Readonly<Record<string, JsonCellValue>>;\nexport type WorkbookInputRow = JsonRow | JsonRecord;\n\nexport interface WorkbookCreateInput {\n readonly sheetName: string;\n readonly headers: readonly string[];\n readonly rows: readonly WorkbookInputRow[];\n readonly tableName?: string;\n}\n\nexport interface WorkbookReadOptions {\n readonly sheetName?: string;\n readonly range?: string;\n}\n\nexport interface WorkbookSheetReadResult {\n readonly name: string;\n readonly rowCount: number;\n readonly columnCount: number;\n readonly rows: readonly JsonRow[];\n}\n\nexport interface WorkbookReadResult {\n readonly sheets: readonly WorkbookSheetReadResult[];\n}\n\nexport interface WorkbookMutationResult {\n readonly bytes: Uint8Array;\n readonly sheetName: string;\n readonly rowCount: number;\n readonly columnCount: number;\n}\n\nexport const DEFAULT_PROFILE_NAME = \"default\";\nexport const DEFAULT_AUTH_BASE = \"https://login.microsoftonline.com\";\nexport const DEFAULT_GRAPH_BASE = \"https://graph.microsoft.com/v1.0\";\n\nexport const ENV_TENANT = \"SHAREPOINT_EXCEL_TENANT_ID\";\nexport const ENV_CLIENT_ID = \"SHAREPOINT_EXCEL_CLIENT_ID\";\nexport const ENV_CLIENT_SECRET = \"SHAREPOINT_EXCEL_CLIENT_SECRET\";\nexport const ENV_SITE = \"SHAREPOINT_EXCEL_SITE\";\nexport const ENV_DRIVE = \"SHAREPOINT_EXCEL_DRIVE\";\nexport const ENV_PROFILE = \"SHAREPOINT_EXCEL_PROFILE\";\nexport const ENV_AUTH_BASE = \"SHAREPOINT_EXCEL_AUTH_BASE\";\nexport const ENV_GRAPH_BASE = \"SHAREPOINT_EXCEL_GRAPH_BASE\";\nexport const ENV_HOME = \"SAPTOOLS_SHAREPOINT_EXCEL_HOME\";\nexport const ENV_ALLOW_PLAINTEXT = \"SAPTOOLS_SHAREPOINT_EXCEL_ALLOW_PLAINTEXT\";\n\nexport const FALLBACK_ENV_TENANT = \"SHAREPOINT_TENANT_ID\";\nexport const FALLBACK_ENV_CLIENT_ID = \"SHAREPOINT_CLIENT_ID\";\nexport const FALLBACK_ENV_CLIENT_SECRET = \"SHAREPOINT_CLIENT_SECRET\";\nexport const FALLBACK_ENV_SITE = \"SHAREPOINT_SITE\";\nexport const FALLBACK_ENV_DRIVE = \"SHAREPOINT_DRIVE\";\n","import process from \"node:process\";\n\nimport type { FetchLike } from \"../graph/client.js\";\nimport type { AccessTokenInfo, SharePointCredentials } from \"../types.js\";\nimport { DEFAULT_AUTH_BASE, ENV_AUTH_BASE } from \"../types.js\";\n\nexport interface AcquireTokenOptions {\n readonly authBase?: string;\n readonly scope?: string;\n readonly fetchFn?: FetchLike;\n readonly env?: NodeJS.ProcessEnv;\n}\n\ninterface TokenResponse {\n readonly access_token?: unknown;\n readonly token_type?: unknown;\n readonly expires_in?: unknown;\n readonly scope?: unknown;\n readonly error?: unknown;\n readonly error_description?: unknown;\n}\n\nconst DEFAULT_SCOPE = \"https://graph.microsoft.com/.default\";\n\nfunction resolveAuthBase(options: AcquireTokenOptions): string {\n if (options.authBase !== undefined && options.authBase.length > 0) {\n return options.authBase.replace(/\\/+$/, \"\");\n }\n const fromEnv = (options.env ?? process.env)[ENV_AUTH_BASE];\n return fromEnv === undefined || fromEnv.length === 0\n ? DEFAULT_AUTH_BASE\n : fromEnv.replace(/\\/+$/, \"\");\n}\n\nfunction assertString(value: unknown, field: string): string {\n if (typeof value !== \"string\" || value.length === 0) {\n throw new Error(`Token response missing field: ${field}`);\n }\n return value;\n}\n\nfunction assertNumber(value: unknown, field: string): number {\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n throw new Error(`Token response missing numeric field: ${field}`);\n }\n return value;\n}\n\nfunction parseTokenResponse(text: string, status: number): TokenResponse {\n try {\n return JSON.parse(text) as TokenResponse;\n } catch (err) {\n throw new Error(`Failed to parse token response (HTTP ${status.toString()})`, { cause: err });\n }\n}\n\nfunction throwIfTokenError(response: Response, parsed: TokenResponse): void {\n if (response.ok && typeof parsed.error !== \"string\") {\n return;\n }\n const code = typeof parsed.error === \"string\" ? parsed.error : \"unknown_error\";\n const description =\n typeof parsed.error_description === \"string\" && parsed.error_description.length > 0\n ? parsed.error_description\n : response.statusText;\n throw new Error(\n `Azure AD token request failed (HTTP ${response.status.toString()} ${code}): ${description}`,\n );\n}\n\nexport async function acquireAppToken(\n credentials: SharePointCredentials,\n options: AcquireTokenOptions = {},\n): Promise<AccessTokenInfo> {\n if (credentials.tenantId.length === 0) {\n throw new Error(\"tenantId is required\");\n }\n if (credentials.clientId.length === 0) {\n throw new Error(\"clientId is required\");\n }\n if (credentials.clientSecret.length === 0) {\n throw new Error(\"clientSecret is required\");\n }\n\n const authBase = resolveAuthBase(options);\n const fetchFn = options.fetchFn ?? fetch;\n const url = `${authBase}/${encodeURIComponent(credentials.tenantId)}/oauth2/v2.0/token`;\n const form = new URLSearchParams({\n grant_type: \"client_credentials\",\n client_id: credentials.clientId,\n client_secret: credentials.clientSecret,\n scope: options.scope ?? DEFAULT_SCOPE,\n });\n\n const response = await fetchFn(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\", Accept: \"application/json\" },\n body: form.toString(),\n });\n const parsed = parseTokenResponse(await response.text(), response.status);\n throwIfTokenError(response, parsed);\n\n const scopeValue = typeof parsed.scope === \"string\" ? parsed.scope : undefined;\n const base = {\n accessToken: assertString(parsed.access_token, \"access_token\"),\n tokenType: assertString(parsed.token_type, \"token_type\"),\n expiresOn: Math.floor(Date.now() / 1000) + assertNumber(parsed.expires_in, \"expires_in\"),\n };\n return scopeValue === undefined ? base : { ...base, scope: scopeValue };\n}\n","import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport process from \"node:process\";\n\nimport { ENV_HOME } from \"../types.js\";\n\nexport const SAPTOOLS_DIR_NAME = \".saptools\";\nexport const PACKAGE_DIR_NAME = \"sharepoint-excel\";\nexport const PROFILES_FILENAME = \"profiles.json\";\nexport const FILE_SECRETS_FILENAME = \"secrets.json\";\n\nexport function packageDataDir(env: NodeJS.ProcessEnv = process.env): string {\n const override = env[ENV_HOME];\n if (override !== undefined && override.length > 0) {\n return override;\n }\n return join(homedir(), SAPTOOLS_DIR_NAME, PACKAGE_DIR_NAME);\n}\n\nexport function profilesPath(env: NodeJS.ProcessEnv = process.env): string {\n return join(packageDataDir(env), PROFILES_FILENAME);\n}\n\nexport function fileSecretsPath(env: NodeJS.ProcessEnv = process.env): string {\n return join(packageDataDir(env), FILE_SECRETS_FILENAME);\n}\n","import process from \"node:process\";\n\nimport type { ProfileStore } from \"../credentials/profile-store.js\";\nimport { createProfileStore, findProfile } from \"../credentials/profile-store.js\";\nimport type { SecretVault } from \"../credentials/secret-vault.js\";\nimport { createFileSecretVault, createKeyringSecretVault } from \"../credentials/secret-vault.js\";\nimport { parseSiteRef } from \"../graph/site.js\";\nimport type { SecretStoreKind, SharePointTarget, StoredProfile } from \"../types.js\";\nimport {\n DEFAULT_PROFILE_NAME,\n ENV_CLIENT_ID,\n ENV_CLIENT_SECRET,\n ENV_DRIVE,\n ENV_PROFILE,\n ENV_SITE,\n ENV_TENANT,\n FALLBACK_ENV_CLIENT_ID,\n FALLBACK_ENV_CLIENT_SECRET,\n FALLBACK_ENV_DRIVE,\n FALLBACK_ENV_SITE,\n FALLBACK_ENV_TENANT,\n} from \"../types.js\";\n\nexport interface RuntimeOverrides {\n readonly profile?: string | undefined;\n readonly tenant?: string | undefined;\n readonly clientId?: string | undefined;\n readonly clientSecret?: string | undefined;\n readonly site?: string | undefined;\n readonly drive?: string | undefined;\n}\n\nexport interface ResolveRuntimeOptions {\n readonly env?: NodeJS.ProcessEnv;\n readonly overrides?: RuntimeOverrides;\n readonly profileStore?: ProfileStore;\n readonly keyringVault?: SecretVault;\n readonly fileVault?: SecretVault;\n}\n\nexport interface ResolvedRuntime {\n readonly target: SharePointTarget;\n readonly drive?: string;\n readonly profileName: string;\n readonly source: \"profile\" | \"env\";\n}\n\nfunction pickEnv(env: NodeJS.ProcessEnv, primary: string, fallback: string): string | undefined {\n const value = env[primary] ?? env[fallback];\n return value === undefined || value.length === 0 ? undefined : value;\n}\n\nfunction pickValue(\n override: string | undefined,\n envValue: string | undefined,\n profileValue: string | undefined,\n): string | undefined {\n if (override !== undefined && override.length > 0) {\n return override;\n }\n return envValue ?? profileValue;\n}\n\nfunction vaultForProfile(\n profile: StoredProfile | undefined,\n options: ResolveRuntimeOptions,\n): SecretVault {\n if (profile?.secretStore === \"file\") {\n return options.fileVault ?? createFileSecretVault();\n }\n return options.keyringVault ?? createKeyringSecretVault();\n}\n\nasync function resolveClientSecret(\n override: string | undefined,\n envValue: string | undefined,\n profile: StoredProfile | undefined,\n options: ResolveRuntimeOptions,\n): Promise<string | undefined> {\n if (override !== undefined && override.length > 0) {\n return override;\n }\n if (envValue !== undefined) {\n return envValue;\n }\n return profile === undefined ? undefined : await vaultForProfile(profile, options).getSecret(profile.name);\n}\n\nfunction requireValue(value: string | undefined, humanName: string): string {\n if (value === undefined || value.length === 0) {\n throw new Error(`${humanName} is required (pass a flag, set env, or run config set)`);\n }\n return value;\n}\n\nexport async function resolveRuntime(options: ResolveRuntimeOptions = {}): Promise<ResolvedRuntime> {\n const env = options.env ?? process.env;\n const overrides = options.overrides ?? {};\n const profileName =\n overrides.profile ?? env[ENV_PROFILE] ?? DEFAULT_PROFILE_NAME;\n const store = options.profileStore ?? createProfileStore();\n const profile = findProfile(await store.readProfiles(), profileName);\n\n const tenantId = pickValue(\n overrides.tenant,\n pickEnv(env, ENV_TENANT, FALLBACK_ENV_TENANT),\n profile?.tenantId,\n );\n const clientId = pickValue(\n overrides.clientId,\n pickEnv(env, ENV_CLIENT_ID, FALLBACK_ENV_CLIENT_ID),\n profile?.clientId,\n );\n const site = pickValue(overrides.site, pickEnv(env, ENV_SITE, FALLBACK_ENV_SITE), profile?.site);\n const drive = pickValue(overrides.drive, pickEnv(env, ENV_DRIVE, FALLBACK_ENV_DRIVE), profile?.drive);\n const clientSecret = await resolveClientSecret(\n overrides.clientSecret,\n pickEnv(env, ENV_CLIENT_SECRET, FALLBACK_ENV_CLIENT_SECRET),\n profile,\n options,\n );\n\n return {\n target: {\n credentials: {\n tenantId: requireValue(tenantId, \"Tenant ID\"),\n clientId: requireValue(clientId, \"Client ID\"),\n clientSecret: requireValue(clientSecret, \"Client secret\"),\n },\n site: parseSiteRef(requireValue(site, \"SharePoint site\")),\n },\n ...(drive === undefined ? {} : { drive }),\n profileName,\n source: profile === undefined ? \"env\" : \"profile\",\n };\n}\n\nexport function parseSecretStoreKind(value: string | undefined): SecretStoreKind {\n if (value === undefined || value === \"keyring\") {\n return \"keyring\";\n }\n if (value === \"file\") {\n return \"file\";\n }\n throw new Error(`Invalid secret store \"${value}\". Expected keyring or file`);\n}\n","import { chmod, mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\nimport { profilesPath } from \"../config/paths.js\";\nimport type { RedactedProfile, SecretStoreKind, StoredProfile } from \"../types.js\";\nimport { DEFAULT_PROFILE_NAME } from \"../types.js\";\n\nimport type { SecretVault } from \"./secret-vault.js\";\n\ninterface ProfileFile {\n readonly version: 1;\n readonly profiles: readonly StoredProfile[];\n}\n\nexport interface ProfileStore {\n readProfiles: () => Promise<readonly StoredProfile[]>;\n writeProfiles: (profiles: readonly StoredProfile[]) => Promise<void>;\n}\n\nexport interface UpsertProfileInput {\n readonly name?: string;\n readonly tenantId: string;\n readonly clientId: string;\n readonly clientSecret: string;\n readonly site: string;\n readonly drive?: string;\n readonly secretStore: SecretStoreKind;\n readonly updatedAt?: Date;\n}\n\nconst PROFILE_FILE_MODE = 0o600;\nconst EMPTY_PROFILE_FILE: ProfileFile = { version: 1, profiles: [] };\n\nfunction isMissingFileError(err: unknown): boolean {\n return err instanceof Error && \"code\" in err && err.code === \"ENOENT\";\n}\n\nfunction isSecretStoreKind(value: unknown): value is SecretStoreKind {\n return value === \"keyring\" || value === \"file\";\n}\n\nfunction toStoredProfile(value: unknown): StoredProfile | undefined {\n if (typeof value !== \"object\" || value === null) {\n return undefined;\n }\n const raw = value as Record<string, unknown>;\n const name = raw[\"name\"];\n const tenantId = raw[\"tenantId\"];\n const clientId = raw[\"clientId\"];\n const site = raw[\"site\"];\n const drive = raw[\"drive\"];\n const secretStore = raw[\"secretStore\"];\n const updatedAt = raw[\"updatedAt\"];\n if (\n typeof name !== \"string\" ||\n typeof tenantId !== \"string\" ||\n typeof clientId !== \"string\" ||\n typeof site !== \"string\" ||\n typeof updatedAt !== \"string\" ||\n !isSecretStoreKind(secretStore)\n ) {\n return undefined;\n }\n return {\n name,\n tenantId,\n clientId,\n site,\n ...(typeof drive === \"string\" ? { drive } : {}),\n secretStore,\n updatedAt,\n };\n}\n\nfunction isStoredProfile(value: StoredProfile | undefined): value is StoredProfile {\n return value !== undefined;\n}\n\nasync function readProfileFile(path: string): Promise<ProfileFile> {\n try {\n const raw = await readFile(path, \"utf8\");\n const parsed = JSON.parse(raw) as { readonly version?: unknown; readonly profiles?: unknown };\n if (parsed.version !== 1 || !Array.isArray(parsed.profiles)) {\n return EMPTY_PROFILE_FILE;\n }\n return { version: 1, profiles: parsed.profiles.map(toStoredProfile).filter(isStoredProfile) };\n } catch (err) {\n if (isMissingFileError(err)) {\n return EMPTY_PROFILE_FILE;\n }\n throw err;\n }\n}\n\nasync function writeProfileFile(path: string, value: ProfileFile): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, `${JSON.stringify(value, null, 2)}\\n`, {\n encoding: \"utf8\",\n mode: PROFILE_FILE_MODE,\n });\n await chmod(path, PROFILE_FILE_MODE);\n}\n\nexport function createProfileStore(path = profilesPath()): ProfileStore {\n return {\n async readProfiles(): Promise<readonly StoredProfile[]> {\n return (await readProfileFile(path)).profiles;\n },\n async writeProfiles(profiles: readonly StoredProfile[]): Promise<void> {\n await writeProfileFile(path, { version: 1, profiles });\n },\n };\n}\n\nexport function findProfile(\n profiles: readonly StoredProfile[],\n name = DEFAULT_PROFILE_NAME,\n): StoredProfile | undefined {\n return profiles.find((profile) => profile.name === name);\n}\n\nexport async function upsertProfile(\n store: ProfileStore,\n vault: SecretVault,\n input: UpsertProfileInput,\n): Promise<StoredProfile> {\n const name = input.name ?? DEFAULT_PROFILE_NAME;\n const stored: StoredProfile = {\n name,\n tenantId: input.tenantId,\n clientId: input.clientId,\n site: input.site,\n ...(input.drive === undefined || input.drive.length === 0 ? {} : { drive: input.drive }),\n secretStore: input.secretStore,\n updatedAt: (input.updatedAt ?? new Date()).toISOString(),\n };\n const profiles = await store.readProfiles();\n const nextProfiles = profiles.some((profile) => profile.name === name)\n ? profiles.map((profile) => (profile.name === name ? stored : profile))\n : [...profiles, stored];\n await vault.setSecret(name, input.clientSecret);\n await store.writeProfiles(nextProfiles);\n return stored;\n}\n\nexport async function removeProfile(\n store: ProfileStore,\n vault: SecretVault,\n name = DEFAULT_PROFILE_NAME,\n): Promise<boolean> {\n const profiles = await store.readProfiles();\n const nextProfiles = profiles.filter((profile) => profile.name !== name);\n await vault.deleteSecret(name);\n if (nextProfiles.length === profiles.length) {\n return false;\n }\n await store.writeProfiles(nextProfiles);\n return true;\n}\n\nexport async function redactProfile(\n profile: StoredProfile,\n vault: SecretVault,\n): Promise<RedactedProfile> {\n const secret = await vault.getSecret(profile.name);\n return {\n ...profile,\n clientId: `${profile.clientId.slice(0, 4)}...${profile.clientId.slice(-4)}`,\n hasClientSecret: secret !== undefined,\n };\n}\n","import { chmod, mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\nimport { Entry } from \"@napi-rs/keyring\";\n\nimport { fileSecretsPath } from \"../config/paths.js\";\n\nexport interface SecretVault {\n getSecret: (profileName: string) => Promise<string | undefined>;\n setSecret: (profileName: string, secret: string) => Promise<void>;\n deleteSecret: (profileName: string) => Promise<void>;\n}\n\ninterface SecretFile {\n readonly version: 1;\n readonly entries: Readonly<Record<string, string>>;\n}\n\nconst SERVICE_NAME = \"saptools-sharepoint-excel\";\nconst SECRET_FILE_MODE = 0o600;\nconst EMPTY_SECRET_FILE: SecretFile = { version: 1, entries: {} };\n\nfunction isMissingFileError(err: unknown): boolean {\n return err instanceof Error && \"code\" in err && err.code === \"ENOENT\";\n}\n\nasync function readSecretFile(path: string): Promise<SecretFile> {\n try {\n const raw = await readFile(path, \"utf8\");\n const parsed = JSON.parse(raw) as { readonly version?: unknown; readonly entries?: unknown };\n if (parsed.version !== 1 || typeof parsed.entries !== \"object\" || parsed.entries === null) {\n return EMPTY_SECRET_FILE;\n }\n const entries: Record<string, string> = {};\n for (const [key, value] of Object.entries(parsed.entries)) {\n if (typeof value === \"string\") {\n entries[key] = value;\n }\n }\n return { version: 1, entries };\n } catch (err) {\n if (isMissingFileError(err)) {\n return EMPTY_SECRET_FILE;\n }\n throw err;\n }\n}\n\nasync function writeSecretFile(path: string, value: SecretFile): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, `${JSON.stringify(value, null, 2)}\\n`, {\n encoding: \"utf8\",\n mode: SECRET_FILE_MODE,\n });\n await chmod(path, SECRET_FILE_MODE);\n}\n\nexport function createKeyringSecretVault(serviceName = SERVICE_NAME): SecretVault {\n return {\n getSecret(profileName: string): Promise<string | undefined> {\n const password = new Entry(serviceName, profileName).getPassword();\n return Promise.resolve(password === null || password.length === 0 ? undefined : password);\n },\n setSecret(profileName: string, secret: string): Promise<void> {\n new Entry(serviceName, profileName).setPassword(secret);\n return Promise.resolve();\n },\n deleteSecret(profileName: string): Promise<void> {\n try {\n new Entry(serviceName, profileName).deletePassword();\n } catch (err) {\n if (err instanceof Error && /not found|no entry|missing/i.test(err.message)) {\n return Promise.resolve();\n }\n return Promise.reject(err instanceof Error ? err : new Error(String(err)));\n }\n return Promise.resolve();\n },\n };\n}\n\nexport function createFileSecretVault(path = fileSecretsPath()): SecretVault {\n return {\n async getSecret(profileName: string): Promise<string | undefined> {\n const file = await readSecretFile(path);\n return file.entries[profileName];\n },\n async setSecret(profileName: string, secret: string): Promise<void> {\n const file = await readSecretFile(path);\n await writeSecretFile(path, {\n version: 1,\n entries: { ...file.entries, [profileName]: secret },\n });\n },\n async deleteSecret(profileName: string): Promise<void> {\n const file = await readSecretFile(path);\n const remaining = Object.fromEntries(\n Object.entries(file.entries).filter(([entryName]) => entryName !== profileName),\n );\n await writeSecretFile(path, { version: 1, entries: remaining });\n },\n };\n}\n","import process from \"node:process\";\n\nimport { DEFAULT_GRAPH_BASE, ENV_GRAPH_BASE } from \"../types.js\";\n\nexport type FetchLike = typeof fetch;\n\nexport interface GraphRetryOptions {\n readonly maxRetries?: number;\n readonly baseDelayMs?: number;\n readonly sleepFn?: (ms: number) => Promise<void>;\n}\n\nexport interface GraphClientOptions {\n readonly accessToken: string;\n readonly baseUrl?: string;\n readonly fetchFn?: FetchLike;\n readonly retry?: GraphRetryOptions;\n readonly env?: NodeJS.ProcessEnv;\n}\n\nexport interface GraphRequestOptions {\n readonly method?: string;\n readonly body?: unknown;\n readonly rawBody?: Uint8Array | string;\n readonly headers?: Readonly<Record<string, string>>;\n}\n\nexport interface GraphClient {\n readonly baseUrl: string;\n requestJson: <T>(path: string, options?: GraphRequestOptions) => Promise<T>;\n requestBytes: (path: string, options?: GraphRequestOptions) => Promise<Uint8Array>;\n requestNoContent: (path: string, options?: GraphRequestOptions) => Promise<void>;\n}\n\ninterface GraphErrorBody {\n readonly error?: {\n readonly code?: unknown;\n readonly message?: unknown;\n };\n}\n\nconst RETRYABLE_STATUSES = new Set<number>([429, 503]);\nconst DEFAULT_MAX_RETRIES = 2;\nconst DEFAULT_BASE_DELAY_MS = 500;\n\nfunction defaultSleep(ms: number): Promise<void> {\n return new Promise((resolve) => {\n setTimeout(resolve, ms);\n });\n}\n\nfunction parseRetryAfter(header: string | null): number | undefined {\n if (header === null || header.length === 0) {\n return undefined;\n }\n const seconds = Number.parseFloat(header);\n if (Number.isFinite(seconds) && seconds >= 0) {\n return Math.ceil(seconds * 1000);\n }\n const dateMs = Date.parse(header);\n return Number.isNaN(dateMs) ? undefined : Math.max(0, dateMs - Date.now());\n}\n\nfunction resolveBaseUrl(options: GraphClientOptions): string {\n if (options.baseUrl !== undefined && options.baseUrl.length > 0) {\n return options.baseUrl.replace(/\\/+$/, \"\");\n }\n const fromEnv = (options.env ?? process.env)[ENV_GRAPH_BASE];\n return fromEnv === undefined || fromEnv.length === 0\n ? DEFAULT_GRAPH_BASE\n : fromEnv.replace(/\\/+$/, \"\");\n}\n\nfunction resolveUrl(base: string, path: string): string {\n if (/^https?:\\/\\//i.test(path)) {\n return path;\n }\n return `${base}${path.startsWith(\"/\") ? path : `/${path}`}`;\n}\n\nexport class GraphHttpError extends Error {\n public readonly status: number;\n public readonly code: string | undefined;\n public readonly detail: string;\n\n public constructor(status: number, code: string | undefined, detail: string) {\n super(\n `Microsoft Graph request failed (${status.toString()}${\n code === undefined ? \"\" : ` ${code}`\n }): ${detail}`,\n );\n this.name = \"GraphHttpError\";\n this.status = status;\n this.code = code;\n this.detail = detail;\n }\n}\n\nasync function extractErrorDetail(response: Response): Promise<{ code: string | undefined; detail: string }> {\n const text = await response.text().catch(() => \"\");\n if (text.length === 0) {\n return { code: undefined, detail: response.statusText };\n }\n try {\n const body = JSON.parse(text) as GraphErrorBody;\n const code = typeof body.error?.code === \"string\" ? body.error.code : undefined;\n const detail =\n typeof body.error?.message === \"string\" && body.error.message.length > 0\n ? body.error.message\n : response.statusText;\n return { code, detail };\n } catch {\n return { code: undefined, detail: text };\n }\n}\n\nfunction buildInit(accessToken: string, options: GraphRequestOptions): RequestInit {\n const headers: Record<string, string> = {\n Authorization: `Bearer ${accessToken}`,\n Accept: \"application/json\",\n ...options.headers,\n };\n const init: RequestInit = { method: options.method ?? \"GET\", headers };\n if (options.rawBody !== undefined) {\n init.body = rawBodyToBodyInit(options.rawBody);\n return init;\n }\n if (options.body !== undefined) {\n headers[\"Content-Type\"] = headers[\"Content-Type\"] ?? \"application/json\";\n init.body = typeof options.body === \"string\" ? options.body : JSON.stringify(options.body);\n }\n return init;\n}\n\ntype RequestBody = NonNullable<RequestInit[\"body\"]>;\n\nfunction rawBodyToBodyInit(rawBody: Uint8Array | string): RequestBody {\n if (typeof rawBody === \"string\") {\n return rawBody;\n }\n const copy = new ArrayBuffer(rawBody.byteLength);\n new Uint8Array(copy).set(rawBody);\n return copy;\n}\n\nasync function discardBody(response: Response): Promise<void> {\n if (response.body === null) {\n return;\n }\n await response.body.cancel().catch(() => {\n /* ignore */\n });\n}\n\nexport function createGraphClient(options: GraphClientOptions): GraphClient {\n const baseUrl = resolveBaseUrl(options);\n const fetchFn = options.fetchFn ?? fetch;\n const maxRetries = options.retry?.maxRetries ?? DEFAULT_MAX_RETRIES;\n const baseDelayMs = options.retry?.baseDelayMs ?? DEFAULT_BASE_DELAY_MS;\n const sleepFn = options.retry?.sleepFn ?? defaultSleep;\n\n async function execute(path: string, requestOptions: GraphRequestOptions): Promise<Response> {\n const url = resolveUrl(baseUrl, path);\n const init = buildInit(options.accessToken, requestOptions);\n let attempt = 0;\n let response = await fetchFn(url, init);\n while (!response.ok && RETRYABLE_STATUSES.has(response.status) && attempt < maxRetries) {\n const retryAfterMs =\n parseRetryAfter(response.headers.get(\"retry-after\")) ?? baseDelayMs * 2 ** attempt;\n await discardBody(response);\n await sleepFn(retryAfterMs);\n attempt += 1;\n response = await fetchFn(url, init);\n }\n if (!response.ok) {\n const { code, detail } = await extractErrorDetail(response);\n throw new GraphHttpError(response.status, code, detail);\n }\n return response;\n }\n\n async function requestJson<T>(path: string, requestOptions: GraphRequestOptions = {}): Promise<T> {\n const response = await execute(path, requestOptions);\n if (response.status === 204) {\n return undefined as T;\n }\n const contentType = response.headers.get(\"content-type\")?.toLowerCase() ?? \"\";\n if (!contentType.includes(\"application/json\")) {\n return undefined as T;\n }\n return (await response.json()) as T;\n }\n\n async function requestBytes(path: string, requestOptions: GraphRequestOptions = {}): Promise<Uint8Array> {\n const response = await execute(path, requestOptions);\n return new Uint8Array(await response.arrayBuffer());\n }\n\n async function requestNoContent(path: string, requestOptions: GraphRequestOptions = {}): Promise<void> {\n await execute(path, requestOptions);\n }\n\n return { baseUrl, requestJson, requestBytes, requestNoContent };\n}\n","import type { SharePointSite, SharePointSiteRef } from \"../types.js\";\n\nimport type { GraphClient } from \"./client.js\";\nimport { GraphHttpError } from \"./client.js\";\n\ninterface RawSiteResponse {\n readonly id?: unknown;\n readonly name?: unknown;\n readonly displayName?: unknown;\n readonly webUrl?: unknown;\n}\n\nfunction asString(value: unknown, fallback = \"\"): string {\n return typeof value === \"string\" ? value : fallback;\n}\n\nfunction stripQueryAndHash(value: string): string {\n const markerIndex = value.search(/[?#]/);\n return markerIndex === -1 ? value : value.slice(0, markerIndex);\n}\n\nfunction decodeSitePath(sitePath: string, input: string): string {\n return sitePath\n .split(\"/\")\n .map((segment) => {\n try {\n return decodeURIComponent(segment);\n } catch (err) {\n throw new Error(`Invalid site reference \"${input}\". Site path has invalid encoding`, {\n cause: err,\n });\n }\n })\n .join(\"/\");\n}\n\nfunction parseSiteInput(trimmed: string): { readonly hostname: string; readonly rawPath: string } {\n if (/^https?:\\/\\//i.test(trimmed)) {\n const url = new URL(trimmed);\n return { hostname: url.hostname, rawPath: url.pathname };\n }\n const withoutQuery = stripQueryAndHash(trimmed);\n const firstSlash = withoutQuery.indexOf(\"/\");\n if (firstSlash === -1) {\n throw new Error(`Invalid site reference \"${trimmed}\". Expected host/sites/<name> or full URL`);\n }\n return { hostname: withoutQuery.slice(0, firstSlash), rawPath: withoutQuery.slice(firstSlash + 1) };\n}\n\nexport function parseSiteRef(input: string): SharePointSiteRef {\n const trimmed = input.trim();\n if (trimmed.length === 0) {\n throw new Error(\"Site reference is empty\");\n }\n const { hostname, rawPath } = parseSiteInput(trimmed);\n const sitePath = decodeSitePath(rawPath.replace(/^\\/+|\\/+$/g, \"\"), trimmed);\n if (hostname.length === 0 || sitePath.length === 0) {\n throw new Error(`Invalid site reference \"${trimmed}\". Missing hostname or site path`);\n }\n return { hostname, sitePath };\n}\n\nfunction encodeSitePath(sitePath: string): string {\n return sitePath.split(\"/\").map((segment) => encodeURIComponent(segment)).join(\"/\");\n}\n\nexport async function resolveSite(\n client: GraphClient,\n ref: SharePointSiteRef,\n): Promise<SharePointSite> {\n const path = `/sites/${encodeURIComponent(ref.hostname)}:/${encodeSitePath(ref.sitePath)}`;\n let raw: RawSiteResponse;\n try {\n raw = await client.requestJson<RawSiteResponse>(path);\n } catch (err) {\n if (err instanceof GraphHttpError && err.status === 404) {\n throw new Error(`SharePoint site not found at ${ref.hostname}/${ref.sitePath}`, {\n cause: err,\n });\n }\n throw err;\n }\n const id = asString(raw.id);\n if (id.length === 0) {\n throw new Error(`Site response missing id for ${ref.hostname}/${ref.sitePath}`);\n }\n return {\n id,\n name: asString(raw.name, ref.sitePath),\n displayName: asString(raw.displayName, asString(raw.name, ref.sitePath)),\n webUrl: asString(raw.webUrl),\n };\n}\n","import type { DriveItemSummary, SharePointDrive } from \"../types.js\";\n\nimport type { GraphClient } from \"./client.js\";\nimport { GraphHttpError } from \"./client.js\";\n\ninterface RawDriveResponse {\n readonly id?: unknown;\n readonly name?: unknown;\n readonly driveType?: unknown;\n readonly webUrl?: unknown;\n}\n\ninterface RawDriveListResponse {\n readonly value?: unknown;\n}\n\ninterface RawDriveItem {\n readonly id?: unknown;\n readonly name?: unknown;\n readonly size?: unknown;\n readonly eTag?: unknown;\n readonly cTag?: unknown;\n readonly webUrl?: unknown;\n readonly folder?: unknown;\n readonly file?: unknown;\n}\n\ninterface UploadSessionResponse {\n readonly uploadUrl?: unknown;\n}\n\nconst XLSX_CONTENT_TYPE = \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\";\n\nfunction asString(value: unknown, fallback = \"\"): string {\n return typeof value === \"string\" ? value : fallback;\n}\n\nfunction asNumber(value: unknown, fallback = 0): number {\n return typeof value === \"number\" && Number.isFinite(value) ? value : fallback;\n}\n\nexport function encodeDrivePath(relativePath: string): string {\n return relativePath\n .split(\"/\")\n .filter((segment) => segment.length > 0)\n .map((segment) => encodeURIComponent(segment))\n .join(\"/\");\n}\n\nfunction toDrive(raw: RawDriveResponse): SharePointDrive {\n return {\n id: asString(raw.id),\n name: asString(raw.name),\n driveType: asString(raw.driveType, \"documentLibrary\"),\n webUrl: asString(raw.webUrl),\n };\n}\n\nfunction toDriveItem(raw: RawDriveItem): DriveItemSummary {\n const base = {\n id: asString(raw.id),\n name: asString(raw.name),\n isFolder: raw.folder !== undefined && raw.folder !== null,\n size: asNumber(raw.size),\n };\n return {\n ...base,\n ...(typeof raw.eTag === \"string\" ? { eTag: raw.eTag } : {}),\n ...(typeof raw.cTag === \"string\" ? { cTag: raw.cTag } : {}),\n ...(typeof raw.webUrl === \"string\" ? { webUrl: raw.webUrl } : {}),\n };\n}\n\nexport async function listDrives(\n client: GraphClient,\n siteId: string,\n): Promise<readonly SharePointDrive[]> {\n const response = await client.requestJson<RawDriveListResponse>(`/sites/${encodeURIComponent(siteId)}/drives`);\n if (!Array.isArray(response.value)) {\n return [];\n }\n return response.value\n .filter((entry): entry is RawDriveResponse => typeof entry === \"object\" && entry !== null)\n .map(toDrive);\n}\n\nexport function selectDrive(\n drives: readonly SharePointDrive[],\n driveHint: string | undefined,\n): SharePointDrive {\n if (drives.length === 0) {\n throw new Error(\"SharePoint site has no drives (document libraries)\");\n }\n if (driveHint === undefined || driveHint.length === 0) {\n const first = drives[0];\n if (first === undefined) {\n throw new Error(\"No drives available\");\n }\n return first;\n }\n const match = drives.find((drive) => drive.id === driveHint || drive.name === driveHint);\n if (match === undefined) {\n throw new Error(`Drive \"${driveHint}\" not found. Available: ${drives.map((d) => d.name).join(\", \")}`);\n }\n return match;\n}\n\nexport async function getDriveItemByPath(\n client: GraphClient,\n driveId: string,\n relativePath: string,\n): Promise<DriveItemSummary | null> {\n const normalized = relativePath.replace(/^\\/+|\\/+$/g, \"\");\n const path =\n normalized.length === 0\n ? `/drives/${encodeURIComponent(driveId)}/root`\n : `/drives/${encodeURIComponent(driveId)}/root:/${encodeDrivePath(normalized)}`;\n try {\n return toDriveItem(await client.requestJson<RawDriveItem>(path));\n } catch (err) {\n if (err instanceof GraphHttpError && err.status === 404) {\n return null;\n }\n throw err;\n }\n}\n\nexport async function downloadDriveFile(\n client: GraphClient,\n driveId: string,\n relativePath: string,\n): Promise<Uint8Array> {\n const encodedPath = encodeDrivePath(relativePath.replace(/^\\/+|\\/+$/g, \"\"));\n return await client.requestBytes(`/drives/${encodeURIComponent(driveId)}/root:/${encodedPath}:/content`, {\n headers: { Accept: XLSX_CONTENT_TYPE },\n });\n}\n\nasync function createUploadSession(\n client: GraphClient,\n driveId: string,\n relativePath: string,\n): Promise<string> {\n const encodedPath = encodeDrivePath(relativePath.replace(/^\\/+|\\/+$/g, \"\"));\n const response = await client.requestJson<UploadSessionResponse>(\n `/drives/${encodeURIComponent(driveId)}/root:/${encodedPath}:/createUploadSession`,\n {\n method: \"POST\",\n body: { item: { \"@microsoft.graph.conflictBehavior\": \"fail\" } },\n },\n );\n if (typeof response.uploadUrl !== \"string\" || response.uploadUrl.length === 0) {\n throw new Error(\"Graph upload session response missing uploadUrl\");\n }\n return response.uploadUrl;\n}\n\nexport async function uploadNewDriveFile(\n client: GraphClient,\n driveId: string,\n relativePath: string,\n bytes: Uint8Array,\n): Promise<DriveItemSummary> {\n const existing = await getDriveItemByPath(client, driveId, relativePath);\n if (existing !== null) {\n throw new Error(`Refusing to overwrite existing SharePoint file: ${relativePath}`);\n }\n const uploadUrl = await createUploadSession(client, driveId, relativePath);\n const lastByte = bytes.byteLength - 1;\n const raw = await client.requestJson<RawDriveItem>(uploadUrl, {\n method: \"PUT\",\n rawBody: bytes,\n headers: {\n \"Content-Length\": bytes.byteLength.toString(),\n \"Content-Range\": `bytes 0-${lastByte.toString()}/${bytes.byteLength.toString()}`,\n \"Content-Type\": XLSX_CONTENT_TYPE,\n },\n });\n return toDriveItem(raw);\n}\n\nexport async function replaceDriveFile(\n client: GraphClient,\n driveId: string,\n relativePath: string,\n eTag: string,\n bytes: Uint8Array,\n): Promise<DriveItemSummary> {\n const encodedPath = encodeDrivePath(relativePath.replace(/^\\/+|\\/+$/g, \"\"));\n const raw = await client.requestJson<RawDriveItem>(\n `/drives/${encodeURIComponent(driveId)}/root:/${encodedPath}:/content`,\n {\n method: \"PUT\",\n rawBody: bytes,\n headers: {\n \"Content-Type\": XLSX_CONTENT_TYPE,\n \"If-Match\": eTag,\n },\n },\n );\n return toDriveItem(raw);\n}\n","import { acquireAppToken } from \"./auth/token.js\";\nimport type { AcquireTokenOptions } from \"./auth/token.js\";\nimport { createGraphClient } from \"./graph/client.js\";\nimport type { FetchLike, GraphClient, GraphRetryOptions } from \"./graph/client.js\";\nimport { listDrives } from \"./graph/drive.js\";\nimport { resolveSite } from \"./graph/site.js\";\nimport type { AccessTokenInfo, SharePointDrive, SharePointSite, SharePointTarget } from \"./types.js\";\n\nexport interface SessionOptions {\n readonly fetchFn?: FetchLike;\n readonly authBase?: string;\n readonly graphBase?: string;\n readonly retry?: GraphRetryOptions;\n}\n\nexport interface SharePointExcelSession {\n readonly token: AccessTokenInfo;\n readonly client: GraphClient;\n readonly site: SharePointSite;\n readonly drives: readonly SharePointDrive[];\n}\n\nexport async function openSession(\n target: SharePointTarget,\n options: SessionOptions = {},\n): Promise<SharePointExcelSession> {\n const tokenOptions: AcquireTokenOptions = {\n ...(options.authBase === undefined ? {} : { authBase: options.authBase }),\n ...(options.fetchFn === undefined ? {} : { fetchFn: options.fetchFn }),\n };\n const token = await acquireAppToken(target.credentials, tokenOptions);\n const client = createGraphClient({\n accessToken: token.accessToken,\n ...(options.graphBase === undefined ? {} : { baseUrl: options.graphBase }),\n ...(options.fetchFn === undefined ? {} : { fetchFn: options.fetchFn }),\n ...(options.retry === undefined ? {} : { retry: options.retry }),\n });\n const site = await resolveSite(client, target.site);\n const drives = await listDrives(client, site.id);\n return { token, client, site, drives };\n}\n","export interface A1CellRef {\n readonly row: number;\n readonly column: number;\n}\n\nexport interface A1RangeRef {\n readonly start: A1CellRef;\n readonly end: A1CellRef;\n}\n\nconst CELL_REF_PATTERN = /^([A-Za-z]+)([1-9]\\d*)$/;\n\nexport function columnNameToNumber(columnName: string): number {\n const normalized = columnName.trim().toUpperCase();\n if (!/^[A-Z]+$/.test(normalized)) {\n throw new Error(`Invalid column name \"${columnName}\"`);\n }\n let total = 0;\n for (const char of normalized) {\n total = total * 26 + char.charCodeAt(0) - 64;\n }\n return total;\n}\n\nexport function parseA1Cell(input: string): A1CellRef {\n const trimmed = input.trim();\n const match = CELL_REF_PATTERN.exec(trimmed);\n if (match === null) {\n throw new Error(`Invalid A1 cell reference \"${input}\"`);\n }\n const columnName = match[1];\n const rowValue = match[2];\n if (columnName === undefined || rowValue === undefined) {\n throw new Error(`Invalid A1 cell reference \"${input}\"`);\n }\n return {\n row: Number.parseInt(rowValue, 10),\n column: columnNameToNumber(columnName),\n };\n}\n\nfunction orderRange(start: A1CellRef, end: A1CellRef): A1RangeRef {\n return {\n start: {\n row: Math.min(start.row, end.row),\n column: Math.min(start.column, end.column),\n },\n end: {\n row: Math.max(start.row, end.row),\n column: Math.max(start.column, end.column),\n },\n };\n}\n\nexport function parseA1Range(input: string): A1RangeRef {\n const parts = input.split(\":\").map((part) => part.trim());\n if (parts.length === 1) {\n const cell = parseA1Cell(parts[0] ?? \"\");\n return { start: cell, end: cell };\n }\n if (parts.length !== 2) {\n throw new Error(`Invalid A1 range \"${input}\"`);\n }\n return orderRange(parseA1Cell(parts[0] ?? \"\"), parseA1Cell(parts[1] ?? \"\"));\n}\n","import ExcelJS from \"exceljs\";\nimport type { CellValue, Worksheet } from \"exceljs\";\n\nimport type {\n JsonCellValue,\n JsonRecord,\n JsonRow,\n WorkbookCreateInput,\n WorkbookInputRow,\n WorkbookMutationResult,\n WorkbookReadOptions,\n WorkbookReadResult,\n WorkbookSheetReadResult,\n} from \"../types.js\";\n\nimport { parseA1Cell, parseA1Range } from \"./a1.js\";\n\nconst INVALID_SHEET_CHARS = /[\\][:*?/\\\\]/;\n\nfunction validateSheetName(sheetName: string): string {\n const trimmed = sheetName.trim();\n if (trimmed.length === 0 || trimmed.length > 31 || INVALID_SHEET_CHARS.test(trimmed)) {\n throw new Error(`Invalid Excel sheet name \"${sheetName}\"`);\n }\n return trimmed;\n}\n\nfunction isRecord(row: WorkbookInputRow): row is JsonRecord {\n return !Array.isArray(row);\n}\n\nfunction deriveHeaders(headers: readonly string[], rows: readonly WorkbookInputRow[]): readonly string[] {\n if (headers.length > 0) {\n return headers;\n }\n const firstRecord = rows.find(isRecord);\n return firstRecord === undefined ? [] : Object.keys(firstRecord);\n}\n\nfunction rowToValues(row: WorkbookInputRow, headers: readonly string[]): JsonRow {\n if (!isRecord(row)) {\n return [...row];\n }\n const record = row;\n if (headers.length === 0) {\n return Object.keys(record).map((key) => record[key] ?? null);\n }\n return headers.map((header) => record[header] ?? null);\n}\n\nfunction addRows(sheet: Worksheet, headers: readonly string[], rows: readonly WorkbookInputRow[]): void {\n if (headers.length > 0) {\n sheet.addRow([...headers]);\n }\n for (const row of rows) {\n sheet.addRow([...rowToValues(row, headers)]);\n }\n}\n\nfunction addTable(sheet: Worksheet, tableName: string, headers: readonly string[], rows: readonly WorkbookInputRow[]): void {\n sheet.addTable({\n name: tableName,\n ref: \"A1\",\n headerRow: true,\n totalsRow: false,\n style: { theme: \"TableStyleMedium2\", showRowStripes: true },\n columns: headers.map((name) => ({ name })),\n rows: rows.map((row) => [...rowToValues(row, headers)]),\n });\n}\n\nasync function workbookToBytes(workbook: ExcelJS.Workbook): Promise<Uint8Array> {\n const buffer = await workbook.xlsx.writeBuffer();\n return new Uint8Array(buffer);\n}\n\nasync function loadWorkbook(bytes: Uint8Array): Promise<ExcelJS.Workbook> {\n const workbook = new ExcelJS.Workbook();\n await workbook.xlsx.load(uint8ArrayToArrayBuffer(bytes));\n return workbook;\n}\n\nfunction uint8ArrayToArrayBuffer(bytes: Uint8Array): ArrayBuffer {\n const copy = new ArrayBuffer(bytes.byteLength);\n new Uint8Array(copy).set(bytes);\n return copy;\n}\n\nfunction getWorksheet(workbook: ExcelJS.Workbook, sheetName: string): Worksheet {\n const sheet = workbook.getWorksheet(sheetName);\n if (sheet === undefined) {\n throw new Error(`Sheet \"${sheetName}\" not found`);\n }\n return sheet;\n}\n\nfunction serializeCellValue(value: unknown): JsonCellValue {\n if (value === null || value === undefined) {\n return null;\n }\n if (typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\") {\n return value;\n }\n if (value instanceof Date) {\n return value.toISOString();\n }\n if (typeof value === \"object\" && \"result\" in value) {\n return serializeCellValue((value as { readonly result?: unknown }).result);\n }\n return JSON.stringify(value);\n}\n\nfunction readRow(sheet: Worksheet, rowNumber: number, startColumn: number, endColumn: number): JsonRow {\n const row = sheet.getRow(rowNumber);\n const columnCount = endColumn - startColumn + 1;\n return Array.from({ length: columnCount }, (_value, index) =>\n serializeCellValue(row.getCell(startColumn + index).value),\n );\n}\n\nfunction readHeaderRow(sheet: Worksheet): readonly string[] {\n if (sheet.actualRowCount === 0) {\n return [];\n }\n return readRow(sheet, 1, 1, Math.max(1, sheet.actualColumnCount)).map((value) => String(value ?? \"\"));\n}\n\nfunction readSheet(sheet: Worksheet, options: WorkbookReadOptions): WorkbookSheetReadResult {\n const range = options.range === undefined ? undefined : parseA1Range(options.range);\n const startRow = range?.start.row ?? 1;\n const endRow = range?.end.row ?? Math.max(1, sheet.actualRowCount);\n const startColumn = range?.start.column ?? 1;\n const endColumn = range?.end.column ?? Math.max(1, sheet.actualColumnCount);\n const rows: JsonRow[] = [];\n for (let row = startRow; row <= endRow; row += 1) {\n rows.push(readRow(sheet, row, startColumn, endColumn));\n }\n return { name: sheet.name, rowCount: rows.length, columnCount: endColumn - startColumn + 1, rows };\n}\n\nexport async function createWorkbookBytes(input: WorkbookCreateInput): Promise<Uint8Array> {\n const workbook = new ExcelJS.Workbook();\n const sheet = workbook.addWorksheet(validateSheetName(input.sheetName));\n const headers = deriveHeaders(input.headers, input.rows);\n if (input.tableName !== undefined && input.tableName.length > 0 && headers.length > 0) {\n addTable(sheet, input.tableName, headers, input.rows);\n } else {\n addRows(sheet, headers, input.rows);\n }\n return await workbookToBytes(workbook);\n}\n\nexport async function readWorkbookBytes(\n bytes: Uint8Array,\n options: WorkbookReadOptions = {},\n): Promise<WorkbookReadResult> {\n const workbook = await loadWorkbook(bytes);\n const sheets =\n options.sheetName === undefined\n ? workbook.worksheets\n : [getWorksheet(workbook, validateSheetName(options.sheetName))];\n return { sheets: sheets.map((sheet) => readSheet(sheet, options)) };\n}\n\nexport async function appendWorkbookRows(\n bytes: Uint8Array,\n sheetName: string,\n rows: readonly WorkbookInputRow[],\n matchHeader: boolean,\n): Promise<WorkbookMutationResult> {\n const workbook = await loadWorkbook(bytes);\n const sheet = getWorksheet(workbook, validateSheetName(sheetName));\n const headers = matchHeader ? readHeaderRow(sheet) : deriveHeaders([], rows);\n for (const row of rows) {\n sheet.addRow([...rowToValues(row, headers)]);\n }\n return {\n bytes: await workbookToBytes(workbook),\n sheetName: sheet.name,\n rowCount: sheet.actualRowCount,\n columnCount: sheet.actualColumnCount,\n };\n}\n\nexport async function updateWorkbookCell(\n bytes: Uint8Array,\n sheetName: string,\n cellRef: string,\n value: CellValue,\n): Promise<WorkbookMutationResult> {\n const workbook = await loadWorkbook(bytes);\n const sheet = getWorksheet(workbook, validateSheetName(sheetName));\n const cell = parseA1Cell(cellRef);\n sheet.getCell(cell.row, cell.column).value = value;\n return {\n bytes: await workbookToBytes(workbook),\n sheetName: sheet.name,\n rowCount: sheet.actualRowCount,\n columnCount: sheet.actualColumnCount,\n };\n}\n\nexport async function addWorkbookSheet(\n bytes: Uint8Array,\n sheetName: string,\n headers: readonly string[],\n): Promise<WorkbookMutationResult> {\n const workbook = await loadWorkbook(bytes);\n const normalized = validateSheetName(sheetName);\n if (workbook.getWorksheet(normalized) !== undefined) {\n throw new Error(`Sheet \"${normalized}\" already exists`);\n }\n const sheet = workbook.addWorksheet(normalized);\n if (headers.length > 0) {\n sheet.addRow([...headers]);\n }\n return {\n bytes: await workbookToBytes(workbook),\n sheetName: sheet.name,\n rowCount: sheet.actualRowCount,\n columnCount: sheet.actualColumnCount,\n };\n}\n","import { z } from \"zod\";\n\nimport type { JsonCellValue, WorkbookInputRow } from \"../types.js\";\n\nconst JsonCellValueSchema = z.union([z.string(), z.number(), z.boolean(), z.null()]);\nconst JsonRowSchema = z.array(JsonCellValueSchema);\nconst JsonRecordSchema = z.record(z.string(), JsonCellValueSchema);\n\nexport function parseHeaders(input: string | undefined): readonly string[] {\n if (input === undefined || input.trim().length === 0) {\n return [];\n }\n return input\n .split(\",\")\n .map((entry) => entry.trim())\n .filter((entry) => entry.length > 0);\n}\n\nfunction parseJson(input: string, label: string): unknown {\n try {\n return JSON.parse(input) as unknown;\n } catch (err) {\n throw new Error(`Invalid JSON for ${label}`, { cause: err });\n }\n}\n\nexport function parseCellValue(input: string): JsonCellValue {\n const trimmed = input.trim();\n if (trimmed.length === 0) {\n return \"\";\n }\n let parsed: unknown;\n try {\n parsed = parseJson(trimmed, \"cell value\");\n } catch {\n return input;\n }\n const result = JsonCellValueSchema.safeParse(parsed);\n if (!result.success) {\n return input;\n }\n return result.data;\n}\n\nexport function parseWorkbookRows(input: string | undefined): readonly WorkbookInputRow[] {\n if (input === undefined || input.trim().length === 0) {\n return [];\n }\n const parsed = parseJson(input, \"rows\");\n const rowResult = JsonRowSchema.safeParse(parsed);\n if (rowResult.success) {\n return [rowResult.data];\n }\n const recordResult = JsonRecordSchema.safeParse(parsed);\n if (recordResult.success) {\n return [recordResult.data];\n }\n if (Array.isArray(parsed)) {\n return parsed.map(parseWorkbookRow);\n }\n throw new Error(`Rows JSON must be an object, row array, or array of rows/objects`);\n}\n\nfunction parseWorkbookRow(value: unknown): WorkbookInputRow {\n const rowResult = JsonRowSchema.safeParse(value);\n if (rowResult.success) {\n return rowResult.data;\n }\n const recordResult = JsonRecordSchema.safeParse(value);\n if (recordResult.success) {\n return recordResult.data;\n }\n throw new Error(`Rows JSON must be an object, row array, or array of rows/objects`);\n}\n","import {\n downloadDriveFile,\n getDriveItemByPath,\n replaceDriveFile,\n selectDrive,\n uploadNewDriveFile,\n} from \"../graph/drive.js\";\nimport type { SharePointExcelSession } from \"../session.js\";\nimport type {\n DriveItemSummary,\n WorkbookCreateInput,\n WorkbookInputRow,\n WorkbookMutationResult,\n WorkbookReadOptions,\n WorkbookReadResult,\n} from \"../types.js\";\n\nimport {\n addWorkbookSheet,\n appendWorkbookRows,\n createWorkbookBytes,\n readWorkbookBytes,\n updateWorkbookCell,\n} from \"./excel.js\";\n\nexport interface WorkbookServiceTarget {\n readonly session: SharePointExcelSession;\n readonly driveHint?: string;\n}\n\nexport interface RemoteWorkbookResult {\n readonly driveId: string;\n readonly driveName: string;\n readonly path: string;\n readonly item: DriveItemSummary;\n}\n\nexport interface RemoteReadResult extends RemoteWorkbookResult {\n readonly workbook: WorkbookReadResult;\n}\n\nexport interface RemoteMutationResult extends RemoteWorkbookResult {\n readonly mutation: WorkbookMutationResult;\n}\n\nfunction normalizeWorkbookPath(path: string): string {\n const normalized = path.trim().replace(/^\\/+|\\/+$/g, \"\");\n if (normalized.length === 0) {\n throw new Error(\"Workbook path is required\");\n }\n if (!normalized.toLowerCase().endsWith(\".xlsx\")) {\n throw new Error(`Workbook path must end with .xlsx: ${path}`);\n }\n return normalized;\n}\n\nfunction requireEtag(item: DriveItemSummary, path: string): string {\n if (item.eTag === undefined || item.eTag.length === 0) {\n throw new Error(`Cannot update ${path}: SharePoint item is missing an ETag`);\n }\n return item.eTag;\n}\n\nasync function downloadExistingWorkbook(\n target: WorkbookServiceTarget,\n path: string,\n): Promise<{ readonly bytes: Uint8Array; readonly item: DriveItemSummary; readonly driveId: string; readonly driveName: string }> {\n const drive = selectDrive(target.session.drives, target.driveHint);\n const item = await getDriveItemByPath(target.session.client, drive.id, path);\n if (item === null || item.isFolder) {\n throw new Error(`Workbook not found: ${path}`);\n }\n const bytes = await downloadDriveFile(target.session.client, drive.id, path);\n return { bytes, item, driveId: drive.id, driveName: drive.name };\n}\n\nexport async function createRemoteWorkbook(\n target: WorkbookServiceTarget,\n path: string,\n input: WorkbookCreateInput,\n): Promise<RemoteWorkbookResult> {\n const normalizedPath = normalizeWorkbookPath(path);\n const drive = selectDrive(target.session.drives, target.driveHint);\n const bytes = await createWorkbookBytes(input);\n const item = await uploadNewDriveFile(target.session.client, drive.id, normalizedPath, bytes);\n return { driveId: drive.id, driveName: drive.name, path: normalizedPath, item };\n}\n\nexport async function readRemoteWorkbook(\n target: WorkbookServiceTarget,\n path: string,\n options: WorkbookReadOptions = {},\n): Promise<RemoteReadResult> {\n const normalizedPath = normalizeWorkbookPath(path);\n const downloaded = await downloadExistingWorkbook(target, normalizedPath);\n const workbook = await readWorkbookBytes(downloaded.bytes, options);\n return { ...downloaded, path: normalizedPath, workbook };\n}\n\nexport async function appendRemoteWorkbookRows(\n target: WorkbookServiceTarget,\n path: string,\n sheetName: string,\n rows: readonly WorkbookInputRow[],\n matchHeader: boolean,\n): Promise<RemoteMutationResult> {\n const normalizedPath = normalizeWorkbookPath(path);\n const downloaded = await downloadExistingWorkbook(target, normalizedPath);\n const mutation = await appendWorkbookRows(downloaded.bytes, sheetName, rows, matchHeader);\n const item = await replaceDriveFile(\n target.session.client,\n downloaded.driveId,\n normalizedPath,\n requireEtag(downloaded.item, normalizedPath),\n mutation.bytes,\n );\n return { ...downloaded, item, path: normalizedPath, mutation };\n}\n\nexport async function updateRemoteWorkbookCell(\n target: WorkbookServiceTarget,\n path: string,\n sheetName: string,\n cellRef: string,\n value: string | number | boolean | null,\n): Promise<RemoteMutationResult> {\n const normalizedPath = normalizeWorkbookPath(path);\n const downloaded = await downloadExistingWorkbook(target, normalizedPath);\n const mutation = await updateWorkbookCell(downloaded.bytes, sheetName, cellRef, value);\n const item = await replaceDriveFile(\n target.session.client,\n downloaded.driveId,\n normalizedPath,\n requireEtag(downloaded.item, normalizedPath),\n mutation.bytes,\n );\n return { ...downloaded, item, path: normalizedPath, mutation };\n}\n\nexport async function addRemoteWorkbookSheet(\n target: WorkbookServiceTarget,\n path: string,\n sheetName: string,\n headers: readonly string[],\n): Promise<RemoteMutationResult> {\n const normalizedPath = normalizeWorkbookPath(path);\n const downloaded = await downloadExistingWorkbook(target, normalizedPath);\n const mutation = await addWorkbookSheet(downloaded.bytes, sheetName, headers);\n const item = await replaceDriveFile(\n target.session.client,\n downloaded.driveId,\n normalizedPath,\n requireEtag(downloaded.item, normalizedPath),\n mutation.bytes,\n );\n return { ...downloaded, item, path: normalizedPath, mutation };\n}\n"],"mappings":"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","names":["process","process","process","chmod","mkdir","readFile","writeFile","dirname","isMissingFileError","readFile","mkdir","dirname","writeFile","chmod","process","process","process","asString"]}
|
|
1
|
+
{"version":3,"sources":["../src/types.ts","../src/auth/token.ts","../src/config/paths.ts","../src/config/resolve.ts","../src/credentials/profile-store.ts","../src/credentials/secret-vault.ts","../src/graph/client.ts","../src/graph/site.ts","../src/graph/drive.ts","../src/session.ts","../src/workbook/a1.ts","../src/workbook/excel.ts","../src/workbook/json.ts","../src/workbook/service.ts"],"sourcesContent":["export type SecretStoreKind = \"keyring\" | \"file\";\n\nexport interface SharePointCredentials {\n readonly tenantId: string;\n readonly clientId: string;\n readonly clientSecret: string;\n}\n\nexport interface SharePointSiteRef {\n readonly hostname: string;\n readonly sitePath: string;\n}\n\nexport interface SharePointTarget {\n readonly credentials: SharePointCredentials;\n readonly site: SharePointSiteRef;\n}\n\nexport interface AccessTokenInfo {\n readonly accessToken: string;\n readonly expiresOn: number;\n readonly tokenType: string;\n readonly scope?: string;\n}\n\nexport interface SharePointSite {\n readonly id: string;\n readonly name: string;\n readonly displayName: string;\n readonly webUrl: string;\n}\n\nexport interface SharePointDrive {\n readonly id: string;\n readonly name: string;\n readonly driveType: string;\n readonly webUrl: string;\n}\n\nexport interface DriveItemSummary {\n readonly id: string;\n readonly name: string;\n readonly isFolder: boolean;\n readonly size: number;\n readonly eTag?: string;\n readonly cTag?: string;\n readonly webUrl?: string;\n}\n\nexport interface StoredProfile {\n readonly name: string;\n readonly tenantId: string;\n readonly clientId: string;\n readonly site: string;\n readonly drive?: string;\n readonly secretStore: SecretStoreKind;\n readonly updatedAt: string;\n}\n\nexport interface RedactedProfile extends Omit<StoredProfile, \"clientId\"> {\n readonly clientId: string;\n readonly hasClientSecret: boolean;\n}\n\nexport type JsonCellValue = string | number | boolean | null;\nexport type JsonRow = readonly JsonCellValue[];\nexport type JsonRecord = Readonly<Record<string, JsonCellValue>>;\nexport type WorkbookInputRow = JsonRow | JsonRecord;\n\nexport interface WorkbookCreateInput {\n readonly sheetName: string;\n readonly headers: readonly string[];\n readonly rows: readonly WorkbookInputRow[];\n readonly tableName?: string;\n}\n\nexport interface WorkbookReadOptions {\n readonly sheetName?: string;\n readonly range?: string;\n}\n\nexport interface WorkbookSheetReadResult {\n readonly name: string;\n readonly rowCount: number;\n readonly columnCount: number;\n readonly rows: readonly JsonRow[];\n}\n\nexport interface WorkbookReadResult {\n readonly sheets: readonly WorkbookSheetReadResult[];\n}\n\nexport interface WorkbookMutationResult {\n readonly bytes: Uint8Array;\n readonly sheetName: string;\n readonly rowCount: number;\n readonly columnCount: number;\n}\n\nexport const DEFAULT_PROFILE_NAME = \"default\";\nexport const DEFAULT_AUTH_BASE = \"https://login.microsoftonline.com\";\nexport const DEFAULT_GRAPH_BASE = \"https://graph.microsoft.com/v1.0\";\n\nexport const ENV_TENANT = \"SHAREPOINT_EXCEL_TENANT_ID\";\nexport const ENV_CLIENT_ID = \"SHAREPOINT_EXCEL_CLIENT_ID\";\nexport const ENV_CLIENT_SECRET = \"SHAREPOINT_EXCEL_CLIENT_SECRET\";\nexport const ENV_SITE = \"SHAREPOINT_EXCEL_SITE\";\nexport const ENV_DRIVE = \"SHAREPOINT_EXCEL_DRIVE\";\nexport const ENV_PROFILE = \"SHAREPOINT_EXCEL_PROFILE\";\nexport const ENV_AUTH_BASE = \"SHAREPOINT_EXCEL_AUTH_BASE\";\nexport const ENV_GRAPH_BASE = \"SHAREPOINT_EXCEL_GRAPH_BASE\";\nexport const ENV_HOME = \"SAPTOOLS_SHAREPOINT_EXCEL_HOME\";\nexport const ENV_ALLOW_PLAINTEXT = \"SAPTOOLS_SHAREPOINT_EXCEL_ALLOW_PLAINTEXT\";\n\nexport const FALLBACK_ENV_TENANT = \"SHAREPOINT_TENANT_ID\";\nexport const FALLBACK_ENV_CLIENT_ID = \"SHAREPOINT_CLIENT_ID\";\nexport const FALLBACK_ENV_CLIENT_SECRET = \"SHAREPOINT_CLIENT_SECRET\";\nexport const FALLBACK_ENV_SITE = \"SHAREPOINT_SITE\";\nexport const FALLBACK_ENV_DRIVE = \"SHAREPOINT_DRIVE\";\n","import process from \"node:process\";\n\nimport type { FetchLike } from \"../graph/client.js\";\nimport type { AccessTokenInfo, SharePointCredentials } from \"../types.js\";\nimport { DEFAULT_AUTH_BASE, ENV_AUTH_BASE } from \"../types.js\";\n\nexport interface AcquireTokenOptions {\n readonly authBase?: string;\n readonly scope?: string;\n readonly fetchFn?: FetchLike;\n readonly env?: NodeJS.ProcessEnv;\n}\n\ninterface TokenResponse {\n readonly access_token?: unknown;\n readonly token_type?: unknown;\n readonly expires_in?: unknown;\n readonly scope?: unknown;\n readonly error?: unknown;\n readonly error_description?: unknown;\n}\n\nconst DEFAULT_SCOPE = \"https://graph.microsoft.com/.default\";\n\nfunction resolveAuthBase(options: AcquireTokenOptions): string {\n if (options.authBase !== undefined && options.authBase.length > 0) {\n return options.authBase.replace(/\\/+$/, \"\");\n }\n const fromEnv = (options.env ?? process.env)[ENV_AUTH_BASE];\n return fromEnv === undefined || fromEnv.length === 0\n ? DEFAULT_AUTH_BASE\n : fromEnv.replace(/\\/+$/, \"\");\n}\n\nfunction assertString(value: unknown, field: string): string {\n if (typeof value !== \"string\" || value.length === 0) {\n throw new Error(`Token response missing field: ${field}`);\n }\n return value;\n}\n\nfunction assertNumber(value: unknown, field: string): number {\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n throw new Error(`Token response missing numeric field: ${field}`);\n }\n return value;\n}\n\nfunction parseTokenResponse(text: string, status: number): TokenResponse {\n try {\n return JSON.parse(text) as TokenResponse;\n } catch (err) {\n throw new Error(`Failed to parse token response (HTTP ${status.toString()})`, { cause: err });\n }\n}\n\nfunction throwIfTokenError(response: Response, parsed: TokenResponse): void {\n if (response.ok && typeof parsed.error !== \"string\") {\n return;\n }\n const code = typeof parsed.error === \"string\" ? parsed.error : \"unknown_error\";\n const description =\n typeof parsed.error_description === \"string\" && parsed.error_description.length > 0\n ? parsed.error_description\n : response.statusText;\n throw new Error(\n `Azure AD token request failed (HTTP ${response.status.toString()} ${code}): ${description}`,\n );\n}\n\nexport async function acquireAppToken(\n credentials: SharePointCredentials,\n options: AcquireTokenOptions = {},\n): Promise<AccessTokenInfo> {\n if (credentials.tenantId.length === 0) {\n throw new Error(\"tenantId is required\");\n }\n if (credentials.clientId.length === 0) {\n throw new Error(\"clientId is required\");\n }\n if (credentials.clientSecret.length === 0) {\n throw new Error(\"clientSecret is required\");\n }\n\n const authBase = resolveAuthBase(options);\n const fetchFn = options.fetchFn ?? fetch;\n const url = `${authBase}/${encodeURIComponent(credentials.tenantId)}/oauth2/v2.0/token`;\n const form = new URLSearchParams({\n grant_type: \"client_credentials\",\n client_id: credentials.clientId,\n client_secret: credentials.clientSecret,\n scope: options.scope ?? DEFAULT_SCOPE,\n });\n\n const response = await fetchFn(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\", Accept: \"application/json\" },\n body: form.toString(),\n });\n const parsed = parseTokenResponse(await response.text(), response.status);\n throwIfTokenError(response, parsed);\n\n const scopeValue = typeof parsed.scope === \"string\" ? parsed.scope : undefined;\n const base = {\n accessToken: assertString(parsed.access_token, \"access_token\"),\n tokenType: assertString(parsed.token_type, \"token_type\"),\n expiresOn: Math.floor(Date.now() / 1000) + assertNumber(parsed.expires_in, \"expires_in\"),\n };\n return scopeValue === undefined ? base : { ...base, scope: scopeValue };\n}\n","import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport process from \"node:process\";\n\nimport { ENV_HOME } from \"../types.js\";\n\nexport const SAPTOOLS_DIR_NAME = \".saptools\";\nexport const PACKAGE_DIR_NAME = \"sharepoint-excel\";\nexport const PROFILES_FILENAME = \"profiles.json\";\nexport const FILE_SECRETS_FILENAME = \"secrets.json\";\n\nexport function packageDataDir(env: NodeJS.ProcessEnv = process.env): string {\n const override = env[ENV_HOME];\n if (override !== undefined && override.length > 0) {\n return override;\n }\n return join(homedir(), SAPTOOLS_DIR_NAME, PACKAGE_DIR_NAME);\n}\n\nexport function profilesPath(env: NodeJS.ProcessEnv = process.env): string {\n return join(packageDataDir(env), PROFILES_FILENAME);\n}\n\nexport function fileSecretsPath(env: NodeJS.ProcessEnv = process.env): string {\n return join(packageDataDir(env), FILE_SECRETS_FILENAME);\n}\n","import process from \"node:process\";\n\nimport type { ProfileStore } from \"../credentials/profile-store.js\";\nimport { createProfileStore, findProfile } from \"../credentials/profile-store.js\";\nimport type { SecretVault } from \"../credentials/secret-vault.js\";\nimport { createFileSecretVault, createKeyringSecretVault } from \"../credentials/secret-vault.js\";\nimport { parseSiteRef } from \"../graph/site.js\";\nimport type { SecretStoreKind, SharePointTarget, StoredProfile } from \"../types.js\";\nimport {\n DEFAULT_PROFILE_NAME,\n ENV_CLIENT_ID,\n ENV_CLIENT_SECRET,\n ENV_DRIVE,\n ENV_PROFILE,\n ENV_SITE,\n ENV_TENANT,\n FALLBACK_ENV_CLIENT_ID,\n FALLBACK_ENV_CLIENT_SECRET,\n FALLBACK_ENV_DRIVE,\n FALLBACK_ENV_SITE,\n FALLBACK_ENV_TENANT,\n} from \"../types.js\";\n\nexport interface RuntimeOverrides {\n readonly profile?: string | undefined;\n readonly tenant?: string | undefined;\n readonly clientId?: string | undefined;\n readonly clientSecret?: string | undefined;\n readonly site?: string | undefined;\n readonly drive?: string | undefined;\n}\n\nexport interface ResolveRuntimeOptions {\n readonly env?: NodeJS.ProcessEnv;\n readonly overrides?: RuntimeOverrides;\n readonly profileStore?: ProfileStore;\n readonly keyringVault?: SecretVault;\n readonly fileVault?: SecretVault;\n}\n\nexport interface ResolvedRuntime {\n readonly target: SharePointTarget;\n readonly drive?: string;\n readonly profileName: string;\n readonly source: \"profile\" | \"env\";\n}\n\nfunction pickEnv(env: NodeJS.ProcessEnv, primary: string, fallback: string): string | undefined {\n const value = env[primary] ?? env[fallback];\n return value === undefined || value.length === 0 ? undefined : value;\n}\n\nfunction pickValue(\n override: string | undefined,\n envValue: string | undefined,\n profileValue: string | undefined,\n): string | undefined {\n if (override !== undefined && override.length > 0) {\n return override;\n }\n return envValue ?? profileValue;\n}\n\nfunction vaultForProfile(\n profile: StoredProfile | undefined,\n options: ResolveRuntimeOptions,\n): SecretVault {\n if (profile?.secretStore === \"file\") {\n return options.fileVault ?? createFileSecretVault();\n }\n return options.keyringVault ?? createKeyringSecretVault();\n}\n\nasync function resolveClientSecret(\n override: string | undefined,\n envValue: string | undefined,\n profile: StoredProfile | undefined,\n options: ResolveRuntimeOptions,\n): Promise<string | undefined> {\n if (override !== undefined && override.length > 0) {\n return override;\n }\n if (envValue !== undefined) {\n return envValue;\n }\n return profile === undefined ? undefined : await vaultForProfile(profile, options).getSecret(profile.name);\n}\n\nfunction requireValue(value: string | undefined, humanName: string): string {\n if (value === undefined || value.length === 0) {\n throw new Error(`${humanName} is required (pass a flag, set env, or run config set)`);\n }\n return value;\n}\n\nexport async function resolveRuntime(options: ResolveRuntimeOptions = {}): Promise<ResolvedRuntime> {\n const env = options.env ?? process.env;\n const overrides = options.overrides ?? {};\n const profileName =\n overrides.profile ?? env[ENV_PROFILE] ?? DEFAULT_PROFILE_NAME;\n const store = options.profileStore ?? createProfileStore();\n const profile = findProfile(await store.readProfiles(), profileName);\n\n const tenantId = pickValue(\n overrides.tenant,\n pickEnv(env, ENV_TENANT, FALLBACK_ENV_TENANT),\n profile?.tenantId,\n );\n const clientId = pickValue(\n overrides.clientId,\n pickEnv(env, ENV_CLIENT_ID, FALLBACK_ENV_CLIENT_ID),\n profile?.clientId,\n );\n const site = pickValue(overrides.site, pickEnv(env, ENV_SITE, FALLBACK_ENV_SITE), profile?.site);\n const drive = pickValue(overrides.drive, pickEnv(env, ENV_DRIVE, FALLBACK_ENV_DRIVE), profile?.drive);\n const clientSecret = await resolveClientSecret(\n overrides.clientSecret,\n pickEnv(env, ENV_CLIENT_SECRET, FALLBACK_ENV_CLIENT_SECRET),\n profile,\n options,\n );\n\n return {\n target: {\n credentials: {\n tenantId: requireValue(tenantId, \"Tenant ID\"),\n clientId: requireValue(clientId, \"Client ID\"),\n clientSecret: requireValue(clientSecret, \"Client secret\"),\n },\n site: parseSiteRef(requireValue(site, \"SharePoint site\")),\n },\n ...(drive === undefined ? {} : { drive }),\n profileName,\n source: profile === undefined ? \"env\" : \"profile\",\n };\n}\n\nexport function parseSecretStoreKind(value: string | undefined): SecretStoreKind {\n if (value === undefined || value === \"keyring\") {\n return \"keyring\";\n }\n if (value === \"file\") {\n return \"file\";\n }\n throw new Error(`Invalid secret store \"${value}\". Expected keyring or file`);\n}\n","import { chmod, mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\nimport { profilesPath } from \"../config/paths.js\";\nimport type { RedactedProfile, SecretStoreKind, StoredProfile } from \"../types.js\";\nimport { DEFAULT_PROFILE_NAME } from \"../types.js\";\n\nimport type { SecretVault } from \"./secret-vault.js\";\n\ninterface ProfileFile {\n readonly version: 1;\n readonly profiles: readonly StoredProfile[];\n}\n\nexport interface ProfileStore {\n readProfiles: () => Promise<readonly StoredProfile[]>;\n writeProfiles: (profiles: readonly StoredProfile[]) => Promise<void>;\n}\n\nexport interface UpsertProfileInput {\n readonly name?: string;\n readonly tenantId: string;\n readonly clientId: string;\n readonly clientSecret: string;\n readonly site: string;\n readonly drive?: string;\n readonly secretStore: SecretStoreKind;\n readonly updatedAt?: Date;\n}\n\nconst PROFILE_FILE_MODE = 0o600;\nconst EMPTY_PROFILE_FILE: ProfileFile = { version: 1, profiles: [] };\n\nfunction isMissingFileError(err: unknown): boolean {\n return err instanceof Error && \"code\" in err && err.code === \"ENOENT\";\n}\n\nfunction isSecretStoreKind(value: unknown): value is SecretStoreKind {\n return value === \"keyring\" || value === \"file\";\n}\n\nfunction toStoredProfile(value: unknown): StoredProfile | undefined {\n if (typeof value !== \"object\" || value === null) {\n return undefined;\n }\n const raw = value as Record<string, unknown>;\n const name = raw[\"name\"];\n const tenantId = raw[\"tenantId\"];\n const clientId = raw[\"clientId\"];\n const site = raw[\"site\"];\n const drive = raw[\"drive\"];\n const secretStore = raw[\"secretStore\"];\n const updatedAt = raw[\"updatedAt\"];\n if (\n typeof name !== \"string\" ||\n typeof tenantId !== \"string\" ||\n typeof clientId !== \"string\" ||\n typeof site !== \"string\" ||\n typeof updatedAt !== \"string\" ||\n !isSecretStoreKind(secretStore)\n ) {\n return undefined;\n }\n return {\n name,\n tenantId,\n clientId,\n site,\n ...(typeof drive === \"string\" ? { drive } : {}),\n secretStore,\n updatedAt,\n };\n}\n\nfunction isStoredProfile(value: StoredProfile | undefined): value is StoredProfile {\n return value !== undefined;\n}\n\nasync function readProfileFile(path: string): Promise<ProfileFile> {\n try {\n const raw = await readFile(path, \"utf8\");\n const parsed = JSON.parse(raw) as { readonly version?: unknown; readonly profiles?: unknown };\n if (parsed.version !== 1 || !Array.isArray(parsed.profiles)) {\n return EMPTY_PROFILE_FILE;\n }\n return { version: 1, profiles: parsed.profiles.map(toStoredProfile).filter(isStoredProfile) };\n } catch (err) {\n if (isMissingFileError(err)) {\n return EMPTY_PROFILE_FILE;\n }\n throw err;\n }\n}\n\nasync function writeProfileFile(path: string, value: ProfileFile): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, `${JSON.stringify(value, null, 2)}\\n`, {\n encoding: \"utf8\",\n mode: PROFILE_FILE_MODE,\n });\n await chmod(path, PROFILE_FILE_MODE);\n}\n\nexport function createProfileStore(path = profilesPath()): ProfileStore {\n return {\n async readProfiles(): Promise<readonly StoredProfile[]> {\n return (await readProfileFile(path)).profiles;\n },\n async writeProfiles(profiles: readonly StoredProfile[]): Promise<void> {\n await writeProfileFile(path, { version: 1, profiles });\n },\n };\n}\n\nexport function findProfile(\n profiles: readonly StoredProfile[],\n name = DEFAULT_PROFILE_NAME,\n): StoredProfile | undefined {\n return profiles.find((profile) => profile.name === name);\n}\n\nexport async function upsertProfile(\n store: ProfileStore,\n vault: SecretVault,\n input: UpsertProfileInput,\n): Promise<StoredProfile> {\n const name = input.name ?? DEFAULT_PROFILE_NAME;\n const stored: StoredProfile = {\n name,\n tenantId: input.tenantId,\n clientId: input.clientId,\n site: input.site,\n ...(input.drive === undefined || input.drive.length === 0 ? {} : { drive: input.drive }),\n secretStore: input.secretStore,\n updatedAt: (input.updatedAt ?? new Date()).toISOString(),\n };\n const profiles = await store.readProfiles();\n const nextProfiles = profiles.some((profile) => profile.name === name)\n ? profiles.map((profile) => (profile.name === name ? stored : profile))\n : [...profiles, stored];\n await vault.setSecret(name, input.clientSecret);\n await store.writeProfiles(nextProfiles);\n return stored;\n}\n\nexport async function removeProfile(\n store: ProfileStore,\n vault: SecretVault,\n name = DEFAULT_PROFILE_NAME,\n): Promise<boolean> {\n const profiles = await store.readProfiles();\n const nextProfiles = profiles.filter((profile) => profile.name !== name);\n await vault.deleteSecret(name);\n if (nextProfiles.length === profiles.length) {\n return false;\n }\n await store.writeProfiles(nextProfiles);\n return true;\n}\n\nexport async function redactProfile(\n profile: StoredProfile,\n vault: SecretVault,\n): Promise<RedactedProfile> {\n const secret = await vault.getSecret(profile.name);\n return {\n ...profile,\n clientId: `${profile.clientId.slice(0, 4)}...${profile.clientId.slice(-4)}`,\n hasClientSecret: secret !== undefined,\n };\n}\n","import { chmod, mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\nimport { Entry } from \"@napi-rs/keyring\";\n\nimport { fileSecretsPath } from \"../config/paths.js\";\n\nexport interface SecretVault {\n getSecret: (profileName: string) => Promise<string | undefined>;\n setSecret: (profileName: string, secret: string) => Promise<void>;\n deleteSecret: (profileName: string) => Promise<void>;\n}\n\ninterface SecretFile {\n readonly version: 1;\n readonly entries: Readonly<Record<string, string>>;\n}\n\nconst SERVICE_NAME = \"saptools-sharepoint-excel\";\nconst SECRET_FILE_MODE = 0o600;\nconst EMPTY_SECRET_FILE: SecretFile = { version: 1, entries: {} };\n\nfunction isMissingFileError(err: unknown): boolean {\n return err instanceof Error && \"code\" in err && err.code === \"ENOENT\";\n}\n\nasync function readSecretFile(path: string): Promise<SecretFile> {\n try {\n const raw = await readFile(path, \"utf8\");\n const parsed = JSON.parse(raw) as { readonly version?: unknown; readonly entries?: unknown };\n if (parsed.version !== 1 || typeof parsed.entries !== \"object\" || parsed.entries === null) {\n return EMPTY_SECRET_FILE;\n }\n const entries: Record<string, string> = {};\n for (const [key, value] of Object.entries(parsed.entries)) {\n if (typeof value === \"string\") {\n entries[key] = value;\n }\n }\n return { version: 1, entries };\n } catch (err) {\n if (isMissingFileError(err)) {\n return EMPTY_SECRET_FILE;\n }\n throw err;\n }\n}\n\nasync function writeSecretFile(path: string, value: SecretFile): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, `${JSON.stringify(value, null, 2)}\\n`, {\n encoding: \"utf8\",\n mode: SECRET_FILE_MODE,\n });\n await chmod(path, SECRET_FILE_MODE);\n}\n\nexport function createKeyringSecretVault(serviceName = SERVICE_NAME): SecretVault {\n return {\n getSecret(profileName: string): Promise<string | undefined> {\n const password = new Entry(serviceName, profileName).getPassword();\n return Promise.resolve(password === null || password.length === 0 ? undefined : password);\n },\n setSecret(profileName: string, secret: string): Promise<void> {\n new Entry(serviceName, profileName).setPassword(secret);\n return Promise.resolve();\n },\n deleteSecret(profileName: string): Promise<void> {\n try {\n new Entry(serviceName, profileName).deletePassword();\n } catch (err) {\n if (err instanceof Error && /not found|no entry|missing/i.test(err.message)) {\n return Promise.resolve();\n }\n return Promise.reject(err instanceof Error ? err : new Error(String(err)));\n }\n return Promise.resolve();\n },\n };\n}\n\nexport function createFileSecretVault(path = fileSecretsPath()): SecretVault {\n return {\n async getSecret(profileName: string): Promise<string | undefined> {\n const file = await readSecretFile(path);\n return file.entries[profileName];\n },\n async setSecret(profileName: string, secret: string): Promise<void> {\n const file = await readSecretFile(path);\n await writeSecretFile(path, {\n version: 1,\n entries: { ...file.entries, [profileName]: secret },\n });\n },\n async deleteSecret(profileName: string): Promise<void> {\n const file = await readSecretFile(path);\n const remaining = Object.fromEntries(\n Object.entries(file.entries).filter(([entryName]) => entryName !== profileName),\n );\n await writeSecretFile(path, { version: 1, entries: remaining });\n },\n };\n}\n","import process from \"node:process\";\n\nimport { DEFAULT_GRAPH_BASE, ENV_GRAPH_BASE } from \"../types.js\";\n\nexport type FetchLike = typeof fetch;\n\nexport interface GraphRetryOptions {\n readonly maxRetries?: number;\n readonly baseDelayMs?: number;\n readonly sleepFn?: (ms: number) => Promise<void>;\n}\n\nexport interface GraphClientOptions {\n readonly accessToken: string;\n readonly baseUrl?: string;\n readonly fetchFn?: FetchLike;\n readonly retry?: GraphRetryOptions;\n readonly env?: NodeJS.ProcessEnv;\n}\n\nexport interface GraphRequestOptions {\n readonly method?: string;\n readonly body?: unknown;\n readonly rawBody?: Uint8Array | string;\n readonly headers?: Readonly<Record<string, string>>;\n readonly includeAuthorization?: boolean;\n}\n\nexport interface GraphClient {\n readonly baseUrl: string;\n requestJson: <T>(path: string, options?: GraphRequestOptions) => Promise<T>;\n requestBytes: (path: string, options?: GraphRequestOptions) => Promise<Uint8Array>;\n requestNoContent: (path: string, options?: GraphRequestOptions) => Promise<void>;\n}\n\ninterface GraphErrorBody {\n readonly error?: {\n readonly code?: unknown;\n readonly message?: unknown;\n };\n}\n\nconst RETRYABLE_STATUSES = new Set<number>([429, 503]);\nconst DEFAULT_MAX_RETRIES = 2;\nconst DEFAULT_BASE_DELAY_MS = 500;\n\nfunction defaultSleep(ms: number): Promise<void> {\n return new Promise((resolve) => {\n setTimeout(resolve, ms);\n });\n}\n\nfunction parseRetryAfter(header: string | null): number | undefined {\n if (header === null || header.length === 0) {\n return undefined;\n }\n const seconds = Number.parseFloat(header);\n if (Number.isFinite(seconds) && seconds >= 0) {\n return Math.ceil(seconds * 1000);\n }\n const dateMs = Date.parse(header);\n return Number.isNaN(dateMs) ? undefined : Math.max(0, dateMs - Date.now());\n}\n\nfunction resolveBaseUrl(options: GraphClientOptions): string {\n if (options.baseUrl !== undefined && options.baseUrl.length > 0) {\n return options.baseUrl.replace(/\\/+$/, \"\");\n }\n const fromEnv = (options.env ?? process.env)[ENV_GRAPH_BASE];\n return fromEnv === undefined || fromEnv.length === 0\n ? DEFAULT_GRAPH_BASE\n : fromEnv.replace(/\\/+$/, \"\");\n}\n\nfunction resolveUrl(base: string, path: string, includeAuthorization: boolean): string {\n if (/^https?:\\/\\//i.test(path)) {\n if (includeAuthorization && new URL(path).origin !== new URL(base).origin) {\n throw new Error(\"Refusing to send a Graph bearer token to a different origin\");\n }\n return path;\n }\n return `${base}${path.startsWith(\"/\") ? path : `/${path}`}`;\n}\n\nexport class GraphHttpError extends Error {\n public readonly status: number;\n public readonly code: string | undefined;\n public readonly detail: string;\n\n public constructor(status: number, code: string | undefined, detail: string) {\n super(\n `Microsoft Graph request failed (${status.toString()}${\n code === undefined ? \"\" : ` ${code}`\n }): ${detail}`,\n );\n this.name = \"GraphHttpError\";\n this.status = status;\n this.code = code;\n this.detail = detail;\n }\n}\n\nasync function extractErrorDetail(response: Response): Promise<{ code: string | undefined; detail: string }> {\n const text = await response.text().catch(() => \"\");\n if (text.length === 0) {\n return { code: undefined, detail: response.statusText };\n }\n try {\n const body = JSON.parse(text) as GraphErrorBody;\n const code = typeof body.error?.code === \"string\" ? body.error.code : undefined;\n const detail =\n typeof body.error?.message === \"string\" && body.error.message.length > 0\n ? body.error.message\n : response.statusText;\n return { code, detail };\n } catch {\n return { code: undefined, detail: text };\n }\n}\n\nfunction buildInit(accessToken: string, options: GraphRequestOptions): RequestInit {\n const headers: Record<string, string> = {\n Accept: \"application/json\",\n ...(options.includeAuthorization === false ? {} : { Authorization: `Bearer ${accessToken}` }),\n ...options.headers,\n };\n const init: RequestInit = { method: options.method ?? \"GET\", headers };\n if (options.rawBody !== undefined) {\n init.body = rawBodyToBodyInit(options.rawBody);\n return init;\n }\n if (options.body !== undefined) {\n headers[\"Content-Type\"] = headers[\"Content-Type\"] ?? \"application/json\";\n init.body = typeof options.body === \"string\" ? options.body : JSON.stringify(options.body);\n }\n return init;\n}\n\ntype RequestBody = NonNullable<RequestInit[\"body\"]>;\n\nfunction rawBodyToBodyInit(rawBody: Uint8Array | string): RequestBody {\n if (typeof rawBody === \"string\") {\n return rawBody;\n }\n const copy = new ArrayBuffer(rawBody.byteLength);\n new Uint8Array(copy).set(rawBody);\n return copy;\n}\n\nasync function discardBody(response: Response): Promise<void> {\n if (response.body === null) {\n return;\n }\n await response.body.cancel().catch(() => {\n /* ignore */\n });\n}\n\nexport function createGraphClient(options: GraphClientOptions): GraphClient {\n const baseUrl = resolveBaseUrl(options);\n const fetchFn = options.fetchFn ?? fetch;\n const maxRetries = options.retry?.maxRetries ?? DEFAULT_MAX_RETRIES;\n const baseDelayMs = options.retry?.baseDelayMs ?? DEFAULT_BASE_DELAY_MS;\n const sleepFn = options.retry?.sleepFn ?? defaultSleep;\n\n async function execute(path: string, requestOptions: GraphRequestOptions): Promise<Response> {\n const includeAuthorization = requestOptions.includeAuthorization !== false;\n const url = resolveUrl(baseUrl, path, includeAuthorization);\n const init = buildInit(options.accessToken, requestOptions);\n let attempt = 0;\n let response = await fetchFn(url, init);\n while (!response.ok && RETRYABLE_STATUSES.has(response.status) && attempt < maxRetries) {\n const retryAfterMs =\n parseRetryAfter(response.headers.get(\"retry-after\")) ?? baseDelayMs * 2 ** attempt;\n await discardBody(response);\n await sleepFn(retryAfterMs);\n attempt += 1;\n response = await fetchFn(url, init);\n }\n if (!response.ok) {\n const { code, detail } = await extractErrorDetail(response);\n throw new GraphHttpError(response.status, code, detail);\n }\n return response;\n }\n\n async function requestJson<T>(path: string, requestOptions: GraphRequestOptions = {}): Promise<T> {\n const response = await execute(path, requestOptions);\n if (response.status === 204) {\n return undefined as T;\n }\n const contentType = response.headers.get(\"content-type\")?.toLowerCase() ?? \"\";\n if (!contentType.includes(\"application/json\")) {\n return undefined as T;\n }\n return (await response.json()) as T;\n }\n\n async function requestBytes(path: string, requestOptions: GraphRequestOptions = {}): Promise<Uint8Array> {\n const response = await execute(path, requestOptions);\n return new Uint8Array(await response.arrayBuffer());\n }\n\n async function requestNoContent(path: string, requestOptions: GraphRequestOptions = {}): Promise<void> {\n await execute(path, requestOptions);\n }\n\n return { baseUrl, requestJson, requestBytes, requestNoContent };\n}\n","import type { SharePointSite, SharePointSiteRef } from \"../types.js\";\n\nimport type { GraphClient } from \"./client.js\";\nimport { GraphHttpError } from \"./client.js\";\n\ninterface RawSiteResponse {\n readonly id?: unknown;\n readonly name?: unknown;\n readonly displayName?: unknown;\n readonly webUrl?: unknown;\n}\n\nfunction asString(value: unknown, fallback = \"\"): string {\n return typeof value === \"string\" ? value : fallback;\n}\n\nfunction stripQueryAndHash(value: string): string {\n const markerIndex = value.search(/[?#]/);\n return markerIndex === -1 ? value : value.slice(0, markerIndex);\n}\n\nfunction decodeSitePath(sitePath: string, input: string): string {\n return sitePath\n .split(\"/\")\n .map((segment) => {\n try {\n return decodeURIComponent(segment);\n } catch (err) {\n throw new Error(`Invalid site reference \"${input}\". Site path has invalid encoding`, {\n cause: err,\n });\n }\n })\n .join(\"/\");\n}\n\nfunction parseSiteInput(trimmed: string): { readonly hostname: string; readonly rawPath: string } {\n if (/^https?:\\/\\//i.test(trimmed)) {\n const url = new URL(trimmed);\n return { hostname: url.hostname, rawPath: url.pathname };\n }\n const withoutQuery = stripQueryAndHash(trimmed);\n const firstSlash = withoutQuery.indexOf(\"/\");\n if (firstSlash === -1) {\n throw new Error(`Invalid site reference \"${trimmed}\". Expected host/sites/<name> or full URL`);\n }\n return { hostname: withoutQuery.slice(0, firstSlash), rawPath: withoutQuery.slice(firstSlash + 1) };\n}\n\nexport function parseSiteRef(input: string): SharePointSiteRef {\n const trimmed = input.trim();\n if (trimmed.length === 0) {\n throw new Error(\"Site reference is empty\");\n }\n const { hostname, rawPath } = parseSiteInput(trimmed);\n const sitePath = decodeSitePath(rawPath.replace(/^\\/+|\\/+$/g, \"\"), trimmed);\n if (hostname.length === 0 || sitePath.length === 0) {\n throw new Error(`Invalid site reference \"${trimmed}\". Missing hostname or site path`);\n }\n return { hostname, sitePath };\n}\n\nfunction encodeSitePath(sitePath: string): string {\n return sitePath.split(\"/\").map((segment) => encodeURIComponent(segment)).join(\"/\");\n}\n\nexport async function resolveSite(\n client: GraphClient,\n ref: SharePointSiteRef,\n): Promise<SharePointSite> {\n const path = `/sites/${encodeURIComponent(ref.hostname)}:/${encodeSitePath(ref.sitePath)}`;\n let raw: RawSiteResponse;\n try {\n raw = await client.requestJson<RawSiteResponse>(path);\n } catch (err) {\n if (err instanceof GraphHttpError && err.status === 404) {\n throw new Error(`SharePoint site not found at ${ref.hostname}/${ref.sitePath}`, {\n cause: err,\n });\n }\n throw err;\n }\n const id = asString(raw.id);\n if (id.length === 0) {\n throw new Error(`Site response missing id for ${ref.hostname}/${ref.sitePath}`);\n }\n return {\n id,\n name: asString(raw.name, ref.sitePath),\n displayName: asString(raw.displayName, asString(raw.name, ref.sitePath)),\n webUrl: asString(raw.webUrl),\n };\n}\n","import type { DriveItemSummary, SharePointDrive } from \"../types.js\";\n\nimport type { GraphClient } from \"./client.js\";\nimport { GraphHttpError } from \"./client.js\";\n\ninterface RawDriveResponse {\n readonly id?: unknown;\n readonly name?: unknown;\n readonly driveType?: unknown;\n readonly webUrl?: unknown;\n}\n\ninterface RawDriveListResponse {\n readonly value?: unknown;\n}\n\ninterface RawDriveItem {\n readonly id?: unknown;\n readonly name?: unknown;\n readonly size?: unknown;\n readonly eTag?: unknown;\n readonly cTag?: unknown;\n readonly webUrl?: unknown;\n readonly folder?: unknown;\n readonly file?: unknown;\n}\n\ninterface UploadSessionResponse {\n readonly uploadUrl?: unknown;\n}\n\nconst XLSX_CONTENT_TYPE = \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\";\n\nfunction asString(value: unknown, fallback = \"\"): string {\n return typeof value === \"string\" ? value : fallback;\n}\n\nfunction asNumber(value: unknown, fallback = 0): number {\n return typeof value === \"number\" && Number.isFinite(value) ? value : fallback;\n}\n\nexport function encodeDrivePath(relativePath: string): string {\n return relativePath\n .split(\"/\")\n .filter((segment) => segment.length > 0)\n .map((segment) => encodeURIComponent(segment))\n .join(\"/\");\n}\n\nfunction toDrive(raw: RawDriveResponse): SharePointDrive {\n return {\n id: asString(raw.id),\n name: asString(raw.name),\n driveType: asString(raw.driveType, \"documentLibrary\"),\n webUrl: asString(raw.webUrl),\n };\n}\n\nfunction toDriveItem(raw: RawDriveItem): DriveItemSummary {\n const base = {\n id: asString(raw.id),\n name: asString(raw.name),\n isFolder: raw.folder !== undefined && raw.folder !== null,\n size: asNumber(raw.size),\n };\n return {\n ...base,\n ...(typeof raw.eTag === \"string\" ? { eTag: raw.eTag } : {}),\n ...(typeof raw.cTag === \"string\" ? { cTag: raw.cTag } : {}),\n ...(typeof raw.webUrl === \"string\" ? { webUrl: raw.webUrl } : {}),\n };\n}\n\nexport async function listDrives(\n client: GraphClient,\n siteId: string,\n): Promise<readonly SharePointDrive[]> {\n const response = await client.requestJson<RawDriveListResponse>(`/sites/${encodeURIComponent(siteId)}/drives`);\n if (!Array.isArray(response.value)) {\n return [];\n }\n return response.value\n .filter((entry): entry is RawDriveResponse => typeof entry === \"object\" && entry !== null)\n .map(toDrive);\n}\n\nexport function selectDrive(\n drives: readonly SharePointDrive[],\n driveHint: string | undefined,\n): SharePointDrive {\n if (drives.length === 0) {\n throw new Error(\"SharePoint site has no drives (document libraries)\");\n }\n if (driveHint === undefined || driveHint.length === 0) {\n const first = drives[0];\n if (first === undefined) {\n throw new Error(\"No drives available\");\n }\n return first;\n }\n const match = drives.find((drive) => drive.id === driveHint || drive.name === driveHint);\n if (match === undefined) {\n throw new Error(`Drive \"${driveHint}\" not found. Available: ${drives.map((d) => d.name).join(\", \")}`);\n }\n return match;\n}\n\nexport async function getDriveItemByPath(\n client: GraphClient,\n driveId: string,\n relativePath: string,\n): Promise<DriveItemSummary | null> {\n const normalized = relativePath.replace(/^\\/+|\\/+$/g, \"\");\n const path =\n normalized.length === 0\n ? `/drives/${encodeURIComponent(driveId)}/root`\n : `/drives/${encodeURIComponent(driveId)}/root:/${encodeDrivePath(normalized)}`;\n try {\n return toDriveItem(await client.requestJson<RawDriveItem>(path));\n } catch (err) {\n if (err instanceof GraphHttpError && err.status === 404) {\n return null;\n }\n throw err;\n }\n}\n\nexport async function downloadDriveFile(\n client: GraphClient,\n driveId: string,\n relativePath: string,\n): Promise<Uint8Array> {\n const encodedPath = encodeDrivePath(relativePath.replace(/^\\/+|\\/+$/g, \"\"));\n return await client.requestBytes(`/drives/${encodeURIComponent(driveId)}/root:/${encodedPath}:/content`, {\n headers: { Accept: XLSX_CONTENT_TYPE },\n });\n}\n\nasync function createUploadSession(\n client: GraphClient,\n driveId: string,\n relativePath: string,\n): Promise<string> {\n const encodedPath = encodeDrivePath(relativePath.replace(/^\\/+|\\/+$/g, \"\"));\n const response = await client.requestJson<UploadSessionResponse>(\n `/drives/${encodeURIComponent(driveId)}/root:/${encodedPath}:/createUploadSession`,\n {\n method: \"POST\",\n body: { item: { \"@microsoft.graph.conflictBehavior\": \"fail\" } },\n },\n );\n if (typeof response.uploadUrl !== \"string\" || response.uploadUrl.length === 0) {\n throw new Error(\"Graph upload session response missing uploadUrl\");\n }\n return response.uploadUrl;\n}\n\nexport async function uploadNewDriveFile(\n client: GraphClient,\n driveId: string,\n relativePath: string,\n bytes: Uint8Array,\n): Promise<DriveItemSummary> {\n const existing = await getDriveItemByPath(client, driveId, relativePath);\n if (existing !== null) {\n throw new Error(`Refusing to overwrite existing SharePoint file: ${relativePath}`);\n }\n const uploadUrl = await createUploadSession(client, driveId, relativePath);\n const lastByte = bytes.byteLength - 1;\n const raw = await client.requestJson<RawDriveItem>(uploadUrl, {\n method: \"PUT\",\n rawBody: bytes,\n includeAuthorization: false,\n headers: {\n \"Content-Length\": bytes.byteLength.toString(),\n \"Content-Range\": `bytes 0-${lastByte.toString()}/${bytes.byteLength.toString()}`,\n \"Content-Type\": XLSX_CONTENT_TYPE,\n },\n });\n return toDriveItem(raw);\n}\n\nexport async function replaceDriveFile(\n client: GraphClient,\n driveId: string,\n relativePath: string,\n eTag: string,\n bytes: Uint8Array,\n): Promise<DriveItemSummary> {\n const encodedPath = encodeDrivePath(relativePath.replace(/^\\/+|\\/+$/g, \"\"));\n const raw = await client.requestJson<RawDriveItem>(\n `/drives/${encodeURIComponent(driveId)}/root:/${encodedPath}:/content`,\n {\n method: \"PUT\",\n rawBody: bytes,\n headers: {\n \"Content-Type\": XLSX_CONTENT_TYPE,\n \"If-Match\": eTag,\n },\n },\n );\n return toDriveItem(raw);\n}\n","import { acquireAppToken } from \"./auth/token.js\";\nimport type { AcquireTokenOptions } from \"./auth/token.js\";\nimport { createGraphClient } from \"./graph/client.js\";\nimport type { FetchLike, GraphClient, GraphRetryOptions } from \"./graph/client.js\";\nimport { listDrives } from \"./graph/drive.js\";\nimport { resolveSite } from \"./graph/site.js\";\nimport type { AccessTokenInfo, SharePointDrive, SharePointSite, SharePointTarget } from \"./types.js\";\n\nexport interface SessionOptions {\n readonly fetchFn?: FetchLike;\n readonly authBase?: string;\n readonly graphBase?: string;\n readonly retry?: GraphRetryOptions;\n}\n\nexport interface SharePointExcelSession {\n readonly token: AccessTokenInfo;\n readonly client: GraphClient;\n readonly site: SharePointSite;\n readonly drives: readonly SharePointDrive[];\n}\n\nexport async function openSession(\n target: SharePointTarget,\n options: SessionOptions = {},\n): Promise<SharePointExcelSession> {\n const tokenOptions: AcquireTokenOptions = {\n ...(options.authBase === undefined ? {} : { authBase: options.authBase }),\n ...(options.fetchFn === undefined ? {} : { fetchFn: options.fetchFn }),\n };\n const token = await acquireAppToken(target.credentials, tokenOptions);\n const client = createGraphClient({\n accessToken: token.accessToken,\n ...(options.graphBase === undefined ? {} : { baseUrl: options.graphBase }),\n ...(options.fetchFn === undefined ? {} : { fetchFn: options.fetchFn }),\n ...(options.retry === undefined ? {} : { retry: options.retry }),\n });\n const site = await resolveSite(client, target.site);\n const drives = await listDrives(client, site.id);\n return { token, client, site, drives };\n}\n","export interface A1CellRef {\n readonly row: number;\n readonly column: number;\n}\n\nexport interface A1RangeRef {\n readonly start: A1CellRef;\n readonly end: A1CellRef;\n}\n\nconst CELL_REF_PATTERN = /^([A-Za-z]+)([1-9]\\d*)$/;\n\nexport function columnNameToNumber(columnName: string): number {\n const normalized = columnName.trim().toUpperCase();\n if (!/^[A-Z]+$/.test(normalized)) {\n throw new Error(`Invalid column name \"${columnName}\"`);\n }\n let total = 0;\n for (const char of normalized) {\n total = total * 26 + char.charCodeAt(0) - 64;\n }\n return total;\n}\n\nexport function parseA1Cell(input: string): A1CellRef {\n const trimmed = input.trim();\n const match = CELL_REF_PATTERN.exec(trimmed);\n if (match === null) {\n throw new Error(`Invalid A1 cell reference \"${input}\"`);\n }\n const columnName = match[1];\n const rowValue = match[2];\n if (columnName === undefined || rowValue === undefined) {\n throw new Error(`Invalid A1 cell reference \"${input}\"`);\n }\n return {\n row: Number.parseInt(rowValue, 10),\n column: columnNameToNumber(columnName),\n };\n}\n\nfunction orderRange(start: A1CellRef, end: A1CellRef): A1RangeRef {\n return {\n start: {\n row: Math.min(start.row, end.row),\n column: Math.min(start.column, end.column),\n },\n end: {\n row: Math.max(start.row, end.row),\n column: Math.max(start.column, end.column),\n },\n };\n}\n\nexport function parseA1Range(input: string): A1RangeRef {\n const parts = input.split(\":\").map((part) => part.trim());\n if (parts.length === 1) {\n const cell = parseA1Cell(parts[0] ?? \"\");\n return { start: cell, end: cell };\n }\n if (parts.length !== 2) {\n throw new Error(`Invalid A1 range \"${input}\"`);\n }\n return orderRange(parseA1Cell(parts[0] ?? \"\"), parseA1Cell(parts[1] ?? \"\"));\n}\n","import ExcelJS from \"exceljs\";\nimport type { CellValue, Worksheet } from \"exceljs\";\n\nimport type {\n JsonCellValue,\n JsonRecord,\n JsonRow,\n WorkbookCreateInput,\n WorkbookInputRow,\n WorkbookMutationResult,\n WorkbookReadOptions,\n WorkbookReadResult,\n WorkbookSheetReadResult,\n} from \"../types.js\";\n\nimport { parseA1Cell, parseA1Range } from \"./a1.js\";\n\nconst INVALID_SHEET_CHARS = /[\\][:*?/\\\\]/;\n\nfunction validateSheetName(sheetName: string): string {\n const trimmed = sheetName.trim();\n if (trimmed.length === 0 || trimmed.length > 31 || INVALID_SHEET_CHARS.test(trimmed)) {\n throw new Error(`Invalid Excel sheet name \"${sheetName}\"`);\n }\n return trimmed;\n}\n\nfunction isRecord(row: WorkbookInputRow): row is JsonRecord {\n return !Array.isArray(row);\n}\n\nfunction deriveHeaders(headers: readonly string[], rows: readonly WorkbookInputRow[]): readonly string[] {\n if (headers.length > 0) {\n return headers;\n }\n const firstRecord = rows.find(isRecord);\n return firstRecord === undefined ? [] : Object.keys(firstRecord);\n}\n\nfunction rowToValues(row: WorkbookInputRow, headers: readonly string[]): JsonRow {\n if (!isRecord(row)) {\n return [...row];\n }\n const record = row;\n if (headers.length === 0) {\n return Object.keys(record).map((key) => record[key] ?? null);\n }\n return headers.map((header) => record[header] ?? null);\n}\n\nfunction addRows(sheet: Worksheet, headers: readonly string[], rows: readonly WorkbookInputRow[]): void {\n if (headers.length > 0) {\n sheet.addRow([...headers]);\n }\n for (const row of rows) {\n sheet.addRow([...rowToValues(row, headers)]);\n }\n}\n\nfunction addTable(sheet: Worksheet, tableName: string, headers: readonly string[], rows: readonly WorkbookInputRow[]): void {\n sheet.addTable({\n name: tableName,\n ref: \"A1\",\n headerRow: true,\n totalsRow: false,\n style: { theme: \"TableStyleMedium2\", showRowStripes: true },\n columns: headers.map((name) => ({ name })),\n rows: rows.map((row) => [...rowToValues(row, headers)]),\n });\n}\n\nasync function workbookToBytes(workbook: ExcelJS.Workbook): Promise<Uint8Array> {\n const buffer = await workbook.xlsx.writeBuffer();\n return new Uint8Array(buffer);\n}\n\nasync function loadWorkbook(bytes: Uint8Array): Promise<ExcelJS.Workbook> {\n const workbook = new ExcelJS.Workbook();\n await workbook.xlsx.load(uint8ArrayToArrayBuffer(bytes));\n return workbook;\n}\n\nfunction uint8ArrayToArrayBuffer(bytes: Uint8Array): ArrayBuffer {\n const copy = new ArrayBuffer(bytes.byteLength);\n new Uint8Array(copy).set(bytes);\n return copy;\n}\n\nfunction getWorksheet(workbook: ExcelJS.Workbook, sheetName: string): Worksheet {\n const sheet = workbook.getWorksheet(sheetName);\n if (sheet === undefined) {\n throw new Error(`Sheet \"${sheetName}\" not found`);\n }\n return sheet;\n}\n\nfunction serializeCellValue(value: unknown): JsonCellValue {\n if (value === null || value === undefined) {\n return null;\n }\n if (typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\") {\n return value;\n }\n if (value instanceof Date) {\n return value.toISOString();\n }\n if (typeof value === \"object\" && \"result\" in value) {\n return serializeCellValue((value as { readonly result?: unknown }).result);\n }\n return JSON.stringify(value);\n}\n\nfunction readRow(sheet: Worksheet, rowNumber: number, startColumn: number, endColumn: number): JsonRow {\n const row = sheet.getRow(rowNumber);\n const columnCount = endColumn - startColumn + 1;\n return Array.from({ length: columnCount }, (_value, index) =>\n serializeCellValue(row.getCell(startColumn + index).value),\n );\n}\n\nfunction readHeaderRow(sheet: Worksheet): readonly string[] {\n if (sheet.actualRowCount === 0) {\n return [];\n }\n return readRow(sheet, 1, 1, Math.max(1, sheet.actualColumnCount)).map((value) => String(value ?? \"\"));\n}\n\nfunction readSheet(sheet: Worksheet, options: WorkbookReadOptions): WorkbookSheetReadResult {\n const range = options.range === undefined ? undefined : parseA1Range(options.range);\n const startRow = range?.start.row ?? 1;\n const endRow = range?.end.row ?? Math.max(1, sheet.actualRowCount);\n const startColumn = range?.start.column ?? 1;\n const endColumn = range?.end.column ?? Math.max(1, sheet.actualColumnCount);\n const rows: JsonRow[] = [];\n for (let row = startRow; row <= endRow; row += 1) {\n rows.push(readRow(sheet, row, startColumn, endColumn));\n }\n return { name: sheet.name, rowCount: rows.length, columnCount: endColumn - startColumn + 1, rows };\n}\n\nexport async function createWorkbookBytes(input: WorkbookCreateInput): Promise<Uint8Array> {\n const workbook = new ExcelJS.Workbook();\n const sheet = workbook.addWorksheet(validateSheetName(input.sheetName));\n const headers = deriveHeaders(input.headers, input.rows);\n if (input.tableName !== undefined && input.tableName.length > 0 && headers.length > 0) {\n addTable(sheet, input.tableName, headers, input.rows);\n } else {\n addRows(sheet, headers, input.rows);\n }\n return await workbookToBytes(workbook);\n}\n\nexport async function readWorkbookBytes(\n bytes: Uint8Array,\n options: WorkbookReadOptions = {},\n): Promise<WorkbookReadResult> {\n const workbook = await loadWorkbook(bytes);\n const sheets =\n options.sheetName === undefined\n ? workbook.worksheets\n : [getWorksheet(workbook, validateSheetName(options.sheetName))];\n return { sheets: sheets.map((sheet) => readSheet(sheet, options)) };\n}\n\nexport async function appendWorkbookRows(\n bytes: Uint8Array,\n sheetName: string,\n rows: readonly WorkbookInputRow[],\n matchHeader: boolean,\n): Promise<WorkbookMutationResult> {\n const workbook = await loadWorkbook(bytes);\n const sheet = getWorksheet(workbook, validateSheetName(sheetName));\n const headers = matchHeader ? readHeaderRow(sheet) : deriveHeaders([], rows);\n for (const row of rows) {\n sheet.addRow([...rowToValues(row, headers)]);\n }\n return {\n bytes: await workbookToBytes(workbook),\n sheetName: sheet.name,\n rowCount: sheet.actualRowCount,\n columnCount: sheet.actualColumnCount,\n };\n}\n\nexport async function updateWorkbookCell(\n bytes: Uint8Array,\n sheetName: string,\n cellRef: string,\n value: CellValue,\n): Promise<WorkbookMutationResult> {\n const workbook = await loadWorkbook(bytes);\n const sheet = getWorksheet(workbook, validateSheetName(sheetName));\n const cell = parseA1Cell(cellRef);\n sheet.getCell(cell.row, cell.column).value = value;\n return {\n bytes: await workbookToBytes(workbook),\n sheetName: sheet.name,\n rowCount: sheet.actualRowCount,\n columnCount: sheet.actualColumnCount,\n };\n}\n\nexport async function addWorkbookSheet(\n bytes: Uint8Array,\n sheetName: string,\n headers: readonly string[],\n): Promise<WorkbookMutationResult> {\n const workbook = await loadWorkbook(bytes);\n const normalized = validateSheetName(sheetName);\n if (workbook.getWorksheet(normalized) !== undefined) {\n throw new Error(`Sheet \"${normalized}\" already exists`);\n }\n const sheet = workbook.addWorksheet(normalized);\n if (headers.length > 0) {\n sheet.addRow([...headers]);\n }\n return {\n bytes: await workbookToBytes(workbook),\n sheetName: sheet.name,\n rowCount: sheet.actualRowCount,\n columnCount: sheet.actualColumnCount,\n };\n}\n","import { z } from \"zod\";\n\nimport type { JsonCellValue, WorkbookInputRow } from \"../types.js\";\n\nconst JsonCellValueSchema = z.union([z.string(), z.number(), z.boolean(), z.null()]);\nconst JsonRowSchema = z.array(JsonCellValueSchema);\nconst JsonRecordSchema = z.record(z.string(), JsonCellValueSchema);\n\nexport function parseHeaders(input: string | undefined): readonly string[] {\n if (input === undefined || input.trim().length === 0) {\n return [];\n }\n return input\n .split(\",\")\n .map((entry) => entry.trim())\n .filter((entry) => entry.length > 0);\n}\n\nfunction parseJson(input: string, label: string): unknown {\n try {\n return JSON.parse(input) as unknown;\n } catch (err) {\n throw new Error(`Invalid JSON for ${label}`, { cause: err });\n }\n}\n\nexport function parseCellValue(input: string): JsonCellValue {\n const trimmed = input.trim();\n if (trimmed.length === 0) {\n return \"\";\n }\n let parsed: unknown;\n try {\n parsed = parseJson(trimmed, \"cell value\");\n } catch {\n return input;\n }\n const result = JsonCellValueSchema.safeParse(parsed);\n if (!result.success) {\n return input;\n }\n return result.data;\n}\n\nexport function parseWorkbookRows(input: string | undefined): readonly WorkbookInputRow[] {\n if (input === undefined || input.trim().length === 0) {\n return [];\n }\n const parsed = parseJson(input, \"rows\");\n const rowResult = JsonRowSchema.safeParse(parsed);\n if (rowResult.success) {\n return [rowResult.data];\n }\n const recordResult = JsonRecordSchema.safeParse(parsed);\n if (recordResult.success) {\n return [recordResult.data];\n }\n if (Array.isArray(parsed)) {\n return parsed.map(parseWorkbookRow);\n }\n throw new Error(`Rows JSON must be an object, row array, or array of rows/objects`);\n}\n\nfunction parseWorkbookRow(value: unknown): WorkbookInputRow {\n const rowResult = JsonRowSchema.safeParse(value);\n if (rowResult.success) {\n return rowResult.data;\n }\n const recordResult = JsonRecordSchema.safeParse(value);\n if (recordResult.success) {\n return recordResult.data;\n }\n throw new Error(`Rows JSON must be an object, row array, or array of rows/objects`);\n}\n","import {\n downloadDriveFile,\n getDriveItemByPath,\n replaceDriveFile,\n selectDrive,\n uploadNewDriveFile,\n} from \"../graph/drive.js\";\nimport type { SharePointExcelSession } from \"../session.js\";\nimport type {\n DriveItemSummary,\n WorkbookCreateInput,\n WorkbookInputRow,\n WorkbookMutationResult,\n WorkbookReadOptions,\n WorkbookReadResult,\n} from \"../types.js\";\n\nimport {\n addWorkbookSheet,\n appendWorkbookRows,\n createWorkbookBytes,\n readWorkbookBytes,\n updateWorkbookCell,\n} from \"./excel.js\";\n\nexport interface WorkbookServiceTarget {\n readonly session: SharePointExcelSession;\n readonly driveHint?: string;\n}\n\nexport interface RemoteWorkbookResult {\n readonly driveId: string;\n readonly driveName: string;\n readonly path: string;\n readonly item: DriveItemSummary;\n}\n\nexport interface RemoteReadResult extends RemoteWorkbookResult {\n readonly workbook: WorkbookReadResult;\n}\n\nexport interface RemoteMutationResult extends RemoteWorkbookResult {\n readonly mutation: WorkbookMutationResult;\n}\n\nfunction normalizeWorkbookPath(path: string): string {\n const normalized = path.trim().replace(/^\\/+|\\/+$/g, \"\");\n if (normalized.length === 0) {\n throw new Error(\"Workbook path is required\");\n }\n if (!normalized.toLowerCase().endsWith(\".xlsx\")) {\n throw new Error(`Workbook path must end with .xlsx: ${path}`);\n }\n return normalized;\n}\n\nfunction requireEtag(item: DriveItemSummary, path: string): string {\n if (item.eTag === undefined || item.eTag.length === 0) {\n throw new Error(`Cannot update ${path}: SharePoint item is missing an ETag`);\n }\n return item.eTag;\n}\n\nasync function downloadExistingWorkbook(\n target: WorkbookServiceTarget,\n path: string,\n): Promise<{ readonly bytes: Uint8Array; readonly item: DriveItemSummary; readonly driveId: string; readonly driveName: string }> {\n const drive = selectDrive(target.session.drives, target.driveHint);\n const item = await getDriveItemByPath(target.session.client, drive.id, path);\n if (item === null || item.isFolder) {\n throw new Error(`Workbook not found: ${path}`);\n }\n const bytes = await downloadDriveFile(target.session.client, drive.id, path);\n return { bytes, item, driveId: drive.id, driveName: drive.name };\n}\n\nexport async function createRemoteWorkbook(\n target: WorkbookServiceTarget,\n path: string,\n input: WorkbookCreateInput,\n): Promise<RemoteWorkbookResult> {\n const normalizedPath = normalizeWorkbookPath(path);\n const drive = selectDrive(target.session.drives, target.driveHint);\n const bytes = await createWorkbookBytes(input);\n const item = await uploadNewDriveFile(target.session.client, drive.id, normalizedPath, bytes);\n return { driveId: drive.id, driveName: drive.name, path: normalizedPath, item };\n}\n\nexport async function readRemoteWorkbook(\n target: WorkbookServiceTarget,\n path: string,\n options: WorkbookReadOptions = {},\n): Promise<RemoteReadResult> {\n const normalizedPath = normalizeWorkbookPath(path);\n const downloaded = await downloadExistingWorkbook(target, normalizedPath);\n const workbook = await readWorkbookBytes(downloaded.bytes, options);\n return { ...downloaded, path: normalizedPath, workbook };\n}\n\nexport async function appendRemoteWorkbookRows(\n target: WorkbookServiceTarget,\n path: string,\n sheetName: string,\n rows: readonly WorkbookInputRow[],\n matchHeader: boolean,\n): Promise<RemoteMutationResult> {\n const normalizedPath = normalizeWorkbookPath(path);\n const downloaded = await downloadExistingWorkbook(target, normalizedPath);\n const mutation = await appendWorkbookRows(downloaded.bytes, sheetName, rows, matchHeader);\n const item = await replaceDriveFile(\n target.session.client,\n downloaded.driveId,\n normalizedPath,\n requireEtag(downloaded.item, normalizedPath),\n mutation.bytes,\n );\n return { ...downloaded, item, path: normalizedPath, mutation };\n}\n\nexport async function updateRemoteWorkbookCell(\n target: WorkbookServiceTarget,\n path: string,\n sheetName: string,\n cellRef: string,\n value: string | number | boolean | null,\n): Promise<RemoteMutationResult> {\n const normalizedPath = normalizeWorkbookPath(path);\n const downloaded = await downloadExistingWorkbook(target, normalizedPath);\n const mutation = await updateWorkbookCell(downloaded.bytes, sheetName, cellRef, value);\n const item = await replaceDriveFile(\n target.session.client,\n downloaded.driveId,\n normalizedPath,\n requireEtag(downloaded.item, normalizedPath),\n mutation.bytes,\n );\n return { ...downloaded, item, path: normalizedPath, mutation };\n}\n\nexport async function addRemoteWorkbookSheet(\n target: WorkbookServiceTarget,\n path: string,\n sheetName: string,\n headers: readonly string[],\n): Promise<RemoteMutationResult> {\n const normalizedPath = normalizeWorkbookPath(path);\n const downloaded = await downloadExistingWorkbook(target, normalizedPath);\n const mutation = await addWorkbookSheet(downloaded.bytes, sheetName, headers);\n const item = await replaceDriveFile(\n target.session.client,\n downloaded.driveId,\n normalizedPath,\n requireEtag(downloaded.item, normalizedPath),\n mutation.bytes,\n );\n return { ...downloaded, item, path: normalizedPath, mutation };\n}\n"],"mappings":";;;AAmGO,IAAM,uBAAuB;AAC7B,IAAM,oBAAoB;AAC1B,IAAM,qBAAqB;AAE3B,IAAM,aAAa;AACnB,IAAM,gBAAgB;AACtB,IAAM,oBAAoB;AAC1B,IAAM,WAAW;AACjB,IAAM,YAAY;AAClB,IAAM,cAAc;AACpB,IAAM,gBAAgB;AACtB,IAAM,iBAAiB;AACvB,IAAM,WAAW;AACjB,IAAM,sBAAsB;AAE5B,IAAM,sBAAsB;AAC5B,IAAM,yBAAyB;AAC/B,IAAM,6BAA6B;AACnC,IAAM,oBAAoB;AAC1B,IAAM,qBAAqB;;;ACtHlC,OAAO,aAAa;AAsBpB,IAAM,gBAAgB;AAEtB,SAAS,gBAAgB,SAAsC;AAC7D,MAAI,QAAQ,aAAa,UAAa,QAAQ,SAAS,SAAS,GAAG;AACjE,WAAO,QAAQ,SAAS,QAAQ,QAAQ,EAAE;AAAA,EAC5C;AACA,QAAM,WAAW,QAAQ,OAAO,QAAQ,KAAK,aAAa;AAC1D,SAAO,YAAY,UAAa,QAAQ,WAAW,IAC/C,oBACA,QAAQ,QAAQ,QAAQ,EAAE;AAChC;AAEA,SAAS,aAAa,OAAgB,OAAuB;AAC3D,MAAI,OAAO,UAAU,YAAY,MAAM,WAAW,GAAG;AACnD,UAAM,IAAI,MAAM,iCAAiC,KAAK,EAAE;AAAA,EAC1D;AACA,SAAO;AACT;AAEA,SAAS,aAAa,OAAgB,OAAuB;AAC3D,MAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,GAAG;AACxD,UAAM,IAAI,MAAM,yCAAyC,KAAK,EAAE;AAAA,EAClE;AACA,SAAO;AACT;AAEA,SAAS,mBAAmB,MAAc,QAA+B;AACvE,MAAI;AACF,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB,SAAS,KAAK;AACZ,UAAM,IAAI,MAAM,wCAAwC,OAAO,SAAS,CAAC,KAAK,EAAE,OAAO,IAAI,CAAC;AAAA,EAC9F;AACF;AAEA,SAAS,kBAAkB,UAAoB,QAA6B;AAC1E,MAAI,SAAS,MAAM,OAAO,OAAO,UAAU,UAAU;AACnD;AAAA,EACF;AACA,QAAM,OAAO,OAAO,OAAO,UAAU,WAAW,OAAO,QAAQ;AAC/D,QAAM,cACJ,OAAO,OAAO,sBAAsB,YAAY,OAAO,kBAAkB,SAAS,IAC9E,OAAO,oBACP,SAAS;AACf,QAAM,IAAI;AAAA,IACR,uCAAuC,SAAS,OAAO,SAAS,CAAC,IAAI,IAAI,MAAM,WAAW;AAAA,EAC5F;AACF;AAEA,eAAsB,gBACpB,aACA,UAA+B,CAAC,GACN;AAC1B,MAAI,YAAY,SAAS,WAAW,GAAG;AACrC,UAAM,IAAI,MAAM,sBAAsB;AAAA,EACxC;AACA,MAAI,YAAY,SAAS,WAAW,GAAG;AACrC,UAAM,IAAI,MAAM,sBAAsB;AAAA,EACxC;AACA,MAAI,YAAY,aAAa,WAAW,GAAG;AACzC,UAAM,IAAI,MAAM,0BAA0B;AAAA,EAC5C;AAEA,QAAM,WAAW,gBAAgB,OAAO;AACxC,QAAM,UAAU,QAAQ,WAAW;AACnC,QAAM,MAAM,GAAG,QAAQ,IAAI,mBAAmB,YAAY,QAAQ,CAAC;AACnE,QAAM,OAAO,IAAI,gBAAgB;AAAA,IAC/B,YAAY;AAAA,IACZ,WAAW,YAAY;AAAA,IACvB,eAAe,YAAY;AAAA,IAC3B,OAAO,QAAQ,SAAS;AAAA,EAC1B,CAAC;AAED,QAAM,WAAW,MAAM,QAAQ,KAAK;AAAA,IAClC,QAAQ;AAAA,IACR,SAAS,EAAE,gBAAgB,qCAAqC,QAAQ,mBAAmB;AAAA,IAC3F,MAAM,KAAK,SAAS;AAAA,EACtB,CAAC;AACD,QAAM,SAAS,mBAAmB,MAAM,SAAS,KAAK,GAAG,SAAS,MAAM;AACxE,oBAAkB,UAAU,MAAM;AAElC,QAAM,aAAa,OAAO,OAAO,UAAU,WAAW,OAAO,QAAQ;AACrE,QAAM,OAAO;AAAA,IACX,aAAa,aAAa,OAAO,cAAc,cAAc;AAAA,IAC7D,WAAW,aAAa,OAAO,YAAY,YAAY;AAAA,IACvD,WAAW,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI,IAAI,aAAa,OAAO,YAAY,YAAY;AAAA,EACzF;AACA,SAAO,eAAe,SAAY,OAAO,EAAE,GAAG,MAAM,OAAO,WAAW;AACxE;;;AC7GA,SAAS,eAAe;AACxB,SAAS,YAAY;AACrB,OAAOA,cAAa;AAIb,IAAM,oBAAoB;AAC1B,IAAM,mBAAmB;AACzB,IAAM,oBAAoB;AAC1B,IAAM,wBAAwB;AAE9B,SAAS,eAAe,MAAyBC,SAAQ,KAAa;AAC3E,QAAM,WAAW,IAAI,QAAQ;AAC7B,MAAI,aAAa,UAAa,SAAS,SAAS,GAAG;AACjD,WAAO;AAAA,EACT;AACA,SAAO,KAAK,QAAQ,GAAG,mBAAmB,gBAAgB;AAC5D;AAEO,SAAS,aAAa,MAAyBA,SAAQ,KAAa;AACzE,SAAO,KAAK,eAAe,GAAG,GAAG,iBAAiB;AACpD;AAEO,SAAS,gBAAgB,MAAyBA,SAAQ,KAAa;AAC5E,SAAO,KAAK,eAAe,GAAG,GAAG,qBAAqB;AACxD;;;ACzBA,OAAOC,cAAa;;;ACApB,SAAS,OAAO,OAAO,UAAU,iBAAiB;AAClD,SAAS,eAAe;AA6BxB,IAAM,oBAAoB;AAC1B,IAAM,qBAAkC,EAAE,SAAS,GAAG,UAAU,CAAC,EAAE;AAEnE,SAAS,mBAAmB,KAAuB;AACjD,SAAO,eAAe,SAAS,UAAU,OAAO,IAAI,SAAS;AAC/D;AAEA,SAAS,kBAAkB,OAA0C;AACnE,SAAO,UAAU,aAAa,UAAU;AAC1C;AAEA,SAAS,gBAAgB,OAA2C;AAClE,MAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AAC/C,WAAO;AAAA,EACT;AACA,QAAM,MAAM;AACZ,QAAM,OAAO,IAAI,MAAM;AACvB,QAAM,WAAW,IAAI,UAAU;AAC/B,QAAM,WAAW,IAAI,UAAU;AAC/B,QAAM,OAAO,IAAI,MAAM;AACvB,QAAM,QAAQ,IAAI,OAAO;AACzB,QAAM,cAAc,IAAI,aAAa;AACrC,QAAM,YAAY,IAAI,WAAW;AACjC,MACE,OAAO,SAAS,YAChB,OAAO,aAAa,YACpB,OAAO,aAAa,YACpB,OAAO,SAAS,YAChB,OAAO,cAAc,YACrB,CAAC,kBAAkB,WAAW,GAC9B;AACA,WAAO;AAAA,EACT;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAI,OAAO,UAAU,WAAW,EAAE,MAAM,IAAI,CAAC;AAAA,IAC7C;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,gBAAgB,OAA0D;AACjF,SAAO,UAAU;AACnB;AAEA,eAAe,gBAAgB,MAAoC;AACjE,MAAI;AACF,UAAM,MAAM,MAAM,SAAS,MAAM,MAAM;AACvC,UAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,QAAI,OAAO,YAAY,KAAK,CAAC,MAAM,QAAQ,OAAO,QAAQ,GAAG;AAC3D,aAAO;AAAA,IACT;AACA,WAAO,EAAE,SAAS,GAAG,UAAU,OAAO,SAAS,IAAI,eAAe,EAAE,OAAO,eAAe,EAAE;AAAA,EAC9F,SAAS,KAAK;AACZ,QAAI,mBAAmB,GAAG,GAAG;AAC3B,aAAO;AAAA,IACT;AACA,UAAM;AAAA,EACR;AACF;AAEA,eAAe,iBAAiB,MAAc,OAAmC;AAC/E,QAAM,MAAM,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AAC9C,QAAM,UAAU,MAAM,GAAG,KAAK,UAAU,OAAO,MAAM,CAAC,CAAC;AAAA,GAAM;AAAA,IAC3D,UAAU;AAAA,IACV,MAAM;AAAA,EACR,CAAC;AACD,QAAM,MAAM,MAAM,iBAAiB;AACrC;AAEO,SAAS,mBAAmB,OAAO,aAAa,GAAiB;AACtE,SAAO;AAAA,IACL,MAAM,eAAkD;AACtD,cAAQ,MAAM,gBAAgB,IAAI,GAAG;AAAA,IACvC;AAAA,IACA,MAAM,cAAc,UAAmD;AACrE,YAAM,iBAAiB,MAAM,EAAE,SAAS,GAAG,SAAS,CAAC;AAAA,IACvD;AAAA,EACF;AACF;AAEO,SAAS,YACd,UACA,OAAO,sBACoB;AAC3B,SAAO,SAAS,KAAK,CAAC,YAAY,QAAQ,SAAS,IAAI;AACzD;AAEA,eAAsB,cACpB,OACA,OACA,OACwB;AACxB,QAAM,OAAO,MAAM,QAAQ;AAC3B,QAAM,SAAwB;AAAA,IAC5B;AAAA,IACA,UAAU,MAAM;AAAA,IAChB,UAAU,MAAM;AAAA,IAChB,MAAM,MAAM;AAAA,IACZ,GAAI,MAAM,UAAU,UAAa,MAAM,MAAM,WAAW,IAAI,CAAC,IAAI,EAAE,OAAO,MAAM,MAAM;AAAA,IACtF,aAAa,MAAM;AAAA,IACnB,YAAY,MAAM,aAAa,oBAAI,KAAK,GAAG,YAAY;AAAA,EACzD;AACA,QAAM,WAAW,MAAM,MAAM,aAAa;AAC1C,QAAM,eAAe,SAAS,KAAK,CAAC,YAAY,QAAQ,SAAS,IAAI,IACjE,SAAS,IAAI,CAAC,YAAa,QAAQ,SAAS,OAAO,SAAS,OAAQ,IACpE,CAAC,GAAG,UAAU,MAAM;AACxB,QAAM,MAAM,UAAU,MAAM,MAAM,YAAY;AAC9C,QAAM,MAAM,cAAc,YAAY;AACtC,SAAO;AACT;AAEA,eAAsB,cACpB,OACA,OACA,OAAO,sBACW;AAClB,QAAM,WAAW,MAAM,MAAM,aAAa;AAC1C,QAAM,eAAe,SAAS,OAAO,CAAC,YAAY,QAAQ,SAAS,IAAI;AACvE,QAAM,MAAM,aAAa,IAAI;AAC7B,MAAI,aAAa,WAAW,SAAS,QAAQ;AAC3C,WAAO;AAAA,EACT;AACA,QAAM,MAAM,cAAc,YAAY;AACtC,SAAO;AACT;AAEA,eAAsB,cACpB,SACA,OAC0B;AAC1B,QAAM,SAAS,MAAM,MAAM,UAAU,QAAQ,IAAI;AACjD,SAAO;AAAA,IACL,GAAG;AAAA,IACH,UAAU,GAAG,QAAQ,SAAS,MAAM,GAAG,CAAC,CAAC,MAAM,QAAQ,SAAS,MAAM,EAAE,CAAC;AAAA,IACzE,iBAAiB,WAAW;AAAA,EAC9B;AACF;;;AC1KA,SAAS,SAAAC,QAAO,SAAAC,QAAO,YAAAC,WAAU,aAAAC,kBAAiB;AAClD,SAAS,WAAAC,gBAAe;AAExB,SAAS,aAAa;AAetB,IAAM,eAAe;AACrB,IAAM,mBAAmB;AACzB,IAAM,oBAAgC,EAAE,SAAS,GAAG,SAAS,CAAC,EAAE;AAEhE,SAASC,oBAAmB,KAAuB;AACjD,SAAO,eAAe,SAAS,UAAU,OAAO,IAAI,SAAS;AAC/D;AAEA,eAAe,eAAe,MAAmC;AAC/D,MAAI;AACF,UAAM,MAAM,MAAMC,UAAS,MAAM,MAAM;AACvC,UAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,QAAI,OAAO,YAAY,KAAK,OAAO,OAAO,YAAY,YAAY,OAAO,YAAY,MAAM;AACzF,aAAO;AAAA,IACT;AACA,UAAM,UAAkC,CAAC;AACzC,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,OAAO,OAAO,GAAG;AACzD,UAAI,OAAO,UAAU,UAAU;AAC7B,gBAAQ,GAAG,IAAI;AAAA,MACjB;AAAA,IACF;AACA,WAAO,EAAE,SAAS,GAAG,QAAQ;AAAA,EAC/B,SAAS,KAAK;AACZ,QAAID,oBAAmB,GAAG,GAAG;AAC3B,aAAO;AAAA,IACT;AACA,UAAM;AAAA,EACR;AACF;AAEA,eAAe,gBAAgB,MAAc,OAAkC;AAC7E,QAAME,OAAMC,SAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AAC9C,QAAMC,WAAU,MAAM,GAAG,KAAK,UAAU,OAAO,MAAM,CAAC,CAAC;AAAA,GAAM;AAAA,IAC3D,UAAU;AAAA,IACV,MAAM;AAAA,EACR,CAAC;AACD,QAAMC,OAAM,MAAM,gBAAgB;AACpC;AAEO,SAAS,yBAAyB,cAAc,cAA2B;AAChF,SAAO;AAAA,IACL,UAAU,aAAkD;AAC1D,YAAM,WAAW,IAAI,MAAM,aAAa,WAAW,EAAE,YAAY;AACjE,aAAO,QAAQ,QAAQ,aAAa,QAAQ,SAAS,WAAW,IAAI,SAAY,QAAQ;AAAA,IAC1F;AAAA,IACA,UAAU,aAAqB,QAA+B;AAC5D,UAAI,MAAM,aAAa,WAAW,EAAE,YAAY,MAAM;AACtD,aAAO,QAAQ,QAAQ;AAAA,IACzB;AAAA,IACA,aAAa,aAAoC;AAC/C,UAAI;AACF,YAAI,MAAM,aAAa,WAAW,EAAE,eAAe;AAAA,MACrD,SAAS,KAAK;AACZ,YAAI,eAAe,SAAS,8BAA8B,KAAK,IAAI,OAAO,GAAG;AAC3E,iBAAO,QAAQ,QAAQ;AAAA,QACzB;AACA,eAAO,QAAQ,OAAO,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,GAAG,CAAC,CAAC;AAAA,MAC3E;AACA,aAAO,QAAQ,QAAQ;AAAA,IACzB;AAAA,EACF;AACF;AAEO,SAAS,sBAAsB,OAAO,gBAAgB,GAAgB;AAC3E,SAAO;AAAA,IACL,MAAM,UAAU,aAAkD;AAChE,YAAM,OAAO,MAAM,eAAe,IAAI;AACtC,aAAO,KAAK,QAAQ,WAAW;AAAA,IACjC;AAAA,IACA,MAAM,UAAU,aAAqB,QAA+B;AAClE,YAAM,OAAO,MAAM,eAAe,IAAI;AACtC,YAAM,gBAAgB,MAAM;AAAA,QAC1B,SAAS;AAAA,QACT,SAAS,EAAE,GAAG,KAAK,SAAS,CAAC,WAAW,GAAG,OAAO;AAAA,MACpD,CAAC;AAAA,IACH;AAAA,IACA,MAAM,aAAa,aAAoC;AACrD,YAAM,OAAO,MAAM,eAAe,IAAI;AACtC,YAAM,YAAY,OAAO;AAAA,QACvB,OAAO,QAAQ,KAAK,OAAO,EAAE,OAAO,CAAC,CAAC,SAAS,MAAM,cAAc,WAAW;AAAA,MAChF;AACA,YAAM,gBAAgB,MAAM,EAAE,SAAS,GAAG,SAAS,UAAU,CAAC;AAAA,IAChE;AAAA,EACF;AACF;;;ACtGA,OAAOC,cAAa;AA0CpB,IAAM,qBAAqB,oBAAI,IAAY,CAAC,KAAK,GAAG,CAAC;AACrD,IAAM,sBAAsB;AAC5B,IAAM,wBAAwB;AAE9B,SAAS,aAAa,IAA2B;AAC/C,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,eAAW,SAAS,EAAE;AAAA,EACxB,CAAC;AACH;AAEA,SAAS,gBAAgB,QAA2C;AAClE,MAAI,WAAW,QAAQ,OAAO,WAAW,GAAG;AAC1C,WAAO;AAAA,EACT;AACA,QAAM,UAAU,OAAO,WAAW,MAAM;AACxC,MAAI,OAAO,SAAS,OAAO,KAAK,WAAW,GAAG;AAC5C,WAAO,KAAK,KAAK,UAAU,GAAI;AAAA,EACjC;AACA,QAAM,SAAS,KAAK,MAAM,MAAM;AAChC,SAAO,OAAO,MAAM,MAAM,IAAI,SAAY,KAAK,IAAI,GAAG,SAAS,KAAK,IAAI,CAAC;AAC3E;AAEA,SAAS,eAAe,SAAqC;AAC3D,MAAI,QAAQ,YAAY,UAAa,QAAQ,QAAQ,SAAS,GAAG;AAC/D,WAAO,QAAQ,QAAQ,QAAQ,QAAQ,EAAE;AAAA,EAC3C;AACA,QAAM,WAAW,QAAQ,OAAOC,SAAQ,KAAK,cAAc;AAC3D,SAAO,YAAY,UAAa,QAAQ,WAAW,IAC/C,qBACA,QAAQ,QAAQ,QAAQ,EAAE;AAChC;AAEA,SAAS,WAAW,MAAc,MAAc,sBAAuC;AACrF,MAAI,gBAAgB,KAAK,IAAI,GAAG;AAC9B,QAAI,wBAAwB,IAAI,IAAI,IAAI,EAAE,WAAW,IAAI,IAAI,IAAI,EAAE,QAAQ;AACzE,YAAM,IAAI,MAAM,6DAA6D;AAAA,IAC/E;AACA,WAAO;AAAA,EACT;AACA,SAAO,GAAG,IAAI,GAAG,KAAK,WAAW,GAAG,IAAI,OAAO,IAAI,IAAI,EAAE;AAC3D;AAEO,IAAM,iBAAN,cAA6B,MAAM;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,QAAgB,MAA0B,QAAgB;AAC3E;AAAA,MACE,mCAAmC,OAAO,SAAS,CAAC,GAClD,SAAS,SAAY,KAAK,IAAI,IAAI,EACpC,MAAM,MAAM;AAAA,IACd;AACA,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,SAAK,OAAO;AACZ,SAAK,SAAS;AAAA,EAChB;AACF;AAEA,eAAe,mBAAmB,UAA2E;AAC3G,QAAM,OAAO,MAAM,SAAS,KAAK,EAAE,MAAM,MAAM,EAAE;AACjD,MAAI,KAAK,WAAW,GAAG;AACrB,WAAO,EAAE,MAAM,QAAW,QAAQ,SAAS,WAAW;AAAA,EACxD;AACA,MAAI;AACF,UAAM,OAAO,KAAK,MAAM,IAAI;AAC5B,UAAM,OAAO,OAAO,KAAK,OAAO,SAAS,WAAW,KAAK,MAAM,OAAO;AACtE,UAAM,SACJ,OAAO,KAAK,OAAO,YAAY,YAAY,KAAK,MAAM,QAAQ,SAAS,IACnE,KAAK,MAAM,UACX,SAAS;AACf,WAAO,EAAE,MAAM,OAAO;AAAA,EACxB,QAAQ;AACN,WAAO,EAAE,MAAM,QAAW,QAAQ,KAAK;AAAA,EACzC;AACF;AAEA,SAAS,UAAU,aAAqB,SAA2C;AACjF,QAAM,UAAkC;AAAA,IACtC,QAAQ;AAAA,IACR,GAAI,QAAQ,yBAAyB,QAAQ,CAAC,IAAI,EAAE,eAAe,UAAU,WAAW,GAAG;AAAA,IAC3F,GAAG,QAAQ;AAAA,EACb;AACA,QAAM,OAAoB,EAAE,QAAQ,QAAQ,UAAU,OAAO,QAAQ;AACrE,MAAI,QAAQ,YAAY,QAAW;AACjC,SAAK,OAAO,kBAAkB,QAAQ,OAAO;AAC7C,WAAO;AAAA,EACT;AACA,MAAI,QAAQ,SAAS,QAAW;AAC9B,YAAQ,cAAc,IAAI,QAAQ,cAAc,KAAK;AACrD,SAAK,OAAO,OAAO,QAAQ,SAAS,WAAW,QAAQ,OAAO,KAAK,UAAU,QAAQ,IAAI;AAAA,EAC3F;AACA,SAAO;AACT;AAIA,SAAS,kBAAkB,SAA2C;AACpE,MAAI,OAAO,YAAY,UAAU;AAC/B,WAAO;AAAA,EACT;AACA,QAAM,OAAO,IAAI,YAAY,QAAQ,UAAU;AAC/C,MAAI,WAAW,IAAI,EAAE,IAAI,OAAO;AAChC,SAAO;AACT;AAEA,eAAe,YAAY,UAAmC;AAC5D,MAAI,SAAS,SAAS,MAAM;AAC1B;AAAA,EACF;AACA,QAAM,SAAS,KAAK,OAAO,EAAE,MAAM,MAAM;AAAA,EAEzC,CAAC;AACH;AAEO,SAAS,kBAAkB,SAA0C;AAC1E,QAAM,UAAU,eAAe,OAAO;AACtC,QAAM,UAAU,QAAQ,WAAW;AACnC,QAAM,aAAa,QAAQ,OAAO,cAAc;AAChD,QAAM,cAAc,QAAQ,OAAO,eAAe;AAClD,QAAM,UAAU,QAAQ,OAAO,WAAW;AAE1C,iBAAe,QAAQ,MAAc,gBAAwD;AAC3F,UAAM,uBAAuB,eAAe,yBAAyB;AACrE,UAAM,MAAM,WAAW,SAAS,MAAM,oBAAoB;AAC1D,UAAM,OAAO,UAAU,QAAQ,aAAa,cAAc;AAC1D,QAAI,UAAU;AACd,QAAI,WAAW,MAAM,QAAQ,KAAK,IAAI;AACtC,WAAO,CAAC,SAAS,MAAM,mBAAmB,IAAI,SAAS,MAAM,KAAK,UAAU,YAAY;AACtF,YAAM,eACJ,gBAAgB,SAAS,QAAQ,IAAI,aAAa,CAAC,KAAK,cAAc,KAAK;AAC7E,YAAM,YAAY,QAAQ;AAC1B,YAAM,QAAQ,YAAY;AAC1B,iBAAW;AACX,iBAAW,MAAM,QAAQ,KAAK,IAAI;AAAA,IACpC;AACA,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,EAAE,MAAM,OAAO,IAAI,MAAM,mBAAmB,QAAQ;AAC1D,YAAM,IAAI,eAAe,SAAS,QAAQ,MAAM,MAAM;AAAA,IACxD;AACA,WAAO;AAAA,EACT;AAEA,iBAAe,YAAe,MAAc,iBAAsC,CAAC,GAAe;AAChG,UAAM,WAAW,MAAM,QAAQ,MAAM,cAAc;AACnD,QAAI,SAAS,WAAW,KAAK;AAC3B,aAAO;AAAA,IACT;AACA,UAAM,cAAc,SAAS,QAAQ,IAAI,cAAc,GAAG,YAAY,KAAK;AAC3E,QAAI,CAAC,YAAY,SAAS,kBAAkB,GAAG;AAC7C,aAAO;AAAA,IACT;AACA,WAAQ,MAAM,SAAS,KAAK;AAAA,EAC9B;AAEA,iBAAe,aAAa,MAAc,iBAAsC,CAAC,GAAwB;AACvG,UAAM,WAAW,MAAM,QAAQ,MAAM,cAAc;AACnD,WAAO,IAAI,WAAW,MAAM,SAAS,YAAY,CAAC;AAAA,EACpD;AAEA,iBAAe,iBAAiB,MAAc,iBAAsC,CAAC,GAAkB;AACrG,UAAM,QAAQ,MAAM,cAAc;AAAA,EACpC;AAEA,SAAO,EAAE,SAAS,aAAa,cAAc,iBAAiB;AAChE;;;ACpMA,SAAS,SAAS,OAAgB,WAAW,IAAY;AACvD,SAAO,OAAO,UAAU,WAAW,QAAQ;AAC7C;AAEA,SAAS,kBAAkB,OAAuB;AAChD,QAAM,cAAc,MAAM,OAAO,MAAM;AACvC,SAAO,gBAAgB,KAAK,QAAQ,MAAM,MAAM,GAAG,WAAW;AAChE;AAEA,SAAS,eAAe,UAAkB,OAAuB;AAC/D,SAAO,SACJ,MAAM,GAAG,EACT,IAAI,CAAC,YAAY;AAChB,QAAI;AACF,aAAO,mBAAmB,OAAO;AAAA,IACnC,SAAS,KAAK;AACZ,YAAM,IAAI,MAAM,2BAA2B,KAAK,qCAAqC;AAAA,QACnF,OAAO;AAAA,MACT,CAAC;AAAA,IACH;AAAA,EACF,CAAC,EACA,KAAK,GAAG;AACb;AAEA,SAAS,eAAe,SAA0E;AAChG,MAAI,gBAAgB,KAAK,OAAO,GAAG;AACjC,UAAM,MAAM,IAAI,IAAI,OAAO;AAC3B,WAAO,EAAE,UAAU,IAAI,UAAU,SAAS,IAAI,SAAS;AAAA,EACzD;AACA,QAAM,eAAe,kBAAkB,OAAO;AAC9C,QAAM,aAAa,aAAa,QAAQ,GAAG;AAC3C,MAAI,eAAe,IAAI;AACrB,UAAM,IAAI,MAAM,2BAA2B,OAAO,2CAA2C;AAAA,EAC/F;AACA,SAAO,EAAE,UAAU,aAAa,MAAM,GAAG,UAAU,GAAG,SAAS,aAAa,MAAM,aAAa,CAAC,EAAE;AACpG;AAEO,SAAS,aAAa,OAAkC;AAC7D,QAAM,UAAU,MAAM,KAAK;AAC3B,MAAI,QAAQ,WAAW,GAAG;AACxB,UAAM,IAAI,MAAM,yBAAyB;AAAA,EAC3C;AACA,QAAM,EAAE,UAAU,QAAQ,IAAI,eAAe,OAAO;AACpD,QAAM,WAAW,eAAe,QAAQ,QAAQ,cAAc,EAAE,GAAG,OAAO;AAC1E,MAAI,SAAS,WAAW,KAAK,SAAS,WAAW,GAAG;AAClD,UAAM,IAAI,MAAM,2BAA2B,OAAO,kCAAkC;AAAA,EACtF;AACA,SAAO,EAAE,UAAU,SAAS;AAC9B;AAEA,SAAS,eAAe,UAA0B;AAChD,SAAO,SAAS,MAAM,GAAG,EAAE,IAAI,CAAC,YAAY,mBAAmB,OAAO,CAAC,EAAE,KAAK,GAAG;AACnF;AAEA,eAAsB,YACpB,QACA,KACyB;AACzB,QAAM,OAAO,UAAU,mBAAmB,IAAI,QAAQ,CAAC,KAAK,eAAe,IAAI,QAAQ,CAAC;AACxF,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,OAAO,YAA6B,IAAI;AAAA,EACtD,SAAS,KAAK;AACZ,QAAI,eAAe,kBAAkB,IAAI,WAAW,KAAK;AACvD,YAAM,IAAI,MAAM,gCAAgC,IAAI,QAAQ,IAAI,IAAI,QAAQ,IAAI;AAAA,QAC9E,OAAO;AAAA,MACT,CAAC;AAAA,IACH;AACA,UAAM;AAAA,EACR;AACA,QAAM,KAAK,SAAS,IAAI,EAAE;AAC1B,MAAI,GAAG,WAAW,GAAG;AACnB,UAAM,IAAI,MAAM,gCAAgC,IAAI,QAAQ,IAAI,IAAI,QAAQ,EAAE;AAAA,EAChF;AACA,SAAO;AAAA,IACL;AAAA,IACA,MAAM,SAAS,IAAI,MAAM,IAAI,QAAQ;AAAA,IACrC,aAAa,SAAS,IAAI,aAAa,SAAS,IAAI,MAAM,IAAI,QAAQ,CAAC;AAAA,IACvE,QAAQ,SAAS,IAAI,MAAM;AAAA,EAC7B;AACF;;;AJ7CA,SAAS,QAAQ,KAAwB,SAAiB,UAAsC;AAC9F,QAAM,QAAQ,IAAI,OAAO,KAAK,IAAI,QAAQ;AAC1C,SAAO,UAAU,UAAa,MAAM,WAAW,IAAI,SAAY;AACjE;AAEA,SAAS,UACP,UACA,UACA,cACoB;AACpB,MAAI,aAAa,UAAa,SAAS,SAAS,GAAG;AACjD,WAAO;AAAA,EACT;AACA,SAAO,YAAY;AACrB;AAEA,SAAS,gBACP,SACA,SACa;AACb,MAAI,SAAS,gBAAgB,QAAQ;AACnC,WAAO,QAAQ,aAAa,sBAAsB;AAAA,EACpD;AACA,SAAO,QAAQ,gBAAgB,yBAAyB;AAC1D;AAEA,eAAe,oBACb,UACA,UACA,SACA,SAC6B;AAC7B,MAAI,aAAa,UAAa,SAAS,SAAS,GAAG;AACjD,WAAO;AAAA,EACT;AACA,MAAI,aAAa,QAAW;AAC1B,WAAO;AAAA,EACT;AACA,SAAO,YAAY,SAAY,SAAY,MAAM,gBAAgB,SAAS,OAAO,EAAE,UAAU,QAAQ,IAAI;AAC3G;AAEA,SAAS,aAAa,OAA2B,WAA2B;AAC1E,MAAI,UAAU,UAAa,MAAM,WAAW,GAAG;AAC7C,UAAM,IAAI,MAAM,GAAG,SAAS,wDAAwD;AAAA,EACtF;AACA,SAAO;AACT;AAEA,eAAsB,eAAe,UAAiC,CAAC,GAA6B;AAClG,QAAM,MAAM,QAAQ,OAAOC,SAAQ;AACnC,QAAM,YAAY,QAAQ,aAAa,CAAC;AACxC,QAAM,cACJ,UAAU,WAAW,IAAI,WAAW,KAAK;AAC3C,QAAM,QAAQ,QAAQ,gBAAgB,mBAAmB;AACzD,QAAM,UAAU,YAAY,MAAM,MAAM,aAAa,GAAG,WAAW;AAEnE,QAAM,WAAW;AAAA,IACf,UAAU;AAAA,IACV,QAAQ,KAAK,YAAY,mBAAmB;AAAA,IAC5C,SAAS;AAAA,EACX;AACA,QAAM,WAAW;AAAA,IACf,UAAU;AAAA,IACV,QAAQ,KAAK,eAAe,sBAAsB;AAAA,IAClD,SAAS;AAAA,EACX;AACA,QAAM,OAAO,UAAU,UAAU,MAAM,QAAQ,KAAK,UAAU,iBAAiB,GAAG,SAAS,IAAI;AAC/F,QAAM,QAAQ,UAAU,UAAU,OAAO,QAAQ,KAAK,WAAW,kBAAkB,GAAG,SAAS,KAAK;AACpG,QAAM,eAAe,MAAM;AAAA,IACzB,UAAU;AAAA,IACV,QAAQ,KAAK,mBAAmB,0BAA0B;AAAA,IAC1D;AAAA,IACA;AAAA,EACF;AAEA,SAAO;AAAA,IACL,QAAQ;AAAA,MACN,aAAa;AAAA,QACX,UAAU,aAAa,UAAU,WAAW;AAAA,QAC5C,UAAU,aAAa,UAAU,WAAW;AAAA,QAC5C,cAAc,aAAa,cAAc,eAAe;AAAA,MAC1D;AAAA,MACA,MAAM,aAAa,aAAa,MAAM,iBAAiB,CAAC;AAAA,IAC1D;AAAA,IACA,GAAI,UAAU,SAAY,CAAC,IAAI,EAAE,MAAM;AAAA,IACvC;AAAA,IACA,QAAQ,YAAY,SAAY,QAAQ;AAAA,EAC1C;AACF;AAEO,SAAS,qBAAqB,OAA4C;AAC/E,MAAI,UAAU,UAAa,UAAU,WAAW;AAC9C,WAAO;AAAA,EACT;AACA,MAAI,UAAU,QAAQ;AACpB,WAAO;AAAA,EACT;AACA,QAAM,IAAI,MAAM,yBAAyB,KAAK,6BAA6B;AAC7E;;;AKlHA,IAAM,oBAAoB;AAE1B,SAASC,UAAS,OAAgB,WAAW,IAAY;AACvD,SAAO,OAAO,UAAU,WAAW,QAAQ;AAC7C;AAEA,SAAS,SAAS,OAAgB,WAAW,GAAW;AACtD,SAAO,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,IAAI,QAAQ;AACvE;AAEO,SAAS,gBAAgB,cAA8B;AAC5D,SAAO,aACJ,MAAM,GAAG,EACT,OAAO,CAAC,YAAY,QAAQ,SAAS,CAAC,EACtC,IAAI,CAAC,YAAY,mBAAmB,OAAO,CAAC,EAC5C,KAAK,GAAG;AACb;AAEA,SAAS,QAAQ,KAAwC;AACvD,SAAO;AAAA,IACL,IAAIA,UAAS,IAAI,EAAE;AAAA,IACnB,MAAMA,UAAS,IAAI,IAAI;AAAA,IACvB,WAAWA,UAAS,IAAI,WAAW,iBAAiB;AAAA,IACpD,QAAQA,UAAS,IAAI,MAAM;AAAA,EAC7B;AACF;AAEA,SAAS,YAAY,KAAqC;AACxD,QAAM,OAAO;AAAA,IACX,IAAIA,UAAS,IAAI,EAAE;AAAA,IACnB,MAAMA,UAAS,IAAI,IAAI;AAAA,IACvB,UAAU,IAAI,WAAW,UAAa,IAAI,WAAW;AAAA,IACrD,MAAM,SAAS,IAAI,IAAI;AAAA,EACzB;AACA,SAAO;AAAA,IACL,GAAG;AAAA,IACH,GAAI,OAAO,IAAI,SAAS,WAAW,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;AAAA,IACzD,GAAI,OAAO,IAAI,SAAS,WAAW,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;AAAA,IACzD,GAAI,OAAO,IAAI,WAAW,WAAW,EAAE,QAAQ,IAAI,OAAO,IAAI,CAAC;AAAA,EACjE;AACF;AAEA,eAAsB,WACpB,QACA,QACqC;AACrC,QAAM,WAAW,MAAM,OAAO,YAAkC,UAAU,mBAAmB,MAAM,CAAC,SAAS;AAC7G,MAAI,CAAC,MAAM,QAAQ,SAAS,KAAK,GAAG;AAClC,WAAO,CAAC;AAAA,EACV;AACA,SAAO,SAAS,MACb,OAAO,CAAC,UAAqC,OAAO,UAAU,YAAY,UAAU,IAAI,EACxF,IAAI,OAAO;AAChB;AAEO,SAAS,YACd,QACA,WACiB;AACjB,MAAI,OAAO,WAAW,GAAG;AACvB,UAAM,IAAI,MAAM,oDAAoD;AAAA,EACtE;AACA,MAAI,cAAc,UAAa,UAAU,WAAW,GAAG;AACrD,UAAM,QAAQ,OAAO,CAAC;AACtB,QAAI,UAAU,QAAW;AACvB,YAAM,IAAI,MAAM,qBAAqB;AAAA,IACvC;AACA,WAAO;AAAA,EACT;AACA,QAAM,QAAQ,OAAO,KAAK,CAAC,UAAU,MAAM,OAAO,aAAa,MAAM,SAAS,SAAS;AACvF,MAAI,UAAU,QAAW;AACvB,UAAM,IAAI,MAAM,UAAU,SAAS,2BAA2B,OAAO,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,EACtG;AACA,SAAO;AACT;AAEA,eAAsB,mBACpB,QACA,SACA,cACkC;AAClC,QAAM,aAAa,aAAa,QAAQ,cAAc,EAAE;AACxD,QAAM,OACJ,WAAW,WAAW,IAClB,WAAW,mBAAmB,OAAO,CAAC,UACtC,WAAW,mBAAmB,OAAO,CAAC,UAAU,gBAAgB,UAAU,CAAC;AACjF,MAAI;AACF,WAAO,YAAY,MAAM,OAAO,YAA0B,IAAI,CAAC;AAAA,EACjE,SAAS,KAAK;AACZ,QAAI,eAAe,kBAAkB,IAAI,WAAW,KAAK;AACvD,aAAO;AAAA,IACT;AACA,UAAM;AAAA,EACR;AACF;AAEA,eAAsB,kBACpB,QACA,SACA,cACqB;AACrB,QAAM,cAAc,gBAAgB,aAAa,QAAQ,cAAc,EAAE,CAAC;AAC1E,SAAO,MAAM,OAAO,aAAa,WAAW,mBAAmB,OAAO,CAAC,UAAU,WAAW,aAAa;AAAA,IACvG,SAAS,EAAE,QAAQ,kBAAkB;AAAA,EACvC,CAAC;AACH;AAEA,eAAe,oBACb,QACA,SACA,cACiB;AACjB,QAAM,cAAc,gBAAgB,aAAa,QAAQ,cAAc,EAAE,CAAC;AAC1E,QAAM,WAAW,MAAM,OAAO;AAAA,IAC5B,WAAW,mBAAmB,OAAO,CAAC,UAAU,WAAW;AAAA,IAC3D;AAAA,MACE,QAAQ;AAAA,MACR,MAAM,EAAE,MAAM,EAAE,qCAAqC,OAAO,EAAE;AAAA,IAChE;AAAA,EACF;AACA,MAAI,OAAO,SAAS,cAAc,YAAY,SAAS,UAAU,WAAW,GAAG;AAC7E,UAAM,IAAI,MAAM,iDAAiD;AAAA,EACnE;AACA,SAAO,SAAS;AAClB;AAEA,eAAsB,mBACpB,QACA,SACA,cACA,OAC2B;AAC3B,QAAM,WAAW,MAAM,mBAAmB,QAAQ,SAAS,YAAY;AACvE,MAAI,aAAa,MAAM;AACrB,UAAM,IAAI,MAAM,mDAAmD,YAAY,EAAE;AAAA,EACnF;AACA,QAAM,YAAY,MAAM,oBAAoB,QAAQ,SAAS,YAAY;AACzE,QAAM,WAAW,MAAM,aAAa;AACpC,QAAM,MAAM,MAAM,OAAO,YAA0B,WAAW;AAAA,IAC5D,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,sBAAsB;AAAA,IACtB,SAAS;AAAA,MACP,kBAAkB,MAAM,WAAW,SAAS;AAAA,MAC5C,iBAAiB,WAAW,SAAS,SAAS,CAAC,IAAI,MAAM,WAAW,SAAS,CAAC;AAAA,MAC9E,gBAAgB;AAAA,IAClB;AAAA,EACF,CAAC;AACD,SAAO,YAAY,GAAG;AACxB;AAEA,eAAsB,iBACpB,QACA,SACA,cACA,MACA,OAC2B;AAC3B,QAAM,cAAc,gBAAgB,aAAa,QAAQ,cAAc,EAAE,CAAC;AAC1E,QAAM,MAAM,MAAM,OAAO;AAAA,IACvB,WAAW,mBAAmB,OAAO,CAAC,UAAU,WAAW;AAAA,IAC3D;AAAA,MACE,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,YAAY;AAAA,MACd;AAAA,IACF;AAAA,EACF;AACA,SAAO,YAAY,GAAG;AACxB;;;ACpLA,eAAsB,YACpB,QACA,UAA0B,CAAC,GACM;AACjC,QAAM,eAAoC;AAAA,IACxC,GAAI,QAAQ,aAAa,SAAY,CAAC,IAAI,EAAE,UAAU,QAAQ,SAAS;AAAA,IACvE,GAAI,QAAQ,YAAY,SAAY,CAAC,IAAI,EAAE,SAAS,QAAQ,QAAQ;AAAA,EACtE;AACA,QAAM,QAAQ,MAAM,gBAAgB,OAAO,aAAa,YAAY;AACpE,QAAM,SAAS,kBAAkB;AAAA,IAC/B,aAAa,MAAM;AAAA,IACnB,GAAI,QAAQ,cAAc,SAAY,CAAC,IAAI,EAAE,SAAS,QAAQ,UAAU;AAAA,IACxE,GAAI,QAAQ,YAAY,SAAY,CAAC,IAAI,EAAE,SAAS,QAAQ,QAAQ;AAAA,IACpE,GAAI,QAAQ,UAAU,SAAY,CAAC,IAAI,EAAE,OAAO,QAAQ,MAAM;AAAA,EAChE,CAAC;AACD,QAAM,OAAO,MAAM,YAAY,QAAQ,OAAO,IAAI;AAClD,QAAM,SAAS,MAAM,WAAW,QAAQ,KAAK,EAAE;AAC/C,SAAO,EAAE,OAAO,QAAQ,MAAM,OAAO;AACvC;;;AC9BA,IAAM,mBAAmB;AAElB,SAAS,mBAAmB,YAA4B;AAC7D,QAAM,aAAa,WAAW,KAAK,EAAE,YAAY;AACjD,MAAI,CAAC,WAAW,KAAK,UAAU,GAAG;AAChC,UAAM,IAAI,MAAM,wBAAwB,UAAU,GAAG;AAAA,EACvD;AACA,MAAI,QAAQ;AACZ,aAAW,QAAQ,YAAY;AAC7B,YAAQ,QAAQ,KAAK,KAAK,WAAW,CAAC,IAAI;AAAA,EAC5C;AACA,SAAO;AACT;AAEO,SAAS,YAAY,OAA0B;AACpD,QAAM,UAAU,MAAM,KAAK;AAC3B,QAAM,QAAQ,iBAAiB,KAAK,OAAO;AAC3C,MAAI,UAAU,MAAM;AAClB,UAAM,IAAI,MAAM,8BAA8B,KAAK,GAAG;AAAA,EACxD;AACA,QAAM,aAAa,MAAM,CAAC;AAC1B,QAAM,WAAW,MAAM,CAAC;AACxB,MAAI,eAAe,UAAa,aAAa,QAAW;AACtD,UAAM,IAAI,MAAM,8BAA8B,KAAK,GAAG;AAAA,EACxD;AACA,SAAO;AAAA,IACL,KAAK,OAAO,SAAS,UAAU,EAAE;AAAA,IACjC,QAAQ,mBAAmB,UAAU;AAAA,EACvC;AACF;AAEA,SAAS,WAAW,OAAkB,KAA4B;AAChE,SAAO;AAAA,IACL,OAAO;AAAA,MACL,KAAK,KAAK,IAAI,MAAM,KAAK,IAAI,GAAG;AAAA,MAChC,QAAQ,KAAK,IAAI,MAAM,QAAQ,IAAI,MAAM;AAAA,IAC3C;AAAA,IACA,KAAK;AAAA,MACH,KAAK,KAAK,IAAI,MAAM,KAAK,IAAI,GAAG;AAAA,MAChC,QAAQ,KAAK,IAAI,MAAM,QAAQ,IAAI,MAAM;AAAA,IAC3C;AAAA,EACF;AACF;AAEO,SAAS,aAAa,OAA2B;AACtD,QAAM,QAAQ,MAAM,MAAM,GAAG,EAAE,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC;AACxD,MAAI,MAAM,WAAW,GAAG;AACtB,UAAM,OAAO,YAAY,MAAM,CAAC,KAAK,EAAE;AACvC,WAAO,EAAE,OAAO,MAAM,KAAK,KAAK;AAAA,EAClC;AACA,MAAI,MAAM,WAAW,GAAG;AACtB,UAAM,IAAI,MAAM,qBAAqB,KAAK,GAAG;AAAA,EAC/C;AACA,SAAO,WAAW,YAAY,MAAM,CAAC,KAAK,EAAE,GAAG,YAAY,MAAM,CAAC,KAAK,EAAE,CAAC;AAC5E;;;AChEA,OAAO,aAAa;AAiBpB,IAAM,sBAAsB;AAE5B,SAAS,kBAAkB,WAA2B;AACpD,QAAM,UAAU,UAAU,KAAK;AAC/B,MAAI,QAAQ,WAAW,KAAK,QAAQ,SAAS,MAAM,oBAAoB,KAAK,OAAO,GAAG;AACpF,UAAM,IAAI,MAAM,6BAA6B,SAAS,GAAG;AAAA,EAC3D;AACA,SAAO;AACT;AAEA,SAAS,SAAS,KAA0C;AAC1D,SAAO,CAAC,MAAM,QAAQ,GAAG;AAC3B;AAEA,SAAS,cAAc,SAA4B,MAAsD;AACvG,MAAI,QAAQ,SAAS,GAAG;AACtB,WAAO;AAAA,EACT;AACA,QAAM,cAAc,KAAK,KAAK,QAAQ;AACtC,SAAO,gBAAgB,SAAY,CAAC,IAAI,OAAO,KAAK,WAAW;AACjE;AAEA,SAAS,YAAY,KAAuB,SAAqC;AAC/E,MAAI,CAAC,SAAS,GAAG,GAAG;AAClB,WAAO,CAAC,GAAG,GAAG;AAAA,EAChB;AACA,QAAM,SAAS;AACf,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAO,OAAO,KAAK,MAAM,EAAE,IAAI,CAAC,QAAQ,OAAO,GAAG,KAAK,IAAI;AAAA,EAC7D;AACA,SAAO,QAAQ,IAAI,CAAC,WAAW,OAAO,MAAM,KAAK,IAAI;AACvD;AAEA,SAAS,QAAQ,OAAkB,SAA4B,MAAyC;AACtG,MAAI,QAAQ,SAAS,GAAG;AACtB,UAAM,OAAO,CAAC,GAAG,OAAO,CAAC;AAAA,EAC3B;AACA,aAAW,OAAO,MAAM;AACtB,UAAM,OAAO,CAAC,GAAG,YAAY,KAAK,OAAO,CAAC,CAAC;AAAA,EAC7C;AACF;AAEA,SAAS,SAAS,OAAkB,WAAmB,SAA4B,MAAyC;AAC1H,QAAM,SAAS;AAAA,IACb,MAAM;AAAA,IACN,KAAK;AAAA,IACL,WAAW;AAAA,IACX,WAAW;AAAA,IACX,OAAO,EAAE,OAAO,qBAAqB,gBAAgB,KAAK;AAAA,IAC1D,SAAS,QAAQ,IAAI,CAAC,UAAU,EAAE,KAAK,EAAE;AAAA,IACzC,MAAM,KAAK,IAAI,CAAC,QAAQ,CAAC,GAAG,YAAY,KAAK,OAAO,CAAC,CAAC;AAAA,EACxD,CAAC;AACH;AAEA,eAAe,gBAAgB,UAAiD;AAC9E,QAAM,SAAS,MAAM,SAAS,KAAK,YAAY;AAC/C,SAAO,IAAI,WAAW,MAAM;AAC9B;AAEA,eAAe,aAAa,OAA8C;AACxE,QAAM,WAAW,IAAI,QAAQ,SAAS;AACtC,QAAM,SAAS,KAAK,KAAK,wBAAwB,KAAK,CAAC;AACvD,SAAO;AACT;AAEA,SAAS,wBAAwB,OAAgC;AAC/D,QAAM,OAAO,IAAI,YAAY,MAAM,UAAU;AAC7C,MAAI,WAAW,IAAI,EAAE,IAAI,KAAK;AAC9B,SAAO;AACT;AAEA,SAAS,aAAa,UAA4B,WAA8B;AAC9E,QAAM,QAAQ,SAAS,aAAa,SAAS;AAC7C,MAAI,UAAU,QAAW;AACvB,UAAM,IAAI,MAAM,UAAU,SAAS,aAAa;AAAA,EAClD;AACA,SAAO;AACT;AAEA,SAAS,mBAAmB,OAA+B;AACzD,MAAI,UAAU,QAAQ,UAAU,QAAW;AACzC,WAAO;AAAA,EACT;AACA,MAAI,OAAO,UAAU,YAAY,OAAO,UAAU,YAAY,OAAO,UAAU,WAAW;AACxF,WAAO;AAAA,EACT;AACA,MAAI,iBAAiB,MAAM;AACzB,WAAO,MAAM,YAAY;AAAA,EAC3B;AACA,MAAI,OAAO,UAAU,YAAY,YAAY,OAAO;AAClD,WAAO,mBAAoB,MAAwC,MAAM;AAAA,EAC3E;AACA,SAAO,KAAK,UAAU,KAAK;AAC7B;AAEA,SAAS,QAAQ,OAAkB,WAAmB,aAAqB,WAA4B;AACrG,QAAM,MAAM,MAAM,OAAO,SAAS;AAClC,QAAM,cAAc,YAAY,cAAc;AAC9C,SAAO,MAAM;AAAA,IAAK,EAAE,QAAQ,YAAY;AAAA,IAAG,CAAC,QAAQ,UAClD,mBAAmB,IAAI,QAAQ,cAAc,KAAK,EAAE,KAAK;AAAA,EAC3D;AACF;AAEA,SAAS,cAAc,OAAqC;AAC1D,MAAI,MAAM,mBAAmB,GAAG;AAC9B,WAAO,CAAC;AAAA,EACV;AACA,SAAO,QAAQ,OAAO,GAAG,GAAG,KAAK,IAAI,GAAG,MAAM,iBAAiB,CAAC,EAAE,IAAI,CAAC,UAAU,OAAO,SAAS,EAAE,CAAC;AACtG;AAEA,SAAS,UAAU,OAAkB,SAAuD;AAC1F,QAAM,QAAQ,QAAQ,UAAU,SAAY,SAAY,aAAa,QAAQ,KAAK;AAClF,QAAM,WAAW,OAAO,MAAM,OAAO;AACrC,QAAM,SAAS,OAAO,IAAI,OAAO,KAAK,IAAI,GAAG,MAAM,cAAc;AACjE,QAAM,cAAc,OAAO,MAAM,UAAU;AAC3C,QAAM,YAAY,OAAO,IAAI,UAAU,KAAK,IAAI,GAAG,MAAM,iBAAiB;AAC1E,QAAM,OAAkB,CAAC;AACzB,WAAS,MAAM,UAAU,OAAO,QAAQ,OAAO,GAAG;AAChD,SAAK,KAAK,QAAQ,OAAO,KAAK,aAAa,SAAS,CAAC;AAAA,EACvD;AACA,SAAO,EAAE,MAAM,MAAM,MAAM,UAAU,KAAK,QAAQ,aAAa,YAAY,cAAc,GAAG,KAAK;AACnG;AAEA,eAAsB,oBAAoB,OAAiD;AACzF,QAAM,WAAW,IAAI,QAAQ,SAAS;AACtC,QAAM,QAAQ,SAAS,aAAa,kBAAkB,MAAM,SAAS,CAAC;AACtE,QAAM,UAAU,cAAc,MAAM,SAAS,MAAM,IAAI;AACvD,MAAI,MAAM,cAAc,UAAa,MAAM,UAAU,SAAS,KAAK,QAAQ,SAAS,GAAG;AACrF,aAAS,OAAO,MAAM,WAAW,SAAS,MAAM,IAAI;AAAA,EACtD,OAAO;AACL,YAAQ,OAAO,SAAS,MAAM,IAAI;AAAA,EACpC;AACA,SAAO,MAAM,gBAAgB,QAAQ;AACvC;AAEA,eAAsB,kBACpB,OACA,UAA+B,CAAC,GACH;AAC7B,QAAM,WAAW,MAAM,aAAa,KAAK;AACzC,QAAM,SACJ,QAAQ,cAAc,SAClB,SAAS,aACT,CAAC,aAAa,UAAU,kBAAkB,QAAQ,SAAS,CAAC,CAAC;AACnE,SAAO,EAAE,QAAQ,OAAO,IAAI,CAAC,UAAU,UAAU,OAAO,OAAO,CAAC,EAAE;AACpE;AAEA,eAAsB,mBACpB,OACA,WACA,MACA,aACiC;AACjC,QAAM,WAAW,MAAM,aAAa,KAAK;AACzC,QAAM,QAAQ,aAAa,UAAU,kBAAkB,SAAS,CAAC;AACjE,QAAM,UAAU,cAAc,cAAc,KAAK,IAAI,cAAc,CAAC,GAAG,IAAI;AAC3E,aAAW,OAAO,MAAM;AACtB,UAAM,OAAO,CAAC,GAAG,YAAY,KAAK,OAAO,CAAC,CAAC;AAAA,EAC7C;AACA,SAAO;AAAA,IACL,OAAO,MAAM,gBAAgB,QAAQ;AAAA,IACrC,WAAW,MAAM;AAAA,IACjB,UAAU,MAAM;AAAA,IAChB,aAAa,MAAM;AAAA,EACrB;AACF;AAEA,eAAsB,mBACpB,OACA,WACA,SACA,OACiC;AACjC,QAAM,WAAW,MAAM,aAAa,KAAK;AACzC,QAAM,QAAQ,aAAa,UAAU,kBAAkB,SAAS,CAAC;AACjE,QAAM,OAAO,YAAY,OAAO;AAChC,QAAM,QAAQ,KAAK,KAAK,KAAK,MAAM,EAAE,QAAQ;AAC7C,SAAO;AAAA,IACL,OAAO,MAAM,gBAAgB,QAAQ;AAAA,IACrC,WAAW,MAAM;AAAA,IACjB,UAAU,MAAM;AAAA,IAChB,aAAa,MAAM;AAAA,EACrB;AACF;AAEA,eAAsB,iBACpB,OACA,WACA,SACiC;AACjC,QAAM,WAAW,MAAM,aAAa,KAAK;AACzC,QAAM,aAAa,kBAAkB,SAAS;AAC9C,MAAI,SAAS,aAAa,UAAU,MAAM,QAAW;AACnD,UAAM,IAAI,MAAM,UAAU,UAAU,kBAAkB;AAAA,EACxD;AACA,QAAM,QAAQ,SAAS,aAAa,UAAU;AAC9C,MAAI,QAAQ,SAAS,GAAG;AACtB,UAAM,OAAO,CAAC,GAAG,OAAO,CAAC;AAAA,EAC3B;AACA,SAAO;AAAA,IACL,OAAO,MAAM,gBAAgB,QAAQ;AAAA,IACrC,WAAW,MAAM;AAAA,IACjB,UAAU,MAAM;AAAA,IAChB,aAAa,MAAM;AAAA,EACrB;AACF;;;AC9NA,SAAS,SAAS;AAIlB,IAAM,sBAAsB,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,OAAO,GAAG,EAAE,QAAQ,GAAG,EAAE,KAAK,CAAC,CAAC;AACnF,IAAM,gBAAgB,EAAE,MAAM,mBAAmB;AACjD,IAAM,mBAAmB,EAAE,OAAO,EAAE,OAAO,GAAG,mBAAmB;AAE1D,SAAS,aAAa,OAA8C;AACzE,MAAI,UAAU,UAAa,MAAM,KAAK,EAAE,WAAW,GAAG;AACpD,WAAO,CAAC;AAAA,EACV;AACA,SAAO,MACJ,MAAM,GAAG,EACT,IAAI,CAAC,UAAU,MAAM,KAAK,CAAC,EAC3B,OAAO,CAAC,UAAU,MAAM,SAAS,CAAC;AACvC;AAEA,SAAS,UAAU,OAAe,OAAwB;AACxD,MAAI;AACF,WAAO,KAAK,MAAM,KAAK;AAAA,EACzB,SAAS,KAAK;AACZ,UAAM,IAAI,MAAM,oBAAoB,KAAK,IAAI,EAAE,OAAO,IAAI,CAAC;AAAA,EAC7D;AACF;AAEO,SAAS,eAAe,OAA8B;AAC3D,QAAM,UAAU,MAAM,KAAK;AAC3B,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAO;AAAA,EACT;AACA,MAAI;AACJ,MAAI;AACF,aAAS,UAAU,SAAS,YAAY;AAAA,EAC1C,QAAQ;AACN,WAAO;AAAA,EACT;AACA,QAAM,SAAS,oBAAoB,UAAU,MAAM;AACnD,MAAI,CAAC,OAAO,SAAS;AACnB,WAAO;AAAA,EACT;AACA,SAAO,OAAO;AAChB;AAEO,SAAS,kBAAkB,OAAwD;AACxF,MAAI,UAAU,UAAa,MAAM,KAAK,EAAE,WAAW,GAAG;AACpD,WAAO,CAAC;AAAA,EACV;AACA,QAAM,SAAS,UAAU,OAAO,MAAM;AACtC,QAAM,YAAY,cAAc,UAAU,MAAM;AAChD,MAAI,UAAU,SAAS;AACrB,WAAO,CAAC,UAAU,IAAI;AAAA,EACxB;AACA,QAAM,eAAe,iBAAiB,UAAU,MAAM;AACtD,MAAI,aAAa,SAAS;AACxB,WAAO,CAAC,aAAa,IAAI;AAAA,EAC3B;AACA,MAAI,MAAM,QAAQ,MAAM,GAAG;AACzB,WAAO,OAAO,IAAI,gBAAgB;AAAA,EACpC;AACA,QAAM,IAAI,MAAM,kEAAkE;AACpF;AAEA,SAAS,iBAAiB,OAAkC;AAC1D,QAAM,YAAY,cAAc,UAAU,KAAK;AAC/C,MAAI,UAAU,SAAS;AACrB,WAAO,UAAU;AAAA,EACnB;AACA,QAAM,eAAe,iBAAiB,UAAU,KAAK;AACrD,MAAI,aAAa,SAAS;AACxB,WAAO,aAAa;AAAA,EACtB;AACA,QAAM,IAAI,MAAM,kEAAkE;AACpF;;;AC5BA,SAAS,sBAAsB,MAAsB;AACnD,QAAM,aAAa,KAAK,KAAK,EAAE,QAAQ,cAAc,EAAE;AACvD,MAAI,WAAW,WAAW,GAAG;AAC3B,UAAM,IAAI,MAAM,2BAA2B;AAAA,EAC7C;AACA,MAAI,CAAC,WAAW,YAAY,EAAE,SAAS,OAAO,GAAG;AAC/C,UAAM,IAAI,MAAM,sCAAsC,IAAI,EAAE;AAAA,EAC9D;AACA,SAAO;AACT;AAEA,SAAS,YAAY,MAAwB,MAAsB;AACjE,MAAI,KAAK,SAAS,UAAa,KAAK,KAAK,WAAW,GAAG;AACrD,UAAM,IAAI,MAAM,iBAAiB,IAAI,sCAAsC;AAAA,EAC7E;AACA,SAAO,KAAK;AACd;AAEA,eAAe,yBACb,QACA,MACgI;AAChI,QAAM,QAAQ,YAAY,OAAO,QAAQ,QAAQ,OAAO,SAAS;AACjE,QAAM,OAAO,MAAM,mBAAmB,OAAO,QAAQ,QAAQ,MAAM,IAAI,IAAI;AAC3E,MAAI,SAAS,QAAQ,KAAK,UAAU;AAClC,UAAM,IAAI,MAAM,uBAAuB,IAAI,EAAE;AAAA,EAC/C;AACA,QAAM,QAAQ,MAAM,kBAAkB,OAAO,QAAQ,QAAQ,MAAM,IAAI,IAAI;AAC3E,SAAO,EAAE,OAAO,MAAM,SAAS,MAAM,IAAI,WAAW,MAAM,KAAK;AACjE;AAEA,eAAsB,qBACpB,QACA,MACA,OAC+B;AAC/B,QAAM,iBAAiB,sBAAsB,IAAI;AACjD,QAAM,QAAQ,YAAY,OAAO,QAAQ,QAAQ,OAAO,SAAS;AACjE,QAAM,QAAQ,MAAM,oBAAoB,KAAK;AAC7C,QAAM,OAAO,MAAM,mBAAmB,OAAO,QAAQ,QAAQ,MAAM,IAAI,gBAAgB,KAAK;AAC5F,SAAO,EAAE,SAAS,MAAM,IAAI,WAAW,MAAM,MAAM,MAAM,gBAAgB,KAAK;AAChF;AAEA,eAAsB,mBACpB,QACA,MACA,UAA+B,CAAC,GACL;AAC3B,QAAM,iBAAiB,sBAAsB,IAAI;AACjD,QAAM,aAAa,MAAM,yBAAyB,QAAQ,cAAc;AACxE,QAAM,WAAW,MAAM,kBAAkB,WAAW,OAAO,OAAO;AAClE,SAAO,EAAE,GAAG,YAAY,MAAM,gBAAgB,SAAS;AACzD;AAEA,eAAsB,yBACpB,QACA,MACA,WACA,MACA,aAC+B;AAC/B,QAAM,iBAAiB,sBAAsB,IAAI;AACjD,QAAM,aAAa,MAAM,yBAAyB,QAAQ,cAAc;AACxE,QAAM,WAAW,MAAM,mBAAmB,WAAW,OAAO,WAAW,MAAM,WAAW;AACxF,QAAM,OAAO,MAAM;AAAA,IACjB,OAAO,QAAQ;AAAA,IACf,WAAW;AAAA,IACX;AAAA,IACA,YAAY,WAAW,MAAM,cAAc;AAAA,IAC3C,SAAS;AAAA,EACX;AACA,SAAO,EAAE,GAAG,YAAY,MAAM,MAAM,gBAAgB,SAAS;AAC/D;AAEA,eAAsB,yBACpB,QACA,MACA,WACA,SACA,OAC+B;AAC/B,QAAM,iBAAiB,sBAAsB,IAAI;AACjD,QAAM,aAAa,MAAM,yBAAyB,QAAQ,cAAc;AACxE,QAAM,WAAW,MAAM,mBAAmB,WAAW,OAAO,WAAW,SAAS,KAAK;AACrF,QAAM,OAAO,MAAM;AAAA,IACjB,OAAO,QAAQ;AAAA,IACf,WAAW;AAAA,IACX;AAAA,IACA,YAAY,WAAW,MAAM,cAAc;AAAA,IAC3C,SAAS;AAAA,EACX;AACA,SAAO,EAAE,GAAG,YAAY,MAAM,MAAM,gBAAgB,SAAS;AAC/D;AAEA,eAAsB,uBACpB,QACA,MACA,WACA,SAC+B;AAC/B,QAAM,iBAAiB,sBAAsB,IAAI;AACjD,QAAM,aAAa,MAAM,yBAAyB,QAAQ,cAAc;AACxE,QAAM,WAAW,MAAM,iBAAiB,WAAW,OAAO,WAAW,OAAO;AAC5E,QAAM,OAAO,MAAM;AAAA,IACjB,OAAO,QAAQ;AAAA,IACf,WAAW;AAAA,IACX;AAAA,IACA,YAAY,WAAW,MAAM,cAAc;AAAA,IAC3C,SAAS;AAAA,EACX;AACA,SAAO,EAAE,GAAG,YAAY,MAAM,MAAM,gBAAgB,SAAS;AAC/D;","names":["process","process","process","chmod","mkdir","readFile","writeFile","dirname","isMissingFileError","readFile","mkdir","dirname","writeFile","chmod","process","process","process","asString"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@saptools/sharepoint-excel",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Create, read, and update SharePoint-hosted Excel workbooks through Microsoft Graph with safe local credential profiles",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -25,6 +25,15 @@
|
|
|
25
25
|
"engines": {
|
|
26
26
|
"node": ">=20.0.0"
|
|
27
27
|
},
|
|
28
|
+
"scripts": {
|
|
29
|
+
"build": "tsup",
|
|
30
|
+
"typecheck": "tsc --noEmit",
|
|
31
|
+
"lint": "eslint src tests --ignore-pattern tests/e2e/fixtures/fake-graph.mjs --max-warnings 0",
|
|
32
|
+
"test:unit": "vitest run --coverage",
|
|
33
|
+
"test:e2e": "playwright test",
|
|
34
|
+
"test:e2e:fake": "playwright test tests/e2e/sharepoint-excel.e2e.ts",
|
|
35
|
+
"check": "pnpm lint && pnpm typecheck && pnpm build && pnpm test:unit && pnpm test:e2e:fake"
|
|
36
|
+
},
|
|
28
37
|
"keywords": [
|
|
29
38
|
"sap",
|
|
30
39
|
"sharepoint",
|
|
@@ -57,14 +66,5 @@
|
|
|
57
66
|
"@vitest/coverage-v8": "^3.0.0",
|
|
58
67
|
"tsup": "^8.3.0",
|
|
59
68
|
"vitest": "^3.0.0"
|
|
60
|
-
},
|
|
61
|
-
"scripts": {
|
|
62
|
-
"build": "tsup",
|
|
63
|
-
"typecheck": "tsc --noEmit",
|
|
64
|
-
"lint": "eslint src tests --ignore-pattern tests/e2e/fixtures/fake-graph.mjs --max-warnings 0",
|
|
65
|
-
"test:unit": "vitest run --coverage",
|
|
66
|
-
"test:e2e": "playwright test",
|
|
67
|
-
"test:e2e:fake": "playwright test tests/e2e/sharepoint-excel.e2e.ts",
|
|
68
|
-
"check": "pnpm lint && pnpm typecheck && pnpm build && pnpm test:unit && pnpm test:e2e:fake"
|
|
69
69
|
}
|
|
70
|
-
}
|
|
70
|
+
}
|