@dropthis/cli 0.11.0 → 0.13.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 +13 -6
- package/dist/cli.cjs +608 -106
- package/dist/cli.cjs.map +1 -1
- package/node_modules/@dropthis/node/README.md +1 -0
- package/node_modules/@dropthis/node/dist/{drops-DEJcU6qw.d.cts → drops-DP4F1PQu.d.cts} +7 -1
- package/node_modules/@dropthis/node/dist/{drops-DEJcU6qw.d.ts → drops-DP4F1PQu.d.ts} +7 -1
- package/node_modules/@dropthis/node/dist/edge.cjs +7 -3
- 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 +7 -3
- package/node_modules/@dropthis/node/dist/edge.mjs.map +1 -1
- package/node_modules/@dropthis/node/dist/index.cjs +7 -3
- 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 +7 -3
- package/node_modules/@dropthis/node/dist/index.mjs.map +1 -1
- package/node_modules/@dropthis/node/package.json +1 -1
- package/package.json +2 -2
package/dist/cli.cjs
CHANGED
|
@@ -202,13 +202,31 @@ function normalizeApiErrorCode(error2) {
|
|
|
202
202
|
if (error2.statusCode === 404) return "not_found";
|
|
203
203
|
return "api_error";
|
|
204
204
|
}
|
|
205
|
-
function nextActionForApiError(error2) {
|
|
205
|
+
function nextActionForApiError(error2, mode = "json") {
|
|
206
|
+
const cliHint = cliNextAction(error2);
|
|
207
|
+
if (mode === "human" && cliHint) return cliHint;
|
|
206
208
|
if (error2.suggestion) return error2.suggestion;
|
|
209
|
+
if (cliHint) return cliHint;
|
|
210
|
+
if (error2.statusCode === 422) {
|
|
211
|
+
return "Fix the input shown in the error detail and retry.";
|
|
212
|
+
}
|
|
213
|
+
if (error2.statusCode !== void 0 && error2.statusCode !== null && error2.statusCode >= 500) {
|
|
214
|
+
return "Retry the request with the same idempotency key, or contact support with the request id.";
|
|
215
|
+
}
|
|
216
|
+
return "Fix the request or retry after checking the drop state.";
|
|
217
|
+
}
|
|
218
|
+
function cliNextAction(error2) {
|
|
207
219
|
const uploadNextAction = error2.code ? UPLOAD_NEXT_ACTIONS[error2.code] : void 0;
|
|
208
220
|
if (uploadNextAction) return uploadNextAction;
|
|
221
|
+
if (error2.code === "network_error") {
|
|
222
|
+
return "Could not reach the dropthis API \u2014 check your network or DROPTHIS_API_URL.";
|
|
223
|
+
}
|
|
209
224
|
if (error2.code === "revision_conflict") {
|
|
210
225
|
return "Re-read the drop with dropthis get <drop-id>, merge your changes, and retry with --if-revision set to the current revision.";
|
|
211
226
|
}
|
|
227
|
+
if (error2.code === "publish_conflict") {
|
|
228
|
+
return "The drop changed state mid-publish (likely deleted). Run dropthis publish again to create a fresh drop.";
|
|
229
|
+
}
|
|
212
230
|
if (error2.statusCode === 404 || error2.code === "not_found") {
|
|
213
231
|
return "Check the drop id or slug and retry; list your drops with dropthis list.";
|
|
214
232
|
}
|
|
@@ -218,13 +236,7 @@ function nextActionForApiError(error2) {
|
|
|
218
236
|
if (error2.statusCode === 413 || error2.code === "quota_exceeded") {
|
|
219
237
|
return "Reduce the upload size or upgrade the account limit.";
|
|
220
238
|
}
|
|
221
|
-
|
|
222
|
-
return "Fix the input shown in the error detail and retry.";
|
|
223
|
-
}
|
|
224
|
-
if (error2.statusCode !== void 0 && error2.statusCode !== null && error2.statusCode >= 500) {
|
|
225
|
-
return "Retry the request with the same idempotency key, or contact support with the request id.";
|
|
226
|
-
}
|
|
227
|
-
return "Fix the request or retry after checking the drop state.";
|
|
239
|
+
return void 0;
|
|
228
240
|
}
|
|
229
241
|
function exitCodeFor(code) {
|
|
230
242
|
if (code === "usage_error") return 2;
|
|
@@ -239,7 +251,7 @@ function exitCodeFor(code) {
|
|
|
239
251
|
|
|
240
252
|
// src/program.ts
|
|
241
253
|
var import_commander = require("commander");
|
|
242
|
-
var
|
|
254
|
+
var import_picocolors6 = __toESM(require("picocolors"), 1);
|
|
243
255
|
|
|
244
256
|
// src/auth.ts
|
|
245
257
|
async function resolveCredential(input) {
|
|
@@ -318,6 +330,10 @@ function writeResult(deps, link, verb, data) {
|
|
|
318
330
|
`${hint(`Vanity slug was taken \u2014 served at: ${w.detail ?? "see URL"}`)}
|
|
319
331
|
`
|
|
320
332
|
);
|
|
333
|
+
} else {
|
|
334
|
+
const text2 = typeof w.detail === "string" ? w.detail : typeof w.message === "string" ? w.message : typeof w.code === "string" ? w.code : void 0;
|
|
335
|
+
if (text2) deps.stderr(`${hint(text2)}
|
|
336
|
+
`);
|
|
321
337
|
}
|
|
322
338
|
}
|
|
323
339
|
}
|
|
@@ -339,6 +355,13 @@ function formatDropDetails(data) {
|
|
|
339
355
|
if (parts.length === 0) return "";
|
|
340
356
|
return ` ${import_picocolors2.default.dim(parts.join(" \xB7 "))}`;
|
|
341
357
|
}
|
|
358
|
+
function formatDate(iso) {
|
|
359
|
+
return iso.split("T")[0] ?? iso;
|
|
360
|
+
}
|
|
361
|
+
function formatDateTime(iso) {
|
|
362
|
+
const match = iso.match(/^(\d{4}-\d{2}-\d{2})T(\d{2}:\d{2})/);
|
|
363
|
+
return match ? `${match[1]} ${match[2]}` : iso;
|
|
364
|
+
}
|
|
342
365
|
function formatBytes(bytes) {
|
|
343
366
|
if (bytes < 1024) return `${bytes} B`;
|
|
344
367
|
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
@@ -384,7 +407,7 @@ function writeApiError(deps, details) {
|
|
|
384
407
|
if (deps.outputMode === "human") {
|
|
385
408
|
deps.stderr(`${error(details.message)}
|
|
386
409
|
`);
|
|
387
|
-
const nextAction = nextActionForApiError(details);
|
|
410
|
+
const nextAction = nextActionForApiError(details, "human");
|
|
388
411
|
if (nextAction) deps.stderr(`${hint(nextAction)}
|
|
389
412
|
`);
|
|
390
413
|
if (details.currentRevision !== void 0)
|
|
@@ -399,7 +422,12 @@ function writeApiError(deps, details) {
|
|
|
399
422
|
deps.stderr(`${JSON.stringify(apiErrorEnvelope(details))}
|
|
400
423
|
`);
|
|
401
424
|
}
|
|
402
|
-
return { exitCode: exitCodeFor(
|
|
425
|
+
return { exitCode: exitCodeFor(cliErrorCodeFor(details)) };
|
|
426
|
+
}
|
|
427
|
+
function cliErrorCodeFor(details) {
|
|
428
|
+
if (details.code === "network_error") return "network_error";
|
|
429
|
+
if (details.code === "file_not_found") return "local_input_error";
|
|
430
|
+
return "api_error";
|
|
403
431
|
}
|
|
404
432
|
function writeApiErrorSimple(deps, message) {
|
|
405
433
|
if (deps.outputMode === "human") {
|
|
@@ -507,6 +535,14 @@ async function runAccountDelete(input, deps) {
|
|
|
507
535
|
var prompts = __toESM(require("@clack/prompts"), 1);
|
|
508
536
|
|
|
509
537
|
// src/types.ts
|
|
538
|
+
function extractPagination(data) {
|
|
539
|
+
if (!data || typeof data !== "object") return void 0;
|
|
540
|
+
const rec = data;
|
|
541
|
+
if (!("nextCursor" in rec) && !("hasMore" in rec)) return void 0;
|
|
542
|
+
const nextCursor = typeof rec.nextCursor === "string" ? rec.nextCursor : null;
|
|
543
|
+
const hasMore = typeof rec.hasMore === "boolean" ? rec.hasMore : nextCursor !== null;
|
|
544
|
+
return { nextCursor, hasMore };
|
|
545
|
+
}
|
|
510
546
|
function unwrapListData(data, ...fallbackKeys) {
|
|
511
547
|
if (data && typeof data === "object") {
|
|
512
548
|
if ("data" in data) {
|
|
@@ -639,7 +675,10 @@ var COMMAND_ANNOTATIONS = {
|
|
|
639
675
|
},
|
|
640
676
|
list: {
|
|
641
677
|
auth: "required",
|
|
642
|
-
examples: [
|
|
678
|
+
examples: [
|
|
679
|
+
"dropthis list --json",
|
|
680
|
+
"dropthis list --domain reports.example.com --json"
|
|
681
|
+
]
|
|
643
682
|
},
|
|
644
683
|
delete: {
|
|
645
684
|
auth: "required",
|
|
@@ -647,7 +686,7 @@ var COMMAND_ANNOTATIONS = {
|
|
|
647
686
|
},
|
|
648
687
|
deployments: {
|
|
649
688
|
auth: "required",
|
|
650
|
-
examples: ["dropthis deployments drop_abc --json"]
|
|
689
|
+
examples: ["dropthis deployments list drop_abc --json"]
|
|
651
690
|
},
|
|
652
691
|
"deployments list": {
|
|
653
692
|
auth: "required",
|
|
@@ -657,6 +696,36 @@ var COMMAND_ANNOTATIONS = {
|
|
|
657
696
|
auth: "required",
|
|
658
697
|
examples: ["dropthis deployments get drop_abc dep_abc --json"]
|
|
659
698
|
},
|
|
699
|
+
domains: {
|
|
700
|
+
auth: "required",
|
|
701
|
+
examples: ["dropthis domains list --json"]
|
|
702
|
+
},
|
|
703
|
+
"domains connect": {
|
|
704
|
+
auth: "required",
|
|
705
|
+
examples: [
|
|
706
|
+
"dropthis domains connect reports.example.com --mode path --json"
|
|
707
|
+
]
|
|
708
|
+
},
|
|
709
|
+
"domains list": {
|
|
710
|
+
auth: "required",
|
|
711
|
+
examples: ["dropthis domains list --json"]
|
|
712
|
+
},
|
|
713
|
+
"domains status": {
|
|
714
|
+
auth: "required",
|
|
715
|
+
examples: ["dropthis domains status reports.example.com --json"]
|
|
716
|
+
},
|
|
717
|
+
"domains verify": {
|
|
718
|
+
auth: "required",
|
|
719
|
+
examples: ["dropthis domains verify reports.example.com --wait --json"]
|
|
720
|
+
},
|
|
721
|
+
"domains update": {
|
|
722
|
+
auth: "required",
|
|
723
|
+
examples: ["dropthis domains update reports.example.com --default --json"]
|
|
724
|
+
},
|
|
725
|
+
"domains remove": {
|
|
726
|
+
auth: "required",
|
|
727
|
+
examples: ["dropthis domains remove reports.example.com --yes --json"]
|
|
728
|
+
},
|
|
660
729
|
"api-keys": {
|
|
661
730
|
auth: "required",
|
|
662
731
|
examples: ["dropthis api-keys create --label CI --json"]
|
|
@@ -679,6 +748,7 @@ var COMMAND_ANNOTATIONS = {
|
|
|
679
748
|
examples: ["dropthis account delete --yes --json"]
|
|
680
749
|
},
|
|
681
750
|
doctor: { examples: ["dropthis doctor --json"] },
|
|
751
|
+
upgrade: { examples: ["dropthis upgrade", "dropthis upgrade --json"] },
|
|
682
752
|
commands: { examples: ["dropthis commands --json"] }
|
|
683
753
|
};
|
|
684
754
|
function describeArgs(cmd) {
|
|
@@ -738,6 +808,7 @@ async function runDeploymentsList(dropId, input, deps) {
|
|
|
738
808
|
return writeApiError(deps, result.error);
|
|
739
809
|
}
|
|
740
810
|
const spread = spreadData(result.data);
|
|
811
|
+
const page = extractPagination(result.data);
|
|
741
812
|
const items = spread.deployments ?? spread.data ?? result.data;
|
|
742
813
|
if (deps.outputMode === "human") {
|
|
743
814
|
if (!items || Array.isArray(items) && items.length === 0) {
|
|
@@ -747,8 +818,15 @@ async function runDeploymentsList(dropId, input, deps) {
|
|
|
747
818
|
});
|
|
748
819
|
} else if (Array.isArray(items)) {
|
|
749
820
|
for (const item of items) {
|
|
821
|
+
const created = typeof item.createdAt === "string" ? formatDateTime(item.createdAt) : "";
|
|
750
822
|
deps.stdout(
|
|
751
|
-
`${item.id ?? ""} rev ${item.revision ?? "?"} ${
|
|
823
|
+
`${item.id ?? ""} rev ${item.revision ?? "?"} ${created}
|
|
824
|
+
`
|
|
825
|
+
);
|
|
826
|
+
}
|
|
827
|
+
if (page?.hasMore && page.nextCursor) {
|
|
828
|
+
deps.stdout(
|
|
829
|
+
`${hint(`More deployments: dropthis deployments list ${dropId} --cursor ${page.nextCursor}`)}
|
|
752
830
|
`
|
|
753
831
|
);
|
|
754
832
|
}
|
|
@@ -756,7 +834,11 @@ async function runDeploymentsList(dropId, input, deps) {
|
|
|
756
834
|
writeJson(deps, { ok: true, ...spread });
|
|
757
835
|
}
|
|
758
836
|
} else {
|
|
759
|
-
writeJson(deps, {
|
|
837
|
+
writeJson(deps, {
|
|
838
|
+
ok: true,
|
|
839
|
+
...spread,
|
|
840
|
+
...page ? { next_cursor: page.nextCursor, has_more: page.hasMore } : {}
|
|
841
|
+
});
|
|
760
842
|
}
|
|
761
843
|
return { exitCode: 0 };
|
|
762
844
|
}
|
|
@@ -779,7 +861,8 @@ async function runDeploymentsGet(dropId, deploymentId, _input, deps) {
|
|
|
779
861
|
if (data.id) pairs.push(["ID", String(data.id)]);
|
|
780
862
|
if (data.revision !== void 0)
|
|
781
863
|
pairs.push(["Revision", String(data.revision)]);
|
|
782
|
-
if (data.createdAt)
|
|
864
|
+
if (data.createdAt)
|
|
865
|
+
pairs.push(["Created", formatDateTime(String(data.createdAt))]);
|
|
783
866
|
writeKv(deps, pairs, { ok: true, deployment: result.data });
|
|
784
867
|
return { exitCode: 0 };
|
|
785
868
|
}
|
|
@@ -797,13 +880,13 @@ async function runDoctor(_input, deps) {
|
|
|
797
880
|
const authSource = credential?.source ?? "missing";
|
|
798
881
|
const storageBackend = stored?.storage ?? "none";
|
|
799
882
|
const pairs = [
|
|
800
|
-
["Version", "0.
|
|
883
|
+
["Version", "0.13.0"],
|
|
801
884
|
["Auth", authSource],
|
|
802
885
|
["Storage", storageBackend]
|
|
803
886
|
];
|
|
804
887
|
writeKv(deps, pairs, {
|
|
805
888
|
ok: true,
|
|
806
|
-
version: "0.
|
|
889
|
+
version: "0.13.0",
|
|
807
890
|
auth: { source: authSource },
|
|
808
891
|
storage: { backend: storageBackend }
|
|
809
892
|
});
|
|
@@ -811,6 +894,7 @@ async function runDoctor(_input, deps) {
|
|
|
811
894
|
}
|
|
812
895
|
|
|
813
896
|
// src/commands/domains.ts
|
|
897
|
+
var prompts2 = __toESM(require("@clack/prompts"), 1);
|
|
814
898
|
var import_picocolors3 = __toESM(require("picocolors"), 1);
|
|
815
899
|
function formatDnsTable(records) {
|
|
816
900
|
if (records.length === 0) return "";
|
|
@@ -848,11 +932,32 @@ function formatDnsTable(records) {
|
|
|
848
932
|
}
|
|
849
933
|
return rows.join("\n");
|
|
850
934
|
}
|
|
851
|
-
function
|
|
852
|
-
if (
|
|
935
|
+
function renderNextHint(h, hostname, maxRetryAfter) {
|
|
936
|
+
if (h.action === "verify") {
|
|
937
|
+
const recheck = maxRetryAfter > 0 ? ` (re-checks every ${maxRetryAfter}s)` : "";
|
|
938
|
+
return `Run: dropthis domains verify ${hostname} --wait${recheck}`;
|
|
939
|
+
}
|
|
940
|
+
if (h.action === "publish") {
|
|
941
|
+
return `Run: dropthis publish <file> --domain ${hostname}`;
|
|
942
|
+
}
|
|
943
|
+
return h.message;
|
|
944
|
+
}
|
|
945
|
+
function duplicatesRecordHint(h, dns) {
|
|
946
|
+
if (h.action !== "dns") return false;
|
|
947
|
+
return dns.some(
|
|
948
|
+
(r) => r.hint && h.message.includes(r.name) && h.message.includes(r.value)
|
|
949
|
+
);
|
|
950
|
+
}
|
|
951
|
+
function printNextHints(deps, hints, hostname, dns) {
|
|
952
|
+
const lines = hints.filter((h) => !duplicatesRecordHint(h, dns));
|
|
953
|
+
if (lines.length === 0) return;
|
|
954
|
+
const maxRetryAfter = dns.reduce(
|
|
955
|
+
(max, r) => Math.max(max, r.retryAfter ?? 0),
|
|
956
|
+
0
|
|
957
|
+
);
|
|
853
958
|
deps.stdout("\n");
|
|
854
|
-
for (const h of
|
|
855
|
-
deps.stdout(`${hint(h
|
|
959
|
+
for (const h of lines) {
|
|
960
|
+
deps.stdout(`${hint(renderNextHint(h, hostname, maxRetryAfter))}
|
|
856
961
|
`);
|
|
857
962
|
}
|
|
858
963
|
}
|
|
@@ -889,7 +994,7 @@ async function runDomainsConnect(input, deps) {
|
|
|
889
994
|
deps.stdout(`${formatDnsTable(domain.dns)}
|
|
890
995
|
`);
|
|
891
996
|
}
|
|
892
|
-
printNextHints(deps, domain.next);
|
|
997
|
+
printNextHints(deps, domain.next, domain.hostname, domain.dns);
|
|
893
998
|
} else {
|
|
894
999
|
writeJson(deps, { ok: true, domain });
|
|
895
1000
|
}
|
|
@@ -957,17 +1062,19 @@ async function runDomainsStatus(idOrHostname, _input, deps) {
|
|
|
957
1062
|
`);
|
|
958
1063
|
}
|
|
959
1064
|
if (domain.verifiedAt) {
|
|
960
|
-
deps.stdout(
|
|
961
|
-
`)
|
|
1065
|
+
deps.stdout(
|
|
1066
|
+
` ${import_picocolors3.default.dim("Verified:")} ${formatDate(domain.verifiedAt)}
|
|
1067
|
+
`
|
|
1068
|
+
);
|
|
962
1069
|
}
|
|
963
|
-
deps.stdout(` ${import_picocolors3.default.dim("Created: ")} ${domain.createdAt}
|
|
1070
|
+
deps.stdout(` ${import_picocolors3.default.dim("Created: ")} ${formatDate(domain.createdAt)}
|
|
964
1071
|
`);
|
|
965
1072
|
if (domain.dns.length > 0) {
|
|
966
1073
|
deps.stdout("\nDNS records:\n\n");
|
|
967
1074
|
deps.stdout(`${formatDnsTable(domain.dns)}
|
|
968
1075
|
`);
|
|
969
1076
|
}
|
|
970
|
-
printNextHints(deps, domain.next);
|
|
1077
|
+
printNextHints(deps, domain.next, domain.hostname, domain.dns);
|
|
971
1078
|
} else {
|
|
972
1079
|
writeJson(deps, { ok: true, domain });
|
|
973
1080
|
}
|
|
@@ -1000,7 +1107,7 @@ async function runDomainsVerify(idOrHostname, input, deps, sleep = defaultSleep)
|
|
|
1000
1107
|
deps.stdout(`${formatDnsTable(domain.dns)}
|
|
1001
1108
|
`);
|
|
1002
1109
|
}
|
|
1003
|
-
printNextHints(deps, domain.next);
|
|
1110
|
+
printNextHints(deps, domain.next, domain.hostname, domain.dns);
|
|
1004
1111
|
} else {
|
|
1005
1112
|
writeJson(deps, { ok: true, domain });
|
|
1006
1113
|
}
|
|
@@ -1081,7 +1188,22 @@ async function runDomainsUpdate(idOrHostname, input, deps) {
|
|
|
1081
1188
|
});
|
|
1082
1189
|
return { exitCode: 0 };
|
|
1083
1190
|
}
|
|
1084
|
-
async function runDomainsRemove(idOrHostname,
|
|
1191
|
+
async function runDomainsRemove(idOrHostname, input, deps) {
|
|
1192
|
+
if (!input.yes && input.interactive === false) {
|
|
1193
|
+
return writeError(
|
|
1194
|
+
deps,
|
|
1195
|
+
"invalid_usage",
|
|
1196
|
+
"Pass --yes to remove the domain in non-interactive mode."
|
|
1197
|
+
);
|
|
1198
|
+
}
|
|
1199
|
+
if (!input.yes && input.interactive !== false) {
|
|
1200
|
+
const confirmed = await prompts2.confirm({
|
|
1201
|
+
message: `Remove ${idOrHostname}? This removes the domain and unmounts its drops.`
|
|
1202
|
+
});
|
|
1203
|
+
if (prompts2.isCancel(confirmed) || !confirmed) {
|
|
1204
|
+
return { exitCode: 0 };
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1085
1207
|
try {
|
|
1086
1208
|
await requireCredential({
|
|
1087
1209
|
...deps.apiKey ? { apiKey: deps.apiKey } : {},
|
|
@@ -1114,7 +1236,30 @@ async function runDomainsRemove(idOrHostname, _input, deps) {
|
|
|
1114
1236
|
}
|
|
1115
1237
|
|
|
1116
1238
|
// src/commands/drops.ts
|
|
1117
|
-
var
|
|
1239
|
+
var prompts3 = __toESM(require("@clack/prompts"), 1);
|
|
1240
|
+
var import_picocolors4 = __toESM(require("picocolors"), 1);
|
|
1241
|
+
async function resolveDropTarget(target, deps) {
|
|
1242
|
+
if (target.startsWith("drop_")) return { ok: true, dropId: target };
|
|
1243
|
+
const resolved = await deps.client.drops.resolve(target);
|
|
1244
|
+
if (resolved.error) {
|
|
1245
|
+
return { ok: false, ...writeApiError(deps, resolved.error) };
|
|
1246
|
+
}
|
|
1247
|
+
if (resolved.data === null) {
|
|
1248
|
+
return {
|
|
1249
|
+
ok: false,
|
|
1250
|
+
...writeApiError(deps, {
|
|
1251
|
+
code: "not_found",
|
|
1252
|
+
message: `No drop matching "${target}" found in your account.`,
|
|
1253
|
+
suggestion: "It may belong to another account or have been deleted. Run dropthis list to see your drops, or pass the full drop_\u2026 id."
|
|
1254
|
+
})
|
|
1255
|
+
};
|
|
1256
|
+
}
|
|
1257
|
+
return {
|
|
1258
|
+
ok: true,
|
|
1259
|
+
dropId: resolved.data.id,
|
|
1260
|
+
...resolved.data.slug ? { slug: resolved.data.slug } : {}
|
|
1261
|
+
};
|
|
1262
|
+
}
|
|
1118
1263
|
async function runDropsList(input, deps) {
|
|
1119
1264
|
try {
|
|
1120
1265
|
await requireCredential({
|
|
@@ -1127,29 +1272,46 @@ async function runDropsList(input, deps) {
|
|
|
1127
1272
|
}
|
|
1128
1273
|
const params = {
|
|
1129
1274
|
...input.limit !== void 0 ? { limit: input.limit } : {},
|
|
1130
|
-
...input.cursor ? { cursor: input.cursor } : {}
|
|
1275
|
+
...input.cursor ? { cursor: input.cursor } : {},
|
|
1276
|
+
...input.domain ? { domain: input.domain } : {}
|
|
1131
1277
|
};
|
|
1132
1278
|
const result = await deps.client.drops.list(params);
|
|
1133
1279
|
if (result.error) return writeApiError(deps, result.error);
|
|
1134
1280
|
const raw = unwrapListData(result.data, "drops");
|
|
1281
|
+
const page = extractPagination(result.data);
|
|
1135
1282
|
const items = Array.isArray(raw) ? raw : void 0;
|
|
1136
1283
|
if (deps.outputMode === "human") {
|
|
1137
1284
|
if (!items || items.length === 0) {
|
|
1138
1285
|
writeEmpty(deps, "No drops found.", { ok: true, drops: [] });
|
|
1139
1286
|
} else {
|
|
1140
1287
|
for (const item of items) {
|
|
1288
|
+
const created = typeof item.createdAt === "string" ? import_picocolors4.default.dim(formatDate(item.createdAt)) : "";
|
|
1141
1289
|
deps.stdout(
|
|
1142
|
-
`${item.id ?? ""} ${item.title ?? ""} ${item.url ? url(String(item.url)) : ""}
|
|
1290
|
+
`${item.id ?? ""} ${created} ${item.title ?? ""} ${item.url ? url(String(item.url)) : ""}
|
|
1291
|
+
`
|
|
1292
|
+
);
|
|
1293
|
+
}
|
|
1294
|
+
deps.stdout(
|
|
1295
|
+
`${import_picocolors4.default.dim(`${items.length} ${items.length === 1 ? "drop" : "drops"}`)}
|
|
1296
|
+
`
|
|
1297
|
+
);
|
|
1298
|
+
if (page?.hasMore && page.nextCursor) {
|
|
1299
|
+
deps.stdout(
|
|
1300
|
+
`${hint(`More drops: dropthis list --cursor ${page.nextCursor}`)}
|
|
1143
1301
|
`
|
|
1144
1302
|
);
|
|
1145
1303
|
}
|
|
1146
1304
|
}
|
|
1147
1305
|
} else {
|
|
1148
|
-
writeJson(deps, {
|
|
1306
|
+
writeJson(deps, {
|
|
1307
|
+
ok: true,
|
|
1308
|
+
drops: items ?? raw,
|
|
1309
|
+
...page ? { next_cursor: page.nextCursor, has_more: page.hasMore } : {}
|
|
1310
|
+
});
|
|
1149
1311
|
}
|
|
1150
1312
|
return { exitCode: 0 };
|
|
1151
1313
|
}
|
|
1152
|
-
async function runDropsGet(
|
|
1314
|
+
async function runDropsGet(target, _input, deps) {
|
|
1153
1315
|
try {
|
|
1154
1316
|
await requireCredential({
|
|
1155
1317
|
...deps.apiKey ? { apiKey: deps.apiKey } : {},
|
|
@@ -1159,7 +1321,9 @@ async function runDropsGet(dropId, _input, deps) {
|
|
|
1159
1321
|
} catch {
|
|
1160
1322
|
return writeAuthError(deps);
|
|
1161
1323
|
}
|
|
1162
|
-
const
|
|
1324
|
+
const resolved = await resolveDropTarget(target, deps);
|
|
1325
|
+
if (!resolved.ok) return { exitCode: resolved.exitCode };
|
|
1326
|
+
const result = await deps.client.drops.get(resolved.dropId);
|
|
1163
1327
|
if (result.error) return writeApiError(deps, result.error);
|
|
1164
1328
|
const data = result.data;
|
|
1165
1329
|
const pairs = [];
|
|
@@ -1169,7 +1333,8 @@ async function runDropsGet(dropId, _input, deps) {
|
|
|
1169
1333
|
if (data.visibility) pairs.push(["Visibility", String(data.visibility)]);
|
|
1170
1334
|
if (data.revision !== void 0)
|
|
1171
1335
|
pairs.push(["Revision", String(data.revision)]);
|
|
1172
|
-
if (data.createdAt)
|
|
1336
|
+
if (data.createdAt)
|
|
1337
|
+
pairs.push(["Created", formatDate(String(data.createdAt))]);
|
|
1173
1338
|
if (data.accessible !== void 0)
|
|
1174
1339
|
pairs.push(["Accessible", String(data.accessible)]);
|
|
1175
1340
|
if (data.persistent !== void 0)
|
|
@@ -1179,7 +1344,7 @@ async function runDropsGet(dropId, _input, deps) {
|
|
|
1179
1344
|
writeKv(deps, pairs, { ok: true, drop: result.data });
|
|
1180
1345
|
return { exitCode: 0 };
|
|
1181
1346
|
}
|
|
1182
|
-
async function runDropsDelete(
|
|
1347
|
+
async function runDropsDelete(target, input, deps) {
|
|
1183
1348
|
if (!input.yes && input.interactive === false) {
|
|
1184
1349
|
return writeError(
|
|
1185
1350
|
deps,
|
|
@@ -1187,14 +1352,6 @@ async function runDropsDelete(dropId, input, deps) {
|
|
|
1187
1352
|
"Pass --yes to delete in non-interactive mode."
|
|
1188
1353
|
);
|
|
1189
1354
|
}
|
|
1190
|
-
if (!input.yes && input.interactive !== false) {
|
|
1191
|
-
const confirmed = await prompts2.confirm({
|
|
1192
|
-
message: `Delete ${dropId}?`
|
|
1193
|
-
});
|
|
1194
|
-
if (prompts2.isCancel(confirmed) || !confirmed) {
|
|
1195
|
-
return { exitCode: 0 };
|
|
1196
|
-
}
|
|
1197
|
-
}
|
|
1198
1355
|
try {
|
|
1199
1356
|
await requireCredential({
|
|
1200
1357
|
...deps.apiKey ? { apiKey: deps.apiKey } : {},
|
|
@@ -1204,6 +1361,17 @@ async function runDropsDelete(dropId, input, deps) {
|
|
|
1204
1361
|
} catch {
|
|
1205
1362
|
return writeAuthError(deps);
|
|
1206
1363
|
}
|
|
1364
|
+
const resolved = await resolveDropTarget(target, deps);
|
|
1365
|
+
if (!resolved.ok) return { exitCode: resolved.exitCode };
|
|
1366
|
+
const dropId = resolved.dropId;
|
|
1367
|
+
if (!input.yes && input.interactive !== false) {
|
|
1368
|
+
const confirmed = await prompts3.confirm({
|
|
1369
|
+
message: `Delete ${dropId}${dropId === target ? "" : ` (${target})`}?`
|
|
1370
|
+
});
|
|
1371
|
+
if (prompts3.isCancel(confirmed) || !confirmed) {
|
|
1372
|
+
return { exitCode: 0 };
|
|
1373
|
+
}
|
|
1374
|
+
}
|
|
1207
1375
|
const result = await deps.client.drops.delete(dropId);
|
|
1208
1376
|
if (result?.error) return writeApiError(deps, result.error);
|
|
1209
1377
|
writeHumanOrJson(deps, success(`Deleted ${dropId}`), {
|
|
@@ -1215,31 +1383,31 @@ async function runDropsDelete(dropId, input, deps) {
|
|
|
1215
1383
|
}
|
|
1216
1384
|
|
|
1217
1385
|
// src/commands/login.ts
|
|
1218
|
-
var
|
|
1386
|
+
var prompts4 = __toESM(require("@clack/prompts"), 1);
|
|
1219
1387
|
async function runLoginInteractive(deps) {
|
|
1220
|
-
|
|
1221
|
-
const email = await
|
|
1388
|
+
prompts4.intro("dropthis login");
|
|
1389
|
+
const email = await prompts4.text({
|
|
1222
1390
|
message: "Email address",
|
|
1223
1391
|
validate: (v) => v?.includes("@") ? void 0 : "Enter a valid email"
|
|
1224
1392
|
});
|
|
1225
|
-
if (
|
|
1226
|
-
|
|
1393
|
+
if (prompts4.isCancel(email)) {
|
|
1394
|
+
prompts4.cancel("Login cancelled.");
|
|
1227
1395
|
return { exitCode: 0 };
|
|
1228
1396
|
}
|
|
1229
1397
|
const requestResult = await deps.client.auth.requestEmailOtp({ email });
|
|
1230
1398
|
if (requestResult.error) {
|
|
1231
|
-
|
|
1399
|
+
prompts4.cancel(requestResult.error.message);
|
|
1232
1400
|
return { exitCode: exitCodeFor("api_error") };
|
|
1233
1401
|
}
|
|
1234
1402
|
const maxAttempts = 3;
|
|
1235
1403
|
let session;
|
|
1236
1404
|
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
1237
|
-
const otp = await
|
|
1405
|
+
const otp = await prompts4.text({
|
|
1238
1406
|
message: attempt === 1 ? "Paste the code from your email" : "Try again \u2014 paste the code from your email",
|
|
1239
1407
|
validate: (v) => v && v.length >= 4 && v.length <= 8 ? void 0 : "Code must be 4\u20138 characters."
|
|
1240
1408
|
});
|
|
1241
|
-
if (
|
|
1242
|
-
|
|
1409
|
+
if (prompts4.isCancel(otp)) {
|
|
1410
|
+
prompts4.cancel("Login cancelled.");
|
|
1243
1411
|
return { exitCode: 0 };
|
|
1244
1412
|
}
|
|
1245
1413
|
const result = await deps.client.auth.verifyEmailOtp({
|
|
@@ -1251,20 +1419,20 @@ async function runLoginInteractive(deps) {
|
|
|
1251
1419
|
break;
|
|
1252
1420
|
}
|
|
1253
1421
|
if (attempt < maxAttempts) {
|
|
1254
|
-
|
|
1422
|
+
prompts4.log.warning(result.error.message);
|
|
1255
1423
|
} else {
|
|
1256
|
-
|
|
1424
|
+
prompts4.cancel(result.error.message);
|
|
1257
1425
|
return { exitCode: exitCodeFor("api_error") };
|
|
1258
1426
|
}
|
|
1259
1427
|
}
|
|
1260
1428
|
if (!session) {
|
|
1261
|
-
|
|
1429
|
+
prompts4.cancel("Login failed.");
|
|
1262
1430
|
return { exitCode: exitCodeFor("api_error") };
|
|
1263
1431
|
}
|
|
1264
1432
|
const authedClient = deps.createClient(session.data.token);
|
|
1265
1433
|
const apiKey = await authedClient.apiKeys.create({ label: "CLI" });
|
|
1266
1434
|
if (apiKey.error) {
|
|
1267
|
-
|
|
1435
|
+
prompts4.cancel(apiKey.error.message);
|
|
1268
1436
|
return { exitCode: exitCodeFor("api_error") };
|
|
1269
1437
|
}
|
|
1270
1438
|
await deps.store.save({
|
|
@@ -1275,7 +1443,7 @@ async function runLoginInteractive(deps) {
|
|
|
1275
1443
|
email,
|
|
1276
1444
|
storage: "secure"
|
|
1277
1445
|
});
|
|
1278
|
-
|
|
1446
|
+
prompts4.outro("Logged in successfully.");
|
|
1279
1447
|
return { exitCode: 0 };
|
|
1280
1448
|
}
|
|
1281
1449
|
async function runLoginRequest(input, deps) {
|
|
@@ -1464,12 +1632,12 @@ function parseJsonObject(value, label) {
|
|
|
1464
1632
|
}
|
|
1465
1633
|
|
|
1466
1634
|
// src/spinner.ts
|
|
1467
|
-
var
|
|
1635
|
+
var import_picocolors5 = __toESM(require("picocolors"), 1);
|
|
1468
1636
|
var frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
1469
1637
|
function createSpinner(message, stderr) {
|
|
1470
1638
|
let i = 0;
|
|
1471
1639
|
const timer = setInterval(() => {
|
|
1472
|
-
stderr(`\r\x1B[2K${
|
|
1640
|
+
stderr(`\r\x1B[2K${import_picocolors5.default.cyan(frames[i % frames.length])} ${message}`);
|
|
1473
1641
|
i++;
|
|
1474
1642
|
}, 80);
|
|
1475
1643
|
return {
|
|
@@ -1620,24 +1788,10 @@ async function runPull(target, input, deps) {
|
|
|
1620
1788
|
} catch {
|
|
1621
1789
|
return writeAuthError(deps);
|
|
1622
1790
|
}
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
defaultDirName = target;
|
|
1628
|
-
} else {
|
|
1629
|
-
const resolved = await deps.client.drops.resolve(target);
|
|
1630
|
-
if (resolved.error) return writeApiError(deps, resolved.error);
|
|
1631
|
-
if (resolved.data === null) {
|
|
1632
|
-
return writeApiError(deps, {
|
|
1633
|
-
code: "not_found",
|
|
1634
|
-
message: `No drop matching "${target}" found in your account.`,
|
|
1635
|
-
suggestion: "It may belong to another account or have been deleted. Run dropthis list to see your drops, or pass the full drop_\u2026 id."
|
|
1636
|
-
});
|
|
1637
|
-
}
|
|
1638
|
-
dropId = resolved.data.id;
|
|
1639
|
-
defaultDirName = resolved.data.slug || resolved.data.id;
|
|
1640
|
-
}
|
|
1791
|
+
const resolved = await resolveDropTarget(target, deps);
|
|
1792
|
+
if (!resolved.ok) return { exitCode: resolved.exitCode };
|
|
1793
|
+
const dropId = resolved.dropId;
|
|
1794
|
+
const defaultDirName = resolved.slug || resolved.dropId;
|
|
1641
1795
|
const spin = shouldSpin(deps.outputMode) ? createSpinner("Pulling content\u2026", deps.stderr) : void 0;
|
|
1642
1796
|
const manifestResult = await deps.client.drops.getContent(dropId);
|
|
1643
1797
|
if (manifestResult.error) {
|
|
@@ -1820,7 +1974,7 @@ function assertDropId(target) {
|
|
|
1820
1974
|
}
|
|
1821
1975
|
|
|
1822
1976
|
// src/commands/update-settings.ts
|
|
1823
|
-
var
|
|
1977
|
+
var prompts5 = __toESM(require("@clack/prompts"), 1);
|
|
1824
1978
|
var NO_SETTINGS_MESSAGE = "Nothing to update. Provide at least one settings option.";
|
|
1825
1979
|
var NO_SETTINGS_NEXT_ACTION = "Run dropthis update-settings --help, or retry with one of: --title, --visibility, --password, --no-password, --noindex, --index, --expires-at, --metadata, or --metadata-file. To replace the content at the URL instead, use dropthis update-content <dropId> ./dist.";
|
|
1826
1980
|
async function runUpdateSettings(dropId, raw, deps) {
|
|
@@ -1844,7 +1998,7 @@ async function runUpdateSettings(dropId, raw, deps) {
|
|
|
1844
1998
|
if (shouldPrompt(deps)) {
|
|
1845
1999
|
const prompted = await promptForSettings(
|
|
1846
2000
|
dropId,
|
|
1847
|
-
deps.prompts ??
|
|
2001
|
+
deps.prompts ?? prompts5
|
|
1848
2002
|
);
|
|
1849
2003
|
if (!prompted) return { exitCode: 0 };
|
|
1850
2004
|
parsed = { ...parsed, ...prompted };
|
|
@@ -2054,6 +2208,109 @@ function assertDropId2(target) {
|
|
|
2054
2208
|
}
|
|
2055
2209
|
}
|
|
2056
2210
|
|
|
2211
|
+
// src/commands/upgrade.ts
|
|
2212
|
+
var import_node_child_process = require("child_process");
|
|
2213
|
+
var import_node_fs = require("fs");
|
|
2214
|
+
var import_node_util = require("util");
|
|
2215
|
+
|
|
2216
|
+
// src/semver.ts
|
|
2217
|
+
function compareSemver(a, b) {
|
|
2218
|
+
const parse = (v) => (v.split("-")[0] ?? v).split(".").map(Number);
|
|
2219
|
+
const pa = parse(a);
|
|
2220
|
+
const pb = parse(b);
|
|
2221
|
+
for (let i = 0; i < 3; i++) {
|
|
2222
|
+
const d = (pa[i] ?? 0) - (pb[i] ?? 0);
|
|
2223
|
+
if (d !== 0) return d < 0 ? -1 : 1;
|
|
2224
|
+
}
|
|
2225
|
+
return 0;
|
|
2226
|
+
}
|
|
2227
|
+
|
|
2228
|
+
// src/commands/upgrade.ts
|
|
2229
|
+
var execFileAsync = (0, import_node_util.promisify)(import_node_child_process.execFile);
|
|
2230
|
+
var REGISTRY_LATEST = "https://registry.npmjs.org/@dropthis%2fcli/latest";
|
|
2231
|
+
async function fetchLatestFromRegistry() {
|
|
2232
|
+
try {
|
|
2233
|
+
const res = await fetch(REGISTRY_LATEST, {
|
|
2234
|
+
signal: AbortSignal.timeout(1e4)
|
|
2235
|
+
});
|
|
2236
|
+
if (!res.ok) return null;
|
|
2237
|
+
const body = await res.json();
|
|
2238
|
+
return typeof body.version === "string" ? body.version : null;
|
|
2239
|
+
} catch {
|
|
2240
|
+
return null;
|
|
2241
|
+
}
|
|
2242
|
+
}
|
|
2243
|
+
async function detectNpmGlobalInstall() {
|
|
2244
|
+
try {
|
|
2245
|
+
const argv1 = process.argv[1];
|
|
2246
|
+
if (!argv1) return false;
|
|
2247
|
+
const entry = (0, import_node_fs.realpathSync)(argv1);
|
|
2248
|
+
const { stdout } = await execFileAsync("npm", ["root", "-g"]);
|
|
2249
|
+
const root = (0, import_node_fs.realpathSync)(stdout.trim());
|
|
2250
|
+
return entry.startsWith(root);
|
|
2251
|
+
} catch {
|
|
2252
|
+
return false;
|
|
2253
|
+
}
|
|
2254
|
+
}
|
|
2255
|
+
async function npmInstallLatest() {
|
|
2256
|
+
try {
|
|
2257
|
+
await execFileAsync("npm", ["install", "-g", "@dropthis/cli@latest"]);
|
|
2258
|
+
return { ok: true };
|
|
2259
|
+
} catch (err) {
|
|
2260
|
+
return {
|
|
2261
|
+
ok: false,
|
|
2262
|
+
message: err instanceof Error ? err.message : String(err)
|
|
2263
|
+
};
|
|
2264
|
+
}
|
|
2265
|
+
}
|
|
2266
|
+
async function runUpgrade(_input, deps) {
|
|
2267
|
+
const fetchLatest = deps.fetchLatest ?? fetchLatestFromRegistry;
|
|
2268
|
+
const isNpmGlobal = deps.isNpmGlobalInstall ?? detectNpmGlobalInstall;
|
|
2269
|
+
const install = deps.runNpmInstall ?? npmInstallLatest;
|
|
2270
|
+
const latest = await fetchLatest();
|
|
2271
|
+
if (!latest) {
|
|
2272
|
+
return writeError(
|
|
2273
|
+
deps,
|
|
2274
|
+
"upgrade_check_failed",
|
|
2275
|
+
"Could not reach the npm registry to check for updates. Try again, or run: npm install -g @dropthis/cli@latest"
|
|
2276
|
+
);
|
|
2277
|
+
}
|
|
2278
|
+
if (compareSemver(latest, deps.currentVersion) <= 0) {
|
|
2279
|
+
writeHumanOrJson(
|
|
2280
|
+
deps,
|
|
2281
|
+
`Already on latest version (${deps.currentVersion})`,
|
|
2282
|
+
{ ok: true, status: "already-latest", version: deps.currentVersion }
|
|
2283
|
+
);
|
|
2284
|
+
return { exitCode: 0 };
|
|
2285
|
+
}
|
|
2286
|
+
if (!await isNpmGlobal()) {
|
|
2287
|
+
return writeError(
|
|
2288
|
+
deps,
|
|
2289
|
+
"unsupported_install",
|
|
2290
|
+
`Update available (${deps.currentVersion} \u2192 ${latest}), but this install was not made with \`npm install -g\`. Upgrade with the installer you used, e.g.: npm install -g @dropthis/cli@latest`
|
|
2291
|
+
);
|
|
2292
|
+
}
|
|
2293
|
+
if (deps.outputMode === "human") {
|
|
2294
|
+
deps.stdout(`Updating ${deps.currentVersion} \u2192 ${latest}...
|
|
2295
|
+
`);
|
|
2296
|
+
}
|
|
2297
|
+
const result = await install();
|
|
2298
|
+
if (!result.ok) {
|
|
2299
|
+
return writeError(
|
|
2300
|
+
deps,
|
|
2301
|
+
"upgrade_failed",
|
|
2302
|
+
`npm install failed${result.message ? `: ${result.message}` : ""}. Try: npm install -g @dropthis/cli@latest`
|
|
2303
|
+
);
|
|
2304
|
+
}
|
|
2305
|
+
writeHumanOrJson(deps, `Updated ${deps.currentVersion} \u2192 ${latest}`, {
|
|
2306
|
+
ok: true,
|
|
2307
|
+
status: "upgraded",
|
|
2308
|
+
from: deps.currentVersion,
|
|
2309
|
+
to: latest
|
|
2310
|
+
});
|
|
2311
|
+
return { exitCode: 0 };
|
|
2312
|
+
}
|
|
2313
|
+
|
|
2057
2314
|
// src/commands/whoami.ts
|
|
2058
2315
|
async function runWhoami(_input, deps) {
|
|
2059
2316
|
const credential = await resolveCredential({
|
|
@@ -2233,6 +2490,55 @@ async function writeCredentialFile(path, credential) {
|
|
|
2233
2490
|
await (0, import_promises3.rename)(tmpPath, path);
|
|
2234
2491
|
}
|
|
2235
2492
|
|
|
2493
|
+
// src/typo-guard.ts
|
|
2494
|
+
var import_promises4 = require("fs/promises");
|
|
2495
|
+
function levenshtein(a, b) {
|
|
2496
|
+
if (a === b) return 0;
|
|
2497
|
+
if (a.length === 0) return b.length;
|
|
2498
|
+
if (b.length === 0) return a.length;
|
|
2499
|
+
let prev = Array.from({ length: b.length + 1 }, (_, j) => j);
|
|
2500
|
+
for (let i = 1; i <= a.length; i++) {
|
|
2501
|
+
const curr = [i];
|
|
2502
|
+
for (let j = 1; j <= b.length; j++) {
|
|
2503
|
+
const cost = a[i - 1] === b[j - 1] ? 0 : 1;
|
|
2504
|
+
const deletion = (prev[j] ?? 0) + 1;
|
|
2505
|
+
const insertion = (curr[j - 1] ?? 0) + 1;
|
|
2506
|
+
const substitution = (prev[j - 1] ?? 0) + cost;
|
|
2507
|
+
curr[j] = Math.min(deletion, insertion, substitution);
|
|
2508
|
+
}
|
|
2509
|
+
prev = curr;
|
|
2510
|
+
}
|
|
2511
|
+
return prev[b.length] ?? 0;
|
|
2512
|
+
}
|
|
2513
|
+
function suggestCommand(token, names) {
|
|
2514
|
+
const lower = token.toLowerCase();
|
|
2515
|
+
let best = null;
|
|
2516
|
+
for (const name of names) {
|
|
2517
|
+
if (lower.length >= 2 && name.startsWith(lower)) return name;
|
|
2518
|
+
const dist = levenshtein(lower, name);
|
|
2519
|
+
if (best === null || dist < best.dist) best = { name, dist };
|
|
2520
|
+
}
|
|
2521
|
+
if (best !== null && best.dist <= 2 && best.dist < lower.length) {
|
|
2522
|
+
return best.name;
|
|
2523
|
+
}
|
|
2524
|
+
return null;
|
|
2525
|
+
}
|
|
2526
|
+
function isBareWordToken(token) {
|
|
2527
|
+
if (token === "" || token === "-") return false;
|
|
2528
|
+
if (/\s/.test(token)) return false;
|
|
2529
|
+
if (token.includes("/") || token.includes("\\")) return false;
|
|
2530
|
+
if (token.includes(".")) return false;
|
|
2531
|
+
return true;
|
|
2532
|
+
}
|
|
2533
|
+
async function pathExists(path) {
|
|
2534
|
+
try {
|
|
2535
|
+
await (0, import_promises4.stat)(path);
|
|
2536
|
+
return true;
|
|
2537
|
+
} catch {
|
|
2538
|
+
return false;
|
|
2539
|
+
}
|
|
2540
|
+
}
|
|
2541
|
+
|
|
2236
2542
|
// src/program.ts
|
|
2237
2543
|
function buildProgram(options = {}) {
|
|
2238
2544
|
const program = new import_commander.Command();
|
|
@@ -2243,6 +2549,7 @@ function buildProgram(options = {}) {
|
|
|
2243
2549
|
return argv.includes("--json") || argv.includes("--quiet") || argv.includes("-q") || options.env?.CI === "true" || options.env === void 0 && process.env.CI === "true" || options.stdoutIsTTY === false || options.stdoutIsTTY === void 0 && process.stdout.isTTY !== true;
|
|
2244
2550
|
};
|
|
2245
2551
|
program.exitOverride();
|
|
2552
|
+
program.showSuggestionAfterError();
|
|
2246
2553
|
program.configureOutput({
|
|
2247
2554
|
writeErr,
|
|
2248
2555
|
// In JSON mode, suppress commander's default plain-text error so the
|
|
@@ -2253,13 +2560,13 @@ function buildProgram(options = {}) {
|
|
|
2253
2560
|
});
|
|
2254
2561
|
program.name("dropthis").description(
|
|
2255
2562
|
[
|
|
2256
|
-
|
|
2563
|
+
import_picocolors6.default.dim("Publish anything online and get a URL back."),
|
|
2257
2564
|
"",
|
|
2258
|
-
`${
|
|
2259
|
-
` ${
|
|
2260
|
-
` ${
|
|
2565
|
+
`${import_picocolors6.default.bold("Quick start:")}`,
|
|
2566
|
+
` ${import_picocolors6.default.cyan("dropthis login")}`,
|
|
2567
|
+
` ${import_picocolors6.default.cyan("dropthis publish ./dist")}`
|
|
2261
2568
|
].join("\n")
|
|
2262
|
-
).version("0.
|
|
2569
|
+
).version("0.13.0").configureHelp({
|
|
2263
2570
|
subcommandTerm(cmd) {
|
|
2264
2571
|
const args = cmd.registeredArguments.map((a) => {
|
|
2265
2572
|
const name = a.name();
|
|
@@ -2268,16 +2575,28 @@ function buildProgram(options = {}) {
|
|
|
2268
2575
|
}).join(" ");
|
|
2269
2576
|
return args ? `${cmd.name()} ${args}` : cmd.name();
|
|
2270
2577
|
},
|
|
2271
|
-
styleTitle: (title) =>
|
|
2272
|
-
styleCommandText: (str) =>
|
|
2273
|
-
styleSubcommandText: (str) =>
|
|
2274
|
-
styleOptionText: (str) =>
|
|
2578
|
+
styleTitle: (title) => import_picocolors6.default.bold(title),
|
|
2579
|
+
styleCommandText: (str) => import_picocolors6.default.cyan(str),
|
|
2580
|
+
styleSubcommandText: (str) => import_picocolors6.default.cyan(str),
|
|
2581
|
+
styleOptionText: (str) => import_picocolors6.default.yellow(str)
|
|
2275
2582
|
});
|
|
2276
2583
|
program.option("--api-key <key>", "Override API key for this invocation");
|
|
2277
2584
|
program.option("--api-url <url>", "Override API base URL");
|
|
2278
2585
|
program.option("--json", "Force JSON output");
|
|
2279
2586
|
program.option("-q, --quiet", "Suppress status output and imply JSON");
|
|
2280
2587
|
program.option("--no-interactive", "Disable interactive prompts");
|
|
2588
|
+
program.addHelpText(
|
|
2589
|
+
"after",
|
|
2590
|
+
[
|
|
2591
|
+
"",
|
|
2592
|
+
"Output is JSON when piped/CI/--json; human tables in a terminal.",
|
|
2593
|
+
"Docs: https://dropthis.app"
|
|
2594
|
+
].join("\n")
|
|
2595
|
+
);
|
|
2596
|
+
const examplesBlock = (lines) => `
|
|
2597
|
+
${import_picocolors6.default.bold("Examples:")}
|
|
2598
|
+
${lines.map((l) => ` ${l}`).join("\n")}
|
|
2599
|
+
`;
|
|
2281
2600
|
program.command("publish [input...]", { isDefault: true }).description(
|
|
2282
2601
|
"Publish content to a permanent public URL (also: share, post, put online, make public, get a link).\nFiles, folders, URLs, strings, or stdin; multiple files bundle into one drop. Use - for stdin, or pipe without args.\nCreates a NEW drop each run \u2014 to change one you already published, use update-content (the files) or update-settings (title/visibility/password/expiry/metadata) with its drop_\u2026 id, not publish again."
|
|
2283
2602
|
).option("--title <title>", "Drop title").option("--visibility <v>", "public or unlisted (default: public)").option("--password <password>", "Require password to view").option("--noindex", "Prevent search-engine indexing").option("--expires-at <datetime>", "Auto-delete after this ISO 8601 date").option(
|
|
@@ -2301,6 +2620,15 @@ function buildProgram(options = {}) {
|
|
|
2301
2620
|
).option("--json", "Force JSON output").option(
|
|
2302
2621
|
"--idempotency-key <key>",
|
|
2303
2622
|
"Prevent duplicate publishes on retry (auto-generated)"
|
|
2623
|
+
).addHelpText(
|
|
2624
|
+
"after",
|
|
2625
|
+
examplesBlock([
|
|
2626
|
+
"dropthis publish ./report.html",
|
|
2627
|
+
"dropthis publish ./dist --title 'Launch page'",
|
|
2628
|
+
"cat report.md | dropthis publish - --content-type text/markdown --path report.md",
|
|
2629
|
+
"dropthis publish ./dist --domain reports.example.com --slug launch",
|
|
2630
|
+
"URL=$(dropthis publish ./dist --url)"
|
|
2631
|
+
])
|
|
2304
2632
|
).action(async (inputs, commandOptions) => {
|
|
2305
2633
|
const stdinIsTTY = options.stdinIsTTY ?? process.stdin.isTTY ?? false;
|
|
2306
2634
|
if (inputs.length === 0 && stdinIsTTY) {
|
|
@@ -2326,6 +2654,29 @@ function buildProgram(options = {}) {
|
|
|
2326
2654
|
process.exitCode = writeError(deps, "local_input_error", msg).exitCode;
|
|
2327
2655
|
return;
|
|
2328
2656
|
}
|
|
2657
|
+
if (deps.outputMode === "human" && deps.interactive && inputs.length === 1 && typeof publishInput === "string" && isBareWordToken(publishInput) && !await pathExists(publishInput)) {
|
|
2658
|
+
const suggestion = suggestCommand(
|
|
2659
|
+
publishInput,
|
|
2660
|
+
program.commands.map((c) => c.name())
|
|
2661
|
+
);
|
|
2662
|
+
if (suggestion) {
|
|
2663
|
+
process.exitCode = writeError(
|
|
2664
|
+
deps,
|
|
2665
|
+
"invalid_usage",
|
|
2666
|
+
`Unknown command '${publishInput}' \u2014 did you mean '${suggestion}'?`,
|
|
2667
|
+
`To publish the literal text, pipe it: echo '${publishInput}' | dropthis publish`
|
|
2668
|
+
).exitCode;
|
|
2669
|
+
return;
|
|
2670
|
+
}
|
|
2671
|
+
const prompts6 = await import("@clack/prompts");
|
|
2672
|
+
const confirmed = await prompts6.confirm({
|
|
2673
|
+
message: `Publish '${publishInput}' as inline text?`,
|
|
2674
|
+
initialValue: false
|
|
2675
|
+
});
|
|
2676
|
+
if (prompts6.isCancel(confirmed) || !confirmed) {
|
|
2677
|
+
return;
|
|
2678
|
+
}
|
|
2679
|
+
}
|
|
2329
2680
|
let dropOpts;
|
|
2330
2681
|
try {
|
|
2331
2682
|
dropOpts = toDropOptions(commandOptions);
|
|
@@ -2429,7 +2780,14 @@ function buildProgram(options = {}) {
|
|
|
2429
2780
|
);
|
|
2430
2781
|
program.command("pull <target>").description(
|
|
2431
2782
|
"Download a drop's files into a local directory (accepts the drop_\u2026 id, the drop URL, or its slug).\nFetches the current deployment's file manifest and writes every file. Pull, edit, then update-content to ship the changes back to the same URL \u2014 also the rollback path."
|
|
2432
|
-
).option("-o, --output <dir>", "Output directory (default: ./<slug-or-id>)").option("--json", "Force JSON output").
|
|
2783
|
+
).option("-o, --output <dir>", "Output directory (default: ./<slug-or-id>)").option("--json", "Force JSON output").addHelpText(
|
|
2784
|
+
"after",
|
|
2785
|
+
examplesBlock([
|
|
2786
|
+
"dropthis pull drop_abc123 -o ./site # download the drop's files",
|
|
2787
|
+
"$EDITOR ./site/index.html # edit locally",
|
|
2788
|
+
"dropthis update-content drop_abc123 ./site # ship back to the same URL"
|
|
2789
|
+
])
|
|
2790
|
+
).action(
|
|
2433
2791
|
async (target, commandOptions) => {
|
|
2434
2792
|
const deps = await commandDeps(
|
|
2435
2793
|
program,
|
|
@@ -2441,19 +2799,30 @@ function buildProgram(options = {}) {
|
|
|
2441
2799
|
process.exitCode = result.exitCode;
|
|
2442
2800
|
}
|
|
2443
2801
|
);
|
|
2444
|
-
program.command("get <dropId>").description(
|
|
2802
|
+
program.command("get <dropId>").description(
|
|
2803
|
+
"Show drop details (accepts the drop_\u2026 id, the drop URL, or its slug)"
|
|
2804
|
+
).option("--json", "Force JSON output").action(async (dropId, commandOptions) => {
|
|
2445
2805
|
const deps = await commandDeps(program, options, store, commandOptions);
|
|
2446
2806
|
const result = await runDropsGet(dropId, commandOptions, deps);
|
|
2447
2807
|
process.exitCode = result.exitCode;
|
|
2448
2808
|
});
|
|
2449
|
-
program.command("list").description("List your drops").option("--limit <n>", "Page size", parseInteger).option("--cursor <cursor>", "Pagination cursor").option("--json", "Force JSON output").
|
|
2809
|
+
program.command("list").description("List your drops").option("--limit <n>", "Page size", parseInteger).option("--cursor <cursor>", "Pagination cursor").option("--domain <hostname>", "Only drops mounted on this custom domain").option("--json", "Force JSON output").addHelpText(
|
|
2810
|
+
"after",
|
|
2811
|
+
examplesBlock([
|
|
2812
|
+
"dropthis list",
|
|
2813
|
+
"dropthis list --json | jq -r '.drops[] | [.id, .url] | @tsv' # recover drop ids",
|
|
2814
|
+
"dropthis list --domain reports.example.com --json # drops on a custom domain"
|
|
2815
|
+
])
|
|
2816
|
+
).action(
|
|
2450
2817
|
async (commandOptions) => {
|
|
2451
2818
|
const deps = await commandDeps(program, options, store, commandOptions);
|
|
2452
2819
|
const result = await runDropsList(commandOptions, deps);
|
|
2453
2820
|
process.exitCode = result.exitCode;
|
|
2454
2821
|
}
|
|
2455
2822
|
);
|
|
2456
|
-
program.command("delete <dropId>").description(
|
|
2823
|
+
program.command("delete <dropId>").description(
|
|
2824
|
+
"Delete a drop (accepts the drop_\u2026 id, the drop URL, or its slug)"
|
|
2825
|
+
).option("--yes", "Confirm deletion").option("--json", "Force JSON output").action(
|
|
2457
2826
|
async (dropId, commandOptions) => {
|
|
2458
2827
|
const stdinIsTTY = options.stdinIsTTY ?? process.stdin.isTTY ?? false;
|
|
2459
2828
|
const global = globalOptions(program, commandOptions);
|
|
@@ -2497,7 +2866,15 @@ function buildProgram(options = {}) {
|
|
|
2497
2866
|
).requiredOption(
|
|
2498
2867
|
"--mode <mode>",
|
|
2499
2868
|
"Mount mode: path (many drops at hostname/{slug}/) or dedicated (one drop at root)"
|
|
2500
|
-
).option("--json", "Force JSON output").
|
|
2869
|
+
).option("--json", "Force JSON output").addHelpText(
|
|
2870
|
+
"after",
|
|
2871
|
+
examplesBlock([
|
|
2872
|
+
"dropthis domains connect reports.example.com --mode path",
|
|
2873
|
+
"# add the CNAME shown above at your DNS provider, then:",
|
|
2874
|
+
"dropthis domains verify reports.example.com --wait",
|
|
2875
|
+
"dropthis publish ./report.html --domain reports.example.com"
|
|
2876
|
+
])
|
|
2877
|
+
).action(
|
|
2501
2878
|
async (hostname, commandOptions) => {
|
|
2502
2879
|
if (commandOptions.mode !== "path" && commandOptions.mode !== "dedicated") {
|
|
2503
2880
|
process.stderr.write(`error: --mode must be "path" or "dedicated"
|
|
@@ -2529,7 +2906,13 @@ function buildProgram(options = {}) {
|
|
|
2529
2906
|
"--timeout <secs>",
|
|
2530
2907
|
"Max seconds to wait (default: 300)",
|
|
2531
2908
|
parseInteger
|
|
2532
|
-
).option("--json", "Force JSON output").
|
|
2909
|
+
).option("--json", "Force JSON output").addHelpText(
|
|
2910
|
+
"after",
|
|
2911
|
+
examplesBlock([
|
|
2912
|
+
"dropthis domains verify reports.example.com --wait",
|
|
2913
|
+
"dropthis domains verify reports.example.com --wait --timeout 600"
|
|
2914
|
+
])
|
|
2915
|
+
).action(
|
|
2533
2916
|
async (hostname, commandOptions) => {
|
|
2534
2917
|
const deps = await commandDeps(program, options, store, commandOptions);
|
|
2535
2918
|
const result = await runDomainsVerify(hostname, commandOptions, deps);
|
|
@@ -2553,12 +2936,23 @@ function buildProgram(options = {}) {
|
|
|
2553
2936
|
}
|
|
2554
2937
|
);
|
|
2555
2938
|
domains.command("remove <hostname>").description(
|
|
2556
|
-
"Remove a custom domain. IMPORTANT: also delete the DNS CNAME at your provider to prevent DNS hijacking."
|
|
2557
|
-
).option("--json", "Force JSON output").action(
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2939
|
+
"Remove a custom domain (unmounts its drops). IMPORTANT: also delete the DNS CNAME at your provider to prevent DNS hijacking."
|
|
2940
|
+
).option("--yes", "Confirm removal").option("--json", "Force JSON output").action(
|
|
2941
|
+
async (hostname, commandOptions) => {
|
|
2942
|
+
const stdinIsTTY = options.stdinIsTTY ?? process.stdin.isTTY ?? false;
|
|
2943
|
+
const global = globalOptions(program, commandOptions);
|
|
2944
|
+
const deps = await commandDeps(program, options, store, commandOptions);
|
|
2945
|
+
const result = await runDomainsRemove(
|
|
2946
|
+
hostname,
|
|
2947
|
+
{
|
|
2948
|
+
...commandOptions,
|
|
2949
|
+
interactive: isInteractive(stdinIsTTY, deps.env, global)
|
|
2950
|
+
},
|
|
2951
|
+
deps
|
|
2952
|
+
);
|
|
2953
|
+
process.exitCode = result.exitCode;
|
|
2954
|
+
}
|
|
2955
|
+
);
|
|
2562
2956
|
const apiKeys = program.command("api-keys").description("Manage API keys");
|
|
2563
2957
|
apiKeys.command("create").description("Create an API key").option("--label <label>", "API key label", "CLI").option("--json", "Force JSON output").action(async (commandOptions) => {
|
|
2564
2958
|
const deps = await commandDeps(program, options, store, commandOptions);
|
|
@@ -2591,6 +2985,16 @@ function buildProgram(options = {}) {
|
|
|
2591
2985
|
if (!commandOptions.email || !commandOptions.otp) {
|
|
2592
2986
|
const deps2 = await commandDeps(program, options, store, commandOptions);
|
|
2593
2987
|
const global2 = globalOptions(program, commandOptions);
|
|
2988
|
+
const stdinIsTTY = options.stdinIsTTY ?? process.stdin.isTTY ?? false;
|
|
2989
|
+
if (!isInteractive(stdinIsTTY, deps2.env, global2)) {
|
|
2990
|
+
process.exitCode = writeError(
|
|
2991
|
+
deps2,
|
|
2992
|
+
"invalid_usage",
|
|
2993
|
+
"dropthis login is interactive and needs a terminal.",
|
|
2994
|
+
"Set DROPTHIS_API_KEY, or run: dropthis login request --email <email>, then dropthis login verify --email <email> --otp <code>."
|
|
2995
|
+
).exitCode;
|
|
2996
|
+
return;
|
|
2997
|
+
}
|
|
2594
2998
|
const context = createContext({ global: global2 });
|
|
2595
2999
|
const result2 = await runLoginInteractive({
|
|
2596
3000
|
...deps2,
|
|
@@ -2694,6 +3098,19 @@ function buildProgram(options = {}) {
|
|
|
2694
3098
|
const result = await runDoctor(commandOptions, deps);
|
|
2695
3099
|
process.exitCode = result.exitCode;
|
|
2696
3100
|
});
|
|
3101
|
+
program.command("upgrade").description("Update the CLI to the latest version from npm").option("--json", "Force JSON output").action(async (commandOptions) => {
|
|
3102
|
+
const deps = await commandDeps(
|
|
3103
|
+
program,
|
|
3104
|
+
options,
|
|
3105
|
+
store,
|
|
3106
|
+
commandOptions
|
|
3107
|
+
);
|
|
3108
|
+
const result = await runUpgrade(commandOptions, {
|
|
3109
|
+
...deps,
|
|
3110
|
+
currentVersion: "0.13.0"
|
|
3111
|
+
});
|
|
3112
|
+
process.exitCode = result.exitCode;
|
|
3113
|
+
});
|
|
2697
3114
|
program.command("commands").description("Print machine-readable command metadata").option("--json", "Force JSON output").action(async (commandOptions) => {
|
|
2698
3115
|
const deps = await commandDeps(
|
|
2699
3116
|
program,
|
|
@@ -2842,6 +3259,72 @@ async function readStdinBytes(stdin) {
|
|
|
2842
3259
|
return Buffer.concat(chunks);
|
|
2843
3260
|
}
|
|
2844
3261
|
|
|
3262
|
+
// src/update-check.ts
|
|
3263
|
+
var import_node_child_process2 = require("child_process");
|
|
3264
|
+
var import_node_fs2 = require("fs");
|
|
3265
|
+
var import_node_os3 = require("os");
|
|
3266
|
+
var import_node_path3 = require("path");
|
|
3267
|
+
var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
|
|
3268
|
+
var REGISTRY_LATEST2 = "https://registry.npmjs.org/@dropthis%2fcli/latest";
|
|
3269
|
+
function updateCachePath(configDir) {
|
|
3270
|
+
return (0, import_node_path3.join)(
|
|
3271
|
+
configDir ?? (0, import_node_path3.join)((0, import_node_os3.homedir)(), ".config", "dropthis"),
|
|
3272
|
+
"update-check.json"
|
|
3273
|
+
);
|
|
3274
|
+
}
|
|
3275
|
+
function readCache(path) {
|
|
3276
|
+
try {
|
|
3277
|
+
const value = JSON.parse((0, import_node_fs2.readFileSync)(path, "utf8"));
|
|
3278
|
+
if (typeof value.lastCheckedAt !== "string" || typeof value.latestVersion !== "string")
|
|
3279
|
+
return null;
|
|
3280
|
+
return {
|
|
3281
|
+
lastCheckedAt: value.lastCheckedAt,
|
|
3282
|
+
latestVersion: value.latestVersion
|
|
3283
|
+
};
|
|
3284
|
+
} catch {
|
|
3285
|
+
return null;
|
|
3286
|
+
}
|
|
3287
|
+
}
|
|
3288
|
+
function shouldShowNotice(input) {
|
|
3289
|
+
if (input.env.CI) return false;
|
|
3290
|
+
if (input.env.DROPTHIS_NO_UPDATE_NOTIFIER) return false;
|
|
3291
|
+
if (!input.stderrIsTTY) return false;
|
|
3292
|
+
if (input.argv.includes("--json") || input.argv.includes("--quiet") || input.argv.includes("-q"))
|
|
3293
|
+
return false;
|
|
3294
|
+
return true;
|
|
3295
|
+
}
|
|
3296
|
+
function noticeFromCache(input) {
|
|
3297
|
+
if (!input.cache) return null;
|
|
3298
|
+
if (compareSemver(input.cache.latestVersion, input.currentVersion) <= 0)
|
|
3299
|
+
return null;
|
|
3300
|
+
return `Update available ${input.currentVersion} \u2192 ${input.cache.latestVersion} \xB7 run \`dropthis upgrade\``;
|
|
3301
|
+
}
|
|
3302
|
+
function shouldRefresh(cache, now) {
|
|
3303
|
+
if (!cache) return true;
|
|
3304
|
+
const last = Date.parse(cache.lastCheckedAt);
|
|
3305
|
+
if (Number.isNaN(last)) return true;
|
|
3306
|
+
return now.getTime() - last >= CHECK_INTERVAL_MS;
|
|
3307
|
+
}
|
|
3308
|
+
function scheduleBackgroundRefresh(cachePath, spawnFn = import_node_child_process2.spawn) {
|
|
3309
|
+
const script = `
|
|
3310
|
+
const [, cachePath] = process.argv;
|
|
3311
|
+
fetch(${JSON.stringify(REGISTRY_LATEST2)}, { signal: AbortSignal.timeout(5000) })
|
|
3312
|
+
.then((r) => (r.ok ? r.json() : Promise.reject(new Error(String(r.status)))))
|
|
3313
|
+
.then((d) => {
|
|
3314
|
+
const fs = require("node:fs");
|
|
3315
|
+
const path = require("node:path");
|
|
3316
|
+
fs.mkdirSync(path.dirname(cachePath), { recursive: true });
|
|
3317
|
+
fs.writeFileSync(cachePath, JSON.stringify({ lastCheckedAt: new Date().toISOString(), latestVersion: String(d.version) }));
|
|
3318
|
+
})
|
|
3319
|
+
.catch(() => {});
|
|
3320
|
+
`;
|
|
3321
|
+
const child = spawnFn(process.execPath, ["-e", script, cachePath], {
|
|
3322
|
+
detached: true,
|
|
3323
|
+
stdio: "ignore"
|
|
3324
|
+
});
|
|
3325
|
+
child.unref();
|
|
3326
|
+
}
|
|
3327
|
+
|
|
2845
3328
|
// src/cli.ts
|
|
2846
3329
|
function writeUsageErrorEnvelope(input) {
|
|
2847
3330
|
if (input.json) {
|
|
@@ -2849,9 +3332,6 @@ function writeUsageErrorEnvelope(input) {
|
|
|
2849
3332
|
`${JSON.stringify(errorEnvelope("usage_error", input.message))}
|
|
2850
3333
|
`
|
|
2851
3334
|
);
|
|
2852
|
-
} else {
|
|
2853
|
-
input.stderr(`${input.message}
|
|
2854
|
-
`);
|
|
2855
3335
|
}
|
|
2856
3336
|
return 2;
|
|
2857
3337
|
}
|
|
@@ -2861,7 +3341,29 @@ function isCommanderError(err) {
|
|
|
2861
3341
|
function wantsJson(argv) {
|
|
2862
3342
|
return argv.includes("--json") || argv.includes("--quiet") || argv.includes("-q") || process.env.CI === "true" || process.stdout.isTTY !== true;
|
|
2863
3343
|
}
|
|
2864
|
-
|
|
3344
|
+
var updateCache = readCache(updateCachePath());
|
|
3345
|
+
var showNotice = shouldShowNotice({
|
|
3346
|
+
env: process.env,
|
|
3347
|
+
stderrIsTTY: process.stderr.isTTY === true,
|
|
3348
|
+
argv: process.argv.slice(2)
|
|
3349
|
+
});
|
|
3350
|
+
if (showNotice) {
|
|
3351
|
+
const notice = noticeFromCache({
|
|
3352
|
+
cache: updateCache,
|
|
3353
|
+
currentVersion: "0.13.0"
|
|
3354
|
+
});
|
|
3355
|
+
if (notice) {
|
|
3356
|
+
process.stderr.write(`
|
|
3357
|
+
${hint(notice)}
|
|
3358
|
+
|
|
3359
|
+
`);
|
|
3360
|
+
}
|
|
3361
|
+
}
|
|
3362
|
+
buildProgram({ store: createCredentialStore() }).parseAsync(process.argv).finally(() => {
|
|
3363
|
+
if (showNotice && shouldRefresh(updateCache, /* @__PURE__ */ new Date())) {
|
|
3364
|
+
scheduleBackgroundRefresh(updateCachePath());
|
|
3365
|
+
}
|
|
3366
|
+
}).catch((error2) => {
|
|
2865
3367
|
if (isCommanderError(error2)) {
|
|
2866
3368
|
if (error2.code === "commander.help" || error2.code === "commander.helpDisplayed" || error2.code === "commander.version") {
|
|
2867
3369
|
process.exitCode = 0;
|