@dropthis/cli 0.35.0 → 0.37.0
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 +6 -4
- package/dist/cli.cjs +352 -105
- package/dist/cli.cjs.map +1 -1
- package/node_modules/@dropthis/node/dist/edge.cjs +34 -1
- package/node_modules/@dropthis/node/dist/edge.cjs.map +1 -1
- package/node_modules/@dropthis/node/dist/edge.d.cts +1 -1
- package/node_modules/@dropthis/node/dist/edge.d.ts +1 -1
- package/node_modules/@dropthis/node/dist/edge.mjs +34 -1
- package/node_modules/@dropthis/node/dist/edge.mjs.map +1 -1
- package/node_modules/@dropthis/node/dist/index.cjs +34 -1
- package/node_modules/@dropthis/node/dist/index.cjs.map +1 -1
- package/node_modules/@dropthis/node/dist/index.d.cts +2 -2
- package/node_modules/@dropthis/node/dist/index.d.ts +2 -2
- package/node_modules/@dropthis/node/dist/index.mjs +34 -1
- package/node_modules/@dropthis/node/dist/index.mjs.map +1 -1
- package/node_modules/@dropthis/node/dist/{workspaces-Cq705UM6.d.cts → workspaces-CfwVerjp.d.cts} +45 -5
- package/node_modules/@dropthis/node/dist/{workspaces-Cq705UM6.d.ts → workspaces-CfwVerjp.d.ts} +45 -5
- package/node_modules/@dropthis/node/package.json +1 -1
- package/package.json +2 -2
package/dist/cli.cjs
CHANGED
|
@@ -154,6 +154,8 @@ var init_inline_auth = __esm({
|
|
|
154
154
|
// src/cli.ts
|
|
155
155
|
var cli_exports = {};
|
|
156
156
|
__export(cli_exports, {
|
|
157
|
+
wantsInsecureStore: () => wantsInsecureStore,
|
|
158
|
+
writeCredentialStorageError: () => writeCredentialStorageError,
|
|
157
159
|
writeUsageErrorEnvelope: () => writeUsageErrorEnvelope
|
|
158
160
|
});
|
|
159
161
|
module.exports = __toCommonJS(cli_exports);
|
|
@@ -178,8 +180,11 @@ var UPLOAD_NEXT_ACTIONS = {
|
|
|
178
180
|
too_many_active_uploads: "Cancel unused uploads or wait for expired uploads to be cleaned.",
|
|
179
181
|
upload_not_complete: "Complete the upload session before publishing."
|
|
180
182
|
};
|
|
183
|
+
function isCiEnv(env) {
|
|
184
|
+
return Boolean(env.CI);
|
|
185
|
+
}
|
|
181
186
|
function createOutput(input) {
|
|
182
|
-
const json = input.json === true || input.quiet === true || input.stdoutIsTTY === false || input.env
|
|
187
|
+
const json = input.json === true || input.quiet === true || input.stdoutIsTTY === false || isCiEnv(input.env);
|
|
183
188
|
return { mode: json ? "json" : "human", quiet: input.quiet === true };
|
|
184
189
|
}
|
|
185
190
|
function errorEnvelope(code, message, nextAction) {
|
|
@@ -255,7 +260,10 @@ function cliNextAction(error2) {
|
|
|
255
260
|
return `This account belongs to more than one workspace \u2014 pick one. Switch it for every later command with: dropthis workspace use ${example} \u2014 or target just this one with: --workspace ${example}.${list}`;
|
|
256
261
|
}
|
|
257
262
|
if (error2.code === "network_error") {
|
|
258
|
-
return "Could not reach the dropthis API \u2014 check your network or DROPTHIS_API_URL.";
|
|
263
|
+
return "Could not reach the dropthis API \u2014 check your network or DROPTHIS_API_URL. Run `dropthis doctor --online` to diagnose.";
|
|
264
|
+
}
|
|
265
|
+
if (error2.code === "insufficient_scope") {
|
|
266
|
+
return "This key lacks the required capability scope. Mint a team-scoped key: dropthis login request --email <email>, then dropthis login verify --email <email> --otp <code> --scope team.";
|
|
259
267
|
}
|
|
260
268
|
if (error2.code === "workspace_pinned") {
|
|
261
269
|
return "Service keys are pinned to one workspace. To switch workspaces, use a delegated login (run: dropthis login) instead of a service key.";
|
|
@@ -285,10 +293,10 @@ function cliNextAction(error2) {
|
|
|
285
293
|
return "Check the drop id or slug and retry; list your drops with dropthis list.";
|
|
286
294
|
}
|
|
287
295
|
if (error2.code === "invalid_api_key") {
|
|
288
|
-
return "API key is invalid or revoked. Run dropthis login to re-authenticate, or set a valid DROPTHIS_API_KEY.";
|
|
296
|
+
return "API key is invalid or revoked. Run dropthis login to re-authenticate, or set a valid DROPTHIS_API_KEY. Run `dropthis doctor --online` to diagnose.";
|
|
289
297
|
}
|
|
290
298
|
if (error2.statusCode === 401 || error2.code === "missing_api_key") {
|
|
291
|
-
return "Authenticate with dropthis login or set DROPTHIS_API_KEY.";
|
|
299
|
+
return "Authenticate with dropthis login or set DROPTHIS_API_KEY. Run `dropthis doctor --online` to diagnose.";
|
|
292
300
|
}
|
|
293
301
|
if (error2.statusCode === 413 || error2.code === "quota_exceeded") {
|
|
294
302
|
return "Reduce the upload size or upgrade the account limit.";
|
|
@@ -299,6 +307,7 @@ function exitCodeFor(code) {
|
|
|
299
307
|
if (code === "usage_error") return 2;
|
|
300
308
|
if (code === "invalid_usage") return 2;
|
|
301
309
|
if (code === "auth_error") return 3;
|
|
310
|
+
if (code === "credential_storage_unavailable") return 3;
|
|
302
311
|
if (code === "local_input_error") return 4;
|
|
303
312
|
if (code === "network_error") return 5;
|
|
304
313
|
if (code === "verify_pending") return 6;
|
|
@@ -351,6 +360,9 @@ function maskKey(apiKey) {
|
|
|
351
360
|
return apiKey.length <= 8 ? "sk_..." : `${apiKey.slice(0, 3)}...${apiKey.slice(-4)}`;
|
|
352
361
|
}
|
|
353
362
|
|
|
363
|
+
// src/commands/account.ts
|
|
364
|
+
var prompts = __toESM(require("@clack/prompts"), 1);
|
|
365
|
+
|
|
354
366
|
// src/fmt.ts
|
|
355
367
|
var import_picocolors2 = __toESM(require("picocolors"), 1);
|
|
356
368
|
|
|
@@ -404,8 +416,8 @@ function writeResult(deps, link, verb, data) {
|
|
|
404
416
|
`
|
|
405
417
|
);
|
|
406
418
|
} else {
|
|
407
|
-
const
|
|
408
|
-
if (
|
|
419
|
+
const text3 = typeof w.detail === "string" ? w.detail : typeof w.message === "string" ? w.message : typeof w.code === "string" ? w.code : void 0;
|
|
420
|
+
if (text3) deps.stderr(`${hint(text3)}
|
|
409
421
|
`);
|
|
410
422
|
}
|
|
411
423
|
}
|
|
@@ -498,6 +510,10 @@ function writeApiError(deps, details) {
|
|
|
498
510
|
`
|
|
499
511
|
);
|
|
500
512
|
}
|
|
513
|
+
if (details.upgradeUrl) {
|
|
514
|
+
deps.stderr(`${hint(`Upgrade: ${details.upgradeUrl}`)}
|
|
515
|
+
`);
|
|
516
|
+
}
|
|
501
517
|
}
|
|
502
518
|
const nextAction = nextActionForApiError(details, "human");
|
|
503
519
|
if (nextAction) deps.stderr(`${hint(nextAction)}
|
|
@@ -622,15 +638,16 @@ async function runAccountUpdate(input, deps) {
|
|
|
622
638
|
return { exitCode: 0 };
|
|
623
639
|
}
|
|
624
640
|
async function runAccountDelete(input, deps) {
|
|
625
|
-
if (!input.yes && input.interactive
|
|
641
|
+
if (!input.yes && input.interactive !== true) {
|
|
626
642
|
return writeError(
|
|
627
643
|
deps,
|
|
628
644
|
"invalid_usage",
|
|
629
645
|
"Pass --yes to delete the account in non-interactive mode."
|
|
630
646
|
);
|
|
631
647
|
}
|
|
648
|
+
let credential;
|
|
632
649
|
try {
|
|
633
|
-
await requireCredential({
|
|
650
|
+
credential = await requireCredential({
|
|
634
651
|
...deps.apiKey ? { apiKey: deps.apiKey } : {},
|
|
635
652
|
env: deps.env,
|
|
636
653
|
store: deps.store
|
|
@@ -638,6 +655,26 @@ async function runAccountDelete(input, deps) {
|
|
|
638
655
|
} catch {
|
|
639
656
|
return writeAuthError(deps);
|
|
640
657
|
}
|
|
658
|
+
if (!input.yes) {
|
|
659
|
+
if (!credential.email) {
|
|
660
|
+
return writeError(
|
|
661
|
+
deps,
|
|
662
|
+
"invalid_usage",
|
|
663
|
+
"No stored account email to confirm against.",
|
|
664
|
+
"Re-run with --yes to confirm: dropthis account delete --yes"
|
|
665
|
+
);
|
|
666
|
+
}
|
|
667
|
+
const typed = await prompts.text({
|
|
668
|
+
message: `This permanently deletes your account and all its drops. Type ${credential.email} to confirm:`
|
|
669
|
+
});
|
|
670
|
+
if (prompts.isCancel(typed) || typed !== credential.email) {
|
|
671
|
+
deps.stderr(
|
|
672
|
+
`${error("Account deletion cancelled \u2014 confirmation did not match.")}
|
|
673
|
+
`
|
|
674
|
+
);
|
|
675
|
+
return { exitCode: 1 };
|
|
676
|
+
}
|
|
677
|
+
}
|
|
641
678
|
const result = await deps.client.account.delete();
|
|
642
679
|
if (result.error) return writeApiError(deps, result.error);
|
|
643
680
|
writeHumanOrJson(deps, success("Account deleted"), {
|
|
@@ -647,8 +684,38 @@ async function runAccountDelete(input, deps) {
|
|
|
647
684
|
return { exitCode: 0 };
|
|
648
685
|
}
|
|
649
686
|
|
|
687
|
+
// src/commands/analytics.ts
|
|
688
|
+
async function runAnalytics(dropId, _input, deps) {
|
|
689
|
+
try {
|
|
690
|
+
await requireCredential({
|
|
691
|
+
...deps.apiKey ? { apiKey: deps.apiKey } : {},
|
|
692
|
+
env: deps.env,
|
|
693
|
+
store: deps.store
|
|
694
|
+
});
|
|
695
|
+
} catch {
|
|
696
|
+
return writeAuthError(deps);
|
|
697
|
+
}
|
|
698
|
+
const result = await deps.client.drops.analytics(dropId);
|
|
699
|
+
if (result.error) {
|
|
700
|
+
return writeApiError(deps, result.error);
|
|
701
|
+
}
|
|
702
|
+
const data = result.data;
|
|
703
|
+
const pairs = [];
|
|
704
|
+
if (data.views !== void 0) pairs.push(["Views", String(data.views)]);
|
|
705
|
+
if (data.truncated) pairs.push(["Truncated", "yes (lower bound)"]);
|
|
706
|
+
pushBreakdown(pairs, "Top country", data.byCountry);
|
|
707
|
+
pushBreakdown(pairs, "Top referer", data.byReferer);
|
|
708
|
+
writeKv(deps, pairs, { ok: true, analytics: result.data });
|
|
709
|
+
return { exitCode: 0 };
|
|
710
|
+
}
|
|
711
|
+
function pushBreakdown(pairs, label, value) {
|
|
712
|
+
if (!Array.isArray(value) || value.length === 0) return;
|
|
713
|
+
const top = value[0];
|
|
714
|
+
pairs.push([label, `${top.key ?? "?"} (${top.views ?? 0})`]);
|
|
715
|
+
}
|
|
716
|
+
|
|
650
717
|
// src/commands/api-keys.ts
|
|
651
|
-
var
|
|
718
|
+
var prompts2 = __toESM(require("@clack/prompts"), 1);
|
|
652
719
|
|
|
653
720
|
// src/types.ts
|
|
654
721
|
function extractPagination(data) {
|
|
@@ -774,10 +841,10 @@ async function runApiKeysDelete(keyId, input, deps) {
|
|
|
774
841
|
);
|
|
775
842
|
}
|
|
776
843
|
if (!input.yes && input.interactive !== false) {
|
|
777
|
-
const confirmed = await
|
|
844
|
+
const confirmed = await prompts2.confirm({
|
|
778
845
|
message: `Delete API key ${keyId}?`
|
|
779
846
|
});
|
|
780
|
-
if (
|
|
847
|
+
if (prompts2.isCancel(confirmed) || !confirmed) {
|
|
781
848
|
return { exitCode: 0 };
|
|
782
849
|
}
|
|
783
850
|
}
|
|
@@ -1131,12 +1198,40 @@ async function runDeploymentsGet(dropId, deploymentId, _input, deps) {
|
|
|
1131
1198
|
writeKv(deps, pairs, { ok: true, deployment: result.data });
|
|
1132
1199
|
return { exitCode: 0 };
|
|
1133
1200
|
}
|
|
1201
|
+
async function runDeploymentsRestore(dropId, deploymentId, _input, deps) {
|
|
1202
|
+
try {
|
|
1203
|
+
await requireCredential({
|
|
1204
|
+
...deps.apiKey ? { apiKey: deps.apiKey } : {},
|
|
1205
|
+
env: deps.env,
|
|
1206
|
+
store: deps.store
|
|
1207
|
+
});
|
|
1208
|
+
} catch {
|
|
1209
|
+
return writeAuthError(deps);
|
|
1210
|
+
}
|
|
1211
|
+
const result = await deps.client.deployments.restore(dropId, deploymentId);
|
|
1212
|
+
if (result.error) {
|
|
1213
|
+
return writeApiError(deps, result.error);
|
|
1214
|
+
}
|
|
1215
|
+
const data = result.data;
|
|
1216
|
+
if (deps.outputMode === "human") {
|
|
1217
|
+
deps.stdout(`${success(`Restored to deployment ${deploymentId}.`)}
|
|
1218
|
+
`);
|
|
1219
|
+
}
|
|
1220
|
+
const pairs = [];
|
|
1221
|
+
if (data.id) pairs.push(["ID", String(data.id)]);
|
|
1222
|
+
if (data.url) pairs.push(["URL", url(String(data.url))]);
|
|
1223
|
+
if (data.revision !== void 0)
|
|
1224
|
+
pairs.push(["Revision", String(data.revision)]);
|
|
1225
|
+
writeKv(deps, pairs, { ok: true, drop: result.data });
|
|
1226
|
+
return { exitCode: 0 };
|
|
1227
|
+
}
|
|
1134
1228
|
function spreadData(data) {
|
|
1135
1229
|
return data && typeof data === "object" ? data : { data };
|
|
1136
1230
|
}
|
|
1137
1231
|
|
|
1138
1232
|
// src/version.ts
|
|
1139
|
-
var CLI_VERSION = true ? "0.
|
|
1233
|
+
var CLI_VERSION = true ? "0.37.0" : "0.0.0-dev";
|
|
1234
|
+
var SDK_VERSION = true ? "0.33.0" : "0.0.0-dev";
|
|
1140
1235
|
|
|
1141
1236
|
// src/commands/doctor.ts
|
|
1142
1237
|
async function onlineChecks(deps, hasCredential) {
|
|
@@ -1213,39 +1308,35 @@ async function runDoctor(input, deps) {
|
|
|
1213
1308
|
});
|
|
1214
1309
|
const authSource = credential?.source ?? "missing";
|
|
1215
1310
|
const storageBackend = stored?.storage ?? "none";
|
|
1311
|
+
const scopes = credential?.scopes ?? [];
|
|
1216
1312
|
const pairs = [
|
|
1217
1313
|
["Version", CLI_VERSION],
|
|
1314
|
+
["SDK", SDK_VERSION],
|
|
1218
1315
|
["Auth", authSource],
|
|
1219
1316
|
["Storage", storageBackend]
|
|
1220
1317
|
];
|
|
1318
|
+
if (scopes.length > 0) pairs.push(["Scopes", scopes.join(", ")]);
|
|
1319
|
+
const baseEnvelope = {
|
|
1320
|
+
version: CLI_VERSION,
|
|
1321
|
+
sdk_version: SDK_VERSION,
|
|
1322
|
+
auth: { source: authSource },
|
|
1323
|
+
storage: { backend: storageBackend },
|
|
1324
|
+
...scopes.length > 0 ? { scopes } : {}
|
|
1325
|
+
};
|
|
1221
1326
|
if (!input.online) {
|
|
1222
|
-
writeKv(deps, pairs, {
|
|
1223
|
-
ok: true,
|
|
1224
|
-
version: CLI_VERSION,
|
|
1225
|
-
auth: { source: authSource },
|
|
1226
|
-
storage: { backend: storageBackend }
|
|
1227
|
-
});
|
|
1327
|
+
writeKv(deps, pairs, { ok: true, ...baseEnvelope });
|
|
1228
1328
|
return { exitCode: 0 };
|
|
1229
1329
|
}
|
|
1230
|
-
const { checks, exitCode } = await onlineChecks(
|
|
1231
|
-
deps,
|
|
1232
|
-
credential !== void 0
|
|
1233
|
-
);
|
|
1330
|
+
const { checks, exitCode } = await onlineChecks(deps, credential !== null);
|
|
1234
1331
|
for (const c of checks) {
|
|
1235
1332
|
pairs.push([c.name, `${c.status} \u2014 ${c.detail}`]);
|
|
1236
1333
|
}
|
|
1237
|
-
writeKv(deps, pairs, {
|
|
1238
|
-
ok: exitCode === 0,
|
|
1239
|
-
version: CLI_VERSION,
|
|
1240
|
-
auth: { source: authSource },
|
|
1241
|
-
storage: { backend: storageBackend },
|
|
1242
|
-
checks
|
|
1243
|
-
});
|
|
1334
|
+
writeKv(deps, pairs, { ok: exitCode === 0, ...baseEnvelope, checks });
|
|
1244
1335
|
return { exitCode };
|
|
1245
1336
|
}
|
|
1246
1337
|
|
|
1247
1338
|
// src/commands/domains.ts
|
|
1248
|
-
var
|
|
1339
|
+
var prompts3 = __toESM(require("@clack/prompts"), 1);
|
|
1249
1340
|
var import_picocolors3 = __toESM(require("picocolors"), 1);
|
|
1250
1341
|
function formatDnsTable(records) {
|
|
1251
1342
|
if (records.length === 0) return "";
|
|
@@ -1544,7 +1635,7 @@ async function runDomainsVerify(idOrHostname, input, deps, sleep = defaultSleep)
|
|
|
1544
1635
|
if (deps.outputMode === "json" && domain.dns.length > 0) {
|
|
1545
1636
|
const elapsed = Math.round(elapsedMs / 1e3);
|
|
1546
1637
|
deps.stderr(
|
|
1547
|
-
`${JSON.stringify({ ok:
|
|
1638
|
+
`${JSON.stringify({ ok: true, pending: true, status: domain.status, elapsed })}
|
|
1548
1639
|
`
|
|
1549
1640
|
);
|
|
1550
1641
|
}
|
|
@@ -1596,10 +1687,10 @@ async function runDomainsRemove(idOrHostname, input, deps) {
|
|
|
1596
1687
|
);
|
|
1597
1688
|
}
|
|
1598
1689
|
if (!input.yes && input.interactive !== false) {
|
|
1599
|
-
const confirmed = await
|
|
1690
|
+
const confirmed = await prompts3.confirm({
|
|
1600
1691
|
message: `Remove ${idOrHostname}? This removes the domain and unmounts its drops.`
|
|
1601
1692
|
});
|
|
1602
|
-
if (
|
|
1693
|
+
if (prompts3.isCancel(confirmed) || !confirmed) {
|
|
1603
1694
|
return { exitCode: 0 };
|
|
1604
1695
|
}
|
|
1605
1696
|
}
|
|
@@ -1635,7 +1726,7 @@ async function runDomainsRemove(idOrHostname, input, deps) {
|
|
|
1635
1726
|
}
|
|
1636
1727
|
|
|
1637
1728
|
// src/commands/drops.ts
|
|
1638
|
-
var
|
|
1729
|
+
var prompts4 = __toESM(require("@clack/prompts"), 1);
|
|
1639
1730
|
var import_picocolors4 = __toESM(require("picocolors"), 1);
|
|
1640
1731
|
async function resolveDropTarget(target, deps) {
|
|
1641
1732
|
if (target.startsWith("drop_")) return { ok: true, dropId: target };
|
|
@@ -1805,10 +1896,10 @@ async function runDropsDelete(target, input, deps) {
|
|
|
1805
1896
|
writeResolvedLine(deps, resolved);
|
|
1806
1897
|
const dropId = resolved.dropId;
|
|
1807
1898
|
if (!input.yes && input.interactive !== false) {
|
|
1808
|
-
const confirmed = await
|
|
1899
|
+
const confirmed = await prompts4.confirm({
|
|
1809
1900
|
message: `Delete ${dropId}${dropId === target ? "" : ` (${target})`}?`
|
|
1810
1901
|
});
|
|
1811
|
-
if (
|
|
1902
|
+
if (prompts4.isCancel(confirmed) || !confirmed) {
|
|
1812
1903
|
return { exitCode: 0 };
|
|
1813
1904
|
}
|
|
1814
1905
|
}
|
|
@@ -1898,31 +1989,31 @@ async function runInvitationsAcceptById(input, deps) {
|
|
|
1898
1989
|
}
|
|
1899
1990
|
|
|
1900
1991
|
// src/commands/login.ts
|
|
1901
|
-
var
|
|
1992
|
+
var prompts5 = __toESM(require("@clack/prompts"), 1);
|
|
1902
1993
|
async function runLoginInteractive(deps) {
|
|
1903
|
-
|
|
1904
|
-
const email = await
|
|
1994
|
+
prompts5.intro("dropthis login");
|
|
1995
|
+
const email = await prompts5.text({
|
|
1905
1996
|
message: "Email address",
|
|
1906
1997
|
validate: (v) => v?.includes("@") ? void 0 : "Enter a valid email"
|
|
1907
1998
|
});
|
|
1908
|
-
if (
|
|
1909
|
-
|
|
1999
|
+
if (prompts5.isCancel(email)) {
|
|
2000
|
+
prompts5.cancel("Login cancelled.");
|
|
1910
2001
|
return { exitCode: 0 };
|
|
1911
2002
|
}
|
|
1912
2003
|
const requestResult = await deps.client.auth.requestEmailOtp({ email });
|
|
1913
2004
|
if (requestResult.error) {
|
|
1914
|
-
|
|
2005
|
+
prompts5.cancel(requestResult.error.message);
|
|
1915
2006
|
return { exitCode: exitCodeFor("api_error") };
|
|
1916
2007
|
}
|
|
1917
2008
|
const maxAttempts = 3;
|
|
1918
2009
|
let session;
|
|
1919
2010
|
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
1920
|
-
const otp = await
|
|
2011
|
+
const otp = await prompts5.text({
|
|
1921
2012
|
message: attempt === 1 ? "Paste the code from your email" : "Try again \u2014 paste the code from your email",
|
|
1922
2013
|
validate: (v) => v && v.length >= 4 && v.length <= 8 ? void 0 : "Code must be 4\u20138 characters."
|
|
1923
2014
|
});
|
|
1924
|
-
if (
|
|
1925
|
-
|
|
2015
|
+
if (prompts5.isCancel(otp)) {
|
|
2016
|
+
prompts5.cancel("Login cancelled.");
|
|
1926
2017
|
return { exitCode: 0 };
|
|
1927
2018
|
}
|
|
1928
2019
|
const result = await deps.client.auth.verifyEmailOtp({
|
|
@@ -1936,21 +2027,21 @@ async function runLoginInteractive(deps) {
|
|
|
1936
2027
|
if (result.error.code === "otp_expired" && attempt < maxAttempts) {
|
|
1937
2028
|
const resend = await deps.client.auth.requestEmailOtp({ email });
|
|
1938
2029
|
if (resend.error) {
|
|
1939
|
-
|
|
2030
|
+
prompts5.cancel(resend.error.message);
|
|
1940
2031
|
return { exitCode: exitCodeFor("api_error") };
|
|
1941
2032
|
}
|
|
1942
|
-
|
|
2033
|
+
prompts5.log.info("That code expired \u2014 we sent a new one.");
|
|
1943
2034
|
continue;
|
|
1944
2035
|
}
|
|
1945
2036
|
if (attempt < maxAttempts) {
|
|
1946
|
-
|
|
2037
|
+
prompts5.log.warning(result.error.message);
|
|
1947
2038
|
} else {
|
|
1948
|
-
|
|
2039
|
+
prompts5.cancel(result.error.message);
|
|
1949
2040
|
return { exitCode: exitCodeFor("api_error") };
|
|
1950
2041
|
}
|
|
1951
2042
|
}
|
|
1952
2043
|
if (!session) {
|
|
1953
|
-
|
|
2044
|
+
prompts5.cancel("Login failed.");
|
|
1954
2045
|
return { exitCode: exitCodeFor("api_error") };
|
|
1955
2046
|
}
|
|
1956
2047
|
const authedClient = deps.createClient(session.data.token);
|
|
@@ -1959,7 +2050,7 @@ async function runLoginInteractive(deps) {
|
|
|
1959
2050
|
type: "delegated"
|
|
1960
2051
|
});
|
|
1961
2052
|
if (apiKey.error) {
|
|
1962
|
-
|
|
2053
|
+
prompts5.cancel(apiKey.error.message);
|
|
1963
2054
|
return { exitCode: exitCodeFor("api_error") };
|
|
1964
2055
|
}
|
|
1965
2056
|
await deps.store.save({
|
|
@@ -1971,7 +2062,7 @@ async function runLoginInteractive(deps) {
|
|
|
1971
2062
|
...apiKey.data.scopes ? { scopes: apiKey.data.scopes } : {},
|
|
1972
2063
|
storage: "secure"
|
|
1973
2064
|
});
|
|
1974
|
-
|
|
2065
|
+
prompts5.outro("Logged in successfully.");
|
|
1975
2066
|
return { exitCode: 0 };
|
|
1976
2067
|
}
|
|
1977
2068
|
async function runLoginRequest(input, deps) {
|
|
@@ -2025,7 +2116,10 @@ async function runLoginVerify(input, deps) {
|
|
|
2025
2116
|
account_id: apiKey.data.accountId ?? session.data.accountId,
|
|
2026
2117
|
key_id: apiKey.data.id,
|
|
2027
2118
|
key_last4: apiKey.data.keyLast4,
|
|
2028
|
-
is_new_account: apiKey.data.isNewAccount ?? session.data.isNewAccount
|
|
2119
|
+
is_new_account: apiKey.data.isNewAccount ?? session.data.isNewAccount,
|
|
2120
|
+
// Echo the resolved capability scopes the server granted, so a scoped mint
|
|
2121
|
+
// visibly advertises what the new key can do (ADR 0068).
|
|
2122
|
+
...apiKey.data.scopes?.length ? { scopes: apiKey.data.scopes } : {}
|
|
2029
2123
|
});
|
|
2030
2124
|
return { exitCode: 0 };
|
|
2031
2125
|
}
|
|
@@ -2047,7 +2141,7 @@ async function runLogout(input, deps) {
|
|
|
2047
2141
|
}
|
|
2048
2142
|
|
|
2049
2143
|
// src/commands/members.ts
|
|
2050
|
-
var
|
|
2144
|
+
var prompts6 = __toESM(require("@clack/prompts"), 1);
|
|
2051
2145
|
async function runMembersList(workspaceId, _input, deps) {
|
|
2052
2146
|
try {
|
|
2053
2147
|
await requireCredential({
|
|
@@ -2129,10 +2223,10 @@ async function runMembersRemove(workspaceId, accountId, input, deps) {
|
|
|
2129
2223
|
);
|
|
2130
2224
|
}
|
|
2131
2225
|
if (!input.yes && input.interactive !== false) {
|
|
2132
|
-
const confirmed = await
|
|
2226
|
+
const confirmed = await prompts6.confirm({
|
|
2133
2227
|
message: `Remove ${accountId} from workspace ${workspaceId}?`
|
|
2134
2228
|
});
|
|
2135
|
-
if (
|
|
2229
|
+
if (prompts6.isCancel(confirmed) || !confirmed) {
|
|
2136
2230
|
return { exitCode: 0 };
|
|
2137
2231
|
}
|
|
2138
2232
|
}
|
|
@@ -2742,7 +2836,7 @@ async function handleDryRun(dropId, input, raw, deps) {
|
|
|
2742
2836
|
}
|
|
2743
2837
|
|
|
2744
2838
|
// src/commands/update-settings.ts
|
|
2745
|
-
var
|
|
2839
|
+
var prompts7 = __toESM(require("@clack/prompts"), 1);
|
|
2746
2840
|
var NO_SETTINGS_MESSAGE = "Nothing to update. Provide at least one settings option.";
|
|
2747
2841
|
var NO_SETTINGS_NEXT_ACTION = "Run dropthis update-settings --help, or retry with one of: --title, --visibility, --password, --no-password, --noindex, --index, --expires-at, --no-expires, --domain, --shared, --slug, --metadata, or --metadata-file. To replace the content at the URL instead, use dropthis update-content <dropId> ./dist.";
|
|
2748
2842
|
async function runUpdateSettings(target, raw, deps) {
|
|
@@ -2774,7 +2868,7 @@ async function runUpdateSettings(target, raw, deps) {
|
|
|
2774
2868
|
if (shouldPrompt(deps)) {
|
|
2775
2869
|
const prompted = await promptForSettings(
|
|
2776
2870
|
dropId,
|
|
2777
|
-
deps.prompts ??
|
|
2871
|
+
deps.prompts ?? prompts7
|
|
2778
2872
|
);
|
|
2779
2873
|
if (!prompted) return { exitCode: 0 };
|
|
2780
2874
|
parsed = { ...parsed, ...prompted };
|
|
@@ -3097,12 +3191,7 @@ async function runWhoami(_input, deps) {
|
|
|
3097
3191
|
}
|
|
3098
3192
|
const result = await deps.client.account.get();
|
|
3099
3193
|
if (result.error) {
|
|
3100
|
-
|
|
3101
|
-
deps,
|
|
3102
|
-
`Not authenticated: ${result.error.message}. Run dropthis login.`,
|
|
3103
|
-
{ ok: true, authenticated: false, reason: result.error.message }
|
|
3104
|
-
);
|
|
3105
|
-
return { exitCode: 0 };
|
|
3194
|
+
return writeApiError(deps, result.error);
|
|
3106
3195
|
}
|
|
3107
3196
|
const account = result.data ?? {};
|
|
3108
3197
|
const masked = maskKey(credential.apiKey);
|
|
@@ -3132,7 +3221,7 @@ async function runWhoami(_input, deps) {
|
|
|
3132
3221
|
}
|
|
3133
3222
|
|
|
3134
3223
|
// src/commands/workspace.ts
|
|
3135
|
-
var
|
|
3224
|
+
var prompts8 = __toESM(require("@clack/prompts"), 1);
|
|
3136
3225
|
async function runWorkspaceList(_input, deps) {
|
|
3137
3226
|
try {
|
|
3138
3227
|
await requireCredential({
|
|
@@ -3258,10 +3347,10 @@ async function runWorkspaceDelete(workspaceId, input, deps) {
|
|
|
3258
3347
|
);
|
|
3259
3348
|
}
|
|
3260
3349
|
if (!input.yes && input.interactive !== false) {
|
|
3261
|
-
const confirmed = await
|
|
3350
|
+
const confirmed = await prompts8.confirm({
|
|
3262
3351
|
message: `Delete workspace ${workspaceId}?`
|
|
3263
3352
|
});
|
|
3264
|
-
if (
|
|
3353
|
+
if (prompts8.isCancel(confirmed) || !confirmed) {
|
|
3265
3354
|
return { exitCode: 0 };
|
|
3266
3355
|
}
|
|
3267
3356
|
}
|
|
@@ -3315,6 +3404,28 @@ var import_promises4 = require("fs/promises");
|
|
|
3315
3404
|
var import_node_os = require("os");
|
|
3316
3405
|
var import_node_path2 = require("path");
|
|
3317
3406
|
var import_keyring = require("@napi-rs/keyring");
|
|
3407
|
+
var CredentialStorageError = class extends Error {
|
|
3408
|
+
code = "credential_storage_unavailable";
|
|
3409
|
+
constructor(message, options) {
|
|
3410
|
+
super(message, options);
|
|
3411
|
+
this.name = "CredentialStorageError";
|
|
3412
|
+
}
|
|
3413
|
+
};
|
|
3414
|
+
function isCredentialStorageError(error2) {
|
|
3415
|
+
return error2 instanceof CredentialStorageError || typeof error2 === "object" && error2 !== null && error2.code === "credential_storage_unavailable";
|
|
3416
|
+
}
|
|
3417
|
+
async function guardStorage(action, fn) {
|
|
3418
|
+
try {
|
|
3419
|
+
return await fn();
|
|
3420
|
+
} catch (error2) {
|
|
3421
|
+
if (error2 instanceof CredentialStorageError) throw error2;
|
|
3422
|
+
const detail = error2 instanceof Error ? error2.message : String(error2);
|
|
3423
|
+
throw new CredentialStorageError(
|
|
3424
|
+
`Could not ${action} stored credentials: ${detail}`,
|
|
3425
|
+
{ cause: error2 }
|
|
3426
|
+
);
|
|
3427
|
+
}
|
|
3428
|
+
}
|
|
3318
3429
|
var MemoryCredentialStore = class {
|
|
3319
3430
|
credential = null;
|
|
3320
3431
|
async read() {
|
|
@@ -3333,19 +3444,24 @@ var InsecureFileCredentialStore = class {
|
|
|
3333
3444
|
this.filePath = credentialPath(options.configDir);
|
|
3334
3445
|
}
|
|
3335
3446
|
async read() {
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
|
|
3339
|
-
|
|
3447
|
+
return guardStorage("read", async () => {
|
|
3448
|
+
const value = await readJsonFile(this.filePath);
|
|
3449
|
+
if (!value) return null;
|
|
3450
|
+
if (typeof value.apiKey !== "string" || !value.apiKey) return null;
|
|
3451
|
+
return { ...value, storage: "insecure" };
|
|
3452
|
+
});
|
|
3340
3453
|
}
|
|
3341
3454
|
async save(credential) {
|
|
3342
|
-
await
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
|
|
3455
|
+
await guardStorage(
|
|
3456
|
+
"save",
|
|
3457
|
+
() => writeCredentialFile(this.filePath, {
|
|
3458
|
+
...credential,
|
|
3459
|
+
storage: "insecure"
|
|
3460
|
+
})
|
|
3461
|
+
);
|
|
3346
3462
|
}
|
|
3347
3463
|
async clear() {
|
|
3348
|
-
await (0, import_promises4.rm)(this.filePath, { force: true });
|
|
3464
|
+
await guardStorage("clear", () => (0, import_promises4.rm)(this.filePath, { force: true }));
|
|
3349
3465
|
}
|
|
3350
3466
|
};
|
|
3351
3467
|
var KeyringCredentialStore = class {
|
|
@@ -3356,23 +3472,29 @@ var KeyringCredentialStore = class {
|
|
|
3356
3472
|
this.keyring = options.keyring ?? defaultKeyringAdapter();
|
|
3357
3473
|
}
|
|
3358
3474
|
async read() {
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
|
|
3475
|
+
return guardStorage("read", async () => {
|
|
3476
|
+
const metadata = await readJsonFile(this.filePath);
|
|
3477
|
+
if (!metadata) return null;
|
|
3478
|
+
const apiKey = await this.keyring.getPassword();
|
|
3479
|
+
if (typeof apiKey !== "string" || !apiKey) return null;
|
|
3480
|
+
return { ...metadata, apiKey, storage: "secure" };
|
|
3481
|
+
});
|
|
3364
3482
|
}
|
|
3365
3483
|
async save(credential) {
|
|
3366
|
-
await
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
|
|
3484
|
+
await guardStorage("save", async () => {
|
|
3485
|
+
await this.keyring.setPassword(credential.apiKey);
|
|
3486
|
+
const { apiKey: _apiKey, ...metadata } = credential;
|
|
3487
|
+
await writeCredentialFile(this.filePath, {
|
|
3488
|
+
...metadata,
|
|
3489
|
+
storage: "secure"
|
|
3490
|
+
});
|
|
3371
3491
|
});
|
|
3372
3492
|
}
|
|
3373
3493
|
async clear() {
|
|
3374
|
-
await
|
|
3375
|
-
|
|
3494
|
+
await guardStorage("clear", async () => {
|
|
3495
|
+
await this.keyring.deletePassword();
|
|
3496
|
+
await (0, import_promises4.rm)(this.filePath, { force: true });
|
|
3497
|
+
});
|
|
3376
3498
|
}
|
|
3377
3499
|
};
|
|
3378
3500
|
function createCredentialStore(options = {}) {
|
|
@@ -3472,7 +3594,9 @@ function buildProgram(options = {}) {
|
|
|
3472
3594
|
const writeErr = options.stderr ?? ((value) => process.stderr.write(value));
|
|
3473
3595
|
const jsonModeForOutput = () => {
|
|
3474
3596
|
const argv = program.rawArgs ?? process.argv;
|
|
3475
|
-
return argv.includes("--json") || argv.includes("--quiet") || argv.includes("-q") ||
|
|
3597
|
+
return argv.includes("--json") || argv.includes("--quiet") || argv.includes("-q") || isCiEnv(
|
|
3598
|
+
options.env ?? process.env
|
|
3599
|
+
) || options.stdoutIsTTY === false || options.stdoutIsTTY === void 0 && process.stdout.isTTY !== true;
|
|
3476
3600
|
};
|
|
3477
3601
|
program.exitOverride();
|
|
3478
3602
|
program.showSuggestionAfterError();
|
|
@@ -3511,6 +3635,10 @@ function buildProgram(options = {}) {
|
|
|
3511
3635
|
program.option("--json", "Force JSON output");
|
|
3512
3636
|
program.option("-q, --quiet", "Suppress status output and imply JSON");
|
|
3513
3637
|
program.option("--no-interactive", "Disable interactive prompts");
|
|
3638
|
+
program.option(
|
|
3639
|
+
"--insecure-store",
|
|
3640
|
+
"Store credentials in a plaintext file instead of the OS keyring (for headless/CI boxes without a keyring; also DROPTHIS_INSECURE_STORE=1)"
|
|
3641
|
+
);
|
|
3514
3642
|
program.addHelpText(
|
|
3515
3643
|
"after",
|
|
3516
3644
|
[
|
|
@@ -3580,6 +3708,16 @@ ${import_picocolors6.default.bold("Canonical vs raw URLs:")}`,
|
|
|
3580
3708
|
).action(async (inputs, commandOptions) => {
|
|
3581
3709
|
const stdinIsTTY = options.stdinIsTTY ?? process.stdin.isTTY ?? false;
|
|
3582
3710
|
if (inputs.length === 0 && stdinIsTTY && !commandOptions.manifest) {
|
|
3711
|
+
const writer = outputWriter(program, options, commandOptions);
|
|
3712
|
+
if (writer.outputMode !== "human") {
|
|
3713
|
+
process.exitCode = writeError(
|
|
3714
|
+
writer,
|
|
3715
|
+
"invalid_usage",
|
|
3716
|
+
"No input to publish.",
|
|
3717
|
+
"Pass a file, folder, URL, or piped stdin \u2014 e.g. dropthis publish ./dist."
|
|
3718
|
+
).exitCode;
|
|
3719
|
+
return;
|
|
3720
|
+
}
|
|
3583
3721
|
program.outputHelp();
|
|
3584
3722
|
return;
|
|
3585
3723
|
}
|
|
@@ -3624,12 +3762,12 @@ ${import_picocolors6.default.bold("Canonical vs raw URLs:")}`,
|
|
|
3624
3762
|
return;
|
|
3625
3763
|
}
|
|
3626
3764
|
if (deps.outputMode === "human" && deps.interactive) {
|
|
3627
|
-
const
|
|
3628
|
-
const confirmed = await
|
|
3765
|
+
const prompts9 = await import("@clack/prompts");
|
|
3766
|
+
const confirmed = await prompts9.confirm({
|
|
3629
3767
|
message: `Publish '${publishInput}' as inline text?`,
|
|
3630
3768
|
initialValue: false
|
|
3631
3769
|
});
|
|
3632
|
-
if (
|
|
3770
|
+
if (prompts9.isCancel(confirmed) || !confirmed) {
|
|
3633
3771
|
return;
|
|
3634
3772
|
}
|
|
3635
3773
|
}
|
|
@@ -3759,7 +3897,12 @@ ${import_picocolors6.default.bold("Canonical vs raw URLs:")}`,
|
|
|
3759
3897
|
}
|
|
3760
3898
|
const result = await runUpdateSettings(dropId, dropOpts, {
|
|
3761
3899
|
...deps,
|
|
3762
|
-
interactive: isInteractive(
|
|
3900
|
+
interactive: isInteractive(
|
|
3901
|
+
stdinIsTTY,
|
|
3902
|
+
deps.env,
|
|
3903
|
+
global,
|
|
3904
|
+
deps.outputMode
|
|
3905
|
+
)
|
|
3763
3906
|
});
|
|
3764
3907
|
process.exitCode = result.exitCode;
|
|
3765
3908
|
}
|
|
@@ -3830,7 +3973,12 @@ ${import_picocolors6.default.bold("Canonical vs raw URLs:")}`,
|
|
|
3830
3973
|
dropId,
|
|
3831
3974
|
{
|
|
3832
3975
|
...commandOptions,
|
|
3833
|
-
interactive: isInteractive(
|
|
3976
|
+
interactive: isInteractive(
|
|
3977
|
+
stdinIsTTY,
|
|
3978
|
+
deps.env,
|
|
3979
|
+
global,
|
|
3980
|
+
deps.outputMode
|
|
3981
|
+
)
|
|
3834
3982
|
},
|
|
3835
3983
|
deps
|
|
3836
3984
|
);
|
|
@@ -3857,6 +4005,39 @@ ${import_picocolors6.default.bold("Canonical vs raw URLs:")}`,
|
|
|
3857
4005
|
process.exitCode = result.exitCode;
|
|
3858
4006
|
}
|
|
3859
4007
|
);
|
|
4008
|
+
deployments.command("restore <dropId> <deploymentId>").description(
|
|
4009
|
+
"Roll a drop back to a prior deployment's content (Pro+ version history).\nMints a new deployment copying that one and makes it current; the URL is unchanged."
|
|
4010
|
+
).option("--json", "Force JSON output").addHelpText(
|
|
4011
|
+
"after",
|
|
4012
|
+
examplesBlock([
|
|
4013
|
+
"dropthis deployments list drop_abc # find the deployment id to restore",
|
|
4014
|
+
"dropthis deployments restore drop_abc dep_1 # make dep_1's content current again"
|
|
4015
|
+
])
|
|
4016
|
+
).action(
|
|
4017
|
+
async (dropId, deploymentId, commandOptions) => {
|
|
4018
|
+
const deps = await commandDeps(program, options, store, commandOptions);
|
|
4019
|
+
const result = await runDeploymentsRestore(
|
|
4020
|
+
dropId,
|
|
4021
|
+
deploymentId,
|
|
4022
|
+
commandOptions,
|
|
4023
|
+
deps
|
|
4024
|
+
);
|
|
4025
|
+
process.exitCode = result.exitCode;
|
|
4026
|
+
}
|
|
4027
|
+
);
|
|
4028
|
+
program.command("analytics <dropId>").description(
|
|
4029
|
+
"Show a drop's approximate view analytics (Keep+ for counts, Pro for breakdowns)"
|
|
4030
|
+
).option("--json", "Force JSON output").addHelpText(
|
|
4031
|
+
"after",
|
|
4032
|
+
examplesBlock([
|
|
4033
|
+
"dropthis analytics drop_abc",
|
|
4034
|
+
"dropthis analytics drop_abc --json | jq .analytics.views"
|
|
4035
|
+
])
|
|
4036
|
+
).action(async (dropId, commandOptions) => {
|
|
4037
|
+
const deps = await commandDeps(program, options, store, commandOptions);
|
|
4038
|
+
const result = await runAnalytics(dropId, commandOptions, deps);
|
|
4039
|
+
process.exitCode = result.exitCode;
|
|
4040
|
+
});
|
|
3860
4041
|
const domains = program.command("domains").description(
|
|
3861
4042
|
"Manage custom domains. Loop: connect \u2192 create the CNAME at your DNS provider \u2192 verify --wait \u2192 publish --domain"
|
|
3862
4043
|
);
|
|
@@ -3950,7 +4131,12 @@ ${import_picocolors6.default.bold("Canonical vs raw URLs:")}`,
|
|
|
3950
4131
|
hostname,
|
|
3951
4132
|
{
|
|
3952
4133
|
...commandOptions,
|
|
3953
|
-
interactive: isInteractive(
|
|
4134
|
+
interactive: isInteractive(
|
|
4135
|
+
stdinIsTTY,
|
|
4136
|
+
deps.env,
|
|
4137
|
+
global,
|
|
4138
|
+
deps.outputMode
|
|
4139
|
+
)
|
|
3954
4140
|
},
|
|
3955
4141
|
deps
|
|
3956
4142
|
);
|
|
@@ -4001,7 +4187,12 @@ ${import_picocolors6.default.bold("Canonical vs raw URLs:")}`,
|
|
|
4001
4187
|
keyId,
|
|
4002
4188
|
{
|
|
4003
4189
|
...commandOptions,
|
|
4004
|
-
interactive: isInteractive(
|
|
4190
|
+
interactive: isInteractive(
|
|
4191
|
+
stdinIsTTY,
|
|
4192
|
+
deps.env,
|
|
4193
|
+
global,
|
|
4194
|
+
deps.outputMode
|
|
4195
|
+
)
|
|
4005
4196
|
},
|
|
4006
4197
|
deps
|
|
4007
4198
|
);
|
|
@@ -4061,7 +4252,12 @@ ${import_picocolors6.default.bold("Canonical vs raw URLs:")}`,
|
|
|
4061
4252
|
workspaceId,
|
|
4062
4253
|
{
|
|
4063
4254
|
...commandOptions,
|
|
4064
|
-
interactive: isInteractive(
|
|
4255
|
+
interactive: isInteractive(
|
|
4256
|
+
stdinIsTTY,
|
|
4257
|
+
deps.env,
|
|
4258
|
+
global,
|
|
4259
|
+
deps.outputMode
|
|
4260
|
+
)
|
|
4065
4261
|
},
|
|
4066
4262
|
deps
|
|
4067
4263
|
);
|
|
@@ -4123,7 +4319,12 @@ ${import_picocolors6.default.bold("Canonical vs raw URLs:")}`,
|
|
|
4123
4319
|
accountId,
|
|
4124
4320
|
{
|
|
4125
4321
|
...commandOptions,
|
|
4126
|
-
interactive: isInteractive(
|
|
4322
|
+
interactive: isInteractive(
|
|
4323
|
+
stdinIsTTY,
|
|
4324
|
+
deps.env,
|
|
4325
|
+
global,
|
|
4326
|
+
deps.outputMode
|
|
4327
|
+
)
|
|
4127
4328
|
},
|
|
4128
4329
|
deps
|
|
4129
4330
|
);
|
|
@@ -4158,7 +4359,7 @@ ${import_picocolors6.default.bold("Canonical vs raw URLs:")}`,
|
|
|
4158
4359
|
const deps = await commandDeps(program, options, store, commandOptions);
|
|
4159
4360
|
const global = globalOptions(program, commandOptions);
|
|
4160
4361
|
const stdinIsTTY = options.stdinIsTTY ?? process.stdin.isTTY ?? false;
|
|
4161
|
-
if (!isInteractive(stdinIsTTY, deps.env, global)) {
|
|
4362
|
+
if (!isInteractive(stdinIsTTY, deps.env, global, deps.outputMode)) {
|
|
4162
4363
|
process.exitCode = writeError(
|
|
4163
4364
|
deps,
|
|
4164
4365
|
"invalid_usage",
|
|
@@ -4252,7 +4453,12 @@ ${import_picocolors6.default.bold("Canonical vs raw URLs:")}`,
|
|
|
4252
4453
|
const result = await runAccountDelete(
|
|
4253
4454
|
{
|
|
4254
4455
|
...commandOptions,
|
|
4255
|
-
interactive: isInteractive(
|
|
4456
|
+
interactive: isInteractive(
|
|
4457
|
+
stdinIsTTY,
|
|
4458
|
+
deps.env,
|
|
4459
|
+
global,
|
|
4460
|
+
deps.outputMode
|
|
4461
|
+
)
|
|
4256
4462
|
},
|
|
4257
4463
|
deps
|
|
4258
4464
|
);
|
|
@@ -4349,7 +4555,12 @@ async function buildPublishDeps(program, options, store, commandOptions, stdinIs
|
|
|
4349
4555
|
env: context.env,
|
|
4350
4556
|
store
|
|
4351
4557
|
});
|
|
4352
|
-
const interactive = isInteractive(
|
|
4558
|
+
const interactive = isInteractive(
|
|
4559
|
+
stdinIsTTY,
|
|
4560
|
+
context.env,
|
|
4561
|
+
global,
|
|
4562
|
+
context.output.mode
|
|
4563
|
+
);
|
|
4353
4564
|
const inlineAuth = async () => {
|
|
4354
4565
|
const { runInlineAuth: runInlineAuth2 } = await Promise.resolve().then(() => (init_inline_auth(), inline_auth_exports));
|
|
4355
4566
|
return runInlineAuth2({
|
|
@@ -4374,8 +4585,9 @@ async function buildPublishDeps(program, options, store, commandOptions, stdinIs
|
|
|
4374
4585
|
}
|
|
4375
4586
|
};
|
|
4376
4587
|
}
|
|
4377
|
-
function isInteractive(stdinIsTTY, env, global) {
|
|
4378
|
-
|
|
4588
|
+
function isInteractive(stdinIsTTY, env, global, outputMode) {
|
|
4589
|
+
if (outputMode !== "human") return false;
|
|
4590
|
+
return stdinIsTTY && !isCiEnv(env) && !env.DROPTHIS_NON_INTERACTIVE && global.interactive !== false;
|
|
4379
4591
|
}
|
|
4380
4592
|
function globalOptions(program, commandOptions) {
|
|
4381
4593
|
const opts = program.opts();
|
|
@@ -4548,11 +4760,29 @@ function writeUsageErrorEnvelope(input) {
|
|
|
4548
4760
|
}
|
|
4549
4761
|
return 2;
|
|
4550
4762
|
}
|
|
4763
|
+
function writeCredentialStorageError(input) {
|
|
4764
|
+
const nextAction = "Set DROPTHIS_API_KEY, or re-run with --insecure-store (or DROPTHIS_INSECURE_STORE=1) to use a plaintext credential file instead of the OS keyring.";
|
|
4765
|
+
if (input.json) {
|
|
4766
|
+
input.stderr(
|
|
4767
|
+
`${JSON.stringify(errorEnvelope("credential_storage_unavailable", input.message, nextAction))}
|
|
4768
|
+
`
|
|
4769
|
+
);
|
|
4770
|
+
} else {
|
|
4771
|
+
input.stderr(`${error(input.message)}
|
|
4772
|
+
`);
|
|
4773
|
+
input.stderr(`${hint(nextAction)}
|
|
4774
|
+
`);
|
|
4775
|
+
}
|
|
4776
|
+
return exitCodeFor("credential_storage_unavailable");
|
|
4777
|
+
}
|
|
4778
|
+
function wantsInsecureStore(argv, env) {
|
|
4779
|
+
return argv.includes("--insecure-store") || Boolean(env.DROPTHIS_INSECURE_STORE);
|
|
4780
|
+
}
|
|
4551
4781
|
function isCommanderError(err) {
|
|
4552
4782
|
return typeof err === "object" && err !== null && typeof err.code === "string" && err.code.startsWith("commander.");
|
|
4553
4783
|
}
|
|
4554
4784
|
function wantsJson(argv) {
|
|
4555
|
-
return argv.includes("--json") || argv.includes("--quiet") || argv.includes("-q") || process.env
|
|
4785
|
+
return argv.includes("--json") || argv.includes("--quiet") || argv.includes("-q") || isCiEnv(process.env) || process.stdout.isTTY !== true;
|
|
4556
4786
|
}
|
|
4557
4787
|
var updateCache = readCache(updateCachePath());
|
|
4558
4788
|
var showNotice = shouldShowNotice({
|
|
@@ -4572,11 +4802,26 @@ ${hint(notice)}
|
|
|
4572
4802
|
`);
|
|
4573
4803
|
}
|
|
4574
4804
|
}
|
|
4575
|
-
buildProgram({
|
|
4805
|
+
buildProgram({
|
|
4806
|
+
store: createCredentialStore({
|
|
4807
|
+
insecure: wantsInsecureStore(
|
|
4808
|
+
process.argv.slice(2),
|
|
4809
|
+
process.env
|
|
4810
|
+
)
|
|
4811
|
+
})
|
|
4812
|
+
}).parseAsync(process.argv).finally(() => {
|
|
4576
4813
|
if (showNotice && shouldRefresh(updateCache, /* @__PURE__ */ new Date())) {
|
|
4577
4814
|
scheduleBackgroundRefresh(updateCachePath());
|
|
4578
4815
|
}
|
|
4579
4816
|
}).catch((error2) => {
|
|
4817
|
+
if (isCredentialStorageError(error2)) {
|
|
4818
|
+
process.exitCode = writeCredentialStorageError({
|
|
4819
|
+
message: error2.message,
|
|
4820
|
+
json: wantsJson(process.argv.slice(2)),
|
|
4821
|
+
stderr: (value) => process.stderr.write(value)
|
|
4822
|
+
});
|
|
4823
|
+
return;
|
|
4824
|
+
}
|
|
4580
4825
|
if (isCommanderError(error2)) {
|
|
4581
4826
|
if (error2.code === "commander.help" || error2.code === "commander.helpDisplayed" || error2.code === "commander.version") {
|
|
4582
4827
|
process.exitCode = 0;
|
|
@@ -4594,6 +4839,8 @@ buildProgram({ store: createCredentialStore() }).parseAsync(process.argv).finall
|
|
|
4594
4839
|
});
|
|
4595
4840
|
// Annotate the CommonJS export names for ESM import in node:
|
|
4596
4841
|
0 && (module.exports = {
|
|
4842
|
+
wantsInsecureStore,
|
|
4843
|
+
writeCredentialStorageError,
|
|
4597
4844
|
writeUsageErrorEnvelope
|
|
4598
4845
|
});
|
|
4599
4846
|
//# sourceMappingURL=cli.cjs.map
|