@tinycloud/cli 1.0.1-beta.2 → 1.0.1-beta.3
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/legacy-entry.js +62 -80
- package/dist/legacy-entry.js.map +1 -1
- package/package.json +4 -4
package/dist/legacy-entry.js
CHANGED
|
@@ -6888,6 +6888,20 @@ function storageLimitReachedError(service, message, meta) {
|
|
|
6888
6888
|
meta
|
|
6889
6889
|
};
|
|
6890
6890
|
}
|
|
6891
|
+
var STORAGE_FULL_MESSAGE = "TinyCloud storage is full, so this change was not saved. Reading still works. Free up space or upgrade your plan to save again.";
|
|
6892
|
+
var STORAGE_WRITE_TOO_LARGE_MESSAGE = "This change is larger than the TinyCloud storage you have left, so it was not saved. Reading still works. Free up space or upgrade your plan to save it.";
|
|
6893
|
+
function parseStorageQuotaBytes(responseText) {
|
|
6894
|
+
const match = responseText.match(/Used:\s*(\d+)\s*bytes,\s*Limit:\s*(\d+)\s*bytes/i);
|
|
6895
|
+
if (!match) return void 0;
|
|
6896
|
+
return {
|
|
6897
|
+
usedBytes: parseInt(match[1], 10),
|
|
6898
|
+
limitBytes: parseInt(match[2], 10)
|
|
6899
|
+
};
|
|
6900
|
+
}
|
|
6901
|
+
function storageRejectionError(service, status, meta, responseText) {
|
|
6902
|
+
const quotaMeta = { ...meta, ...parseStorageQuotaBytes(responseText) };
|
|
6903
|
+
return status === 402 ? storageQuotaExceededError(service, STORAGE_FULL_MESSAGE, quotaMeta) : storageLimitReachedError(service, STORAGE_WRITE_TOO_LARGE_MESSAGE, quotaMeta);
|
|
6904
|
+
}
|
|
6891
6905
|
function wrapError2(service, error, defaultCode = ErrorCodes.NETWORK_ERROR) {
|
|
6892
6906
|
if (error instanceof Error) {
|
|
6893
6907
|
if (error.name === "AbortError") {
|
|
@@ -7263,47 +7277,21 @@ var KVService = class extends BaseService {
|
|
|
7263
7277
|
get config() {
|
|
7264
7278
|
return this._config;
|
|
7265
7279
|
}
|
|
7266
|
-
// Parses "Used: X bytes, Limit: Y bytes" from tinycloud-node error responses
|
|
7267
|
-
parseQuotaInfo(errorText) {
|
|
7268
|
-
const match = errorText.match(
|
|
7269
|
-
/Used:\s*(\d+)\s*bytes,\s*Limit:\s*(\d+)\s*bytes/i
|
|
7270
|
-
);
|
|
7271
|
-
if (match) {
|
|
7272
|
-
return {
|
|
7273
|
-
usedBytes: parseInt(match[1], 10),
|
|
7274
|
-
limitBytes: parseInt(match[2], 10)
|
|
7275
|
-
};
|
|
7276
|
-
}
|
|
7277
|
-
return void 0;
|
|
7278
|
-
}
|
|
7279
7280
|
handleQuotaErrorResponse(response, errorText, key) {
|
|
7280
|
-
if (response.status
|
|
7281
|
-
|
|
7282
|
-
return err(
|
|
7283
|
-
storageQuotaExceededError(
|
|
7284
|
-
"kv",
|
|
7285
|
-
`Storage quota exceeded for key ${JSON.stringify(key)}: ${errorText}`,
|
|
7286
|
-
{
|
|
7287
|
-
status: response.status,
|
|
7288
|
-
...quotaInfo ? { usedBytes: quotaInfo.usedBytes, limitBytes: quotaInfo.limitBytes } : {}
|
|
7289
|
-
}
|
|
7290
|
-
)
|
|
7291
|
-
);
|
|
7281
|
+
if (response.status !== 402 && response.status !== 413) {
|
|
7282
|
+
return void 0;
|
|
7292
7283
|
}
|
|
7293
|
-
if (response.status === 413) {
|
|
7294
|
-
|
|
7295
|
-
return err(
|
|
7296
|
-
storageLimitReachedError(
|
|
7297
|
-
"kv",
|
|
7298
|
-
`Storage limit reached for key ${JSON.stringify(key)}: ${errorText}`,
|
|
7299
|
-
{
|
|
7300
|
-
status: response.status,
|
|
7301
|
-
...quotaInfo ? { usedBytes: quotaInfo.usedBytes, limitBytes: quotaInfo.limitBytes } : {}
|
|
7302
|
-
}
|
|
7303
|
-
)
|
|
7304
|
-
);
|
|
7284
|
+
if (response.status === 413 && !parseStorageQuotaBytes(errorText)) {
|
|
7285
|
+
return void 0;
|
|
7305
7286
|
}
|
|
7306
|
-
return
|
|
7287
|
+
return err(
|
|
7288
|
+
storageRejectionError(
|
|
7289
|
+
"kv",
|
|
7290
|
+
response.status,
|
|
7291
|
+
{ status: response.status, statusText: response.statusText, key },
|
|
7292
|
+
errorText
|
|
7293
|
+
)
|
|
7294
|
+
);
|
|
7307
7295
|
}
|
|
7308
7296
|
/**
|
|
7309
7297
|
* Classify a KV 404 by reading the response body once.
|
|
@@ -8626,21 +8614,24 @@ var SQLService = class extends BaseService {
|
|
|
8626
8614
|
}
|
|
8627
8615
|
async applyMigrationsOnDbUnlocked(dbName, options) {
|
|
8628
8616
|
return this.withTelemetry("migrations.apply", dbName, async () => {
|
|
8629
|
-
const created = await this.ensureMigrationsTable(dbName, options.signal);
|
|
8630
|
-
if (!created.ok) return created;
|
|
8631
8617
|
const listed = await this.queryOnDb(
|
|
8632
8618
|
dbName,
|
|
8633
8619
|
`SELECT id FROM ${MIGRATIONS_TABLE} WHERE namespace = ? ORDER BY applied_at, id`,
|
|
8634
8620
|
[options.namespace],
|
|
8635
8621
|
{ signal: options.signal }
|
|
8636
8622
|
);
|
|
8637
|
-
|
|
8623
|
+
const tableMissing = !listed.ok && (listed.error.code === ErrorCodes.SQL_DATABASE_NOT_FOUND || isMissingTableError(listed.error.message));
|
|
8624
|
+
if (!listed.ok && !tableMissing) return listed;
|
|
8638
8625
|
const appliedIds = new Set(
|
|
8639
|
-
listed.data.rows.map((row) => rowValue(row, 0)).filter((id) => typeof id === "string")
|
|
8626
|
+
(listed.ok ? listed.data.rows : []).map((row) => rowValue(row, 0)).filter((id) => typeof id === "string")
|
|
8640
8627
|
);
|
|
8641
8628
|
const skipped = options.migrations.filter((migration) => appliedIds.has(migration.id)).map((migration) => migration.id);
|
|
8642
8629
|
const pending = options.migrations.filter((migration) => !appliedIds.has(migration.id));
|
|
8643
8630
|
const applied = [];
|
|
8631
|
+
if (pending.length > 0 && tableMissing) {
|
|
8632
|
+
const created = await this.ensureMigrationsTable(dbName, options.signal);
|
|
8633
|
+
if (!created.ok) return created;
|
|
8634
|
+
}
|
|
8644
8635
|
for (const migration of pending) {
|
|
8645
8636
|
const result = await this.applyOneMigration(dbName, options.namespace, migration, options.signal);
|
|
8646
8637
|
if (!result.ok) return result;
|
|
@@ -8743,6 +8734,10 @@ var SQLService = class extends BaseService {
|
|
|
8743
8734
|
}
|
|
8744
8735
|
async handleErrorResponse(response, operation) {
|
|
8745
8736
|
const errorText = await response.text();
|
|
8737
|
+
const meta = responseErrorMeta(response.status, response.statusText, errorText);
|
|
8738
|
+
if (response.status === 402) {
|
|
8739
|
+
return err(storageRejectionError("sql", 402, meta, errorText));
|
|
8740
|
+
}
|
|
8746
8741
|
const errorBody = parseServiceErrorBody(errorText);
|
|
8747
8742
|
const errorCode2 = this.mapHttpStatusToErrorCode(
|
|
8748
8743
|
response.status,
|
|
@@ -8755,7 +8750,6 @@ var SQLService = class extends BaseService {
|
|
|
8755
8750
|
errorText,
|
|
8756
8751
|
errorBody
|
|
8757
8752
|
);
|
|
8758
|
-
const meta = responseErrorMeta(response.status, response.statusText, errorText);
|
|
8759
8753
|
if (response.status === 401) {
|
|
8760
8754
|
const { resource, action } = parseAuthError(errorText);
|
|
8761
8755
|
if (action) meta.requiredAction = action;
|
|
@@ -8856,6 +8850,9 @@ function serializeSqlValues(values) {
|
|
|
8856
8850
|
(value) => value instanceof Uint8Array ? Array.from(value) : value
|
|
8857
8851
|
);
|
|
8858
8852
|
}
|
|
8853
|
+
function isMissingTableError(message) {
|
|
8854
|
+
return /no such table/i.test(message);
|
|
8855
|
+
}
|
|
8859
8856
|
function migrationKey(namespace, id) {
|
|
8860
8857
|
return `${encodeURIComponent(namespace)}:${encodeURIComponent(id)}`;
|
|
8861
8858
|
}
|
|
@@ -9170,6 +9167,10 @@ var DuckDbService = class extends BaseService {
|
|
|
9170
9167
|
}
|
|
9171
9168
|
async handleErrorResponse(response, operation) {
|
|
9172
9169
|
const errorText = await response.text();
|
|
9170
|
+
const meta = responseErrorMeta(response.status, response.statusText, errorText);
|
|
9171
|
+
if (response.status === 402) {
|
|
9172
|
+
return err(storageRejectionError("duckdb", 402, meta, errorText));
|
|
9173
|
+
}
|
|
9173
9174
|
const errorBody = parseServiceErrorBody(errorText);
|
|
9174
9175
|
const errorCode2 = this.mapHttpStatusToErrorCode(
|
|
9175
9176
|
response.status,
|
|
@@ -9182,7 +9183,6 @@ var DuckDbService = class extends BaseService {
|
|
|
9182
9183
|
errorText,
|
|
9183
9184
|
errorBody
|
|
9184
9185
|
);
|
|
9185
|
-
const meta = responseErrorMeta(response.status, response.statusText, errorText);
|
|
9186
9186
|
if (response.status === 401) {
|
|
9187
9187
|
const { resource, action } = parseAuthError(errorText);
|
|
9188
9188
|
if (action) meta.requiredAction = action;
|
|
@@ -10109,6 +10109,9 @@ function defaultVaultMessage(input) {
|
|
|
10109
10109
|
return input.message ?? `Public key not found for ${input.did}`;
|
|
10110
10110
|
case "STORAGE_ERROR":
|
|
10111
10111
|
return input.message ?? input.cause.message;
|
|
10112
|
+
case "STORAGE_QUOTA_EXCEEDED":
|
|
10113
|
+
case "STORAGE_LIMIT_REACHED":
|
|
10114
|
+
return input.message;
|
|
10112
10115
|
}
|
|
10113
10116
|
}
|
|
10114
10117
|
function vaultError(input) {
|
|
@@ -10119,6 +10122,15 @@ function vaultError(input) {
|
|
|
10119
10122
|
};
|
|
10120
10123
|
return { ok: false, error };
|
|
10121
10124
|
}
|
|
10125
|
+
function kvWriteError(context, error) {
|
|
10126
|
+
if (error.code === ErrorCodes.STORAGE_QUOTA_EXCEEDED || error.code === ErrorCodes.STORAGE_LIMIT_REACHED) {
|
|
10127
|
+
return vaultError({ code: error.code, message: error.message, meta: error.meta });
|
|
10128
|
+
}
|
|
10129
|
+
return vaultError({
|
|
10130
|
+
code: "STORAGE_ERROR",
|
|
10131
|
+
cause: new Error(`${context}: ${error.message}`)
|
|
10132
|
+
});
|
|
10133
|
+
}
|
|
10122
10134
|
var DataVaultService = class extends BaseService {
|
|
10123
10135
|
/**
|
|
10124
10136
|
* Create a new DataVaultService instance.
|
|
@@ -10401,12 +10413,7 @@ var DataVaultService = class extends BaseService {
|
|
|
10401
10413
|
JSON.stringify(envelopeResult.data)
|
|
10402
10414
|
);
|
|
10403
10415
|
if (!valuePutResult.ok) {
|
|
10404
|
-
return
|
|
10405
|
-
code: "STORAGE_ERROR",
|
|
10406
|
-
cause: new Error(
|
|
10407
|
-
`Failed to store encrypted value: ${valuePutResult.error.message}`
|
|
10408
|
-
)
|
|
10409
|
-
});
|
|
10416
|
+
return kvWriteError("Failed to store encrypted value", valuePutResult.error);
|
|
10410
10417
|
}
|
|
10411
10418
|
return { ok: true, data: void 0 };
|
|
10412
10419
|
} catch (error) {
|
|
@@ -10624,12 +10631,7 @@ var DataVaultService = class extends BaseService {
|
|
|
10624
10631
|
keyPayload
|
|
10625
10632
|
);
|
|
10626
10633
|
if (!keyPutResult.ok) {
|
|
10627
|
-
return
|
|
10628
|
-
code: "STORAGE_ERROR",
|
|
10629
|
-
cause: new Error(
|
|
10630
|
-
`Failed to store key blob: ${keyPutResult.error.message}`
|
|
10631
|
-
)
|
|
10632
|
-
});
|
|
10634
|
+
return kvWriteError("Failed to store key blob", keyPutResult.error);
|
|
10633
10635
|
}
|
|
10634
10636
|
const valuePayload = JSON.stringify({
|
|
10635
10637
|
data: base64Encode(encrypted),
|
|
@@ -10640,12 +10642,7 @@ var DataVaultService = class extends BaseService {
|
|
|
10640
10642
|
valuePayload
|
|
10641
10643
|
);
|
|
10642
10644
|
if (!valuePutResult.ok) {
|
|
10643
|
-
return
|
|
10644
|
-
code: "STORAGE_ERROR",
|
|
10645
|
-
cause: new Error(
|
|
10646
|
-
`Failed to store encrypted value: ${valuePutResult.error.message}`
|
|
10647
|
-
)
|
|
10648
|
-
});
|
|
10645
|
+
return kvWriteError("Failed to store encrypted value", valuePutResult.error);
|
|
10649
10646
|
}
|
|
10650
10647
|
return ok(void 0);
|
|
10651
10648
|
} catch (error) {
|
|
@@ -10976,12 +10973,7 @@ var DataVaultService = class extends BaseService {
|
|
|
10976
10973
|
grantPayload
|
|
10977
10974
|
);
|
|
10978
10975
|
if (!grantPutResult.ok) {
|
|
10979
|
-
return
|
|
10980
|
-
code: "STORAGE_ERROR",
|
|
10981
|
-
cause: new Error(
|
|
10982
|
-
`Failed to store grant: ${grantPutResult.error.message}`
|
|
10983
|
-
)
|
|
10984
|
-
});
|
|
10976
|
+
return kvWriteError("Failed to store grant", grantPutResult.error);
|
|
10985
10977
|
}
|
|
10986
10978
|
return ok(void 0);
|
|
10987
10979
|
} catch (error) {
|
|
@@ -11326,12 +11318,7 @@ var DataVaultService = class extends BaseService {
|
|
|
11326
11318
|
keyPayload
|
|
11327
11319
|
);
|
|
11328
11320
|
if (!keyPutResult.ok) {
|
|
11329
|
-
return
|
|
11330
|
-
code: "STORAGE_ERROR",
|
|
11331
|
-
cause: new Error(
|
|
11332
|
-
`Failed to store rotated key blob: ${keyPutResult.error.message}`
|
|
11333
|
-
)
|
|
11334
|
-
});
|
|
11321
|
+
return kvWriteError("Failed to store rotated key blob", keyPutResult.error);
|
|
11335
11322
|
}
|
|
11336
11323
|
const valuePayload = JSON.stringify({
|
|
11337
11324
|
data: base64Encode(encrypted),
|
|
@@ -11342,12 +11329,7 @@ var DataVaultService = class extends BaseService {
|
|
|
11342
11329
|
valuePayload
|
|
11343
11330
|
);
|
|
11344
11331
|
if (!valuePutResult.ok) {
|
|
11345
|
-
return
|
|
11346
|
-
code: "STORAGE_ERROR",
|
|
11347
|
-
cause: new Error(
|
|
11348
|
-
`Failed to store re-encrypted value: ${valuePutResult.error.message}`
|
|
11349
|
-
)
|
|
11350
|
-
});
|
|
11332
|
+
return kvWriteError("Failed to store re-encrypted value", valuePutResult.error);
|
|
11351
11333
|
}
|
|
11352
11334
|
for (const did of remainingGrantees) {
|
|
11353
11335
|
const grantResult = await this.reencrypt(key, did);
|