@tinycloud/sdk-services 3.1.0-beta.9 → 3.1.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/dist/index.cjs +551 -171
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +103 -12
- package/dist/index.d.ts +103 -12
- package/dist/index.js +551 -171
- package/dist/index.js.map +1 -1
- package/dist/kv/index.cjs +56 -11
- package/dist/kv/index.cjs.map +1 -1
- package/dist/kv/index.d.cts +12 -2
- package/dist/kv/index.d.ts +12 -2
- package/dist/kv/index.js +56 -11
- package/dist/kv/index.js.map +1 -1
- package/package.json +3 -3
package/dist/kv/index.d.cts
CHANGED
|
@@ -1073,6 +1073,16 @@ declare class KVService extends BaseService implements IKVService {
|
|
|
1073
1073
|
private createResponseHeaders;
|
|
1074
1074
|
private createBatchResponseHeaders;
|
|
1075
1075
|
private parseBatchValue;
|
|
1076
|
+
/**
|
|
1077
|
+
* Validate a batch read response and return its items in the caller's
|
|
1078
|
+
* request order. The node flattens invocation abilities from a `BTreeMap`,
|
|
1079
|
+
* so results arrive sorted by UTF-8 byte order of the path, not in request
|
|
1080
|
+
* order. Items that carry their path in `key` are matched by path; if no
|
|
1081
|
+
* item carries a key, items are assumed to be in the node's byte-sorted
|
|
1082
|
+
* order and the request is aligned the same way. Any mix of keyed and
|
|
1083
|
+
* keyless items, a missing requested path, an unrequested path, or a
|
|
1084
|
+
* malformed item fails closed (returns undefined).
|
|
1085
|
+
*/
|
|
1076
1086
|
private normalizeBatchReadResponse;
|
|
1077
1087
|
private batchRead;
|
|
1078
1088
|
/**
|
|
@@ -1120,8 +1130,8 @@ declare class KVService extends BaseService implements IKVService {
|
|
|
1120
1130
|
changes(options: KVChangesOptions): Promise<Result<KVChangesResponse>>;
|
|
1121
1131
|
/**
|
|
1122
1132
|
* Map a failed `kv/sync` response. 410 and the retention 403 carry
|
|
1123
|
-
* `{"error":{"code","reason"}}`; a revoked grant is a 401 whose
|
|
1124
|
-
*
|
|
1133
|
+
* `{"error":{"code","reason"}}`; a revoked grant is a 401 whose whole body
|
|
1134
|
+
* is the node's revocation error (see REVOKED_BODY). A body read that
|
|
1125
1135
|
* fails because the request was cancelled or timed out rethrows, so the
|
|
1126
1136
|
* caller sees `ABORTED`/`TIMEOUT` rather than a mapped status.
|
|
1127
1137
|
*/
|
package/dist/kv/index.d.ts
CHANGED
|
@@ -1073,6 +1073,16 @@ declare class KVService extends BaseService implements IKVService {
|
|
|
1073
1073
|
private createResponseHeaders;
|
|
1074
1074
|
private createBatchResponseHeaders;
|
|
1075
1075
|
private parseBatchValue;
|
|
1076
|
+
/**
|
|
1077
|
+
* Validate a batch read response and return its items in the caller's
|
|
1078
|
+
* request order. The node flattens invocation abilities from a `BTreeMap`,
|
|
1079
|
+
* so results arrive sorted by UTF-8 byte order of the path, not in request
|
|
1080
|
+
* order. Items that carry their path in `key` are matched by path; if no
|
|
1081
|
+
* item carries a key, items are assumed to be in the node's byte-sorted
|
|
1082
|
+
* order and the request is aligned the same way. Any mix of keyed and
|
|
1083
|
+
* keyless items, a missing requested path, an unrequested path, or a
|
|
1084
|
+
* malformed item fails closed (returns undefined).
|
|
1085
|
+
*/
|
|
1076
1086
|
private normalizeBatchReadResponse;
|
|
1077
1087
|
private batchRead;
|
|
1078
1088
|
/**
|
|
@@ -1120,8 +1130,8 @@ declare class KVService extends BaseService implements IKVService {
|
|
|
1120
1130
|
changes(options: KVChangesOptions): Promise<Result<KVChangesResponse>>;
|
|
1121
1131
|
/**
|
|
1122
1132
|
* Map a failed `kv/sync` response. 410 and the retention 403 carry
|
|
1123
|
-
* `{"error":{"code","reason"}}`; a revoked grant is a 401 whose
|
|
1124
|
-
*
|
|
1133
|
+
* `{"error":{"code","reason"}}`; a revoked grant is a 401 whose whole body
|
|
1134
|
+
* is the node's revocation error (see REVOKED_BODY). A body read that
|
|
1125
1135
|
* fails because the request was cancelled or timed out rethrows, so the
|
|
1126
1136
|
* caller sees `ABORTED`/`TIMEOUT` rather than a mapped status.
|
|
1127
1137
|
*/
|
package/dist/kv/index.js
CHANGED
|
@@ -801,6 +801,24 @@ var MAX_KV_BATCH_READ_ITEMS = 100;
|
|
|
801
801
|
function isJsonObject(value) {
|
|
802
802
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
803
803
|
}
|
|
804
|
+
var pathByteEncoder = new TextEncoder();
|
|
805
|
+
function comparePathsByBytes(a, b) {
|
|
806
|
+
const left = pathByteEncoder.encode(a);
|
|
807
|
+
const right = pathByteEncoder.encode(b);
|
|
808
|
+
const length = Math.min(left.length, right.length);
|
|
809
|
+
for (let index = 0; index < length; index++) {
|
|
810
|
+
if (left[index] !== right[index]) {
|
|
811
|
+
return left[index] - right[index];
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
return left.length - right.length;
|
|
815
|
+
}
|
|
816
|
+
var REVOKED_BODY = /^(?:Invalid invocation: )?delegation-(?:(revoked): [A-Za-z0-9]+|(ancestor-revoked): ancestor=[A-Za-z0-9]+ invoked=[A-Za-z0-9]+)$/;
|
|
817
|
+
function revocationCodeOf(body) {
|
|
818
|
+
const match = REVOKED_BODY.exec(body.trim());
|
|
819
|
+
if (match === null) return void 0;
|
|
820
|
+
return match[1] !== void 0 ? ErrorCodes.AUTH_DELEGATION_REVOKED : ErrorCodes.AUTH_DELEGATION_ANCESTOR_REVOKED;
|
|
821
|
+
}
|
|
804
822
|
function encodeKvBatchPartName(path) {
|
|
805
823
|
return encodeURIComponent(path).replace(
|
|
806
824
|
/[!'()*]/g,
|
|
@@ -1028,15 +1046,25 @@ var KVService = class extends BaseService {
|
|
|
1028
1046
|
)?.[1];
|
|
1029
1047
|
return contentType?.includes("application/json") ? JSON.parse(text) : text;
|
|
1030
1048
|
}
|
|
1049
|
+
/**
|
|
1050
|
+
* Validate a batch read response and return its items in the caller's
|
|
1051
|
+
* request order. The node flattens invocation abilities from a `BTreeMap`,
|
|
1052
|
+
* so results arrive sorted by UTF-8 byte order of the path, not in request
|
|
1053
|
+
* order. Items that carry their path in `key` are matched by path; if no
|
|
1054
|
+
* item carries a key, items are assumed to be in the node's byte-sorted
|
|
1055
|
+
* order and the request is aligned the same way. Any mix of keyed and
|
|
1056
|
+
* keyless items, a missing requested path, an unrequested path, or a
|
|
1057
|
+
* malformed item fails closed (returns undefined).
|
|
1058
|
+
*/
|
|
1031
1059
|
normalizeBatchReadResponse(data, paths, requireData) {
|
|
1032
1060
|
if (!data || typeof data !== "object") return void 0;
|
|
1033
1061
|
const response = data;
|
|
1034
|
-
|
|
1062
|
+
const items = response.results;
|
|
1063
|
+
if (!Array.isArray(items) || items.length !== paths.length) {
|
|
1035
1064
|
return void 0;
|
|
1036
1065
|
}
|
|
1037
|
-
for (
|
|
1038
|
-
|
|
1039
|
-
if (!item || typeof item !== "object" || item.key !== paths[index] || typeof item.ok !== "boolean") {
|
|
1066
|
+
for (const item of items) {
|
|
1067
|
+
if (!item || typeof item !== "object" || typeof item.ok !== "boolean") {
|
|
1040
1068
|
return void 0;
|
|
1041
1069
|
}
|
|
1042
1070
|
if (item.ok && (!item.headers || typeof item.headers !== "object" || Object.values(item.headers).some((value) => typeof value !== "string") || requireData && typeof item.dataBase64 !== "string")) {
|
|
@@ -1046,7 +1074,24 @@ var KVService = class extends BaseService {
|
|
|
1046
1074
|
return void 0;
|
|
1047
1075
|
}
|
|
1048
1076
|
}
|
|
1049
|
-
|
|
1077
|
+
if (items.every((item) => typeof item.key === "string")) {
|
|
1078
|
+
const byPath = new Map(items.map((item) => [item.key, item]));
|
|
1079
|
+
if (byPath.size !== items.length) return void 0;
|
|
1080
|
+
const aligned2 = [];
|
|
1081
|
+
for (const path of paths) {
|
|
1082
|
+
const item = byPath.get(path);
|
|
1083
|
+
if (!item) return void 0;
|
|
1084
|
+
aligned2.push(item);
|
|
1085
|
+
}
|
|
1086
|
+
return aligned2;
|
|
1087
|
+
}
|
|
1088
|
+
if (items.some((item) => item.key !== void 0)) return void 0;
|
|
1089
|
+
const requestOrder = paths.map((_, index) => index).sort((a, b) => comparePathsByBytes(paths[a], paths[b]));
|
|
1090
|
+
const aligned = new Array(items.length);
|
|
1091
|
+
for (let position = 0; position < requestOrder.length; position++) {
|
|
1092
|
+
aligned[requestOrder[position]] = items[position];
|
|
1093
|
+
}
|
|
1094
|
+
return aligned;
|
|
1050
1095
|
}
|
|
1051
1096
|
async batchRead(keys, action, options) {
|
|
1052
1097
|
if (!this.requireAuth()) return err(authRequiredError("kv"));
|
|
@@ -1139,19 +1184,19 @@ var KVService = class extends BaseService {
|
|
|
1139
1184
|
{ meta: { status: response.status, statusText: response.statusText } }
|
|
1140
1185
|
));
|
|
1141
1186
|
}
|
|
1142
|
-
const
|
|
1187
|
+
const items = this.normalizeBatchReadResponse(
|
|
1143
1188
|
await response.json(),
|
|
1144
1189
|
paths,
|
|
1145
1190
|
action === KVAction.GET
|
|
1146
1191
|
);
|
|
1147
|
-
if (!
|
|
1192
|
+
if (!items) {
|
|
1148
1193
|
return err(serviceError(
|
|
1149
1194
|
ErrorCodes.NETWORK_ERROR,
|
|
1150
1195
|
"KV batch read response did not match the requested keys",
|
|
1151
1196
|
"kv"
|
|
1152
1197
|
));
|
|
1153
1198
|
}
|
|
1154
|
-
const results =
|
|
1199
|
+
const results = items.map((item, index) => {
|
|
1155
1200
|
if (!item.ok) {
|
|
1156
1201
|
return {
|
|
1157
1202
|
key: keys[index],
|
|
@@ -1785,8 +1830,8 @@ var KVService = class extends BaseService {
|
|
|
1785
1830
|
}
|
|
1786
1831
|
/**
|
|
1787
1832
|
* Map a failed `kv/sync` response. 410 and the retention 403 carry
|
|
1788
|
-
* `{"error":{"code","reason"}}`; a revoked grant is a 401 whose
|
|
1789
|
-
*
|
|
1833
|
+
* `{"error":{"code","reason"}}`; a revoked grant is a 401 whose whole body
|
|
1834
|
+
* is the node's revocation error (see REVOKED_BODY). A body read that
|
|
1790
1835
|
* fails because the request was cancelled or timed out rethrows, so the
|
|
1791
1836
|
* caller sees `ABORTED`/`TIMEOUT` rather than a mapped status.
|
|
1792
1837
|
*/
|
|
@@ -1831,7 +1876,7 @@ var KVService = class extends BaseService {
|
|
|
1831
1876
|
));
|
|
1832
1877
|
}
|
|
1833
1878
|
if (response.status === 401) {
|
|
1834
|
-
const revoked =
|
|
1879
|
+
const revoked = revocationCodeOf(errorText);
|
|
1835
1880
|
if (revoked !== void 0) {
|
|
1836
1881
|
return err(serviceError(revoked, `${context}: 401 - ${errorText}`, "kv", { meta }));
|
|
1837
1882
|
}
|