@tinycloud/cli 1.0.0-beta.17 → 1.0.0-beta.18
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/index.js +37 -5
- package/dist/index.js.map +1 -1
- package/dist/legacy-entry.js +33 -1
- package/dist/legacy-entry.js.map +1 -1
- package/package.json +1 -1
- package/skills/tc-cli/REFERENCE.md +4 -2
package/dist/legacy-entry.js
CHANGED
|
@@ -16907,6 +16907,23 @@ async function throwKvError(error, spaceUri, profileName) {
|
|
|
16907
16907
|
if (hosted) throw hosted;
|
|
16908
16908
|
throw new CLIError(error.code, error.message, ExitCode.ERROR);
|
|
16909
16909
|
}
|
|
16910
|
+
function isByteCount(value) {
|
|
16911
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
|
|
16912
|
+
}
|
|
16913
|
+
function storageQuotaError(error) {
|
|
16914
|
+
if (error.code !== "STORAGE_QUOTA_EXCEEDED") return void 0;
|
|
16915
|
+
const { usedBytes, limitBytes } = typeof error.meta === "object" && error.meta !== null ? error.meta : {};
|
|
16916
|
+
const sizes = isByteCount(usedBytes) && isByteCount(limitBytes) ? ` (${formatBytes(usedBytes)} used of ${formatBytes(limitBytes)} limit)` : "";
|
|
16917
|
+
return new CLIError("STORAGE_QUOTA_EXCEEDED", `storage quota exceeded${sizes}; nothing was written`, ExitCode.ERROR);
|
|
16918
|
+
}
|
|
16919
|
+
function assertAddressableKey(key) {
|
|
16920
|
+
for (let i = 0; i < key.length; i++) {
|
|
16921
|
+
const code2 = key.charCodeAt(i);
|
|
16922
|
+
if (code2 <= 32 || code2 === 127) {
|
|
16923
|
+
throw new CLIError("USAGE_ERROR", "KV keys cannot contain spaces or control characters; use a URL-safe key", ExitCode.USAGE_ERROR);
|
|
16924
|
+
}
|
|
16925
|
+
}
|
|
16926
|
+
}
|
|
16910
16927
|
async function readStdin2() {
|
|
16911
16928
|
const chunks = [];
|
|
16912
16929
|
for await (const chunk of process.stdin) {
|
|
@@ -16923,6 +16940,7 @@ function registerKvCommand(program) {
|
|
|
16923
16940
|
const kv = program.command("kv").description("Key-value store operations");
|
|
16924
16941
|
kv.command("get <key>").description("Get a value by key").option("--raw", "Output raw value (no JSON wrapping)").option("-o, --output <file>", "Write value to file").option("--space <name|uri>", "Target a non-primary space (short name or full URI)").action(async (key, options, cmd) => {
|
|
16925
16942
|
try {
|
|
16943
|
+
assertAddressableKey(key);
|
|
16926
16944
|
const globalOpts = cmd.optsWithGlobals();
|
|
16927
16945
|
const ctx = await ProfileManager.resolveContext(globalOpts);
|
|
16928
16946
|
const node = await ensureAuthenticated(ctx);
|
|
@@ -16967,6 +16985,7 @@ function registerKvCommand(program) {
|
|
|
16967
16985
|
});
|
|
16968
16986
|
kv.command("put <key> [value]").description("Set a value").option("--file <path>", "Read value from file").option("--stdin", "Read value from stdin").option("--space <name|uri>", "Target a non-primary space (short name or full URI)").action(async (key, value, options, cmd) => {
|
|
16969
16987
|
try {
|
|
16988
|
+
assertAddressableKey(key);
|
|
16970
16989
|
const globalOpts = cmd.optsWithGlobals();
|
|
16971
16990
|
const ctx = await ProfileManager.resolveContext(globalOpts);
|
|
16972
16991
|
const node = await ensureAuthenticated(ctx);
|
|
@@ -16992,6 +17011,8 @@ function registerKvCommand(program) {
|
|
|
16992
17011
|
const { kv: kv2, spaceUri } = await kvHandle(node, options.space, ctx.profile);
|
|
16993
17012
|
const result = await withSpinner(`Writing ${key}...`, () => kv2.put(key, putValue));
|
|
16994
17013
|
if (!result.ok) {
|
|
17014
|
+
const quota = storageQuotaError(result.error);
|
|
17015
|
+
if (quota) throw quota;
|
|
16995
17016
|
await throwKvError(result.error, spaceUri, ctx.profile);
|
|
16996
17017
|
}
|
|
16997
17018
|
outputJson({ key, written: true });
|
|
@@ -17001,6 +17022,7 @@ function registerKvCommand(program) {
|
|
|
17001
17022
|
});
|
|
17002
17023
|
kv.command("delete <key>").description("Delete a key").option("--space <name|uri>", "Target a non-primary space (short name or full URI)").action(async (key, options, cmd) => {
|
|
17003
17024
|
try {
|
|
17025
|
+
assertAddressableKey(key);
|
|
17004
17026
|
const globalOpts = cmd.optsWithGlobals();
|
|
17005
17027
|
const ctx = await ProfileManager.resolveContext(globalOpts);
|
|
17006
17028
|
const node = await ensureAuthenticated(ctx);
|
|
@@ -17016,6 +17038,7 @@ function registerKvCommand(program) {
|
|
|
17016
17038
|
});
|
|
17017
17039
|
kv.command("list").description("List keys").option("--prefix <prefix>", "Filter by key prefix").option("--space <name|uri>", "Target a non-primary space (short name or full URI)").action(async (options, cmd) => {
|
|
17018
17040
|
try {
|
|
17041
|
+
if (options.prefix) assertAddressableKey(options.prefix);
|
|
17019
17042
|
const globalOpts = cmd.optsWithGlobals();
|
|
17020
17043
|
const ctx = await ProfileManager.resolveContext(globalOpts);
|
|
17021
17044
|
const node = await ensureAuthenticated(ctx);
|
|
@@ -17051,6 +17074,7 @@ function registerKvCommand(program) {
|
|
|
17051
17074
|
});
|
|
17052
17075
|
kv.command("head <key>").description("Get metadata for a key (no body)").option("--space <name|uri>", "Target a non-primary space (short name or full URI)").action(async (key, options, cmd) => {
|
|
17053
17076
|
try {
|
|
17077
|
+
assertAddressableKey(key);
|
|
17054
17078
|
const globalOpts = cmd.optsWithGlobals();
|
|
17055
17079
|
const ctx = await ProfileManager.resolveContext(globalOpts);
|
|
17056
17080
|
const node = await ensureAuthenticated(ctx);
|
|
@@ -27204,6 +27228,7 @@ function parseNativeShareUrl(value) {
|
|
|
27204
27228
|
}
|
|
27205
27229
|
|
|
27206
27230
|
// src/commands/share.ts
|
|
27231
|
+
init_formatter();
|
|
27207
27232
|
init_errors();
|
|
27208
27233
|
|
|
27209
27234
|
// src/share/output.ts
|
|
@@ -27403,7 +27428,7 @@ function shareCliError(error) {
|
|
|
27403
27428
|
}
|
|
27404
27429
|
if (failure.kind === "scope-denied") {
|
|
27405
27430
|
const requiredAction = failure.requiredAction === void 0 ? "" : ` (${failure.requiredAction})`;
|
|
27406
|
-
const renew = localKey ? `renew it with ${loginHint} using the required capability` : `
|
|
27431
|
+
const renew = localKey ? `renew it with ${loginHint} using the required capability` : `verify the session includes the builtin:share-publishing scope; if it does not, request it with ${loginHint}`;
|
|
27407
27432
|
return new CLIError("PERMISSION_DENIED", `the session lacks ${failure.capability} authority${requiredAction}; ${renew}`, 5);
|
|
27408
27433
|
}
|
|
27409
27434
|
if (failure.kind === "lifetime-exceeds-session") {
|
|
@@ -27428,6 +27453,13 @@ function shareCliError(error) {
|
|
|
27428
27453
|
if (failure.kind === "registry-rejected") {
|
|
27429
27454
|
return new CLIError("REGISTRY_REJECTED", "the TinyCloud location registry rejected this session's location record, so nothing was shared; retrying will not help. Log in again, and report the problem if it persists", 6);
|
|
27430
27455
|
}
|
|
27456
|
+
if (failure.kind === "storage-quota-exceeded") {
|
|
27457
|
+
const sizes = failure.usedBytes === void 0 || failure.limitBytes === void 0 ? "" : ` (${formatBytes(failure.usedBytes)} used of ${formatBytes(failure.limitBytes)} limit)`;
|
|
27458
|
+
return new CLIError("STORAGE_QUOTA_EXCEEDED", `storage quota exceeded${sizes}; nothing was shared`, 4);
|
|
27459
|
+
}
|
|
27460
|
+
if (failure.kind === "upload-failed") {
|
|
27461
|
+
return new CLIError("UPLOAD_FAILED", "share source upload failed; nothing was shared", 4);
|
|
27462
|
+
}
|
|
27431
27463
|
}
|
|
27432
27464
|
if (error instanceof ShareNotifyError) {
|
|
27433
27465
|
return new CLIError("INVALID_ARGUMENT", error.message, 2);
|