@tinycloud/operations 0.4.0-beta.10 → 0.4.0-beta.11

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.
@@ -1,4 +1,4 @@
1
- import { I as InvocationTarget, a as OperationResult } from './contract-CjuEjE-M.cjs';
1
+ import { I as InvocationTarget, a as OperationResult } from './contract-eWtDSMeI.cjs';
2
2
 
3
3
  /**
4
4
  * The only published CLI acquisition helper. Its fixed operation identity is
@@ -1,4 +1,4 @@
1
- import { I as InvocationTarget, a as OperationResult } from './contract-CjuEjE-M.js';
1
+ import { I as InvocationTarget, a as OperationResult } from './contract-eWtDSMeI.js';
2
2
 
3
3
  /**
4
4
  * The only published CLI acquisition helper. Its fixed operation identity is
@@ -40,6 +40,17 @@ function operationError(code, message, options = {}) {
40
40
  ...options.details === void 0 ? {} : { details: options.details }
41
41
  };
42
42
  }
43
+ function storageFullOperationError(error) {
44
+ if (typeof error !== "object" || error === null) return void 0;
45
+ const { code, meta } = error;
46
+ if (code !== "STORAGE_QUOTA_EXCEEDED" && code !== "STORAGE_LIMIT_REACHED") return void 0;
47
+ const account = typeof meta === "object" && meta !== null ? meta.account : void 0;
48
+ return operationError(
49
+ "STORAGE_QUOTA_EXCEEDED",
50
+ code === "STORAGE_LIMIT_REACHED" ? `This write is larger than the TinyCloud storage left, so nothing was written. Reading still works. ${MANAGE_STORAGE}` : `TinyCloud storage is full, so nothing was written. Reading still works. ${MANAGE_STORAGE}`,
51
+ { retryable: false, ...account === void 0 ? {} : { details: { account } } }
52
+ );
53
+ }
43
54
  function isOperationErrorCode(value) {
44
55
  return typeof value === "string" && OPERATION_ERROR_CODES.includes(value);
45
56
  }
@@ -65,7 +76,7 @@ function sanitizeOperationError(error) {
65
76
  ...candidate.details === void 0 ? {} : { details: candidate.details }
66
77
  });
67
78
  }
68
- var OPERATION_ERROR_CODES, OperationInvocationError;
79
+ var OPERATION_ERROR_CODES, MANAGE_STORAGE, OperationInvocationError;
69
80
  var init_errors = __esm({
70
81
  "src/errors.ts"() {
71
82
  "use strict";
@@ -88,6 +99,7 @@ var init_errors = __esm({
88
99
  "ENCRYPTION_NETWORK_UNRESOLVED",
89
100
  "NODE_UNREACHABLE",
90
101
  "NODE_ERROR",
102
+ "STORAGE_QUOTA_EXCEEDED",
91
103
  "KV_NOT_FOUND",
92
104
  "KV_PRECONDITION_FAILED",
93
105
  "KV_CONFLICT",
@@ -101,6 +113,7 @@ var init_errors = __esm({
101
113
  "OUTPUT_INVALID",
102
114
  "INTERNAL_ERROR"
103
115
  ];
116
+ MANAGE_STORAGE = "Do not retry: the owner must free up space or upgrade at https://account.tinycloud.xyz/billing.";
104
117
  OperationInvocationError = class extends Error {
105
118
  constructor(operationError2) {
106
119
  super(operationError2.message);
@@ -2545,6 +2558,8 @@ function kvFailure(error, action) {
2545
2558
  if (error.code === "KV_RESPONSE_TOO_LARGE") {
2546
2559
  return { status: "error", error: operationError("KV_RESPONSE_TOO_LARGE", `The TinyCloud KV value exceeds ${MAX_KV_VALUE_BYTES} bytes.`) };
2547
2560
  }
2561
+ const storageFull = storageFullOperationError(error);
2562
+ if (storageFull) return { status: "error", error: storageFull };
2548
2563
  return nodeFailure(action);
2549
2564
  }
2550
2565
  function nodeFailure(action) {
@@ -3163,7 +3178,7 @@ async function executeSqlDml(context, input) {
3163
3178
  const runtime = runtimeContext2(context);
3164
3179
  const space = resolveSqlSpace(runtime, input.space);
3165
3180
  const result = await runtimeNode2(runtime).sqlForSpace(space).db(input.database).execute(input.sql, input.params.map(decodeSqlInputValue));
3166
- if (!result.ok) return authorizationFailure(result.error, "execute the SQLite statement") ?? sqlMutationFailure();
3181
+ if (!result.ok) return authorizationFailure(result.error, "execute the SQLite statement") ?? sqlMutationFailure(result.error);
3167
3182
  const normalized = normalizeExecuteResult(result.data);
3168
3183
  return {
3169
3184
  status: "ok",
@@ -3177,7 +3192,7 @@ async function executeSqlDml(context, input) {
3177
3192
  };
3178
3193
  } catch (error) {
3179
3194
  if (error instanceof OperationInvocationError) return { status: "error", error: error.operationError };
3180
- return authorizationFailure(error, "execute the SQLite statement") ?? sqlMutationFailure();
3195
+ return authorizationFailure(error, "execute the SQLite statement") ?? sqlMutationFailure(error);
3181
3196
  }
3182
3197
  }
3183
3198
  function isSingleReadQuery(sql) {
@@ -3354,7 +3369,9 @@ function sqlServiceFailure(error, action) {
3354
3369
  }
3355
3370
  return nodeFailure2(action);
3356
3371
  }
3357
- function sqlMutationFailure() {
3372
+ function sqlMutationFailure(error) {
3373
+ const storageFull = storageFullOperationError(error);
3374
+ if (storageFull) return { status: "error", error: storageFull };
3358
3375
  return {
3359
3376
  status: "error",
3360
3377
  error: operationError(
@@ -4597,8 +4614,19 @@ var SAFE_ERROR_DETAIL_POLICIES = {
4597
4614
  DELEGATION_HOST_MISMATCH: {
4598
4615
  expectedHost: safeOriginHost,
4599
4616
  artifactHost: safeOriginHost
4617
+ },
4618
+ STORAGE_QUOTA_EXCEEDED: {
4619
+ account: safeStorageAccount
4600
4620
  }
4601
4621
  };
4622
+ function safeStorageAccount(value) {
4623
+ if (!isRecord(value)) return void 0;
4624
+ const { usedBytes, limitBytes, plan } = value;
4625
+ if (!Number.isSafeInteger(usedBytes) || usedBytes < 0 || !Number.isSafeInteger(limitBytes) || limitBytes <= 0) {
4626
+ return void 0;
4627
+ }
4628
+ return typeof plan === "string" && /^[A-Za-z0-9][A-Za-z0-9 _.-]{0,31}$/.test(plan) ? { usedBytes, limitBytes, plan } : { usedBytes, limitBytes };
4629
+ }
4602
4630
  function redactSafeErrorDetails(code, details) {
4603
4631
  const policy = SAFE_ERROR_DETAIL_POLICIES[code];
4604
4632
  if (policy === void 0) return void 0;