@dropthis/cli 0.12.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 +3 -0
- package/dist/cli.cjs +221 -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-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/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.13.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.13.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);
|
|
@@ -2200,6 +2208,109 @@ function assertDropId2(target) {
|
|
|
2200
2208
|
}
|
|
2201
2209
|
}
|
|
2202
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
|
+
|
|
2203
2314
|
// src/commands/whoami.ts
|
|
2204
2315
|
async function runWhoami(_input, deps) {
|
|
2205
2316
|
const credential = await resolveCredential({
|
|
@@ -2455,7 +2566,7 @@ function buildProgram(options = {}) {
|
|
|
2455
2566
|
` ${import_picocolors6.default.cyan("dropthis login")}`,
|
|
2456
2567
|
` ${import_picocolors6.default.cyan("dropthis publish ./dist")}`
|
|
2457
2568
|
].join("\n")
|
|
2458
|
-
).version("0.
|
|
2569
|
+
).version("0.13.0").configureHelp({
|
|
2459
2570
|
subcommandTerm(cmd) {
|
|
2460
2571
|
const args = cmd.registeredArguments.map((a) => {
|
|
2461
2572
|
const name = a.name();
|
|
@@ -2695,11 +2806,12 @@ ${lines.map((l) => ` ${l}`).join("\n")}
|
|
|
2695
2806
|
const result = await runDropsGet(dropId, commandOptions, deps);
|
|
2696
2807
|
process.exitCode = result.exitCode;
|
|
2697
2808
|
});
|
|
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(
|
|
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(
|
|
2699
2810
|
"after",
|
|
2700
2811
|
examplesBlock([
|
|
2701
2812
|
"dropthis list",
|
|
2702
|
-
"dropthis list --json | jq -r '.drops[] | [.id, .url] | @tsv' # recover drop ids"
|
|
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"
|
|
2703
2815
|
])
|
|
2704
2816
|
).action(
|
|
2705
2817
|
async (commandOptions) => {
|
|
@@ -2986,6 +3098,19 @@ ${lines.map((l) => ` ${l}`).join("\n")}
|
|
|
2986
3098
|
const result = await runDoctor(commandOptions, deps);
|
|
2987
3099
|
process.exitCode = result.exitCode;
|
|
2988
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
|
+
});
|
|
2989
3114
|
program.command("commands").description("Print machine-readable command metadata").option("--json", "Force JSON output").action(async (commandOptions) => {
|
|
2990
3115
|
const deps = await commandDeps(
|
|
2991
3116
|
program,
|
|
@@ -3134,6 +3259,72 @@ async function readStdinBytes(stdin) {
|
|
|
3134
3259
|
return Buffer.concat(chunks);
|
|
3135
3260
|
}
|
|
3136
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
|
+
|
|
3137
3328
|
// src/cli.ts
|
|
3138
3329
|
function writeUsageErrorEnvelope(input) {
|
|
3139
3330
|
if (input.json) {
|
|
@@ -3150,7 +3341,29 @@ function isCommanderError(err) {
|
|
|
3150
3341
|
function wantsJson(argv) {
|
|
3151
3342
|
return argv.includes("--json") || argv.includes("--quiet") || argv.includes("-q") || process.env.CI === "true" || process.stdout.isTTY !== true;
|
|
3152
3343
|
}
|
|
3153
|
-
|
|
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) => {
|
|
3154
3367
|
if (isCommanderError(error2)) {
|
|
3155
3368
|
if (error2.code === "commander.help" || error2.code === "commander.helpDisplayed" || error2.code === "commander.version") {
|
|
3156
3369
|
process.exitCode = 0;
|