@saptools/sharepoint-excel 0.1.2 โ 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -22
- package/dist/cli.js +27 -8
- package/dist/cli.js.map +1 -1
- package/dist/index.js +26 -7
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -35,7 +35,7 @@ Create `.xlsx` files, read workbook content, append records, update cells, and a
|
|
|
35
35
|
npm install -g @saptools/sharepoint-excel
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
-
Requires **Node.js >= 20**. The CLI binary is `
|
|
38
|
+
Requires **Node.js >= 20**. The CLI binary is `sharepoint-excel`.
|
|
39
39
|
|
|
40
40
|
---
|
|
41
41
|
|
|
@@ -43,7 +43,7 @@ Requires **Node.js >= 20**. The CLI binary is `saptools-sharepoint-excel`.
|
|
|
43
43
|
|
|
44
44
|
```bash
|
|
45
45
|
# 1. Store an app-only SharePoint profile
|
|
46
|
-
|
|
46
|
+
sharepoint-excel config set \
|
|
47
47
|
--tenant "11111111-1111-1111-1111-111111111111" \
|
|
48
48
|
--client-id "22222222-2222-2222-2222-222222222222" \
|
|
49
49
|
--client-secret "<your-client-secret>" \
|
|
@@ -51,30 +51,30 @@ saptools-sharepoint-excel config set \
|
|
|
51
51
|
--drive "Documents"
|
|
52
52
|
|
|
53
53
|
# 2. Prove auth and target resolution
|
|
54
|
-
|
|
54
|
+
sharepoint-excel test
|
|
55
55
|
|
|
56
56
|
# 3. Create a workbook without overwriting an existing file
|
|
57
|
-
|
|
57
|
+
sharepoint-excel create \
|
|
58
58
|
--path "Reports/orders.xlsx" \
|
|
59
59
|
--sheet "Orders" \
|
|
60
60
|
--headers "Name,Amount,Status" \
|
|
61
61
|
--rows '[{"Name":"Coffee","Amount":3,"Status":"open"}]'
|
|
62
62
|
|
|
63
63
|
# 4. Append one object by matching row 1 headers
|
|
64
|
-
|
|
64
|
+
sharepoint-excel append \
|
|
65
65
|
--path "Reports/orders.xlsx" \
|
|
66
66
|
--sheet "Orders" \
|
|
67
67
|
--record '{"Name":"Tea","Amount":8,"Status":"open"}'
|
|
68
68
|
|
|
69
69
|
# 5. Update one cell
|
|
70
|
-
|
|
70
|
+
sharepoint-excel update-cell \
|
|
71
71
|
--path "Reports/orders.xlsx" \
|
|
72
72
|
--sheet "Orders" \
|
|
73
73
|
--cell "C2" \
|
|
74
74
|
--value '"closed"'
|
|
75
75
|
|
|
76
76
|
# 6. Read workbook JSON
|
|
77
|
-
|
|
77
|
+
sharepoint-excel read --path "Reports/orders.xlsx" --json
|
|
78
78
|
```
|
|
79
79
|
|
|
80
80
|
For CI, every command can also read credentials from environment variables:
|
|
@@ -110,7 +110,7 @@ The CLI also accepts the shorter `SHAREPOINT_TENANT_ID`, `SHAREPOINT_CLIENT_ID`,
|
|
|
110
110
|
Store a reusable local profile.
|
|
111
111
|
|
|
112
112
|
```bash
|
|
113
|
-
|
|
113
|
+
sharepoint-excel config set \
|
|
114
114
|
--profile finance \
|
|
115
115
|
--tenant "$SHAREPOINT_EXCEL_TENANT_ID" \
|
|
116
116
|
--client-id "$SHAREPOINT_EXCEL_CLIENT_ID" \
|
|
@@ -129,7 +129,7 @@ For headless CI containers where an OS keyring is unavailable, an explicit plain
|
|
|
129
129
|
|
|
130
130
|
```bash
|
|
131
131
|
SAPTOOLS_SHAREPOINT_EXCEL_ALLOW_PLAINTEXT=1 \
|
|
132
|
-
|
|
132
|
+
sharepoint-excel config set --store file --allow-plaintext-secret ...
|
|
133
133
|
```
|
|
134
134
|
|
|
135
135
|
Use that only in controlled CI environments. The file is written with `0600` permissions under `~/.saptools/sharepoint-excel/secrets.json`.
|
|
@@ -137,8 +137,8 @@ Use that only in controlled CI environments. The file is written with `0600` per
|
|
|
137
137
|
### ๐ `config get`
|
|
138
138
|
|
|
139
139
|
```bash
|
|
140
|
-
|
|
141
|
-
|
|
140
|
+
sharepoint-excel config get --profile finance
|
|
141
|
+
sharepoint-excel config get --profile finance --json
|
|
142
142
|
```
|
|
143
143
|
|
|
144
144
|
Secrets are never printed.
|
|
@@ -146,7 +146,7 @@ Secrets are never printed.
|
|
|
146
146
|
### ๐งน `config remove`
|
|
147
147
|
|
|
148
148
|
```bash
|
|
149
|
-
|
|
149
|
+
sharepoint-excel config remove --profile finance
|
|
150
150
|
```
|
|
151
151
|
|
|
152
152
|
Removes both profile metadata and the stored secret.
|
|
@@ -156,15 +156,15 @@ Removes both profile metadata and the stored secret.
|
|
|
156
156
|
Authenticate, resolve the site, and list document libraries.
|
|
157
157
|
|
|
158
158
|
```bash
|
|
159
|
-
|
|
160
|
-
|
|
159
|
+
sharepoint-excel test
|
|
160
|
+
sharepoint-excel test --json
|
|
161
161
|
```
|
|
162
162
|
|
|
163
163
|
### ๐๏ธ `drives`
|
|
164
164
|
|
|
165
165
|
```bash
|
|
166
|
-
|
|
167
|
-
|
|
166
|
+
sharepoint-excel drives
|
|
167
|
+
sharepoint-excel drives --json
|
|
168
168
|
```
|
|
169
169
|
|
|
170
170
|
Use this when you are unsure whether the document library is named `Documents`, `Shared Documents`, or something custom.
|
|
@@ -172,7 +172,7 @@ Use this when you are unsure whether the document library is named `Documents`,
|
|
|
172
172
|
### ๐ `create`
|
|
173
173
|
|
|
174
174
|
```bash
|
|
175
|
-
|
|
175
|
+
sharepoint-excel create \
|
|
176
176
|
--path "Reports/orders.xlsx" \
|
|
177
177
|
--sheet "Orders" \
|
|
178
178
|
--headers "Name,Amount,Status" \
|
|
@@ -185,14 +185,14 @@ saptools-sharepoint-excel create \
|
|
|
185
185
|
### ๐ `read`
|
|
186
186
|
|
|
187
187
|
```bash
|
|
188
|
-
|
|
189
|
-
|
|
188
|
+
sharepoint-excel read --path "Reports/orders.xlsx"
|
|
189
|
+
sharepoint-excel read --path "Reports/orders.xlsx" --sheet "Orders" --range "A1:C10" --json
|
|
190
190
|
```
|
|
191
191
|
|
|
192
192
|
### โ `append`
|
|
193
193
|
|
|
194
194
|
```bash
|
|
195
|
-
|
|
195
|
+
sharepoint-excel append \
|
|
196
196
|
--path "Reports/orders.xlsx" \
|
|
197
197
|
--sheet "Orders" \
|
|
198
198
|
--record '{"Name":"Tea","Amount":8,"Status":"open"}'
|
|
@@ -203,7 +203,7 @@ Objects are mapped by the first row's headers by default. Use `--no-match-header
|
|
|
203
203
|
### ๐ฏ `update-cell`
|
|
204
204
|
|
|
205
205
|
```bash
|
|
206
|
-
|
|
206
|
+
sharepoint-excel update-cell \
|
|
207
207
|
--path "Reports/orders.xlsx" \
|
|
208
208
|
--sheet "Orders" \
|
|
209
209
|
--cell "B2" \
|
|
@@ -215,7 +215,7 @@ saptools-sharepoint-excel update-cell \
|
|
|
215
215
|
### ๐ `add-sheet`
|
|
216
216
|
|
|
217
217
|
```bash
|
|
218
|
-
|
|
218
|
+
sharepoint-excel add-sheet \
|
|
219
219
|
--path "Reports/orders.xlsx" \
|
|
220
220
|
--sheet "Audit" \
|
|
221
221
|
--headers "At,Action,Actor"
|
package/dist/cli.js
CHANGED
|
@@ -172,7 +172,8 @@ async function redactProfile(profile, vault) {
|
|
|
172
172
|
import { chmod as chmod2, mkdir as mkdir2, readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
|
|
173
173
|
import { dirname as dirname2 } from "path";
|
|
174
174
|
import { Entry } from "@napi-rs/keyring";
|
|
175
|
-
var SERVICE_NAME = "
|
|
175
|
+
var SERVICE_NAME = "sharepoint-excel";
|
|
176
|
+
var LEGACY_SERVICE_NAME = `saptools-${SERVICE_NAME}`;
|
|
176
177
|
var SECRET_FILE_MODE = 384;
|
|
177
178
|
var EMPTY_SECRET_FILE = { version: 1, entries: {} };
|
|
178
179
|
function isMissingFileError2(err) {
|
|
@@ -208,11 +209,29 @@ async function writeSecretFile(path, value) {
|
|
|
208
209
|
});
|
|
209
210
|
await chmod2(path, SECRET_FILE_MODE);
|
|
210
211
|
}
|
|
212
|
+
function getKeyringPassword(serviceName, profileName) {
|
|
213
|
+
const password = new Entry(serviceName, profileName).getPassword();
|
|
214
|
+
return password === null || password.length === 0 ? void 0 : password;
|
|
215
|
+
}
|
|
216
|
+
function deleteKeyringPassword(serviceName, profileName) {
|
|
217
|
+
try {
|
|
218
|
+
new Entry(serviceName, profileName).deletePassword();
|
|
219
|
+
} catch (err) {
|
|
220
|
+
if (err instanceof Error && /not found|no entry|missing/i.test(err.message)) {
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
throw err instanceof Error ? err : new Error(String(err));
|
|
224
|
+
}
|
|
225
|
+
}
|
|
211
226
|
function createKeyringSecretVault(serviceName = SERVICE_NAME) {
|
|
227
|
+
const legacyServiceName = serviceName === SERVICE_NAME ? LEGACY_SERVICE_NAME : void 0;
|
|
212
228
|
return {
|
|
213
229
|
getSecret(profileName) {
|
|
214
|
-
const password =
|
|
215
|
-
|
|
230
|
+
const password = getKeyringPassword(serviceName, profileName);
|
|
231
|
+
if (password !== void 0 || legacyServiceName === void 0) {
|
|
232
|
+
return Promise.resolve(password);
|
|
233
|
+
}
|
|
234
|
+
return Promise.resolve(getKeyringPassword(legacyServiceName, profileName));
|
|
216
235
|
},
|
|
217
236
|
setSecret(profileName, secret) {
|
|
218
237
|
new Entry(serviceName, profileName).setPassword(secret);
|
|
@@ -220,11 +239,11 @@ function createKeyringSecretVault(serviceName = SERVICE_NAME) {
|
|
|
220
239
|
},
|
|
221
240
|
deleteSecret(profileName) {
|
|
222
241
|
try {
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
return Promise.resolve();
|
|
242
|
+
deleteKeyringPassword(serviceName, profileName);
|
|
243
|
+
if (legacyServiceName !== void 0) {
|
|
244
|
+
deleteKeyringPassword(legacyServiceName, profileName);
|
|
227
245
|
}
|
|
246
|
+
} catch (err) {
|
|
228
247
|
return Promise.reject(err instanceof Error ? err : new Error(String(err)));
|
|
229
248
|
}
|
|
230
249
|
return Promise.resolve();
|
|
@@ -1352,7 +1371,7 @@ function registerCommands(program) {
|
|
|
1352
1371
|
// src/cli/index.ts
|
|
1353
1372
|
async function main(argv) {
|
|
1354
1373
|
const program = new Command();
|
|
1355
|
-
program.name("
|
|
1374
|
+
program.name("sharepoint-excel").description("Create, read, and update SharePoint-hosted Excel workbooks");
|
|
1356
1375
|
registerCommands(program);
|
|
1357
1376
|
await program.parseAsync([...argv]);
|
|
1358
1377
|
}
|