@dropthis/cli 0.17.0 → 0.19.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/dist/cli.cjs CHANGED
@@ -702,6 +702,13 @@ var COMMAND_ANNOTATIONS = {
702
702
  auth: "required",
703
703
  examples: ["dropthis get drop_abc --json"]
704
704
  },
705
+ resolve: {
706
+ auth: "required",
707
+ examples: [
708
+ "dropthis resolve https://abc123.dropthis.app/",
709
+ "dropthis resolve abc123 --json"
710
+ ]
711
+ },
705
712
  list: {
706
713
  auth: "required",
707
714
  examples: [
@@ -909,13 +916,13 @@ async function runDoctor(_input, deps) {
909
916
  const authSource = credential?.source ?? "missing";
910
917
  const storageBackend = stored?.storage ?? "none";
911
918
  const pairs = [
912
- ["Version", "0.17.0"],
919
+ ["Version", "0.19.0"],
913
920
  ["Auth", authSource],
914
921
  ["Storage", storageBackend]
915
922
  ];
916
923
  writeKv(deps, pairs, {
917
924
  ok: true,
918
- version: "0.17.0",
925
+ version: "0.19.0",
919
926
  auth: { source: authSource },
920
927
  storage: { backend: storageBackend }
921
928
  });
@@ -1286,9 +1293,19 @@ async function resolveDropTarget(target, deps) {
1286
1293
  return {
1287
1294
  ok: true,
1288
1295
  dropId: resolved.data.id,
1289
- ...resolved.data.slug ? { slug: resolved.data.slug } : {}
1296
+ resolvedFrom: target,
1297
+ ...resolved.data.slug ? { slug: resolved.data.slug } : {},
1298
+ ...typeof resolved.data.title === "string" ? { title: resolved.data.title } : {}
1290
1299
  };
1291
1300
  }
1301
+ function writeResolvedLine(deps, resolved) {
1302
+ if (!resolved.resolvedFrom || deps.outputMode !== "human") return;
1303
+ const title = resolved.title ? ` (${resolved.title})` : "";
1304
+ deps.stdout(
1305
+ `${hint(`resolved ${resolved.resolvedFrom} \u2192 ${resolved.dropId}${title}`)}
1306
+ `
1307
+ );
1308
+ }
1292
1309
  async function runDropsList(input, deps) {
1293
1310
  try {
1294
1311
  await requireCredential({
@@ -1352,6 +1369,7 @@ async function runDropsGet(target, _input, deps) {
1352
1369
  }
1353
1370
  const resolved = await resolveDropTarget(target, deps);
1354
1371
  if (!resolved.ok) return { exitCode: resolved.exitCode };
1372
+ writeResolvedLine(deps, resolved);
1355
1373
  const result = await deps.client.drops.get(resolved.dropId);
1356
1374
  if (result.error) return writeApiError(deps, result.error);
1357
1375
  const data = result.data;
@@ -1374,6 +1392,34 @@ async function runDropsGet(target, _input, deps) {
1374
1392
  writeKv(deps, pairs, { ok: true, drop: result.data });
1375
1393
  return { exitCode: 0 };
1376
1394
  }
1395
+ async function runDropsResolve(target, _input, deps) {
1396
+ try {
1397
+ await requireCredential({
1398
+ ...deps.apiKey ? { apiKey: deps.apiKey } : {},
1399
+ env: deps.env,
1400
+ store: deps.store
1401
+ });
1402
+ } catch {
1403
+ return writeAuthError(deps);
1404
+ }
1405
+ const result = await deps.client.drops.resolve(target);
1406
+ if (result.error) return writeApiError(deps, result.error);
1407
+ if (result.data === null) {
1408
+ return writeApiError(deps, {
1409
+ code: "not_found",
1410
+ message: `No drop matching "${target}" found in your account.`,
1411
+ 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."
1412
+ });
1413
+ }
1414
+ const drop = result.data;
1415
+ const pairs = [];
1416
+ if (drop.id) pairs.push(["ID", String(drop.id)]);
1417
+ if (drop.url) pairs.push(["URL", url(String(drop.url))]);
1418
+ if (drop.title) pairs.push(["Title", String(drop.title)]);
1419
+ if (drop.slug) pairs.push(["Slug", String(drop.slug)]);
1420
+ writeKv(deps, pairs, { ok: true, drop });
1421
+ return { exitCode: 0 };
1422
+ }
1377
1423
  async function runDropsDelete(target, input, deps) {
1378
1424
  if (!input.yes && input.interactive === false) {
1379
1425
  return writeError(
@@ -1393,6 +1439,7 @@ async function runDropsDelete(target, input, deps) {
1393
1439
  }
1394
1440
  const resolved = await resolveDropTarget(target, deps);
1395
1441
  if (!resolved.ok) return { exitCode: resolved.exitCode };
1442
+ writeResolvedLine(deps, resolved);
1396
1443
  const dropId = resolved.dropId;
1397
1444
  if (!input.yes && input.interactive !== false) {
1398
1445
  const confirmed = await prompts3.confirm({
@@ -1609,6 +1656,7 @@ function formatDryRunManifest(prepared, extra) {
1609
1656
 
1610
1657
  // src/options.ts
1611
1658
  var import_promises = require("fs/promises");
1659
+ var import_node = require("@dropthis/node");
1612
1660
  async function parseDropOptions(raw) {
1613
1661
  if (raw.metadata && raw.metadataFile) {
1614
1662
  throw new Error("Use either --metadata or --metadata-file, not both.");
@@ -1619,6 +1667,9 @@ async function parseDropOptions(raw) {
1619
1667
  if (raw.noindex && raw.index) {
1620
1668
  throw new Error("Use either --noindex or --index, not both.");
1621
1669
  }
1670
+ if (raw.shared && raw.domain) {
1671
+ throw new Error("Use either --shared or --domain <hostname>, not both.");
1672
+ }
1622
1673
  if (raw.visibility && raw.visibility !== "public" && raw.visibility !== "unlisted") {
1623
1674
  throw new Error(
1624
1675
  `Invalid visibility "${raw.visibility}". Use "public" or "unlisted".`
@@ -1649,7 +1700,7 @@ async function parseDropOptions(raw) {
1649
1700
  ...raw.contentType ? { contentType: raw.contentType } : {},
1650
1701
  ...raw.path ? { path: raw.path } : {},
1651
1702
  ...raw.idempotencyKey ? { idempotencyKey: raw.idempotencyKey } : {},
1652
- ...raw.domain ? { domain: raw.domain } : {},
1703
+ ...raw.shared ? { domain: import_node.SHARED_POOL } : raw.domain ? { domain: raw.domain } : {},
1653
1704
  ...raw.slug ? { slug: raw.slug } : {}
1654
1705
  };
1655
1706
  }
@@ -1820,6 +1871,7 @@ async function runPull(target, input, deps) {
1820
1871
  }
1821
1872
  const resolved = await resolveDropTarget(target, deps);
1822
1873
  if (!resolved.ok) return { exitCode: resolved.exitCode };
1874
+ writeResolvedLine(deps, resolved);
1823
1875
  const dropId = resolved.dropId;
1824
1876
  const defaultDirName = resolved.slug || resolved.dropId;
1825
1877
  const spin = shouldSpin(deps.outputMode) ? createSpinner("Pulling content\u2026", deps.stderr) : void 0;
@@ -1905,22 +1957,30 @@ function contentOptions(options) {
1905
1957
  if (options.path !== void 0) out.path = options.path;
1906
1958
  return out;
1907
1959
  }
1908
- async function runUpdateContent(dropId, input, raw, deps) {
1960
+ async function runUpdateContent(target, input, raw, deps) {
1961
+ const apiKey = raw.apiKey ?? deps.apiKey;
1909
1962
  try {
1910
1963
  await requireCredential({
1911
- ...raw.apiKey ?? deps.apiKey ? { apiKey: raw.apiKey ?? deps.apiKey } : {},
1964
+ ...apiKey ? { apiKey } : {},
1912
1965
  env: deps.env,
1913
1966
  store: deps.store
1914
1967
  });
1915
1968
  } catch {
1916
1969
  return writeAuthError(deps);
1917
1970
  }
1971
+ const resolveDeps = {
1972
+ ...deps,
1973
+ ...apiKey ? { apiKey } : {}
1974
+ };
1975
+ const resolved = await resolveDropTarget(target, resolveDeps);
1976
+ if (!resolved.ok) return { exitCode: resolved.exitCode };
1977
+ const dropId = resolved.dropId;
1918
1978
  if (raw.dryRun) {
1919
1979
  return handleDryRun(dropId, input, raw, deps);
1920
1980
  }
1981
+ writeResolvedLine(deps, resolved);
1921
1982
  let spin;
1922
1983
  try {
1923
- assertDropId(dropId);
1924
1984
  const hasInput = Array.isArray(input) ? input.length > 0 : input !== void 0;
1925
1985
  if (!hasInput) {
1926
1986
  return writeError(
@@ -1967,7 +2027,6 @@ async function handleDryRun(dropId, input, raw, deps) {
1967
2027
  );
1968
2028
  }
1969
2029
  try {
1970
- assertDropId(dropId);
1971
2030
  const hasInput = Array.isArray(input) ? input.length > 0 : input !== void 0;
1972
2031
  if (!hasInput) {
1973
2032
  return writeError(
@@ -1995,34 +2054,35 @@ async function handleDryRun(dropId, input, raw, deps) {
1995
2054
  return writeError(deps, code, message);
1996
2055
  }
1997
2056
  }
1998
- function assertDropId(target) {
1999
- if (!target.startsWith("drop_")) {
2000
- throw new Error(
2001
- "update-content needs the full drop_\u2026 id from the publish response, not the URL slug, for example drop_..."
2002
- );
2003
- }
2004
- }
2005
2057
 
2006
2058
  // src/commands/update-settings.ts
2007
2059
  var prompts5 = __toESM(require("@clack/prompts"), 1);
2008
2060
  var NO_SETTINGS_MESSAGE = "Nothing to update. Provide at least one settings option.";
2009
2061
  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.";
2010
- async function runUpdateSettings(dropId, raw, deps) {
2062
+ async function runUpdateSettings(target, raw, deps) {
2063
+ const apiKey = raw.apiKey ?? deps.apiKey;
2011
2064
  try {
2012
2065
  await requireCredential({
2013
- ...raw.apiKey ?? deps.apiKey ? { apiKey: raw.apiKey ?? deps.apiKey } : {},
2066
+ ...apiKey ? { apiKey } : {},
2014
2067
  env: deps.env,
2015
2068
  store: deps.store
2016
2069
  });
2017
2070
  } catch {
2018
2071
  return writeAuthError(deps);
2019
2072
  }
2073
+ const resolveDeps = {
2074
+ ...deps,
2075
+ ...apiKey ? { apiKey } : {}
2076
+ };
2077
+ const resolved = await resolveDropTarget(target, resolveDeps);
2078
+ if (!resolved.ok) return { exitCode: resolved.exitCode };
2079
+ const dropId = resolved.dropId;
2020
2080
  if (raw.dryRun) {
2021
2081
  return handleDryRun2(dropId, raw, deps);
2022
2082
  }
2083
+ writeResolvedLine(deps, resolved);
2023
2084
  let spin;
2024
2085
  try {
2025
- assertDropId2(dropId);
2026
2086
  let parsed = await parseDropOptions(raw);
2027
2087
  if (!hasSettingsFields(parsed)) {
2028
2088
  if (shouldPrompt(deps)) {
@@ -2211,7 +2271,6 @@ async function handleDryRun2(dropId, raw, deps) {
2211
2271
  );
2212
2272
  }
2213
2273
  try {
2214
- assertDropId2(dropId);
2215
2274
  const options = await parseDropOptions(raw);
2216
2275
  const fields = {};
2217
2276
  if (options.title) fields.title = options.title;
@@ -2230,13 +2289,6 @@ async function handleDryRun2(dropId, raw, deps) {
2230
2289
  return writeError(deps, "invalid_usage", message);
2231
2290
  }
2232
2291
  }
2233
- function assertDropId2(target) {
2234
- if (!target.startsWith("drop_")) {
2235
- throw new Error(
2236
- "update-settings needs the full drop_\u2026 id from the publish response, not the URL slug, for example drop_..."
2237
- );
2238
- }
2239
- }
2240
2292
 
2241
2293
  // src/commands/upgrade.ts
2242
2294
  var import_node_child_process = require("child_process");
@@ -2389,7 +2441,7 @@ async function runWhoami(_input, deps) {
2389
2441
  }
2390
2442
 
2391
2443
  // src/context.ts
2392
- var import_node = require("@dropthis/node");
2444
+ var import_node2 = require("@dropthis/node");
2393
2445
  function createContext(input) {
2394
2446
  const env = input.env ?? process.env;
2395
2447
  const global = input.global ?? {};
@@ -2406,7 +2458,7 @@ function createContext(input) {
2406
2458
  stderr: input.stderr ?? ((value) => process.stderr.write(value)),
2407
2459
  createClient(apiKey) {
2408
2460
  const baseUrl = global.apiUrl ?? env.DROPTHIS_API_URL;
2409
- return new import_node.Dropthis({
2461
+ return new import_node2.Dropthis({
2410
2462
  ...apiKey ? { apiKey } : {},
2411
2463
  ...baseUrl ? { baseUrl } : {}
2412
2464
  });
@@ -2596,7 +2648,7 @@ function buildProgram(options = {}) {
2596
2648
  ` ${import_picocolors6.default.cyan("dropthis login")}`,
2597
2649
  ` ${import_picocolors6.default.cyan("dropthis publish ./dist")}`
2598
2650
  ].join("\n")
2599
- ).version("0.17.0").configureHelp({
2651
+ ).version("0.19.0").configureHelp({
2600
2652
  subcommandTerm(cmd) {
2601
2653
  const args = cmd.registeredArguments.map((a) => {
2602
2654
  const name = a.name();
@@ -2640,7 +2692,10 @@ ${lines.map((l) => ` ${l}`).join("\n")}
2640
2692
  `Attach JSON key-value pairs, e.g. '{"source":"ci"}'`
2641
2693
  ).option("--metadata-file <path>", "Read metadata JSON from a file").option("--path <name>", "Set filename when publishing from stdin").option(
2642
2694
  "--domain <hostname>",
2643
- "Serve this drop under a connected custom domain (must be live \u2014 see: dropthis domains list), or pass the literal 'shared' to publish to the shared pool even when the account has a default domain. Path-mode: drop lives at https://domain/{slug}/. Dedicated: drop is at the root (409 if occupied). Omit to use the account's default path domain."
2695
+ "Serve this drop under a connected custom domain (must be live \u2014 see: dropthis domains list). Path-mode: drop lives at https://domain/{slug}/. Dedicated: drop is at the root (409 if occupied). Omit to use the account's default path domain. To publish to the shared pool instead, use --shared."
2696
+ ).option(
2697
+ "--shared",
2698
+ "Deliberately publish to the shared dropthis pool, bypassing your default custom domain (an off-domain publish). Cannot combine with --domain."
2644
2699
  ).option(
2645
2700
  "--slug <vanity-slug>",
2646
2701
  "Vanity slug for path-mode custom domains (1\u201363 lowercase letters/digits/hyphens). Auto-suffixed if taken. Only valid with --domain on a path-mode domain."
@@ -2657,7 +2712,7 @@ ${lines.map((l) => ` ${l}`).join("\n")}
2657
2712
  "dropthis publish ./dist --title 'Launch page'",
2658
2713
  "cat report.md | dropthis publish - --content-type text/markdown --path report.md",
2659
2714
  "dropthis publish ./dist --domain reports.example.com --slug launch",
2660
- "dropthis publish ./report.html --domain shared # bypass the account default domain",
2715
+ "dropthis publish ./report.html --shared # bypass your default domain \u2192 shared pool",
2661
2716
  "URL=$(dropthis publish ./dist --url)"
2662
2717
  ])
2663
2718
  ).addHelpText(
@@ -2849,6 +2904,19 @@ ${import_picocolors6.default.bold("Canonical vs raw URLs:")}`,
2849
2904
  const result = await runDropsGet(dropId, commandOptions, deps);
2850
2905
  process.exitCode = result.exitCode;
2851
2906
  });
2907
+ program.command("resolve <target>").description(
2908
+ "Resolve a public drop URL or slug back to its drop_\u2026 id (accepts the id too).\nWrites are id-only \u2014 use this to recover the id from a URL, then update-content/update-settings/delete by that id."
2909
+ ).option("--json", "Force JSON output").addHelpText(
2910
+ "after",
2911
+ examplesBlock([
2912
+ "dropthis resolve https://abc123.dropthis.app/ # \u2192 drop_\u2026 id + url",
2913
+ "dropthis resolve abc123 --json | jq -r .drop.id"
2914
+ ])
2915
+ ).action(async (target, commandOptions) => {
2916
+ const deps = await commandDeps(program, options, store, commandOptions);
2917
+ const result = await runDropsResolve(target, commandOptions, deps);
2918
+ process.exitCode = result.exitCode;
2919
+ });
2852
2920
  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(
2853
2921
  "after",
2854
2922
  examplesBlock([
@@ -3153,7 +3221,7 @@ ${import_picocolors6.default.bold("Canonical vs raw URLs:")}`,
3153
3221
  );
3154
3222
  const result = await runUpgrade(commandOptions, {
3155
3223
  ...deps,
3156
- currentVersion: "0.17.0"
3224
+ currentVersion: "0.19.0"
3157
3225
  });
3158
3226
  process.exitCode = result.exitCode;
3159
3227
  });
@@ -3261,6 +3329,7 @@ function toDropOptions(options) {
3261
3329
  ...options.path ? { path: options.path } : {},
3262
3330
  ...options.idempotencyKey ? { idempotencyKey: options.idempotencyKey } : {},
3263
3331
  ...options.domain ? { domain: options.domain } : {},
3332
+ ...options.shared ? { shared: true } : {},
3264
3333
  ...options.slug ? { slug: options.slug } : {},
3265
3334
  ...options.json !== void 0 ? { json: options.json } : {},
3266
3335
  ...options.quiet !== void 0 ? { quiet: options.quiet } : {},
@@ -3396,7 +3465,7 @@ var showNotice = shouldShowNotice({
3396
3465
  if (showNotice) {
3397
3466
  const notice = noticeFromCache({
3398
3467
  cache: updateCache,
3399
- currentVersion: "0.17.0"
3468
+ currentVersion: "0.19.0"
3400
3469
  });
3401
3470
  if (notice) {
3402
3471
  process.stderr.write(`