@tinycloud/sdk-services 3.12.0-beta.7 → 3.12.0-beta.8
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.map +1 -1
- package/dist/encryption/index.d.cts +2 -2
- package/dist/encryption/index.d.ts +2 -2
- package/dist/encryption/index.js.map +1 -1
- package/dist/encryption/named-keys.d.cts +1 -1
- package/dist/encryption/named-keys.d.ts +1 -1
- package/dist/index.cjs +97 -50
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +94 -50
- package/dist/index.js.map +1 -1
- package/dist/kv/index.cjs.map +1 -1
- package/dist/kv/index.js.map +1 -1
- package/dist/kv/replication/index.cjs.map +1 -1
- package/dist/kv/replication/index.js.map +1 -1
- package/dist/sql/index.cjs.map +1 -1
- package/dist/sql/index.js.map +1 -1
- package/dist/{types-XE4tyBLH.d.ts → types-Ceti5xVp.d.ts} +39 -4
- package/dist/{types-cWtQmCCw.d.cts → types-CoZ0vXo8.d.cts} +39 -4
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -2,8 +2,8 @@ import { g as ServiceError, f as Result, P as PermissionHint, c as IService, S a
|
|
|
2
2
|
export { k as ErrorCode, l as ErrorCodes, E as EventHandler, F as FetchFunction, d as FetchRequestInit, e as FetchResponse, m as InvocationFact, n as InvocationFacts, o as InvokeAnyEntry, b as InvokeAnyFunction, a as InvokeFunction, R as RetryPolicy, i as RetryStats, p as ServiceErrorEvent, h as ServiceHeaders, q as ServiceRequestEvent, r as ServiceResponseEvent, s as ServiceRetryEvent, T as TelemetryConfig, t as TelemetryEventHandler, u as TelemetryEvents, v as TelemetrySpanEvent, w as defaultRetryPolicy, x as err, y as ok, z as serviceError } from './types-DjAP8dve.cjs';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
export { ServiceContext, ServiceContextConfig } from './context.cjs';
|
|
5
|
-
import { D as DecryptCapabilityProof, R as RoutingFailure } from './types-
|
|
6
|
-
export { B as BuildDecryptInvocationInput, a as BuiltDecryptInvocation, C as CanonicalJson, b as DECRYPT_ACTION, c as DECRYPT_FACT_TYPE, d as DECRYPT_RESULT_TYPE, e as DEFAULT_ENCRYPTION_ALG, f as DEFAULT_KEY_VERSION, g as DecryptInvocationFact, h as DecryptInvocationSigner, i as DecryptRequestBody, j as DecryptResponseBody, k as ENCRYPTION_SERVICE, l as ENCRYPTION_SERVICE_SHORT, m as ENVELOPE_VERSION, E as EncryptionCrypto, n as EncryptionError, o as EncryptionErrorInput, I as InlineEncryptedEnvelope, J as Json, N as NetworkDescriptor, p as NodeIdentityMismatchError, q as NodeNotRespondingError, P as PartialNodeWriteError, r as ReceiverKeyPair, s as ReceiverKeySigner, t as ResourceAccess, u as ResourceDestination, v as
|
|
5
|
+
import { D as DecryptCapabilityProof, R as RoutingFailure } from './types-CoZ0vXo8.cjs';
|
|
6
|
+
export { B as BuildDecryptInvocationInput, a as BuiltDecryptInvocation, C as CanonicalJson, b as DECRYPT_ACTION, c as DECRYPT_FACT_TYPE, d as DECRYPT_RESULT_TYPE, e as DEFAULT_ENCRYPTION_ALG, f as DEFAULT_KEY_VERSION, g as DecryptInvocationFact, h as DecryptInvocationSigner, i as DecryptRequestBody, j as DecryptResponseBody, k as ENCRYPTION_SERVICE, l as ENCRYPTION_SERVICE_SHORT, m as ENVELOPE_VERSION, E as EncryptionCrypto, n as EncryptionError, o as EncryptionErrorInput, I as InlineEncryptedEnvelope, J as Json, N as NetworkDescriptor, p as NodeIdentityMismatchError, q as NodeNotRespondingError, P as PartialNodeWriteError, r as ReceiverKeyPair, s as ReceiverKeySigner, t as ResourceAccess, u as ResourceDestination, v as ResourceNodeInfo, w as ResourceNotRoutedError, x as ResourceRoutingConfig, y as ResourceTransport, z as ResourceTransportOptions, A as ResourceTransportTarget, F as base64Decode, G as base64Encode, H as canonicalHashHex, K as canonicalizeEncryptionJson, L as createResourceRoutingFetch, M as createResourceTransportInvocationFetch, O as encryptionError, Q as hexDecode, S as hexEncode, T as routeResourceRequest, U as routingFailure, V as routingResourceOf, W as utf8Decode, X as utf8Encode, Y as verifyResourceDestination } from './types-CoZ0vXo8.cjs';
|
|
7
7
|
export { RequestEvent, RequestLog, RequestLogReader, RequestService, RequestSink } from './telemetry/requestLog.cjs';
|
|
8
8
|
import { B as BaseService } from './BaseService-CdBkfPGE.cjs';
|
|
9
9
|
export { a as BaseServiceOptions, R as RequestSignal, S as ServiceConstructor, b as ServiceRegistration } from './BaseService-CdBkfPGE.cjs';
|
package/dist/index.d.ts
CHANGED
|
@@ -2,8 +2,8 @@ import { g as ServiceError, f as Result, P as PermissionHint, c as IService, S a
|
|
|
2
2
|
export { k as ErrorCode, l as ErrorCodes, E as EventHandler, F as FetchFunction, d as FetchRequestInit, e as FetchResponse, m as InvocationFact, n as InvocationFacts, o as InvokeAnyEntry, b as InvokeAnyFunction, a as InvokeFunction, R as RetryPolicy, i as RetryStats, p as ServiceErrorEvent, h as ServiceHeaders, q as ServiceRequestEvent, r as ServiceResponseEvent, s as ServiceRetryEvent, T as TelemetryConfig, t as TelemetryEventHandler, u as TelemetryEvents, v as TelemetrySpanEvent, w as defaultRetryPolicy, x as err, y as ok, z as serviceError } from './types-DjAP8dve.js';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
export { ServiceContext, ServiceContextConfig } from './context.js';
|
|
5
|
-
import { D as DecryptCapabilityProof, R as RoutingFailure } from './types-
|
|
6
|
-
export { B as BuildDecryptInvocationInput, a as BuiltDecryptInvocation, C as CanonicalJson, b as DECRYPT_ACTION, c as DECRYPT_FACT_TYPE, d as DECRYPT_RESULT_TYPE, e as DEFAULT_ENCRYPTION_ALG, f as DEFAULT_KEY_VERSION, g as DecryptInvocationFact, h as DecryptInvocationSigner, i as DecryptRequestBody, j as DecryptResponseBody, k as ENCRYPTION_SERVICE, l as ENCRYPTION_SERVICE_SHORT, m as ENVELOPE_VERSION, E as EncryptionCrypto, n as EncryptionError, o as EncryptionErrorInput, I as InlineEncryptedEnvelope, J as Json, N as NetworkDescriptor, p as NodeIdentityMismatchError, q as NodeNotRespondingError, P as PartialNodeWriteError, r as ReceiverKeyPair, s as ReceiverKeySigner, t as ResourceAccess, u as ResourceDestination, v as
|
|
5
|
+
import { D as DecryptCapabilityProof, R as RoutingFailure } from './types-Ceti5xVp.js';
|
|
6
|
+
export { B as BuildDecryptInvocationInput, a as BuiltDecryptInvocation, C as CanonicalJson, b as DECRYPT_ACTION, c as DECRYPT_FACT_TYPE, d as DECRYPT_RESULT_TYPE, e as DEFAULT_ENCRYPTION_ALG, f as DEFAULT_KEY_VERSION, g as DecryptInvocationFact, h as DecryptInvocationSigner, i as DecryptRequestBody, j as DecryptResponseBody, k as ENCRYPTION_SERVICE, l as ENCRYPTION_SERVICE_SHORT, m as ENVELOPE_VERSION, E as EncryptionCrypto, n as EncryptionError, o as EncryptionErrorInput, I as InlineEncryptedEnvelope, J as Json, N as NetworkDescriptor, p as NodeIdentityMismatchError, q as NodeNotRespondingError, P as PartialNodeWriteError, r as ReceiverKeyPair, s as ReceiverKeySigner, t as ResourceAccess, u as ResourceDestination, v as ResourceNodeInfo, w as ResourceNotRoutedError, x as ResourceRoutingConfig, y as ResourceTransport, z as ResourceTransportOptions, A as ResourceTransportTarget, F as base64Decode, G as base64Encode, H as canonicalHashHex, K as canonicalizeEncryptionJson, L as createResourceRoutingFetch, M as createResourceTransportInvocationFetch, O as encryptionError, Q as hexDecode, S as hexEncode, T as routeResourceRequest, U as routingFailure, V as routingResourceOf, W as utf8Decode, X as utf8Encode, Y as verifyResourceDestination } from './types-Ceti5xVp.js';
|
|
7
7
|
export { RequestEvent, RequestLog, RequestLogReader, RequestService, RequestSink } from './telemetry/requestLog.js';
|
|
8
8
|
import { B as BaseService } from './BaseService-BRDG69KR.js';
|
|
9
9
|
export { a as BaseServiceOptions, R as RequestSignal, S as ServiceConstructor, b as ServiceRegistration } from './BaseService-BRDG69KR.js';
|
package/dist/index.js
CHANGED
|
@@ -815,6 +815,7 @@ async function verifyResourceDestination(target, fetchFn) {
|
|
|
815
815
|
if (infoDid !== target.nodeDid || keysDid !== target.nodeDid) {
|
|
816
816
|
throw new NodeIdentityMismatchError(target.url, target.nodeDid, infoDid !== target.nodeDid ? infoDid : keysDid);
|
|
817
817
|
}
|
|
818
|
+
return info;
|
|
818
819
|
}
|
|
819
820
|
var NodeNotRespondingError = class extends Error {
|
|
820
821
|
constructor(hosts, cause) {
|
|
@@ -882,6 +883,17 @@ function authorizationOf(headers) {
|
|
|
882
883
|
if (headers === void 0) return void 0;
|
|
883
884
|
return (Array.isArray(headers) ? headers : Object.entries(headers)).find(([name]) => name.toLowerCase() === "authorization")?.[1];
|
|
884
885
|
}
|
|
886
|
+
function routingResourceOf(uri) {
|
|
887
|
+
if (uri.startsWith("tinycloud://")) {
|
|
888
|
+
const resource = uri.slice("tinycloud://".length).split("/", 1)[0];
|
|
889
|
+
if (resource) return resource;
|
|
890
|
+
} else if (uri.startsWith("urn:tinycloud:encryption:")) {
|
|
891
|
+
return uri;
|
|
892
|
+
} else if (uri.startsWith("tinycloud:")) {
|
|
893
|
+
return uri.split("/", 1)[0];
|
|
894
|
+
}
|
|
895
|
+
throw new ResourceNotRoutedError(uri);
|
|
896
|
+
}
|
|
885
897
|
function invocationResources(authorization) {
|
|
886
898
|
const encoded = authorization.split(".")[1];
|
|
887
899
|
if (!encoded) throw new ResourceNotRoutedError("invalid invocation");
|
|
@@ -893,8 +905,7 @@ function invocationResources(authorization) {
|
|
|
893
905
|
for (const [uri, abilities] of Object.entries(payload.att)) {
|
|
894
906
|
if (typeof abilities !== "object" || abilities === null || Array.isArray(abilities)) throw new ResourceNotRoutedError(uri);
|
|
895
907
|
for (const action of Object.keys(abilities)) {
|
|
896
|
-
const resource =
|
|
897
|
-
if (!resource.startsWith("tinycloud:") && !resource.startsWith("urn:tinycloud:encryption:")) throw new ResourceNotRoutedError(uri);
|
|
908
|
+
const resource = routingResourceOf(uri);
|
|
898
909
|
const read2 = /^(tinycloud\.(kv\/(get|list|metadata|head|sync)|sql\/(read|export)|duckdb\/(read|describe|export)|capabilities\/read|space\/(list|info)|hooks\/list))$/.test(action);
|
|
899
910
|
const access = resource.startsWith("urn:tinycloud:encryption:") ? "encryption" : action === "tinycloud.space/host" ? "host" : read2 ? "read" : "write";
|
|
900
911
|
if (!resources.some((entry) => entry.resource === resource && entry.access === access)) resources.push({ resource, access });
|
|
@@ -903,6 +914,83 @@ function invocationResources(authorization) {
|
|
|
903
914
|
if (resources.length === 0) throw new ResourceNotRoutedError("empty invocation");
|
|
904
915
|
return resources;
|
|
905
916
|
}
|
|
917
|
+
async function routeResourceRequest(resources, routing, send, options) {
|
|
918
|
+
if (resources.length === 0) throw new ResourceNotRoutedError("empty request");
|
|
919
|
+
const routes = await Promise.all(resources.map(({ resource, access }) => routing.resolveResource(resource, access)));
|
|
920
|
+
if (routes.some((route) => route.length === 0)) throw new ResourceNotRoutedError(resources[routes.findIndex((route) => route.length === 0)].resource);
|
|
921
|
+
const write = options?.independentResources === true || resources.some(({ access }) => access === "write" || access === "host");
|
|
922
|
+
let targets;
|
|
923
|
+
if (options?.independentResources) {
|
|
924
|
+
targets = routes.flat();
|
|
925
|
+
const identities = /* @__PURE__ */ new Map();
|
|
926
|
+
for (const target of targets) {
|
|
927
|
+
if (identities.has(target.url) && identities.get(target.url) !== target.nodeDid) throw new ResourceNotRoutedError(target.url);
|
|
928
|
+
identities.set(target.url, target.nodeDid);
|
|
929
|
+
}
|
|
930
|
+
} else {
|
|
931
|
+
targets = routes[0].filter((target) => routes.every((route) => route.some((other) => other.url === target.url && other.nodeDid === target.nodeDid)));
|
|
932
|
+
if (targets.length === 0 || write && routes.some((route) => route.length !== targets.length)) throw new ResourceNotRoutedError(resources.map(({ resource }) => resource).join(", "));
|
|
933
|
+
}
|
|
934
|
+
targets = targets.filter((target, index) => targets.findIndex((other) => other.url === target.url) === index);
|
|
935
|
+
if (options?.nodeDid) targets = targets.filter((target) => target.nodeDid === options.nodeDid || target.nodeDid === void 0);
|
|
936
|
+
if (targets.length === 0 || options?.nodeLocal && targets.length !== 1) throw new ResourceNotRoutedError(resources.map(({ resource }) => resource).join(", "));
|
|
937
|
+
if (!write) {
|
|
938
|
+
let response2;
|
|
939
|
+
let failure;
|
|
940
|
+
for (const target of targets) {
|
|
941
|
+
try {
|
|
942
|
+
response2 = await send(target);
|
|
943
|
+
if (response2.ok || response2.status !== 404) return response2;
|
|
944
|
+
} catch (error) {
|
|
945
|
+
if (!(error instanceof NodeNotRespondingError)) throw error;
|
|
946
|
+
failure = error;
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
if (failure) throw new NodeNotRespondingError(targets.map(({ url }) => url), failure);
|
|
950
|
+
if (response2) return response2;
|
|
951
|
+
throw new NodeNotRespondingError(targets.map(({ url }) => url), failure);
|
|
952
|
+
}
|
|
953
|
+
const succeeded = [];
|
|
954
|
+
const failed = [];
|
|
955
|
+
let response;
|
|
956
|
+
let failureResponse;
|
|
957
|
+
for (const target of targets) {
|
|
958
|
+
try {
|
|
959
|
+
const result = await send(target);
|
|
960
|
+
if (result.ok) {
|
|
961
|
+
succeeded.push(target.url);
|
|
962
|
+
response ?? (response = result);
|
|
963
|
+
} else {
|
|
964
|
+
failed.push({ url: target.url, status: result.status });
|
|
965
|
+
failureResponse ?? (failureResponse = result);
|
|
966
|
+
}
|
|
967
|
+
} catch (error) {
|
|
968
|
+
if (!routingFailure(error) && succeeded.length === 0) throw error;
|
|
969
|
+
failed.push({ url: target.url, cause: error });
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
if (failed.length > 0) {
|
|
973
|
+
if (succeeded.length > 0 || targets.length > 1) throw new PartialNodeWriteError(succeeded, failed);
|
|
974
|
+
if (failureResponse) return failureResponse;
|
|
975
|
+
if (failed[0]?.cause && !(failed[0].cause instanceof NodeNotRespondingError)) throw failed[0].cause;
|
|
976
|
+
throw new NodeNotRespondingError(targets.map(({ url }) => url), failed[0]?.cause);
|
|
977
|
+
}
|
|
978
|
+
return response;
|
|
979
|
+
}
|
|
980
|
+
function createResourceTransportInvocationFetch(transport, session) {
|
|
981
|
+
return async (url, init) => {
|
|
982
|
+
const parsed = new URL(url);
|
|
983
|
+
if (parsed.pathname !== "/invoke") throw new ResourceNotRoutedError(parsed.pathname);
|
|
984
|
+
const authorization = authorizationOf(init?.headers);
|
|
985
|
+
if (!authorization) throw new ResourceNotRoutedError("unsigned invocation");
|
|
986
|
+
return transport(invocationResources(authorization), async (target) => {
|
|
987
|
+
const signed = await target.bindAudience(authorization);
|
|
988
|
+
const headers = (Array.isArray(init?.headers) ? init.headers : Object.entries(init?.headers ?? {})).filter(([name]) => name.toLowerCase() !== "authorization");
|
|
989
|
+
headers.push(["Authorization", signed]);
|
|
990
|
+
return target.fetch(`${target.url}${parsed.pathname}${parsed.search}`, { ...init, headers });
|
|
991
|
+
}, { invocationSession: session });
|
|
992
|
+
};
|
|
993
|
+
}
|
|
906
994
|
function createResourceRoutingFetch(fetchFn, routing) {
|
|
907
995
|
return async (url, init) => {
|
|
908
996
|
const parsed = new URL(url);
|
|
@@ -910,12 +998,6 @@ function createResourceRoutingFetch(fetchFn, routing) {
|
|
|
910
998
|
const authorization = authorizationOf(init?.headers);
|
|
911
999
|
if (!authorization) throw new ResourceNotRoutedError("unsigned invocation");
|
|
912
1000
|
const resources = invocationResources(authorization);
|
|
913
|
-
const routes = await Promise.all(resources.map(({ resource, access }) => routing.resolveResource(resource, access)));
|
|
914
|
-
if (routes.some((route) => route.length === 0)) throw new ResourceNotRoutedError(resources[routes.findIndex((route) => route.length === 0)].resource);
|
|
915
|
-
const write = resources.some(({ access }) => access === "write" || access === "host");
|
|
916
|
-
let targets = routes[0].filter((target) => routes.every((route) => route.some((other) => other.url === target.url && other.nodeDid === target.nodeDid)));
|
|
917
|
-
if (targets.length === 0 || write && routes.some((route) => route.length !== targets.length)) throw new ResourceNotRoutedError(resources.map(({ resource }) => resource).join(", "));
|
|
918
|
-
targets = targets.filter((target, index) => targets.findIndex((other) => other.url === target.url) === index);
|
|
919
1001
|
const send = async (target) => {
|
|
920
1002
|
init?.signal?.throwIfAborted();
|
|
921
1003
|
if (routing.verifyDestination) await routing.verifyDestination(target);
|
|
@@ -933,48 +1015,7 @@ function createResourceRoutingFetch(fetchFn, routing) {
|
|
|
933
1015
|
throw new NodeNotRespondingError([target.url], error);
|
|
934
1016
|
}
|
|
935
1017
|
};
|
|
936
|
-
|
|
937
|
-
let response2;
|
|
938
|
-
let failure;
|
|
939
|
-
for (const target of targets) {
|
|
940
|
-
try {
|
|
941
|
-
response2 = await send(target);
|
|
942
|
-
if (response2.ok || response2.status !== 404) return response2;
|
|
943
|
-
} catch (error) {
|
|
944
|
-
if (!(error instanceof NodeNotRespondingError)) throw error;
|
|
945
|
-
failure = error;
|
|
946
|
-
}
|
|
947
|
-
}
|
|
948
|
-
if (failure) throw new NodeNotRespondingError(targets.map(({ url: url2 }) => url2), failure);
|
|
949
|
-
if (response2) return response2;
|
|
950
|
-
throw new NodeNotRespondingError(targets.map(({ url: url2 }) => url2), failure);
|
|
951
|
-
}
|
|
952
|
-
const succeeded = [];
|
|
953
|
-
const failed = [];
|
|
954
|
-
let response;
|
|
955
|
-
let failureResponse;
|
|
956
|
-
for (const target of targets) {
|
|
957
|
-
try {
|
|
958
|
-
const result = await send(target);
|
|
959
|
-
if (result.ok) {
|
|
960
|
-
succeeded.push(target.url);
|
|
961
|
-
response ?? (response = result);
|
|
962
|
-
} else {
|
|
963
|
-
failed.push({ url: target.url, status: result.status });
|
|
964
|
-
failureResponse ?? (failureResponse = result);
|
|
965
|
-
}
|
|
966
|
-
} catch (error) {
|
|
967
|
-
if (!routingFailure(error) && succeeded.length === 0) throw error;
|
|
968
|
-
failed.push({ url: target.url, cause: error });
|
|
969
|
-
}
|
|
970
|
-
}
|
|
971
|
-
if (failed.length > 0) {
|
|
972
|
-
if (succeeded.length > 0 || targets.length > 1) throw new PartialNodeWriteError(succeeded, failed);
|
|
973
|
-
if (failureResponse) return failureResponse;
|
|
974
|
-
if (failed[0]?.cause && !(failed[0].cause instanceof NodeNotRespondingError)) throw failed[0].cause;
|
|
975
|
-
throw new NodeNotRespondingError(targets.map(({ url: url2 }) => url2), failed[0]?.cause);
|
|
976
|
-
}
|
|
977
|
-
return response;
|
|
1018
|
+
return routeResourceRequest(resources, routing, send);
|
|
978
1019
|
};
|
|
979
1020
|
}
|
|
980
1021
|
|
|
@@ -8905,6 +8946,7 @@ export {
|
|
|
8905
8946
|
clearTinyCloudDebugLogs,
|
|
8906
8947
|
createKVResponseSchema,
|
|
8907
8948
|
createResourceRoutingFetch,
|
|
8949
|
+
createResourceTransportInvocationFetch,
|
|
8908
8950
|
createResultSchema,
|
|
8909
8951
|
createVaultCrypto,
|
|
8910
8952
|
decryptEnvelopeWithKey,
|
|
@@ -8947,7 +8989,9 @@ export {
|
|
|
8947
8989
|
requiresSecretsOptIn,
|
|
8948
8990
|
resolveSecretListPrefix,
|
|
8949
8991
|
resolveSecretPath,
|
|
8992
|
+
routeResourceRequest,
|
|
8950
8993
|
routingFailure,
|
|
8994
|
+
routingResourceOf,
|
|
8951
8995
|
serviceError,
|
|
8952
8996
|
storageLimitReachedError,
|
|
8953
8997
|
storageQuotaExceededError,
|