@dropthis/cli 0.3.4 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.cjs +240 -223
- package/dist/cli.cjs.map +1 -1
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -44,6 +44,15 @@ async function resolveCredential(input) {
|
|
|
44
44
|
...stored.email ? { email: stored.email } : {}
|
|
45
45
|
};
|
|
46
46
|
}
|
|
47
|
+
async function requireCredential(input) {
|
|
48
|
+
const credential = await resolveCredential(input);
|
|
49
|
+
if (!credential) {
|
|
50
|
+
throw Object.assign(new Error("No API key found."), {
|
|
51
|
+
code: "auth_error"
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
return credential;
|
|
55
|
+
}
|
|
47
56
|
function maskKey(apiKey) {
|
|
48
57
|
return apiKey.length <= 8 ? "sk_..." : `${apiKey.slice(0, 3)}...${apiKey.slice(-4)}`;
|
|
49
58
|
}
|
|
@@ -251,11 +260,13 @@ function writeEmpty(deps, message, json) {
|
|
|
251
260
|
|
|
252
261
|
// src/commands/account.ts
|
|
253
262
|
async function runAccountGet(_input, deps) {
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
263
|
+
try {
|
|
264
|
+
await requireCredential({
|
|
265
|
+
...deps.apiKey ? { apiKey: deps.apiKey } : {},
|
|
266
|
+
env: deps.env,
|
|
267
|
+
store: deps.store
|
|
268
|
+
});
|
|
269
|
+
} catch {
|
|
259
270
|
return writeAuthError(deps);
|
|
260
271
|
}
|
|
261
272
|
const result = await deps.client.account.get();
|
|
@@ -273,8 +284,33 @@ async function runAccountGet(_input, deps) {
|
|
|
273
284
|
|
|
274
285
|
// src/commands/api-keys.ts
|
|
275
286
|
var prompts = __toESM(require("@clack/prompts"), 1);
|
|
287
|
+
|
|
288
|
+
// src/types.ts
|
|
289
|
+
function unwrapListData(data, ...fallbackKeys) {
|
|
290
|
+
if (data && typeof data === "object") {
|
|
291
|
+
if ("data" in data) {
|
|
292
|
+
return data.data;
|
|
293
|
+
}
|
|
294
|
+
for (const key of fallbackKeys) {
|
|
295
|
+
if (key in data) {
|
|
296
|
+
return data[key];
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
return data;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// src/commands/api-keys.ts
|
|
276
304
|
async function runApiKeysCreate(input, deps) {
|
|
277
|
-
|
|
305
|
+
try {
|
|
306
|
+
await requireCredential({
|
|
307
|
+
...deps.apiKey ? { apiKey: deps.apiKey } : {},
|
|
308
|
+
env: deps.env,
|
|
309
|
+
store: deps.store
|
|
310
|
+
});
|
|
311
|
+
} catch {
|
|
312
|
+
return writeAuthError(deps);
|
|
313
|
+
}
|
|
278
314
|
const result = await deps.client.apiKeys.create({ label: input.label });
|
|
279
315
|
if (result.error) return writeApiErrorSimple(deps, result.error.message);
|
|
280
316
|
const data = result.data;
|
|
@@ -286,10 +322,18 @@ async function runApiKeysCreate(input, deps) {
|
|
|
286
322
|
return { exitCode: 0 };
|
|
287
323
|
}
|
|
288
324
|
async function runApiKeysList(_input, deps) {
|
|
289
|
-
|
|
325
|
+
try {
|
|
326
|
+
await requireCredential({
|
|
327
|
+
...deps.apiKey ? { apiKey: deps.apiKey } : {},
|
|
328
|
+
env: deps.env,
|
|
329
|
+
store: deps.store
|
|
330
|
+
});
|
|
331
|
+
} catch {
|
|
332
|
+
return writeAuthError(deps);
|
|
333
|
+
}
|
|
290
334
|
const result = await deps.client.apiKeys.list();
|
|
291
335
|
if (result.error) return writeApiErrorSimple(deps, result.error.message);
|
|
292
|
-
const raw =
|
|
336
|
+
const raw = unwrapListData(result.data, "apiKeys", "api_keys");
|
|
293
337
|
const items = Array.isArray(raw) ? raw : void 0;
|
|
294
338
|
if (deps.outputMode === "human") {
|
|
295
339
|
if (!items || items.length === 0) {
|
|
@@ -323,7 +367,15 @@ async function runApiKeysDelete(keyId, input, deps) {
|
|
|
323
367
|
return { exitCode: 0 };
|
|
324
368
|
}
|
|
325
369
|
}
|
|
326
|
-
|
|
370
|
+
try {
|
|
371
|
+
await requireCredential({
|
|
372
|
+
...deps.apiKey ? { apiKey: deps.apiKey } : {},
|
|
373
|
+
env: deps.env,
|
|
374
|
+
store: deps.store
|
|
375
|
+
});
|
|
376
|
+
} catch {
|
|
377
|
+
return writeAuthError(deps);
|
|
378
|
+
}
|
|
327
379
|
const result = await deps.client.apiKeys.delete(keyId);
|
|
328
380
|
if (result?.error) return writeApiErrorSimple(deps, result.error.message);
|
|
329
381
|
writeHumanOrJson(deps, success(`Deleted ${keyId}`), {
|
|
@@ -333,25 +385,9 @@ async function runApiKeysDelete(keyId, input, deps) {
|
|
|
333
385
|
});
|
|
334
386
|
return { exitCode: 0 };
|
|
335
387
|
}
|
|
336
|
-
async function hasCredential(deps) {
|
|
337
|
-
return await resolveCredential({
|
|
338
|
-
...deps.apiKey ? { apiKey: deps.apiKey } : {},
|
|
339
|
-
env: deps.env,
|
|
340
|
-
store: deps.store
|
|
341
|
-
}) !== null;
|
|
342
|
-
}
|
|
343
|
-
function listItems(data) {
|
|
344
|
-
if (data && typeof data === "object" && "data" in data) {
|
|
345
|
-
return data.data;
|
|
346
|
-
}
|
|
347
|
-
if (data && typeof data === "object" && "apiKeys" in data) {
|
|
348
|
-
return data.apiKeys;
|
|
349
|
-
}
|
|
350
|
-
return data;
|
|
351
|
-
}
|
|
352
388
|
|
|
353
|
-
// src/
|
|
354
|
-
var
|
|
389
|
+
// src/catalog.ts
|
|
390
|
+
var COMMAND_CATALOG = [
|
|
355
391
|
{
|
|
356
392
|
name: "publish",
|
|
357
393
|
description: "Publish an input and return a Dropthis URL.",
|
|
@@ -426,12 +462,14 @@ var COMMANDS = [
|
|
|
426
462
|
examples: ["dropthis commands --json"]
|
|
427
463
|
}
|
|
428
464
|
];
|
|
465
|
+
|
|
466
|
+
// src/commands/commands.ts
|
|
429
467
|
async function runCommands(_input, deps) {
|
|
430
468
|
deps.stdout(
|
|
431
469
|
`${JSON.stringify({
|
|
432
470
|
ok: true,
|
|
433
471
|
output: "JSON by default in CI, pipes, non-TTY, --json, or --quiet.",
|
|
434
|
-
commands:
|
|
472
|
+
commands: COMMAND_CATALOG
|
|
435
473
|
})}
|
|
436
474
|
`
|
|
437
475
|
);
|
|
@@ -440,7 +478,15 @@ async function runCommands(_input, deps) {
|
|
|
440
478
|
|
|
441
479
|
// src/commands/deployments.ts
|
|
442
480
|
async function runDeploymentsList(dropId, input, deps) {
|
|
443
|
-
|
|
481
|
+
try {
|
|
482
|
+
await requireCredential({
|
|
483
|
+
...deps.apiKey ? { apiKey: deps.apiKey } : {},
|
|
484
|
+
env: deps.env,
|
|
485
|
+
store: deps.store
|
|
486
|
+
});
|
|
487
|
+
} catch {
|
|
488
|
+
return writeAuthError(deps);
|
|
489
|
+
}
|
|
444
490
|
const params = {
|
|
445
491
|
...input.limit !== void 0 ? { limit: input.limit } : {},
|
|
446
492
|
...input.cursor ? { cursor: input.cursor } : {}
|
|
@@ -473,7 +519,15 @@ async function runDeploymentsList(dropId, input, deps) {
|
|
|
473
519
|
return { exitCode: 0 };
|
|
474
520
|
}
|
|
475
521
|
async function runDeploymentsGet(dropId, deploymentId, _input, deps) {
|
|
476
|
-
|
|
522
|
+
try {
|
|
523
|
+
await requireCredential({
|
|
524
|
+
...deps.apiKey ? { apiKey: deps.apiKey } : {},
|
|
525
|
+
env: deps.env,
|
|
526
|
+
store: deps.store
|
|
527
|
+
});
|
|
528
|
+
} catch {
|
|
529
|
+
return writeAuthError(deps);
|
|
530
|
+
}
|
|
477
531
|
const result = await deps.client.deployments.get(dropId, deploymentId);
|
|
478
532
|
if (result.error) {
|
|
479
533
|
return writeApiError(deps, result.error);
|
|
@@ -487,13 +541,6 @@ async function runDeploymentsGet(dropId, deploymentId, _input, deps) {
|
|
|
487
541
|
writeKv(deps, pairs, { ok: true, deployment: result.data });
|
|
488
542
|
return { exitCode: 0 };
|
|
489
543
|
}
|
|
490
|
-
async function hasCredential2(deps) {
|
|
491
|
-
return await resolveCredential({
|
|
492
|
-
...deps.apiKey ? { apiKey: deps.apiKey } : {},
|
|
493
|
-
env: deps.env,
|
|
494
|
-
store: deps.store
|
|
495
|
-
}) !== null;
|
|
496
|
-
}
|
|
497
544
|
function spreadData(data) {
|
|
498
545
|
return data && typeof data === "object" ? data : { data };
|
|
499
546
|
}
|
|
@@ -508,13 +555,13 @@ async function runDoctor(_input, deps) {
|
|
|
508
555
|
const authSource = credential?.source ?? "missing";
|
|
509
556
|
const storageBackend = stored?.storage ?? "none";
|
|
510
557
|
const pairs = [
|
|
511
|
-
["Version", "0.3.
|
|
558
|
+
["Version", "0.3.5"],
|
|
512
559
|
["Auth", authSource],
|
|
513
560
|
["Storage", storageBackend]
|
|
514
561
|
];
|
|
515
562
|
writeKv(deps, pairs, {
|
|
516
563
|
ok: true,
|
|
517
|
-
version: "0.3.
|
|
564
|
+
version: "0.3.5",
|
|
518
565
|
auth: { source: authSource },
|
|
519
566
|
storage: { backend: storageBackend }
|
|
520
567
|
});
|
|
@@ -524,14 +571,22 @@ async function runDoctor(_input, deps) {
|
|
|
524
571
|
// src/commands/drops.ts
|
|
525
572
|
var prompts2 = __toESM(require("@clack/prompts"), 1);
|
|
526
573
|
async function runDropsList(input, deps) {
|
|
527
|
-
|
|
574
|
+
try {
|
|
575
|
+
await requireCredential({
|
|
576
|
+
...deps.apiKey ? { apiKey: deps.apiKey } : {},
|
|
577
|
+
env: deps.env,
|
|
578
|
+
store: deps.store
|
|
579
|
+
});
|
|
580
|
+
} catch {
|
|
581
|
+
return writeAuthError(deps);
|
|
582
|
+
}
|
|
528
583
|
const params = {
|
|
529
584
|
...input.limit !== void 0 ? { limit: input.limit } : {},
|
|
530
585
|
...input.cursor ? { cursor: input.cursor } : {}
|
|
531
586
|
};
|
|
532
587
|
const result = await deps.client.drops.list(params);
|
|
533
588
|
if (result.error) return writeApiErrorSimple(deps, result.error.message);
|
|
534
|
-
const raw =
|
|
589
|
+
const raw = unwrapListData(result.data, "drops");
|
|
535
590
|
const items = Array.isArray(raw) ? raw : void 0;
|
|
536
591
|
if (deps.outputMode === "human") {
|
|
537
592
|
if (!items || items.length === 0) {
|
|
@@ -550,7 +605,15 @@ async function runDropsList(input, deps) {
|
|
|
550
605
|
return { exitCode: 0 };
|
|
551
606
|
}
|
|
552
607
|
async function runDropsGet(dropId, _input, deps) {
|
|
553
|
-
|
|
608
|
+
try {
|
|
609
|
+
await requireCredential({
|
|
610
|
+
...deps.apiKey ? { apiKey: deps.apiKey } : {},
|
|
611
|
+
env: deps.env,
|
|
612
|
+
store: deps.store
|
|
613
|
+
});
|
|
614
|
+
} catch {
|
|
615
|
+
return writeAuthError(deps);
|
|
616
|
+
}
|
|
554
617
|
const result = await deps.client.drops.get(dropId);
|
|
555
618
|
if (result.error) return writeApiErrorSimple(deps, result.error.message);
|
|
556
619
|
const data = result.data;
|
|
@@ -587,7 +650,15 @@ async function runDropsDelete(dropId, input, deps) {
|
|
|
587
650
|
return { exitCode: 0 };
|
|
588
651
|
}
|
|
589
652
|
}
|
|
590
|
-
|
|
653
|
+
try {
|
|
654
|
+
await requireCredential({
|
|
655
|
+
...deps.apiKey ? { apiKey: deps.apiKey } : {},
|
|
656
|
+
env: deps.env,
|
|
657
|
+
store: deps.store
|
|
658
|
+
});
|
|
659
|
+
} catch {
|
|
660
|
+
return writeAuthError(deps);
|
|
661
|
+
}
|
|
591
662
|
const result = await deps.client.drops.delete(dropId);
|
|
592
663
|
if (result?.error) return writeApiErrorSimple(deps, result.error.message);
|
|
593
664
|
writeHumanOrJson(deps, success(`Deleted ${dropId}`), {
|
|
@@ -597,22 +668,6 @@ async function runDropsDelete(dropId, input, deps) {
|
|
|
597
668
|
});
|
|
598
669
|
return { exitCode: 0 };
|
|
599
670
|
}
|
|
600
|
-
async function hasCredential3(deps) {
|
|
601
|
-
return await resolveCredential({
|
|
602
|
-
...deps.apiKey ? { apiKey: deps.apiKey } : {},
|
|
603
|
-
env: deps.env,
|
|
604
|
-
store: deps.store
|
|
605
|
-
}) !== null;
|
|
606
|
-
}
|
|
607
|
-
function listItems2(data) {
|
|
608
|
-
if (data && typeof data === "object" && "data" in data) {
|
|
609
|
-
return data.data;
|
|
610
|
-
}
|
|
611
|
-
if (data && typeof data === "object" && "drops" in data) {
|
|
612
|
-
return data.drops;
|
|
613
|
-
}
|
|
614
|
-
return data;
|
|
615
|
-
}
|
|
616
671
|
|
|
617
672
|
// src/commands/login.ts
|
|
618
673
|
var prompts3 = __toESM(require("@clack/prompts"), 1);
|
|
@@ -758,9 +813,88 @@ async function runLogout(input, deps) {
|
|
|
758
813
|
}
|
|
759
814
|
|
|
760
815
|
// src/commands/publish.ts
|
|
761
|
-
var import_node_crypto = require("crypto");
|
|
762
816
|
var import_promises3 = require("fs/promises");
|
|
817
|
+
var import_node_path2 = require("path");
|
|
818
|
+
|
|
819
|
+
// src/drop-operations.ts
|
|
820
|
+
var import_node_crypto = require("crypto");
|
|
763
821
|
var import_node_path = require("path");
|
|
822
|
+
var MAX_BUNDLE_FILE_COUNT = 200;
|
|
823
|
+
function isFileSystemError(error2) {
|
|
824
|
+
if (!(error2 instanceof Error)) return false;
|
|
825
|
+
const code = error2.code;
|
|
826
|
+
return code === "ENOENT" || code === "ENOTDIR" || code === "EACCES" || code === "ELIMIT";
|
|
827
|
+
}
|
|
828
|
+
function mimeForPath(filePath) {
|
|
829
|
+
const ext = (0, import_node_path.extname)(filePath).toLowerCase();
|
|
830
|
+
const types = {
|
|
831
|
+
".html": "text/html",
|
|
832
|
+
".htm": "text/html",
|
|
833
|
+
".css": "text/css",
|
|
834
|
+
".js": "text/javascript",
|
|
835
|
+
".mjs": "text/javascript",
|
|
836
|
+
".json": "application/json",
|
|
837
|
+
".xml": "application/xml",
|
|
838
|
+
".svg": "image/svg+xml",
|
|
839
|
+
".txt": "text/plain",
|
|
840
|
+
".md": "text/markdown",
|
|
841
|
+
".jpg": "image/jpeg",
|
|
842
|
+
".jpeg": "image/jpeg",
|
|
843
|
+
".png": "image/png",
|
|
844
|
+
".gif": "image/gif",
|
|
845
|
+
".webp": "image/webp",
|
|
846
|
+
".ico": "image/x-icon",
|
|
847
|
+
".avif": "image/avif",
|
|
848
|
+
".pdf": "application/pdf",
|
|
849
|
+
".zip": "application/zip",
|
|
850
|
+
".woff": "font/woff",
|
|
851
|
+
".woff2": "font/woff2",
|
|
852
|
+
".ttf": "font/ttf",
|
|
853
|
+
".mp4": "video/mp4",
|
|
854
|
+
".webm": "video/webm"
|
|
855
|
+
};
|
|
856
|
+
return types[ext] ?? "application/octet-stream";
|
|
857
|
+
}
|
|
858
|
+
function withIdempotencyKey(options, prefix) {
|
|
859
|
+
return options.idempotencyKey ? options : { ...options, idempotencyKey: `cli_${prefix}_${(0, import_node_crypto.randomUUID)()}` };
|
|
860
|
+
}
|
|
861
|
+
function validateManifestFileCount(count) {
|
|
862
|
+
if (count > MAX_BUNDLE_FILE_COUNT) {
|
|
863
|
+
throw Object.assign(
|
|
864
|
+
new Error(
|
|
865
|
+
`Bundle contains ${count} files, exceeding the maximum of ${MAX_BUNDLE_FILE_COUNT}.`
|
|
866
|
+
),
|
|
867
|
+
{ code: "ELIMIT" }
|
|
868
|
+
);
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
function formatDryRunManifest(prepared, extra) {
|
|
872
|
+
const totalBytes = prepared.manifest.files.reduce(
|
|
873
|
+
(sum, f) => sum + f.sizeBytes,
|
|
874
|
+
0
|
|
875
|
+
);
|
|
876
|
+
return {
|
|
877
|
+
dryRun: true,
|
|
878
|
+
kind: "staged",
|
|
879
|
+
...extra,
|
|
880
|
+
manifest: {
|
|
881
|
+
files: prepared.manifest.files,
|
|
882
|
+
entry: prepared.manifest.entry ?? null
|
|
883
|
+
},
|
|
884
|
+
options: prepared.options,
|
|
885
|
+
...prepared.metadata ? { metadata: prepared.metadata } : {},
|
|
886
|
+
totalBytes
|
|
887
|
+
};
|
|
888
|
+
}
|
|
889
|
+
function dryRunOptionsBody(options) {
|
|
890
|
+
const result = {};
|
|
891
|
+
if (options.title) result.title = options.title;
|
|
892
|
+
if (options.visibility) result.visibility = options.visibility;
|
|
893
|
+
if (options.password !== void 0) result.password = options.password;
|
|
894
|
+
if (options.noindex !== void 0) result.noindex = options.noindex;
|
|
895
|
+
if (options.expiresAt) result.expires_at = options.expiresAt;
|
|
896
|
+
return result;
|
|
897
|
+
}
|
|
764
898
|
|
|
765
899
|
// src/options.ts
|
|
766
900
|
var import_promises = require("fs/promises");
|
|
@@ -856,14 +990,14 @@ async function readJsonObjectFile(path) {
|
|
|
856
990
|
}
|
|
857
991
|
|
|
858
992
|
// src/commands/publish.ts
|
|
859
|
-
var MAX_BUNDLE_FILE_COUNT = 200;
|
|
860
993
|
async function runPublish(input, raw, deps) {
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
994
|
+
try {
|
|
995
|
+
await requireCredential({
|
|
996
|
+
...raw.apiKey ?? deps.apiKey ? { apiKey: raw.apiKey ?? deps.apiKey } : {},
|
|
997
|
+
env: deps.env,
|
|
998
|
+
store: deps.store
|
|
999
|
+
});
|
|
1000
|
+
} catch {
|
|
867
1001
|
return writeAuthError(deps);
|
|
868
1002
|
}
|
|
869
1003
|
if (raw.dryRun) {
|
|
@@ -875,7 +1009,7 @@ async function runPublish(input, raw, deps) {
|
|
|
875
1009
|
if (raw.fromJson && singleInput) {
|
|
876
1010
|
throw new Error("Use either <input> or --from-json, not both.");
|
|
877
1011
|
}
|
|
878
|
-
const options =
|
|
1012
|
+
const options = withIdempotencyKey(await parseDropOptions(raw), "pub");
|
|
879
1013
|
const result = raw.fromJson ? await deps.client.drops.createRaw(
|
|
880
1014
|
await (deps.readJsonObject ?? readJsonObjectFile)(raw.fromJson),
|
|
881
1015
|
options.idempotencyKey ? { idempotencyKey: options.idempotencyKey } : {}
|
|
@@ -931,8 +1065,10 @@ async function handlePublishDryRun(input, raw, deps) {
|
|
|
931
1065
|
throw new Error("Client does not support dry-run.");
|
|
932
1066
|
}
|
|
933
1067
|
const prepared = await deps.client.prepare(input, options);
|
|
934
|
-
const output =
|
|
935
|
-
|
|
1068
|
+
const output = formatDryRunManifest(prepared);
|
|
1069
|
+
validateManifestFileCount(
|
|
1070
|
+
output.manifest.files.length
|
|
1071
|
+
);
|
|
936
1072
|
deps.stdout(`${JSON.stringify(output, null, 2)}
|
|
937
1073
|
`);
|
|
938
1074
|
return { exitCode: 0 };
|
|
@@ -963,18 +1099,12 @@ async function dryRunMultiFile(inputs, options, deps) {
|
|
|
963
1099
|
);
|
|
964
1100
|
}
|
|
965
1101
|
files.push({
|
|
966
|
-
path: (0,
|
|
1102
|
+
path: (0, import_node_path2.basename)(filePath),
|
|
967
1103
|
contentType: mimeForPath(filePath),
|
|
968
1104
|
sizeBytes: info.size
|
|
969
1105
|
});
|
|
970
1106
|
}
|
|
971
|
-
|
|
972
|
-
return writeError(
|
|
973
|
-
deps,
|
|
974
|
-
"local_input_error",
|
|
975
|
-
`Bundle contains ${files.length} files, exceeding the maximum of ${MAX_BUNDLE_FILE_COUNT}.`
|
|
976
|
-
);
|
|
977
|
-
}
|
|
1107
|
+
validateManifestFileCount(files.length);
|
|
978
1108
|
const entry = options.entry ?? files.find((f) => f.path === "index.html")?.path ?? files[0]?.path ?? null;
|
|
979
1109
|
const totalBytes = files.reduce((sum, f) => sum + f.sizeBytes, 0);
|
|
980
1110
|
const output = {
|
|
@@ -988,92 +1118,16 @@ async function dryRunMultiFile(inputs, options, deps) {
|
|
|
988
1118
|
`);
|
|
989
1119
|
return { exitCode: 0 };
|
|
990
1120
|
}
|
|
991
|
-
function formatDryRunOutput(prepared) {
|
|
992
|
-
const totalBytes = prepared.manifest.files.reduce(
|
|
993
|
-
(sum, f) => sum + f.sizeBytes,
|
|
994
|
-
0
|
|
995
|
-
);
|
|
996
|
-
return {
|
|
997
|
-
dryRun: true,
|
|
998
|
-
kind: "staged",
|
|
999
|
-
manifest: {
|
|
1000
|
-
files: prepared.manifest.files,
|
|
1001
|
-
entry: prepared.manifest.entry ?? null
|
|
1002
|
-
},
|
|
1003
|
-
options: prepared.options,
|
|
1004
|
-
...prepared.metadata ? { metadata: prepared.metadata } : {},
|
|
1005
|
-
totalBytes
|
|
1006
|
-
};
|
|
1007
|
-
}
|
|
1008
|
-
function validateDryRunOutput(output) {
|
|
1009
|
-
if (output.kind !== "staged") return;
|
|
1010
|
-
const manifest = output.manifest;
|
|
1011
|
-
if (manifest.files.length > MAX_BUNDLE_FILE_COUNT) {
|
|
1012
|
-
throw Object.assign(
|
|
1013
|
-
new Error(
|
|
1014
|
-
`Bundle contains ${manifest.files.length} files, exceeding the maximum of ${MAX_BUNDLE_FILE_COUNT}.`
|
|
1015
|
-
),
|
|
1016
|
-
{ code: "ELIMIT" }
|
|
1017
|
-
);
|
|
1018
|
-
}
|
|
1019
|
-
}
|
|
1020
|
-
function dryRunOptionsBody(options) {
|
|
1021
|
-
const result = {};
|
|
1022
|
-
if (options.title) result.title = options.title;
|
|
1023
|
-
if (options.visibility) result.visibility = options.visibility;
|
|
1024
|
-
if (options.password !== void 0) result.password = options.password;
|
|
1025
|
-
if (options.noindex !== void 0) result.noindex = options.noindex;
|
|
1026
|
-
if (options.expiresAt) result.expires_at = options.expiresAt;
|
|
1027
|
-
return result;
|
|
1028
|
-
}
|
|
1029
|
-
function mimeForPath(filePath) {
|
|
1030
|
-
const ext = (0, import_node_path.extname)(filePath).toLowerCase();
|
|
1031
|
-
const types = {
|
|
1032
|
-
".html": "text/html",
|
|
1033
|
-
".htm": "text/html",
|
|
1034
|
-
".css": "text/css",
|
|
1035
|
-
".js": "text/javascript",
|
|
1036
|
-
".mjs": "text/javascript",
|
|
1037
|
-
".json": "application/json",
|
|
1038
|
-
".xml": "application/xml",
|
|
1039
|
-
".svg": "image/svg+xml",
|
|
1040
|
-
".txt": "text/plain",
|
|
1041
|
-
".md": "text/markdown",
|
|
1042
|
-
".jpg": "image/jpeg",
|
|
1043
|
-
".jpeg": "image/jpeg",
|
|
1044
|
-
".png": "image/png",
|
|
1045
|
-
".gif": "image/gif",
|
|
1046
|
-
".webp": "image/webp",
|
|
1047
|
-
".ico": "image/x-icon",
|
|
1048
|
-
".avif": "image/avif",
|
|
1049
|
-
".pdf": "application/pdf",
|
|
1050
|
-
".zip": "application/zip",
|
|
1051
|
-
".woff": "font/woff",
|
|
1052
|
-
".woff2": "font/woff2",
|
|
1053
|
-
".ttf": "font/ttf",
|
|
1054
|
-
".mp4": "video/mp4",
|
|
1055
|
-
".webm": "video/webm"
|
|
1056
|
-
};
|
|
1057
|
-
return types[ext] ?? "application/octet-stream";
|
|
1058
|
-
}
|
|
1059
|
-
function isFileSystemError(error2) {
|
|
1060
|
-
if (!(error2 instanceof Error)) return false;
|
|
1061
|
-
const code = error2.code;
|
|
1062
|
-
return code === "ENOENT" || code === "ENOTDIR" || code === "EACCES" || code === "ELIMIT";
|
|
1063
|
-
}
|
|
1064
|
-
function withPublishIdempotency(options) {
|
|
1065
|
-
return options.idempotencyKey ? options : { ...options, idempotencyKey: `cli_pub_${(0, import_node_crypto.randomUUID)()}` };
|
|
1066
|
-
}
|
|
1067
1121
|
|
|
1068
1122
|
// src/commands/update.ts
|
|
1069
|
-
var import_node_crypto2 = require("crypto");
|
|
1070
1123
|
async function runUpdate(target, input, raw, deps) {
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1124
|
+
try {
|
|
1125
|
+
await requireCredential({
|
|
1126
|
+
...raw.apiKey ?? deps.apiKey ? { apiKey: raw.apiKey ?? deps.apiKey } : {},
|
|
1127
|
+
env: deps.env,
|
|
1128
|
+
store: deps.store
|
|
1129
|
+
});
|
|
1130
|
+
} catch {
|
|
1077
1131
|
return writeAuthError(deps);
|
|
1078
1132
|
}
|
|
1079
1133
|
if (raw.dryRun) {
|
|
@@ -1090,17 +1144,23 @@ async function runUpdate(target, input, raw, deps) {
|
|
|
1090
1144
|
const result = raw.fromJson ? await deps.client.deployments.createRaw(
|
|
1091
1145
|
target,
|
|
1092
1146
|
await (deps.readJsonObject ?? readJsonObjectFile)(raw.fromJson),
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1147
|
+
withIdempotencyKey(
|
|
1148
|
+
{
|
|
1149
|
+
...revisionOptions,
|
|
1150
|
+
...parsed.idempotencyKey ? { idempotencyKey: parsed.idempotencyKey } : {}
|
|
1151
|
+
},
|
|
1152
|
+
"upd"
|
|
1153
|
+
)
|
|
1097
1154
|
) : input ? await deps.client.update(
|
|
1098
1155
|
target,
|
|
1099
1156
|
input,
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1157
|
+
withIdempotencyKey(
|
|
1158
|
+
{
|
|
1159
|
+
...parsed,
|
|
1160
|
+
...revisionOptions
|
|
1161
|
+
},
|
|
1162
|
+
"upd"
|
|
1163
|
+
)
|
|
1104
1164
|
) : await deps.client.update(target, parsed, revisionOptions);
|
|
1105
1165
|
if (result.error) {
|
|
1106
1166
|
spin?.fail();
|
|
@@ -1113,8 +1173,9 @@ async function runUpdate(target, input, raw, deps) {
|
|
|
1113
1173
|
return { exitCode: 0 };
|
|
1114
1174
|
} catch (error2) {
|
|
1115
1175
|
const message = error2 instanceof Error ? error2.message : "Update failed.";
|
|
1176
|
+
const code = isFileSystemError(error2) ? "local_input_error" : "invalid_usage";
|
|
1116
1177
|
spin?.fail();
|
|
1117
|
-
return writeError(deps,
|
|
1178
|
+
return writeError(deps, code, message);
|
|
1118
1179
|
}
|
|
1119
1180
|
}
|
|
1120
1181
|
async function handleUpdateDryRun(target, input, raw, deps) {
|
|
@@ -1160,56 +1221,17 @@ async function handleUpdateDryRun(target, input, raw, deps) {
|
|
|
1160
1221
|
throw new Error("Client does not support dry-run.");
|
|
1161
1222
|
}
|
|
1162
1223
|
const prepared = await deps.client.prepare(input, options);
|
|
1163
|
-
const output =
|
|
1164
|
-
|
|
1224
|
+
const output = formatDryRunManifest(prepared, { target });
|
|
1225
|
+
validateManifestFileCount(prepared.manifest.files.length);
|
|
1165
1226
|
deps.stdout(`${JSON.stringify(output, null, 2)}
|
|
1166
1227
|
`);
|
|
1167
1228
|
return { exitCode: 0 };
|
|
1168
1229
|
} catch (error2) {
|
|
1169
|
-
const code =
|
|
1230
|
+
const code = isFileSystemError(error2) ? "local_input_error" : "invalid_usage";
|
|
1170
1231
|
const message = error2 instanceof Error ? error2.message : "Dry-run failed.";
|
|
1171
1232
|
return writeError(deps, code, message);
|
|
1172
1233
|
}
|
|
1173
1234
|
}
|
|
1174
|
-
var MAX_BUNDLE_FILE_COUNT2 = 200;
|
|
1175
|
-
function formatUpdateDryRun(target, prepared) {
|
|
1176
|
-
const totalBytes = prepared.manifest.files.reduce(
|
|
1177
|
-
(sum, f) => sum + f.sizeBytes,
|
|
1178
|
-
0
|
|
1179
|
-
);
|
|
1180
|
-
return {
|
|
1181
|
-
dryRun: true,
|
|
1182
|
-
kind: "staged",
|
|
1183
|
-
target,
|
|
1184
|
-
manifest: {
|
|
1185
|
-
files: prepared.manifest.files,
|
|
1186
|
-
entry: prepared.manifest.entry ?? null
|
|
1187
|
-
},
|
|
1188
|
-
options: prepared.options,
|
|
1189
|
-
...prepared.metadata ? { metadata: prepared.metadata } : {},
|
|
1190
|
-
totalBytes
|
|
1191
|
-
};
|
|
1192
|
-
}
|
|
1193
|
-
function validateDryRunFileCount(output) {
|
|
1194
|
-
if (output.kind !== "staged") return;
|
|
1195
|
-
const manifest = output.manifest;
|
|
1196
|
-
if (manifest.files.length > MAX_BUNDLE_FILE_COUNT2) {
|
|
1197
|
-
throw Object.assign(
|
|
1198
|
-
new Error(
|
|
1199
|
-
`Bundle contains ${manifest.files.length} files, exceeding the maximum of ${MAX_BUNDLE_FILE_COUNT2}.`
|
|
1200
|
-
),
|
|
1201
|
-
{ code: "ELIMIT" }
|
|
1202
|
-
);
|
|
1203
|
-
}
|
|
1204
|
-
}
|
|
1205
|
-
function isFileSystemError2(error2) {
|
|
1206
|
-
if (!(error2 instanceof Error)) return false;
|
|
1207
|
-
const code = error2.code;
|
|
1208
|
-
return code === "ENOENT" || code === "ENOTDIR";
|
|
1209
|
-
}
|
|
1210
|
-
function withUpdateIdempotency(options) {
|
|
1211
|
-
return options.idempotencyKey ? options : { ...options, idempotencyKey: `cli_upd_${(0, import_node_crypto2.randomUUID)()}` };
|
|
1212
|
-
}
|
|
1213
1235
|
function assertDropId(target) {
|
|
1214
1236
|
if (!target.startsWith("drop_")) {
|
|
1215
1237
|
throw new Error(
|
|
@@ -1280,7 +1302,7 @@ function createContext(input) {
|
|
|
1280
1302
|
// src/storage.ts
|
|
1281
1303
|
var import_promises4 = require("fs/promises");
|
|
1282
1304
|
var import_node_os = require("os");
|
|
1283
|
-
var
|
|
1305
|
+
var import_node_path3 = require("path");
|
|
1284
1306
|
var import_keyring = require("@napi-rs/keyring");
|
|
1285
1307
|
var MemoryCredentialStore = class {
|
|
1286
1308
|
credential = null;
|
|
@@ -1357,8 +1379,8 @@ function defaultKeyringAdapter() {
|
|
|
1357
1379
|
};
|
|
1358
1380
|
}
|
|
1359
1381
|
function credentialPath(configDir) {
|
|
1360
|
-
return (0,
|
|
1361
|
-
configDir ?? (0,
|
|
1382
|
+
return (0, import_node_path3.join)(
|
|
1383
|
+
configDir ?? (0, import_node_path3.join)((0, import_node_os.homedir)(), ".config", "dropthis"),
|
|
1362
1384
|
"credentials.json"
|
|
1363
1385
|
);
|
|
1364
1386
|
}
|
|
@@ -1373,7 +1395,7 @@ async function readJsonFile(path) {
|
|
|
1373
1395
|
}
|
|
1374
1396
|
}
|
|
1375
1397
|
async function writeCredentialFile(path, credential) {
|
|
1376
|
-
await (0, import_promises4.mkdir)((0,
|
|
1398
|
+
await (0, import_promises4.mkdir)((0, import_node_path3.dirname)(path), { recursive: true });
|
|
1377
1399
|
await (0, import_promises4.writeFile)(path, `${JSON.stringify(credential, null, 2)}
|
|
1378
1400
|
`, {
|
|
1379
1401
|
mode: 384
|
|
@@ -1393,7 +1415,7 @@ function buildProgram(options = {}) {
|
|
|
1393
1415
|
` ${import_picocolors4.default.cyan("dropthis login")}`,
|
|
1394
1416
|
` ${import_picocolors4.default.cyan("dropthis publish ./dist")}`
|
|
1395
1417
|
].join("\n")
|
|
1396
|
-
).version("0.3.
|
|
1418
|
+
).version("0.3.5").configureHelp({
|
|
1397
1419
|
subcommandTerm(cmd) {
|
|
1398
1420
|
const args = cmd.registeredArguments.map((a) => {
|
|
1399
1421
|
const name = a.name();
|
|
@@ -1696,15 +1718,10 @@ function globalOptions(program, commandOptions) {
|
|
|
1696
1718
|
};
|
|
1697
1719
|
}
|
|
1698
1720
|
function toDropOptions(options) {
|
|
1699
|
-
if (options.visibility && options.visibility !== "public" && options.visibility !== "unlisted") {
|
|
1700
|
-
throw new Error(
|
|
1701
|
-
`Invalid visibility "${options.visibility}". Use "public" or "unlisted".`
|
|
1702
|
-
);
|
|
1703
|
-
}
|
|
1704
1721
|
return {
|
|
1705
1722
|
...options.slug ? { slug: options.slug } : {},
|
|
1706
1723
|
...options.title ? { title: options.title } : {},
|
|
1707
|
-
...options.visibility
|
|
1724
|
+
...options.visibility ? { visibility: options.visibility } : {},
|
|
1708
1725
|
...typeof options.password === "string" ? { password: options.password } : {},
|
|
1709
1726
|
...options.password === false || options.noPassword ? { noPassword: true } : {},
|
|
1710
1727
|
...options.noindex ? { noindex: true } : {},
|