@tinycloud/sdk-services 3.1.0-beta.1 → 3.1.0-beta.6
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/encryption/index.cjs +106 -97
- package/dist/encryption/index.cjs.map +1 -1
- package/dist/encryption/index.js +106 -97
- package/dist/encryption/index.js.map +1 -1
- package/dist/index.cjs +344 -227
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +53 -1
- package/dist/index.d.ts +53 -1
- package/dist/index.js +319 -209
- package/dist/index.js.map +1 -1
- package/dist/kv/index.cjs +236 -58
- package/dist/kv/index.cjs.map +1 -1
- package/dist/kv/index.d.cts +5 -2
- package/dist/kv/index.d.ts +5 -2
- package/dist/kv/index.js +236 -58
- package/dist/kv/index.js.map +1 -1
- package/dist/sql/index.cjs +77 -26
- package/dist/sql/index.cjs.map +1 -1
- package/dist/sql/index.js +68 -17
- package/dist/sql/index.js.map +1 -1
- package/package.json +1 -1
package/dist/kv/index.cjs
CHANGED
|
@@ -99,6 +99,55 @@ function serviceError(code, message, service, options) {
|
|
|
99
99
|
};
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
+
// src/errors.ts
|
|
103
|
+
var import_bootstrap = require("@tinycloud/bootstrap");
|
|
104
|
+
|
|
105
|
+
// src/encryption/networkId.ts
|
|
106
|
+
var URN_PREFIX = "urn:tinycloud:encryption:";
|
|
107
|
+
var NETWORK_NAME_RE = /^[a-z0-9][a-z0-9-]*$/;
|
|
108
|
+
var NetworkIdError = class extends Error {
|
|
109
|
+
constructor(message) {
|
|
110
|
+
super(message);
|
|
111
|
+
this.name = "NetworkIdError";
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
function parseNetworkId(networkId) {
|
|
115
|
+
if (typeof networkId !== "string" || networkId.length === 0) {
|
|
116
|
+
throw new NetworkIdError("networkId must be a non-empty string");
|
|
117
|
+
}
|
|
118
|
+
if (!networkId.startsWith(URN_PREFIX)) {
|
|
119
|
+
throw new NetworkIdError(
|
|
120
|
+
`networkId must start with ${URN_PREFIX} (got ${JSON.stringify(networkId)})`
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
const body = networkId.slice(URN_PREFIX.length);
|
|
124
|
+
const lastColon = body.lastIndexOf(":");
|
|
125
|
+
if (lastColon <= 0 || lastColon === body.length - 1) {
|
|
126
|
+
throw new NetworkIdError(
|
|
127
|
+
`networkId missing ownerDid or name segment (got ${JSON.stringify(networkId)})`
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
const ownerDid = body.slice(0, lastColon);
|
|
131
|
+
const name = body.slice(lastColon + 1);
|
|
132
|
+
if (!ownerDid.startsWith("did:")) {
|
|
133
|
+
throw new NetworkIdError(
|
|
134
|
+
`networkId ownerDid must be a DID (got ${JSON.stringify(ownerDid)})`
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
const didParts = ownerDid.split(":");
|
|
138
|
+
if (didParts.length < 3 || didParts.some((p) => p.length === 0)) {
|
|
139
|
+
throw new NetworkIdError(
|
|
140
|
+
`networkId ownerDid is not a well-formed DID (got ${JSON.stringify(ownerDid)})`
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
if (!NETWORK_NAME_RE.test(name)) {
|
|
144
|
+
throw new NetworkIdError(
|
|
145
|
+
`networkId name ${JSON.stringify(name)} must match ${NETWORK_NAME_RE.source}`
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
return { networkId, ownerDid, name };
|
|
149
|
+
}
|
|
150
|
+
|
|
102
151
|
// src/errors.ts
|
|
103
152
|
function parsePermissionHint(value) {
|
|
104
153
|
if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
|
|
@@ -167,6 +216,101 @@ function parseAuthError(responseText) {
|
|
|
167
216
|
function authUnauthorizedError(service, message, meta) {
|
|
168
217
|
return serviceError(ErrorCodes.AUTH_UNAUTHORIZED, message, service, { meta });
|
|
169
218
|
}
|
|
219
|
+
var grantableActions = new Set(
|
|
220
|
+
import_bootstrap.CAPABILITY_REGISTRY.map(({ urn }) => urn).filter((urn) => !urn.endsWith("/*"))
|
|
221
|
+
);
|
|
222
|
+
var capabilityServices = new Set(
|
|
223
|
+
import_bootstrap.CAPABILITY_REGISTRY.map(({ service }) => service.slice("tinycloud.".length))
|
|
224
|
+
);
|
|
225
|
+
function parseCapabilityResource(resource, service) {
|
|
226
|
+
if (resource.length === 0 || resource.length > 1024 || !capabilityServices.has(service) || /[\s\p{C}*#]/u.test(resource) || resource.includes("://")) return void 0;
|
|
227
|
+
const segments = resource.split("/");
|
|
228
|
+
if (!/^tinycloud:[A-Za-z0-9][A-Za-z0-9:._-]*$/.test(segments[0])) return void 0;
|
|
229
|
+
const serviceIndex = segments.findIndex(
|
|
230
|
+
(segment, index) => index > 0 && capabilityServices.has(segment)
|
|
231
|
+
);
|
|
232
|
+
if (serviceIndex < 1 || segments[serviceIndex] !== service) return void 0;
|
|
233
|
+
if (segments.slice(1, serviceIndex).some(
|
|
234
|
+
(segment) => segment.length === 0 || segment === "." || segment === ".."
|
|
235
|
+
)) return void 0;
|
|
236
|
+
const pathSegments = segments.slice(serviceIndex + 1);
|
|
237
|
+
if (pathSegments.some((segment) => segment === "." || segment === "..")) return void 0;
|
|
238
|
+
if (service !== "kv" && (pathSegments.length === 0 || pathSegments[pathSegments.length - 1] === "")) return void 0;
|
|
239
|
+
return {
|
|
240
|
+
space: segments.slice(0, serviceIndex).join("/"),
|
|
241
|
+
path: pathSegments.join("/")
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
function safeCapabilityResource(value, service, action) {
|
|
245
|
+
if (typeof value !== "string" || value.length === 0 || value.length > 1024) return false;
|
|
246
|
+
if (service === "encryption" && value.startsWith("urn:tinycloud:encryption:")) {
|
|
247
|
+
if (!/^[A-Za-z0-9_][A-Za-z0-9_.:/-]*$/.test(value) || value.includes("//") || value.split("/").some((segment) => segment === "." || segment === "..")) return false;
|
|
248
|
+
try {
|
|
249
|
+
parseNetworkId(value);
|
|
250
|
+
return true;
|
|
251
|
+
} catch {
|
|
252
|
+
return false;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
const parsed = parseCapabilityResource(value, service);
|
|
256
|
+
return parsed !== void 0 && (!parsed.path.endsWith("/") || service === "kv" && action === "tinycloud.kv/list") && (parsed.path !== "" || service === "kv" && action === "tinycloud.kv/list");
|
|
257
|
+
}
|
|
258
|
+
function validatedCapabilityOf(error) {
|
|
259
|
+
const verdict = authorizationVerdictOf(error);
|
|
260
|
+
if (verdict !== "unauthenticated" && verdict !== "forbidden") return void 0;
|
|
261
|
+
const seen = /* @__PURE__ */ new Set();
|
|
262
|
+
let node = error;
|
|
263
|
+
for (let depth = 0; depth < MAX_CAUSE_DEPTH && typeof node === "object" && node !== null && !seen.has(node); depth += 1) {
|
|
264
|
+
seen.add(node);
|
|
265
|
+
const record = node;
|
|
266
|
+
const status = errorStatusOf(record);
|
|
267
|
+
const meta = record.meta;
|
|
268
|
+
if ((status === 401 || status === 403 || status === void 0 && record.code === ErrorCodes.AUTH_UNAUTHORIZED) && typeof meta === "object" && meta !== null && !Array.isArray(meta)) {
|
|
269
|
+
const metadata = meta;
|
|
270
|
+
const { resource, requiredAction } = metadata;
|
|
271
|
+
if (typeof requiredAction === "string" && grantableActions.has(requiredAction)) {
|
|
272
|
+
const actionService = requiredAction.slice("tinycloud.".length, requiredAction.indexOf("/"));
|
|
273
|
+
const explicitService = record.service === void 0 ? metadata.service : record.service;
|
|
274
|
+
if (safeCapabilityResource(resource, actionService, requiredAction) && (explicitService === void 0 || explicitService === actionService || explicitService === `tinycloud.${actionService}`)) {
|
|
275
|
+
return { resource, requiredAction };
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
node = record.cause;
|
|
280
|
+
}
|
|
281
|
+
return void 0;
|
|
282
|
+
}
|
|
283
|
+
var MAX_CAUSE_DEPTH = 8;
|
|
284
|
+
function errorStatusOf(node) {
|
|
285
|
+
const meta = node.meta;
|
|
286
|
+
const candidates = [
|
|
287
|
+
node.status,
|
|
288
|
+
node.statusCode,
|
|
289
|
+
typeof meta === "object" && meta !== null ? meta.status : void 0
|
|
290
|
+
];
|
|
291
|
+
for (const candidate of candidates) {
|
|
292
|
+
if (typeof candidate === "number" && Number.isInteger(candidate) && candidate >= 400 && candidate <= 599) {
|
|
293
|
+
return candidate;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
return void 0;
|
|
297
|
+
}
|
|
298
|
+
function authorizationVerdictOf(error) {
|
|
299
|
+
const seen = /* @__PURE__ */ new Set();
|
|
300
|
+
let sawUnauthorizedCode = false;
|
|
301
|
+
let node = error;
|
|
302
|
+
for (let depth = 0; depth < MAX_CAUSE_DEPTH && typeof node === "object" && node !== null && !seen.has(node); depth += 1) {
|
|
303
|
+
seen.add(node);
|
|
304
|
+
const record = node;
|
|
305
|
+
const status = errorStatusOf(record);
|
|
306
|
+
if (status === 401) return "unauthenticated";
|
|
307
|
+
if (status === 403) return "forbidden";
|
|
308
|
+
if (status !== void 0) return "other";
|
|
309
|
+
if (record.code === ErrorCodes.AUTH_UNAUTHORIZED) sawUnauthorizedCode = true;
|
|
310
|
+
node = record.cause;
|
|
311
|
+
}
|
|
312
|
+
return sawUnauthorizedCode ? "forbidden" : void 0;
|
|
313
|
+
}
|
|
170
314
|
function storageQuotaExceededError(service, message, meta) {
|
|
171
315
|
return {
|
|
172
316
|
code: ErrorCodes.STORAGE_QUOTA_EXCEEDED,
|
|
@@ -183,6 +327,20 @@ function storageLimitReachedError(service, message, meta) {
|
|
|
183
327
|
meta
|
|
184
328
|
};
|
|
185
329
|
}
|
|
330
|
+
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.";
|
|
331
|
+
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.";
|
|
332
|
+
function parseStorageQuotaBytes(responseText) {
|
|
333
|
+
const match = responseText.match(/Used:\s*(\d+)\s*bytes,\s*Limit:\s*(\d+)\s*bytes/i);
|
|
334
|
+
if (!match) return void 0;
|
|
335
|
+
return {
|
|
336
|
+
usedBytes: parseInt(match[1], 10),
|
|
337
|
+
limitBytes: parseInt(match[2], 10)
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
function storageRejectionError(service, status, meta, responseText) {
|
|
341
|
+
const quotaMeta = { ...meta, ...parseStorageQuotaBytes(responseText) };
|
|
342
|
+
return status === 402 ? storageQuotaExceededError(service, STORAGE_FULL_MESSAGE, quotaMeta) : storageLimitReachedError(service, STORAGE_WRITE_TOO_LARGE_MESSAGE, quotaMeta);
|
|
343
|
+
}
|
|
186
344
|
function wrapError(service, error, defaultCode = ErrorCodes.NETWORK_ERROR) {
|
|
187
345
|
if (error instanceof Error) {
|
|
188
346
|
if (error.name === "AbortError") {
|
|
@@ -573,47 +731,21 @@ var KVService = class extends BaseService {
|
|
|
573
731
|
get config() {
|
|
574
732
|
return this._config;
|
|
575
733
|
}
|
|
576
|
-
// Parses "Used: X bytes, Limit: Y bytes" from tinycloud-node error responses
|
|
577
|
-
parseQuotaInfo(errorText) {
|
|
578
|
-
const match = errorText.match(
|
|
579
|
-
/Used:\s*(\d+)\s*bytes,\s*Limit:\s*(\d+)\s*bytes/i
|
|
580
|
-
);
|
|
581
|
-
if (match) {
|
|
582
|
-
return {
|
|
583
|
-
usedBytes: parseInt(match[1], 10),
|
|
584
|
-
limitBytes: parseInt(match[2], 10)
|
|
585
|
-
};
|
|
586
|
-
}
|
|
587
|
-
return void 0;
|
|
588
|
-
}
|
|
589
734
|
handleQuotaErrorResponse(response, errorText, key) {
|
|
590
|
-
if (response.status
|
|
591
|
-
|
|
592
|
-
return err(
|
|
593
|
-
storageQuotaExceededError(
|
|
594
|
-
"kv",
|
|
595
|
-
`Storage quota exceeded for key ${JSON.stringify(key)}: ${errorText}`,
|
|
596
|
-
{
|
|
597
|
-
status: response.status,
|
|
598
|
-
...quotaInfo ? { usedBytes: quotaInfo.usedBytes, limitBytes: quotaInfo.limitBytes } : {}
|
|
599
|
-
}
|
|
600
|
-
)
|
|
601
|
-
);
|
|
735
|
+
if (response.status !== 402 && response.status !== 413) {
|
|
736
|
+
return void 0;
|
|
602
737
|
}
|
|
603
|
-
if (response.status === 413) {
|
|
604
|
-
|
|
605
|
-
return err(
|
|
606
|
-
storageLimitReachedError(
|
|
607
|
-
"kv",
|
|
608
|
-
`Storage limit reached for key ${JSON.stringify(key)}: ${errorText}`,
|
|
609
|
-
{
|
|
610
|
-
status: response.status,
|
|
611
|
-
...quotaInfo ? { usedBytes: quotaInfo.usedBytes, limitBytes: quotaInfo.limitBytes } : {}
|
|
612
|
-
}
|
|
613
|
-
)
|
|
614
|
-
);
|
|
738
|
+
if (response.status === 413 && !parseStorageQuotaBytes(errorText)) {
|
|
739
|
+
return void 0;
|
|
615
740
|
}
|
|
616
|
-
return
|
|
741
|
+
return err(
|
|
742
|
+
storageRejectionError(
|
|
743
|
+
"kv",
|
|
744
|
+
response.status,
|
|
745
|
+
{ status: response.status, statusText: response.statusText, key },
|
|
746
|
+
errorText
|
|
747
|
+
)
|
|
748
|
+
);
|
|
617
749
|
}
|
|
618
750
|
/**
|
|
619
751
|
* Classify a KV 404 by reading the response body once.
|
|
@@ -889,12 +1021,14 @@ var KVService = class extends BaseService {
|
|
|
889
1021
|
signal: this.combineSignals(options?.signal)
|
|
890
1022
|
});
|
|
891
1023
|
if (!response.ok) {
|
|
892
|
-
const errorText = await response.text();
|
|
1024
|
+
const errorText = response.status === 401 || response.status === 403 ? await this.readAuthorizationText(response) : await response.text();
|
|
893
1025
|
if (response.status === 401 || response.status === 403) {
|
|
894
1026
|
return this.authorizationFailure(
|
|
895
1027
|
`Failed to batch read ${keys.length} key(s)`,
|
|
896
1028
|
response,
|
|
897
|
-
errorText
|
|
1029
|
+
errorText,
|
|
1030
|
+
paths,
|
|
1031
|
+
action
|
|
898
1032
|
);
|
|
899
1033
|
}
|
|
900
1034
|
if (response.status === 413) {
|
|
@@ -984,7 +1118,7 @@ var KVService = class extends BaseService {
|
|
|
984
1118
|
return text;
|
|
985
1119
|
}
|
|
986
1120
|
}
|
|
987
|
-
async createSignedReadUrlError(response, key) {
|
|
1121
|
+
async createSignedReadUrlError(response, key, path) {
|
|
988
1122
|
let errorText = response.statusText;
|
|
989
1123
|
try {
|
|
990
1124
|
const text = await response.text();
|
|
@@ -997,7 +1131,9 @@ var KVService = class extends BaseService {
|
|
|
997
1131
|
return this.authorizationFailure(
|
|
998
1132
|
`Failed to create signed read URL for key ${JSON.stringify(key)}`,
|
|
999
1133
|
response,
|
|
1000
|
-
errorText
|
|
1134
|
+
errorText,
|
|
1135
|
+
[path],
|
|
1136
|
+
KVAction.GET
|
|
1001
1137
|
);
|
|
1002
1138
|
}
|
|
1003
1139
|
const code = response.status === 400 ? ErrorCodes.INVALID_INPUT : ErrorCodes.NETWORK_ERROR;
|
|
@@ -1010,21 +1146,42 @@ var KVService = class extends BaseService {
|
|
|
1010
1146
|
)
|
|
1011
1147
|
);
|
|
1012
1148
|
}
|
|
1149
|
+
/** A known 401/403 keeps its typed status even if reading its body fails. */
|
|
1150
|
+
async readAuthorizationText(response) {
|
|
1151
|
+
try {
|
|
1152
|
+
return await response.text();
|
|
1153
|
+
} catch {
|
|
1154
|
+
return "";
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1013
1157
|
/**
|
|
1014
1158
|
* AUTH_UNAUTHORIZED for a 401/403 response. The message keeps the HTTP
|
|
1015
1159
|
* status and the server text (`<context>: <status> - <text>`, the same
|
|
1016
1160
|
* shape as every other KV failure) so callers that rethrow only the message
|
|
1017
1161
|
* still see the status; `meta.status` carries it for typed callers.
|
|
1018
|
-
*
|
|
1162
|
+
* Server hints must match the requested path/action (whether the node sends
|
|
1163
|
+
* a relative path or full resource); metadata uses only the request-derived
|
|
1164
|
+
* canonical resource under the authenticated session's space.
|
|
1019
1165
|
*/
|
|
1020
|
-
authorizationFailure(context, response, errorText, extraMeta = {}) {
|
|
1166
|
+
authorizationFailure(context, response, errorText, paths, expectedAction, extraMeta = {}) {
|
|
1021
1167
|
const { resource, action } = parseAuthError(errorText);
|
|
1168
|
+
const requestedPath = paths.find(
|
|
1169
|
+
(path) => resource === path || resource === `${this.context.session.spaceId}/kv/${path}`
|
|
1170
|
+
);
|
|
1171
|
+
const capability = requestedPath !== void 0 && action === expectedAction ? validatedCapabilityOf({
|
|
1172
|
+
service: "kv",
|
|
1173
|
+
code: ErrorCodes.AUTH_UNAUTHORIZED,
|
|
1174
|
+
meta: {
|
|
1175
|
+
status: response.status,
|
|
1176
|
+
resource: `${this.context.session.spaceId}/kv/${requestedPath}`,
|
|
1177
|
+
requiredAction: action
|
|
1178
|
+
}
|
|
1179
|
+
}) : void 0;
|
|
1022
1180
|
const detail = errorText.trim().length > 0 ? errorText : response.statusText || "authorization failed";
|
|
1023
1181
|
return err(authUnauthorizedError("kv", `${context}: ${response.status} - ${detail}`, {
|
|
1024
1182
|
status: response.status,
|
|
1025
|
-
...
|
|
1026
|
-
...
|
|
1027
|
-
...extraMeta
|
|
1183
|
+
...extraMeta,
|
|
1184
|
+
...capability
|
|
1028
1185
|
}));
|
|
1029
1186
|
}
|
|
1030
1187
|
normalizeSignedReadUrlResponse(data) {
|
|
@@ -1068,13 +1225,24 @@ var KVService = class extends BaseService {
|
|
|
1068
1225
|
);
|
|
1069
1226
|
if (!response.ok) {
|
|
1070
1227
|
if (response.status === 401 || response.status === 403) {
|
|
1071
|
-
const errorText2 = await
|
|
1228
|
+
const errorText2 = await this.readAuthorizationText(response);
|
|
1072
1229
|
const permissionHint = parsePermissionHintFromErrorText(errorText2);
|
|
1230
|
+
const structuredCapability = permissionHint?.service === "tinycloud.kv" && permissionHint.space === this.context.session.spaceId && permissionHint.path === path ? validatedCapabilityOf({
|
|
1231
|
+
service: "kv",
|
|
1232
|
+
code: ErrorCodes.AUTH_UNAUTHORIZED,
|
|
1233
|
+
meta: {
|
|
1234
|
+
status: response.status,
|
|
1235
|
+
resource: `${this.context.session.spaceId}/kv/${path}`,
|
|
1236
|
+
requiredAction: KVAction.GET
|
|
1237
|
+
}
|
|
1238
|
+
}) : void 0;
|
|
1073
1239
|
return this.authorizationFailure(
|
|
1074
1240
|
`Failed to get key ${JSON.stringify(key)}`,
|
|
1075
1241
|
response,
|
|
1076
1242
|
errorText2,
|
|
1077
|
-
|
|
1243
|
+
[path],
|
|
1244
|
+
KVAction.GET,
|
|
1245
|
+
structuredCapability ? { permissionHint, ...structuredCapability } : {}
|
|
1078
1246
|
);
|
|
1079
1247
|
}
|
|
1080
1248
|
if (response.status === 404) {
|
|
@@ -1151,7 +1319,9 @@ var KVService = class extends BaseService {
|
|
|
1151
1319
|
return this.authorizationFailure(
|
|
1152
1320
|
`Failed to put key ${JSON.stringify(key)}`,
|
|
1153
1321
|
response,
|
|
1154
|
-
await
|
|
1322
|
+
await this.readAuthorizationText(response),
|
|
1323
|
+
[path],
|
|
1324
|
+
KVAction.PUT
|
|
1155
1325
|
);
|
|
1156
1326
|
}
|
|
1157
1327
|
if (!response.ok) {
|
|
@@ -1280,7 +1450,9 @@ var KVService = class extends BaseService {
|
|
|
1280
1450
|
return this.authorizationFailure(
|
|
1281
1451
|
`Failed to batch put ${items.length} key(s)`,
|
|
1282
1452
|
response,
|
|
1283
|
-
errorText
|
|
1453
|
+
errorText,
|
|
1454
|
+
paths,
|
|
1455
|
+
KVAction.PUT
|
|
1284
1456
|
);
|
|
1285
1457
|
}
|
|
1286
1458
|
const quotaError = this.handleQuotaErrorResponse(
|
|
@@ -1401,11 +1573,13 @@ var KVService = class extends BaseService {
|
|
|
1401
1573
|
}
|
|
1402
1574
|
);
|
|
1403
1575
|
if (!response.ok) {
|
|
1404
|
-
if (response.status === 401) {
|
|
1576
|
+
if (response.status === 401 || response.status === 403) {
|
|
1405
1577
|
return this.authorizationFailure(
|
|
1406
1578
|
"Failed to list keys",
|
|
1407
1579
|
response,
|
|
1408
|
-
await
|
|
1580
|
+
await this.readAuthorizationText(response),
|
|
1581
|
+
[listPath],
|
|
1582
|
+
KVAction.LIST
|
|
1409
1583
|
);
|
|
1410
1584
|
}
|
|
1411
1585
|
const errorText = await response.text();
|
|
@@ -1454,11 +1628,13 @@ var KVService = class extends BaseService {
|
|
|
1454
1628
|
options?.ifMatch === void 0 ? void 0 : { "if-match": options.ifMatch }
|
|
1455
1629
|
);
|
|
1456
1630
|
if (!response.ok) {
|
|
1457
|
-
if (response.status === 401) {
|
|
1631
|
+
if (response.status === 401 || response.status === 403) {
|
|
1458
1632
|
return this.authorizationFailure(
|
|
1459
1633
|
`Failed to delete key ${JSON.stringify(key)}`,
|
|
1460
1634
|
response,
|
|
1461
|
-
await
|
|
1635
|
+
await this.readAuthorizationText(response),
|
|
1636
|
+
[path],
|
|
1637
|
+
KVAction.DELETE
|
|
1462
1638
|
);
|
|
1463
1639
|
}
|
|
1464
1640
|
if (response.status === 404) {
|
|
@@ -1516,11 +1692,13 @@ var KVService = class extends BaseService {
|
|
|
1516
1692
|
options?.signal
|
|
1517
1693
|
);
|
|
1518
1694
|
if (!response.ok) {
|
|
1519
|
-
if (response.status === 401) {
|
|
1695
|
+
if (response.status === 401 || response.status === 403) {
|
|
1520
1696
|
return this.authorizationFailure(
|
|
1521
1697
|
`Failed to get metadata for key ${JSON.stringify(key)}`,
|
|
1522
1698
|
response,
|
|
1523
|
-
await
|
|
1699
|
+
await this.readAuthorizationText(response),
|
|
1700
|
+
[path],
|
|
1701
|
+
KVAction.HEAD
|
|
1524
1702
|
);
|
|
1525
1703
|
}
|
|
1526
1704
|
if (response.status === 404) {
|
|
@@ -1587,7 +1765,7 @@ var KVService = class extends BaseService {
|
|
|
1587
1765
|
signal: this.combineSignals(options?.signal)
|
|
1588
1766
|
});
|
|
1589
1767
|
if (!response.ok) {
|
|
1590
|
-
return this.createSignedReadUrlError(response, key);
|
|
1768
|
+
return this.createSignedReadUrlError(response, key, path);
|
|
1591
1769
|
}
|
|
1592
1770
|
const signedUrl = this.normalizeSignedReadUrlResponse(
|
|
1593
1771
|
await response.json()
|