@dropthis/cli 0.12.0 → 0.14.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 +3 -0
- package/dist/cli.cjs +222 -8
- 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-DephtJf-.d.cts} +9 -1
- package/node_modules/@dropthis/node/dist/{drops-DEJcU6qw.d.ts → drops-DephtJf-.d.ts} +9 -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/README.md
CHANGED
|
@@ -180,6 +180,7 @@ dropthis update-settings <drop-id> # Change title/visibility/password/
|
|
|
180
180
|
dropthis pull <id|url|slug> [-o <dir>] # Download a drop's files to a local directory
|
|
181
181
|
dropthis get <id|url|slug> # Show drop details
|
|
182
182
|
dropthis list # List your drops
|
|
183
|
+
dropthis list --domain reports.example.com # Only drops on a custom domain
|
|
183
184
|
dropthis delete <id|url|slug> # Delete a drop (--yes to confirm)
|
|
184
185
|
|
|
185
186
|
dropthis deployments # View deployment history
|
|
@@ -197,6 +198,7 @@ dropthis api-keys create # Create an API key
|
|
|
197
198
|
dropthis api-keys list # List API keys
|
|
198
199
|
dropthis api-keys delete <key-id> # Delete an API key (--yes to confirm)
|
|
199
200
|
|
|
201
|
+
dropthis upgrade # Update the CLI to the latest version
|
|
200
202
|
dropthis doctor # CLI diagnostics
|
|
201
203
|
dropthis commands # Machine-readable command metadata
|
|
202
204
|
```
|
|
@@ -211,6 +213,7 @@ The CLI is designed for non-interactive use. In non-TTY environments (pipes, CI,
|
|
|
211
213
|
export DROPTHIS_API_KEY=sk_live_... # API key (same as --api-key)
|
|
212
214
|
export DROPTHIS_API_URL=https://... # Override API base URL (same as --api-url)
|
|
213
215
|
export DROPTHIS_NON_INTERACTIVE=1 # Disable interactive prompts (same as --no-interactive)
|
|
216
|
+
export DROPTHIS_NO_UPDATE_NOTIFIER=1 # Disable the startup update notice (also auto-disabled in CI, non-TTY, --json/--quiet)
|
|
214
217
|
```
|
|
215
218
|
|
|
216
219
|
```bash
|
package/dist/cli.cjs
CHANGED
|
@@ -224,6 +224,9 @@ function cliNextAction(error2) {
|
|
|
224
224
|
if (error2.code === "revision_conflict") {
|
|
225
225
|
return "Re-read the drop with dropthis get <drop-id>, merge your changes, and retry with --if-revision set to the current revision.";
|
|
226
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
|
+
}
|
|
227
230
|
if (error2.statusCode === 404 || error2.code === "not_found") {
|
|
228
231
|
return "Check the drop id or slug and retry; list your drops with dropthis list.";
|
|
229
232
|
}
|
|
@@ -672,7 +675,10 @@ var COMMAND_ANNOTATIONS = {
|
|
|
672
675
|
},
|
|
673
676
|
list: {
|
|
674
677
|
auth: "required",
|
|
675
|
-
examples: [
|
|
678
|
+
examples: [
|
|
679
|
+
"dropthis list --json",
|
|
680
|
+
"dropthis list --domain reports.example.com --json"
|
|
681
|
+
]
|
|
676
682
|
},
|
|
677
683
|
delete: {
|
|
678
684
|
auth: "required",
|
|
@@ -742,6 +748,7 @@ var COMMAND_ANNOTATIONS = {
|
|
|
742
748
|
examples: ["dropthis account delete --yes --json"]
|
|
743
749
|
},
|
|
744
750
|
doctor: { examples: ["dropthis doctor --json"] },
|
|
751
|
+
upgrade: { examples: ["dropthis upgrade", "dropthis upgrade --json"] },
|
|
745
752
|
commands: { examples: ["dropthis commands --json"] }
|
|
746
753
|
};
|
|
747
754
|
function describeArgs(cmd) {
|
|
@@ -873,13 +880,13 @@ async function runDoctor(_input, deps) {
|
|
|
873
880
|
const authSource = credential?.source ?? "missing";
|
|
874
881
|
const storageBackend = stored?.storage ?? "none";
|
|
875
882
|
const pairs = [
|
|
876
|
-
["Version", "0.
|
|
883
|
+
["Version", "0.14.0"],
|
|
877
884
|
["Auth", authSource],
|
|
878
885
|
["Storage", storageBackend]
|
|
879
886
|
];
|
|
880
887
|
writeKv(deps, pairs, {
|
|
881
888
|
ok: true,
|
|
882
|
-
version: "0.
|
|
889
|
+
version: "0.14.0",
|
|
883
890
|
auth: { source: authSource },
|
|
884
891
|
storage: { backend: storageBackend }
|
|
885
892
|
});
|
|
@@ -1265,7 +1272,8 @@ async function runDropsList(input, deps) {
|
|
|
1265
1272
|
}
|
|
1266
1273
|
const params = {
|
|
1267
1274
|
...input.limit !== void 0 ? { limit: input.limit } : {},
|
|
1268
|
-
...input.cursor ? { cursor: input.cursor } : {}
|
|
1275
|
+
...input.cursor ? { cursor: input.cursor } : {},
|
|
1276
|
+
...input.domain ? { domain: input.domain } : {}
|
|
1269
1277
|
};
|
|
1270
1278
|
const result = await deps.client.drops.list(params);
|
|
1271
1279
|
if (result.error) return writeApiError(deps, result.error);
|
|
@@ -1327,6 +1335,7 @@ async function runDropsGet(target, _input, deps) {
|
|
|
1327
1335
|
pairs.push(["Revision", String(data.revision)]);
|
|
1328
1336
|
if (data.createdAt)
|
|
1329
1337
|
pairs.push(["Created", formatDate(String(data.createdAt))]);
|
|
1338
|
+
if (data.domain) pairs.push(["Domain", String(data.domain)]);
|
|
1330
1339
|
if (data.accessible !== void 0)
|
|
1331
1340
|
pairs.push(["Accessible", String(data.accessible)]);
|
|
1332
1341
|
if (data.persistent !== void 0)
|
|
@@ -2200,6 +2209,109 @@ function assertDropId2(target) {
|
|
|
2200
2209
|
}
|
|
2201
2210
|
}
|
|
2202
2211
|
|
|
2212
|
+
// src/commands/upgrade.ts
|
|
2213
|
+
var import_node_child_process = require("child_process");
|
|
2214
|
+
var import_node_fs = require("fs");
|
|
2215
|
+
var import_node_util = require("util");
|
|
2216
|
+
|
|
2217
|
+
// src/semver.ts
|
|
2218
|
+
function compareSemver(a, b) {
|
|
2219
|
+
const parse = (v) => (v.split("-")[0] ?? v).split(".").map(Number);
|
|
2220
|
+
const pa = parse(a);
|
|
2221
|
+
const pb = parse(b);
|
|
2222
|
+
for (let i = 0; i < 3; i++) {
|
|
2223
|
+
const d = (pa[i] ?? 0) - (pb[i] ?? 0);
|
|
2224
|
+
if (d !== 0) return d < 0 ? -1 : 1;
|
|
2225
|
+
}
|
|
2226
|
+
return 0;
|
|
2227
|
+
}
|
|
2228
|
+
|
|
2229
|
+
// src/commands/upgrade.ts
|
|
2230
|
+
var execFileAsync = (0, import_node_util.promisify)(import_node_child_process.execFile);
|
|
2231
|
+
var REGISTRY_LATEST = "https://registry.npmjs.org/@dropthis%2fcli/latest";
|
|
2232
|
+
async function fetchLatestFromRegistry() {
|
|
2233
|
+
try {
|
|
2234
|
+
const res = await fetch(REGISTRY_LATEST, {
|
|
2235
|
+
signal: AbortSignal.timeout(1e4)
|
|
2236
|
+
});
|
|
2237
|
+
if (!res.ok) return null;
|
|
2238
|
+
const body = await res.json();
|
|
2239
|
+
return typeof body.version === "string" ? body.version : null;
|
|
2240
|
+
} catch {
|
|
2241
|
+
return null;
|
|
2242
|
+
}
|
|
2243
|
+
}
|
|
2244
|
+
async function detectNpmGlobalInstall() {
|
|
2245
|
+
try {
|
|
2246
|
+
const argv1 = process.argv[1];
|
|
2247
|
+
if (!argv1) return false;
|
|
2248
|
+
const entry = (0, import_node_fs.realpathSync)(argv1);
|
|
2249
|
+
const { stdout } = await execFileAsync("npm", ["root", "-g"]);
|
|
2250
|
+
const root = (0, import_node_fs.realpathSync)(stdout.trim());
|
|
2251
|
+
return entry.startsWith(root);
|
|
2252
|
+
} catch {
|
|
2253
|
+
return false;
|
|
2254
|
+
}
|
|
2255
|
+
}
|
|
2256
|
+
async function npmInstallLatest() {
|
|
2257
|
+
try {
|
|
2258
|
+
await execFileAsync("npm", ["install", "-g", "@dropthis/cli@latest"]);
|
|
2259
|
+
return { ok: true };
|
|
2260
|
+
} catch (err) {
|
|
2261
|
+
return {
|
|
2262
|
+
ok: false,
|
|
2263
|
+
message: err instanceof Error ? err.message : String(err)
|
|
2264
|
+
};
|
|
2265
|
+
}
|
|
2266
|
+
}
|
|
2267
|
+
async function runUpgrade(_input, deps) {
|
|
2268
|
+
const fetchLatest = deps.fetchLatest ?? fetchLatestFromRegistry;
|
|
2269
|
+
const isNpmGlobal = deps.isNpmGlobalInstall ?? detectNpmGlobalInstall;
|
|
2270
|
+
const install = deps.runNpmInstall ?? npmInstallLatest;
|
|
2271
|
+
const latest = await fetchLatest();
|
|
2272
|
+
if (!latest) {
|
|
2273
|
+
return writeError(
|
|
2274
|
+
deps,
|
|
2275
|
+
"upgrade_check_failed",
|
|
2276
|
+
"Could not reach the npm registry to check for updates. Try again, or run: npm install -g @dropthis/cli@latest"
|
|
2277
|
+
);
|
|
2278
|
+
}
|
|
2279
|
+
if (compareSemver(latest, deps.currentVersion) <= 0) {
|
|
2280
|
+
writeHumanOrJson(
|
|
2281
|
+
deps,
|
|
2282
|
+
`Already on latest version (${deps.currentVersion})`,
|
|
2283
|
+
{ ok: true, status: "already-latest", version: deps.currentVersion }
|
|
2284
|
+
);
|
|
2285
|
+
return { exitCode: 0 };
|
|
2286
|
+
}
|
|
2287
|
+
if (!await isNpmGlobal()) {
|
|
2288
|
+
return writeError(
|
|
2289
|
+
deps,
|
|
2290
|
+
"unsupported_install",
|
|
2291
|
+
`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`
|
|
2292
|
+
);
|
|
2293
|
+
}
|
|
2294
|
+
if (deps.outputMode === "human") {
|
|
2295
|
+
deps.stdout(`Updating ${deps.currentVersion} \u2192 ${latest}...
|
|
2296
|
+
`);
|
|
2297
|
+
}
|
|
2298
|
+
const result = await install();
|
|
2299
|
+
if (!result.ok) {
|
|
2300
|
+
return writeError(
|
|
2301
|
+
deps,
|
|
2302
|
+
"upgrade_failed",
|
|
2303
|
+
`npm install failed${result.message ? `: ${result.message}` : ""}. Try: npm install -g @dropthis/cli@latest`
|
|
2304
|
+
);
|
|
2305
|
+
}
|
|
2306
|
+
writeHumanOrJson(deps, `Updated ${deps.currentVersion} \u2192 ${latest}`, {
|
|
2307
|
+
ok: true,
|
|
2308
|
+
status: "upgraded",
|
|
2309
|
+
from: deps.currentVersion,
|
|
2310
|
+
to: latest
|
|
2311
|
+
});
|
|
2312
|
+
return { exitCode: 0 };
|
|
2313
|
+
}
|
|
2314
|
+
|
|
2203
2315
|
// src/commands/whoami.ts
|
|
2204
2316
|
async function runWhoami(_input, deps) {
|
|
2205
2317
|
const credential = await resolveCredential({
|
|
@@ -2455,7 +2567,7 @@ function buildProgram(options = {}) {
|
|
|
2455
2567
|
` ${import_picocolors6.default.cyan("dropthis login")}`,
|
|
2456
2568
|
` ${import_picocolors6.default.cyan("dropthis publish ./dist")}`
|
|
2457
2569
|
].join("\n")
|
|
2458
|
-
).version("0.
|
|
2570
|
+
).version("0.14.0").configureHelp({
|
|
2459
2571
|
subcommandTerm(cmd) {
|
|
2460
2572
|
const args = cmd.registeredArguments.map((a) => {
|
|
2461
2573
|
const name = a.name();
|
|
@@ -2695,11 +2807,12 @@ ${lines.map((l) => ` ${l}`).join("\n")}
|
|
|
2695
2807
|
const result = await runDropsGet(dropId, commandOptions, deps);
|
|
2696
2808
|
process.exitCode = result.exitCode;
|
|
2697
2809
|
});
|
|
2698
|
-
program.command("list").description("List your drops").option("--limit <n>", "Page size", parseInteger).option("--cursor <cursor>", "Pagination cursor").option("--json", "Force JSON output").addHelpText(
|
|
2810
|
+
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(
|
|
2699
2811
|
"after",
|
|
2700
2812
|
examplesBlock([
|
|
2701
2813
|
"dropthis list",
|
|
2702
|
-
"dropthis list --json | jq -r '.drops[] | [.id, .url] | @tsv' # recover drop ids"
|
|
2814
|
+
"dropthis list --json | jq -r '.drops[] | [.id, .url] | @tsv' # recover drop ids",
|
|
2815
|
+
"dropthis list --domain reports.example.com --json # drops on a custom domain"
|
|
2703
2816
|
])
|
|
2704
2817
|
).action(
|
|
2705
2818
|
async (commandOptions) => {
|
|
@@ -2986,6 +3099,19 @@ ${lines.map((l) => ` ${l}`).join("\n")}
|
|
|
2986
3099
|
const result = await runDoctor(commandOptions, deps);
|
|
2987
3100
|
process.exitCode = result.exitCode;
|
|
2988
3101
|
});
|
|
3102
|
+
program.command("upgrade").description("Update the CLI to the latest version from npm").option("--json", "Force JSON output").action(async (commandOptions) => {
|
|
3103
|
+
const deps = await commandDeps(
|
|
3104
|
+
program,
|
|
3105
|
+
options,
|
|
3106
|
+
store,
|
|
3107
|
+
commandOptions
|
|
3108
|
+
);
|
|
3109
|
+
const result = await runUpgrade(commandOptions, {
|
|
3110
|
+
...deps,
|
|
3111
|
+
currentVersion: "0.14.0"
|
|
3112
|
+
});
|
|
3113
|
+
process.exitCode = result.exitCode;
|
|
3114
|
+
});
|
|
2989
3115
|
program.command("commands").description("Print machine-readable command metadata").option("--json", "Force JSON output").action(async (commandOptions) => {
|
|
2990
3116
|
const deps = await commandDeps(
|
|
2991
3117
|
program,
|
|
@@ -3134,6 +3260,72 @@ async function readStdinBytes(stdin) {
|
|
|
3134
3260
|
return Buffer.concat(chunks);
|
|
3135
3261
|
}
|
|
3136
3262
|
|
|
3263
|
+
// src/update-check.ts
|
|
3264
|
+
var import_node_child_process2 = require("child_process");
|
|
3265
|
+
var import_node_fs2 = require("fs");
|
|
3266
|
+
var import_node_os3 = require("os");
|
|
3267
|
+
var import_node_path3 = require("path");
|
|
3268
|
+
var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
|
|
3269
|
+
var REGISTRY_LATEST2 = "https://registry.npmjs.org/@dropthis%2fcli/latest";
|
|
3270
|
+
function updateCachePath(configDir) {
|
|
3271
|
+
return (0, import_node_path3.join)(
|
|
3272
|
+
configDir ?? (0, import_node_path3.join)((0, import_node_os3.homedir)(), ".config", "dropthis"),
|
|
3273
|
+
"update-check.json"
|
|
3274
|
+
);
|
|
3275
|
+
}
|
|
3276
|
+
function readCache(path) {
|
|
3277
|
+
try {
|
|
3278
|
+
const value = JSON.parse((0, import_node_fs2.readFileSync)(path, "utf8"));
|
|
3279
|
+
if (typeof value.lastCheckedAt !== "string" || typeof value.latestVersion !== "string")
|
|
3280
|
+
return null;
|
|
3281
|
+
return {
|
|
3282
|
+
lastCheckedAt: value.lastCheckedAt,
|
|
3283
|
+
latestVersion: value.latestVersion
|
|
3284
|
+
};
|
|
3285
|
+
} catch {
|
|
3286
|
+
return null;
|
|
3287
|
+
}
|
|
3288
|
+
}
|
|
3289
|
+
function shouldShowNotice(input) {
|
|
3290
|
+
if (input.env.CI) return false;
|
|
3291
|
+
if (input.env.DROPTHIS_NO_UPDATE_NOTIFIER) return false;
|
|
3292
|
+
if (!input.stderrIsTTY) return false;
|
|
3293
|
+
if (input.argv.includes("--json") || input.argv.includes("--quiet") || input.argv.includes("-q"))
|
|
3294
|
+
return false;
|
|
3295
|
+
return true;
|
|
3296
|
+
}
|
|
3297
|
+
function noticeFromCache(input) {
|
|
3298
|
+
if (!input.cache) return null;
|
|
3299
|
+
if (compareSemver(input.cache.latestVersion, input.currentVersion) <= 0)
|
|
3300
|
+
return null;
|
|
3301
|
+
return `Update available ${input.currentVersion} \u2192 ${input.cache.latestVersion} \xB7 run \`dropthis upgrade\``;
|
|
3302
|
+
}
|
|
3303
|
+
function shouldRefresh(cache, now) {
|
|
3304
|
+
if (!cache) return true;
|
|
3305
|
+
const last = Date.parse(cache.lastCheckedAt);
|
|
3306
|
+
if (Number.isNaN(last)) return true;
|
|
3307
|
+
return now.getTime() - last >= CHECK_INTERVAL_MS;
|
|
3308
|
+
}
|
|
3309
|
+
function scheduleBackgroundRefresh(cachePath, spawnFn = import_node_child_process2.spawn) {
|
|
3310
|
+
const script = `
|
|
3311
|
+
const [, cachePath] = process.argv;
|
|
3312
|
+
fetch(${JSON.stringify(REGISTRY_LATEST2)}, { signal: AbortSignal.timeout(5000) })
|
|
3313
|
+
.then((r) => (r.ok ? r.json() : Promise.reject(new Error(String(r.status)))))
|
|
3314
|
+
.then((d) => {
|
|
3315
|
+
const fs = require("node:fs");
|
|
3316
|
+
const path = require("node:path");
|
|
3317
|
+
fs.mkdirSync(path.dirname(cachePath), { recursive: true });
|
|
3318
|
+
fs.writeFileSync(cachePath, JSON.stringify({ lastCheckedAt: new Date().toISOString(), latestVersion: String(d.version) }));
|
|
3319
|
+
})
|
|
3320
|
+
.catch(() => {});
|
|
3321
|
+
`;
|
|
3322
|
+
const child = spawnFn(process.execPath, ["-e", script, cachePath], {
|
|
3323
|
+
detached: true,
|
|
3324
|
+
stdio: "ignore"
|
|
3325
|
+
});
|
|
3326
|
+
child.unref();
|
|
3327
|
+
}
|
|
3328
|
+
|
|
3137
3329
|
// src/cli.ts
|
|
3138
3330
|
function writeUsageErrorEnvelope(input) {
|
|
3139
3331
|
if (input.json) {
|
|
@@ -3150,7 +3342,29 @@ function isCommanderError(err) {
|
|
|
3150
3342
|
function wantsJson(argv) {
|
|
3151
3343
|
return argv.includes("--json") || argv.includes("--quiet") || argv.includes("-q") || process.env.CI === "true" || process.stdout.isTTY !== true;
|
|
3152
3344
|
}
|
|
3153
|
-
|
|
3345
|
+
var updateCache = readCache(updateCachePath());
|
|
3346
|
+
var showNotice = shouldShowNotice({
|
|
3347
|
+
env: process.env,
|
|
3348
|
+
stderrIsTTY: process.stderr.isTTY === true,
|
|
3349
|
+
argv: process.argv.slice(2)
|
|
3350
|
+
});
|
|
3351
|
+
if (showNotice) {
|
|
3352
|
+
const notice = noticeFromCache({
|
|
3353
|
+
cache: updateCache,
|
|
3354
|
+
currentVersion: "0.14.0"
|
|
3355
|
+
});
|
|
3356
|
+
if (notice) {
|
|
3357
|
+
process.stderr.write(`
|
|
3358
|
+
${hint(notice)}
|
|
3359
|
+
|
|
3360
|
+
`);
|
|
3361
|
+
}
|
|
3362
|
+
}
|
|
3363
|
+
buildProgram({ store: createCredentialStore() }).parseAsync(process.argv).finally(() => {
|
|
3364
|
+
if (showNotice && shouldRefresh(updateCache, /* @__PURE__ */ new Date())) {
|
|
3365
|
+
scheduleBackgroundRefresh(updateCachePath());
|
|
3366
|
+
}
|
|
3367
|
+
}).catch((error2) => {
|
|
3154
3368
|
if (isCommanderError(error2)) {
|
|
3155
3369
|
if (error2.code === "commander.help" || error2.code === "commander.helpDisplayed" || error2.code === "commander.version") {
|
|
3156
3370
|
process.exitCode = 0;
|