@tinycloud/sdk-core 3.1.0-beta.3 → 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/index.js CHANGED
@@ -3437,6 +3437,32 @@ import { sha256 as sha2564 } from "@noble/hashes/sha256";
3437
3437
  import { blake3 } from "@noble/hashes/blake3";
3438
3438
  import { ed25519 as ed255193 } from "@noble/curves/ed25519";
3439
3439
  import { z as z2 } from "zod";
3440
+
3441
+ // src/http-error.ts
3442
+ import { ErrorCodes, serviceError } from "@tinycloud/sdk-services";
3443
+ async function httpResponseError(response, context) {
3444
+ let body;
3445
+ try {
3446
+ body = await response.text();
3447
+ } catch {
3448
+ body = response.statusText;
3449
+ }
3450
+ body = body.trim().slice(0, 512);
3451
+ return Object.assign(new Error(`${context}: HTTP ${response.status}${body ? ` - ${body}` : ""}`), {
3452
+ status: response.status
3453
+ });
3454
+ }
3455
+ async function serviceHttpError(response, code3, context, service) {
3456
+ const failure = await httpResponseError(response, context);
3457
+ return serviceError(
3458
+ response.status === 401 || response.status === 403 ? ErrorCodes.AUTH_UNAUTHORIZED : code3,
3459
+ failure.message,
3460
+ service,
3461
+ { meta: { status: response.status } }
3462
+ );
3463
+ }
3464
+
3465
+ // src/policy/unified.ts
3440
3466
  var POLICY_V1_SCHEMA = "xyz.tinycloud.policy/policy/v1";
3441
3467
  var POLICY_CAPABILITY_V1_SCHEMA = "xyz.tinycloud.policy/capability/v1";
3442
3468
  var POLICY_ENFORCEMENT_DELEGATION_V2_SCHEMA = "xyz.tinycloud.policy/enforcement-delegation/v2";
@@ -3464,7 +3490,7 @@ async function requestPolicyChallengeV3(input) {
3464
3490
  headers: { accept: "application/json", "content-type": "application/json" },
3465
3491
  body: JSON.stringify({ policyCid: input.policyCid, recipientDid: input.recipientDid, requestedCapabilities: input.requestedCapabilities.map(normalizeUnifiedPolicyCapability) })
3466
3492
  });
3467
- if (!response.ok) throw new Error(`policy challenge rejected (${response.status})`);
3493
+ if (!response.ok) throw await httpResponseError(response, "policy challenge rejected");
3468
3494
  const value = object2(await response.json(), "policy challenge");
3469
3495
  if (typeof value.challengeId !== "string" || typeof value.nonce !== "string" || value.policyCid !== input.policyCid || value.recipientDid !== input.recipientDid)
3470
3496
  throw new Error("policy challenge binding is invalid");
@@ -3527,7 +3553,7 @@ async function getPolicyRootStatusV3(input) {
3527
3553
  redirect: "error",
3528
3554
  headers: { accept: "application/json" }
3529
3555
  });
3530
- if (!response.ok) throw new Error(`policy root status rejected (${response.status})`);
3556
+ if (!response.ok) throw await httpResponseError(response, "policy root status rejected");
3531
3557
  const value = object2(await response.json(), "policy root status");
3532
3558
  const checkpoint = object2(value.checkpoint, "policy root checkpoint");
3533
3559
  if (value.rootCid !== input.rootCid || value.state !== "active" && value.state !== "revoked" || value.state !== checkpoint.state || !verifyPolicyRootStatusCheckpointV3({ rootCid: input.rootCid, checkpoint, expectedNodeAudience: input.expectedNodeAudience, now: input.now }))
@@ -3587,7 +3613,7 @@ async function renewPolicyRootStatusV3(input) {
3587
3613
  headers: { accept: "application/json", "content-type": "application/json" },
3588
3614
  body: JSON.stringify({ rootCid: input.rootCid, renewal: { ...unsigned, signature: { suite: "Ed25519", signerDid: input.ownerDid, value: encodeBase64Url2(signature) } } })
3589
3615
  });
3590
- if (!response.ok) throw new Error(`policy root renewal rejected (${response.status})`);
3616
+ if (!response.ok) throw await httpResponseError(response, "policy root renewal rejected");
3591
3617
  return object2(await response.json(), "policy root renewal");
3592
3618
  }
3593
3619
  function rfc3339Seconds(value) {
@@ -3614,7 +3640,7 @@ async function revokePolicyRootV3(input) {
3614
3640
  headers: { accept: "application/json", "content-type": "application/json" },
3615
3641
  body: JSON.stringify({ revocation: { ...unsigned, signature: { suite: "Ed25519", signerDid: input.issuerDid, value: encodeBase64Url2(signature) } } })
3616
3642
  });
3617
- if (!response.ok) throw new Error(`policy root revocation rejected (${response.status})`);
3643
+ if (!response.ok) throw await httpResponseError(response, "policy root revocation rejected");
3618
3644
  return object2(await response.json(), "policy root revocation");
3619
3645
  }
3620
3646
  var POLICY_SESSION_FACT_KEYS = [
@@ -3883,7 +3909,7 @@ async function registerPolicyV3(input) {
3883
3909
  }
3884
3910
  );
3885
3911
  if (!bindingResponse.ok) {
3886
- throw new Error(`policy enforcer binding rejected (${bindingResponse.status})`);
3912
+ throw await httpResponseError(bindingResponse, "policy enforcer binding rejected");
3887
3913
  }
3888
3914
  const binding = exactObject(
3889
3915
  await bindingResponse.json(),
@@ -3949,7 +3975,7 @@ async function registerPolicyV3(input) {
3949
3975
  }
3950
3976
  );
3951
3977
  if (!response.ok) {
3952
- throw new Error(`policy registration rejected (${response.status})`);
3978
+ throw await httpResponseError(response, "policy registration rejected");
3953
3979
  }
3954
3980
  const receipt = exactObject(
3955
3981
  await response.json(),
@@ -4635,7 +4661,7 @@ async function admitPolicyCredentialV3(input) {
4635
4661
  requestedSessionExpiry(input.requestedExpiresAt, policy),
4636
4662
  input.signal
4637
4663
  );
4638
- if (!response.ok) throw new Error(`policy delegation rejected (${response.status})`);
4664
+ if (!response.ok) throw await httpResponseError(response, "policy delegation rejected");
4639
4665
  const value = record(await response.json(), "policy delegation");
4640
4666
  if (value.admitted !== true || typeof value.sessionCid !== "string" || typeof value.authorization !== "string") {
4641
4667
  throw new Error("policy delegation response is invalid");
@@ -4688,7 +4714,7 @@ async function admitPolicyCredentialV4(input) {
4688
4714
  requestedSessionExpiry(input.requestedExpiresAt, policy),
4689
4715
  input.signal
4690
4716
  );
4691
- if (!response.ok) throw new Error(`policy delegation rejected (${response.status})`);
4717
+ if (!response.ok) throw await httpResponseError(response, "policy delegation rejected");
4692
4718
  const value = record(await response.json(), "policy delegation");
4693
4719
  if (value.admitted !== true || typeof value.sessionCid !== "string" || typeof value.authorization !== "string") throw new Error("policy delegation response is invalid");
4694
4720
  const session = parsePolicySessionUcan(value.authorization, [
@@ -4707,7 +4733,7 @@ async function admitPolicyCredentialV4(input) {
4707
4733
  signal: input.signal,
4708
4734
  headers: { Authorization: session.authorization }
4709
4735
  });
4710
- if (!importResponse.ok) throw new Error(`delegation import rejected (${importResponse.status})`);
4736
+ if (!importResponse.ok) throw await httpResponseError(importResponse, "delegation import rejected");
4711
4737
  input.signal?.throwIfAborted();
4712
4738
  return Object.freeze({ challenge, presentation, session, delegationImported: true });
4713
4739
  }
@@ -8228,7 +8254,7 @@ import { ed25519 as ed255197 } from "@noble/curves/ed25519";
8228
8254
 
8229
8255
  // src/delegations/ShareRecipientClient.ts
8230
8256
  import {
8231
- ErrorCodes,
8257
+ ErrorCodes as ErrorCodes2,
8232
8258
  KVService,
8233
8259
  ServiceContext
8234
8260
  } from "@tinycloud/sdk-services";
@@ -9349,7 +9375,7 @@ async function importPortableDelegation(fetchFn, host, delegation) {
9349
9375
  headers: { Authorization: parsed.delegationHeader.Authorization }
9350
9376
  });
9351
9377
  if (!response.ok)
9352
- throw new Error(`node rejected delegation import (${response.status})`);
9378
+ throw await httpResponseError(response, "node rejected delegation import");
9353
9379
  const body = await response.json().catch(() => ({}));
9354
9380
  if (body === null || typeof body !== "object" || Array.isArray(body))
9355
9381
  return {};
@@ -9418,7 +9444,7 @@ function redactedCode(error) {
9418
9444
  if (error instanceof ShareConflict) return error.code;
9419
9445
  const code3 = error && typeof error === "object" && "code" in error ? error.code : void 0;
9420
9446
  if (typeof code3 !== "string") return "SHARE_INVALID";
9421
- if (code3 === ErrorCodes.KV_PRECONDITION_FAILED || code3 === ErrorCodes.KV_CONFLICT || code3 === "412") return "SHARE_CONFLICT";
9447
+ if (code3 === ErrorCodes2.KV_PRECONDITION_FAILED || code3 === ErrorCodes2.KV_CONFLICT || code3 === "412") return "SHARE_CONFLICT";
9422
9448
  if (code3 === "KV_NOT_FOUND" || code3 === "NOT_FOUND" || code3 === "404") return "SHARE_NOT_FOUND";
9423
9449
  if (code3.includes("EXPIRED") || code3 === "expired") return "SHARE_EXPIRED";
9424
9450
  if (code3.includes("REVOK")) return "SHARE_REVOKED";
@@ -9657,7 +9683,7 @@ var ShareRecipientClient = class {
9657
9683
  if (portableDelegation !== void 0 && kv !== void 0) {
9658
9684
  const result2 = await kv.put(resolvedPath, bytes2, { contentType: input.contentType ?? envelope.content.mimeType, ifMatch: input.etag });
9659
9685
  if (!result2.ok) {
9660
- if (result2.error.code === ErrorCodes.KV_PRECONDITION_FAILED || result2.error.code === ErrorCodes.KV_CONFLICT) throw new ShareConflict(resolvedPath, result2.error.meta?.etag);
9686
+ if (result2.error.code === ErrorCodes2.KV_PRECONDITION_FAILED || result2.error.code === ErrorCodes2.KV_CONFLICT) throw new ShareConflict(resolvedPath, result2.error.meta?.etag);
9661
9687
  throw result2.error;
9662
9688
  }
9663
9689
  return { etag: result2.data.headers.etag };
@@ -9665,7 +9691,7 @@ var ShareRecipientClient = class {
9665
9691
  if (policySession !== void 0) return this.nativeSave(envelope, policySession, resolvedPath, bytes2, input);
9666
9692
  const result = await kv.put(resolvedPath, bytes2, { contentType: input.contentType ?? envelope.content.mimeType, ifMatch: input.etag });
9667
9693
  if (!result.ok) {
9668
- if (result.error.code === ErrorCodes.KV_PRECONDITION_FAILED || result.error.code === ErrorCodes.KV_CONFLICT) throw new ShareConflict(resolvedPath, result.error.meta?.etag);
9694
+ if (result.error.code === ErrorCodes2.KV_PRECONDITION_FAILED || result.error.code === ErrorCodes2.KV_CONFLICT) throw new ShareConflict(resolvedPath, result.error.meta?.etag);
9669
9695
  throw result.error;
9670
9696
  }
9671
9697
  return { etag: result.data.headers.etag };
@@ -12144,12 +12170,12 @@ import {
12144
12170
  HooksService,
12145
12171
  ok as ok2,
12146
12172
  err as err2,
12147
- serviceError as serviceError2,
12148
- ErrorCodes as ErrorCodes2
12173
+ serviceError as serviceError3,
12174
+ ErrorCodes as ErrorCodes3
12149
12175
  } from "@tinycloud/sdk-services";
12150
12176
 
12151
12177
  // src/spaces/SpaceService.ts
12152
- import { ok, err, serviceError } from "@tinycloud/sdk-services";
12178
+ import { ok, err, serviceError as serviceError2, authorizationVerdictOf } from "@tinycloud/sdk-services";
12153
12179
 
12154
12180
  // src/spaces/Space.ts
12155
12181
  function unavailableSecretsService() {
@@ -12579,7 +12605,7 @@ var SpaceService = class {
12579
12605
  async list() {
12580
12606
  if (!this.session) {
12581
12607
  return err(
12582
- serviceError(SpaceErrorCodes.AUTH_REQUIRED, "Authentication required", SERVICE_NAME)
12608
+ serviceError2(SpaceErrorCodes.AUTH_REQUIRED, "Authentication required", SERVICE_NAME)
12583
12609
  );
12584
12610
  }
12585
12611
  try {
@@ -12587,6 +12613,9 @@ var SpaceService = class {
12587
12613
  const ownedResult = await this.listOwnedSpaces();
12588
12614
  if (ownedResult.ok) {
12589
12615
  spaces.push(...ownedResult.data);
12616
+ } else {
12617
+ const verdict = authorizationVerdictOf(ownedResult.error);
12618
+ if (verdict === "unauthenticated" || verdict === "forbidden") return err(ownedResult.error);
12590
12619
  }
12591
12620
  if (this.capabilityRegistry) {
12592
12621
  const delegatedSpaces = this.discoverDelegatedSpaces();
@@ -12599,7 +12628,7 @@ var SpaceService = class {
12599
12628
  return ok(uniqueSpaces);
12600
12629
  } catch (error) {
12601
12630
  return err(
12602
- serviceError(
12631
+ serviceError2(
12603
12632
  SpaceErrorCodes.NETWORK_ERROR,
12604
12633
  `Failed to list spaces: ${String(error)}`,
12605
12634
  SERVICE_NAME,
@@ -12619,21 +12648,18 @@ var SpaceService = class {
12619
12648
  headers
12620
12649
  });
12621
12650
  if (!response.ok) {
12622
- const errorText = await response.text();
12623
- return err(
12624
- serviceError(
12625
- SpaceErrorCodes.NETWORK_ERROR,
12626
- `Failed to list owned spaces: ${response.status} - ${errorText}`,
12627
- SERVICE_NAME,
12628
- { meta: { status: response.status } }
12629
- )
12630
- );
12651
+ return err(await serviceHttpError(
12652
+ response,
12653
+ SpaceErrorCodes.NETWORK_ERROR,
12654
+ "Failed to list owned spaces",
12655
+ SERVICE_NAME
12656
+ ));
12631
12657
  }
12632
12658
  const rawData = await response.json();
12633
12659
  const validationResult = validateServerOwnedSpacesResponse(rawData);
12634
12660
  if (!validationResult.ok) {
12635
12661
  return err(
12636
- serviceError(
12662
+ serviceError2(
12637
12663
  SpaceErrorCodes.NETWORK_ERROR,
12638
12664
  validationResult.error.message,
12639
12665
  SERVICE_NAME,
@@ -12652,7 +12678,7 @@ var SpaceService = class {
12652
12678
  return ok(spaces);
12653
12679
  } catch (error) {
12654
12680
  return err(
12655
- serviceError(
12681
+ serviceError2(
12656
12682
  SpaceErrorCodes.NETWORK_ERROR,
12657
12683
  `Network error listing owned spaces: ${String(error)}`,
12658
12684
  SERVICE_NAME,
@@ -12734,12 +12760,12 @@ var SpaceService = class {
12734
12760
  async create(name2) {
12735
12761
  if (!this.session) {
12736
12762
  return err(
12737
- serviceError(SpaceErrorCodes.AUTH_REQUIRED, "Authentication required", SERVICE_NAME)
12763
+ serviceError2(SpaceErrorCodes.AUTH_REQUIRED, "Authentication required", SERVICE_NAME)
12738
12764
  );
12739
12765
  }
12740
12766
  if (!name2 || !/^[a-zA-Z0-9_-]+$/.test(name2)) {
12741
12767
  return err(
12742
- serviceError(
12768
+ serviceError2(
12743
12769
  SpaceErrorCodes.INVALID_NAME,
12744
12770
  "Space name must contain only alphanumeric characters, underscores, and hyphens",
12745
12771
  SERVICE_NAME
@@ -12754,30 +12780,26 @@ var SpaceService = class {
12754
12780
  body: JSON.stringify({ name: name2 })
12755
12781
  });
12756
12782
  if (!response.ok) {
12757
- const errorText = await response.text();
12758
12783
  if (response.status === 409) {
12759
- return err(
12760
- serviceError(
12761
- SpaceErrorCodes.ALREADY_EXISTS,
12762
- `Space "${name2}" already exists`,
12763
- SERVICE_NAME
12764
- )
12765
- );
12784
+ return err(await serviceHttpError(
12785
+ response,
12786
+ SpaceErrorCodes.ALREADY_EXISTS,
12787
+ `Space "${name2}" already exists`,
12788
+ SERVICE_NAME
12789
+ ));
12766
12790
  }
12767
- return err(
12768
- serviceError(
12769
- SpaceErrorCodes.CREATION_FAILED,
12770
- `Failed to create space: ${response.status} - ${errorText}`,
12771
- SERVICE_NAME,
12772
- { meta: { status: response.status } }
12773
- )
12774
- );
12791
+ return err(await serviceHttpError(
12792
+ response,
12793
+ SpaceErrorCodes.CREATION_FAILED,
12794
+ "Failed to create space",
12795
+ SERVICE_NAME
12796
+ ));
12775
12797
  }
12776
12798
  const rawData = await response.json();
12777
12799
  const validationResult = validateServerCreateSpaceResponse(rawData);
12778
12800
  if (!validationResult.ok) {
12779
12801
  return err(
12780
- serviceError(
12802
+ serviceError2(
12781
12803
  SpaceErrorCodes.CREATION_FAILED,
12782
12804
  validationResult.error.message,
12783
12805
  SERVICE_NAME,
@@ -12797,7 +12819,7 @@ var SpaceService = class {
12797
12819
  return ok(spaceInfo);
12798
12820
  } catch (error) {
12799
12821
  return err(
12800
- serviceError(
12822
+ serviceError2(
12801
12823
  SpaceErrorCodes.NETWORK_ERROR,
12802
12824
  `Network error creating space: ${String(error)}`,
12803
12825
  SERVICE_NAME,
@@ -12885,7 +12907,7 @@ var SpaceService = class {
12885
12907
  }
12886
12908
  if (!this.session) {
12887
12909
  return err(
12888
- serviceError(SpaceErrorCodes.AUTH_REQUIRED, "Authentication required", SERVICE_NAME)
12910
+ serviceError2(SpaceErrorCodes.AUTH_REQUIRED, "Authentication required", SERVICE_NAME)
12889
12911
  );
12890
12912
  }
12891
12913
  try {
@@ -12897,24 +12919,25 @@ var SpaceService = class {
12897
12919
  });
12898
12920
  if (!response.ok) {
12899
12921
  if (response.status === 404) {
12900
- return err(
12901
- serviceError(SpaceErrorCodes.NOT_FOUND, `Space not found: ${spaceId}`, SERVICE_NAME)
12902
- );
12903
- }
12904
- const errorText = await response.text();
12905
- return err(
12906
- serviceError(
12907
- SpaceErrorCodes.NETWORK_ERROR,
12908
- `Failed to get space info: ${response.status} - ${errorText}`,
12922
+ return err(await serviceHttpError(
12923
+ response,
12924
+ SpaceErrorCodes.NOT_FOUND,
12925
+ `Space not found: ${spaceId}`,
12909
12926
  SERVICE_NAME
12910
- )
12911
- );
12927
+ ));
12928
+ }
12929
+ return err(await serviceHttpError(
12930
+ response,
12931
+ SpaceErrorCodes.NETWORK_ERROR,
12932
+ "Failed to get space info",
12933
+ SERVICE_NAME
12934
+ ));
12912
12935
  }
12913
12936
  const rawData = await response.json();
12914
12937
  const validationResult = validateServerSpaceInfoResponse(rawData);
12915
12938
  if (!validationResult.ok) {
12916
12939
  return err(
12917
- serviceError(
12940
+ serviceError2(
12918
12941
  SpaceErrorCodes.NETWORK_ERROR,
12919
12942
  validationResult.error.message,
12920
12943
  SERVICE_NAME,
@@ -12935,7 +12958,7 @@ var SpaceService = class {
12935
12958
  return ok(spaceInfo);
12936
12959
  } catch (error) {
12937
12960
  return err(
12938
- serviceError(
12961
+ serviceError2(
12939
12962
  SpaceErrorCodes.NETWORK_ERROR,
12940
12963
  `Network error getting space info: ${String(error)}`,
12941
12964
  SERVICE_NAME,
@@ -13020,20 +13043,18 @@ var SpaceService = class {
13020
13043
  headers
13021
13044
  });
13022
13045
  if (!response.ok) {
13023
- const errorText = await response.text();
13024
- return err(
13025
- serviceError(
13026
- SpaceErrorCodes.NETWORK_ERROR,
13027
- `Failed to list delegations: ${response.status} - ${errorText}`,
13028
- SERVICE_NAME
13029
- )
13030
- );
13046
+ return err(await serviceHttpError(
13047
+ response,
13048
+ SpaceErrorCodes.NETWORK_ERROR,
13049
+ "Failed to list delegations",
13050
+ SERVICE_NAME
13051
+ ));
13031
13052
  }
13032
13053
  const rawData = await response.json();
13033
13054
  const validationResult = validateServerDelegationsResponse(rawData);
13034
13055
  if (!validationResult.ok) {
13035
13056
  return err(
13036
- serviceError(
13057
+ serviceError2(
13037
13058
  SpaceErrorCodes.NETWORK_ERROR,
13038
13059
  validationResult.error.message,
13039
13060
  SERVICE_NAME,
@@ -13045,7 +13066,7 @@ var SpaceService = class {
13045
13066
  return ok(delegations);
13046
13067
  } catch (error) {
13047
13068
  return err(
13048
- serviceError(
13069
+ serviceError2(
13049
13070
  SpaceErrorCodes.NETWORK_ERROR,
13050
13071
  `Network error listing delegations: ${String(error)}`,
13051
13072
  SERVICE_NAME
@@ -13075,20 +13096,18 @@ var SpaceService = class {
13075
13096
  headers
13076
13097
  });
13077
13098
  if (!response.ok) {
13078
- const errorText = await response.text();
13079
- return err(
13080
- serviceError(
13081
- SpaceErrorCodes.NETWORK_ERROR,
13082
- `Failed to list received delegations: ${response.status} - ${errorText}`,
13083
- SERVICE_NAME
13084
- )
13085
- );
13099
+ return err(await serviceHttpError(
13100
+ response,
13101
+ SpaceErrorCodes.NETWORK_ERROR,
13102
+ "Failed to list received delegations",
13103
+ SERVICE_NAME
13104
+ ));
13086
13105
  }
13087
13106
  const rawData = await response.json();
13088
13107
  const validationResult = validateServerDelegationsResponse(rawData);
13089
13108
  if (!validationResult.ok) {
13090
13109
  return err(
13091
- serviceError(
13110
+ serviceError2(
13092
13111
  SpaceErrorCodes.NETWORK_ERROR,
13093
13112
  validationResult.error.message,
13094
13113
  SERVICE_NAME,
@@ -13100,7 +13119,7 @@ var SpaceService = class {
13100
13119
  return ok(delegations);
13101
13120
  } catch (error) {
13102
13121
  return err(
13103
- serviceError(
13122
+ serviceError2(
13104
13123
  SpaceErrorCodes.NETWORK_ERROR,
13105
13124
  `Network error listing received delegations: ${String(error)}`,
13106
13125
  SERVICE_NAME
@@ -13113,7 +13132,7 @@ var SpaceService = class {
13113
13132
  return self.createDelegationFn({ ...params, spaceId });
13114
13133
  }
13115
13134
  return err(
13116
- serviceError(
13135
+ serviceError2(
13117
13136
  SpaceErrorCodes.NOT_INITIALIZED,
13118
13137
  "Delegation creation requires a createDelegation function. This should be provided by the platform SDK (web-sdk or node-sdk).",
13119
13138
  SERVICE_NAME
@@ -13134,19 +13153,17 @@ var SpaceService = class {
13134
13153
  body: JSON.stringify({ cid: cid2, spaceId })
13135
13154
  });
13136
13155
  if (!response.ok) {
13137
- const errorText = await response.text();
13138
- return err(
13139
- serviceError(
13140
- SpaceErrorCodes.NETWORK_ERROR,
13141
- `Failed to revoke delegation: ${response.status} - ${errorText}`,
13142
- SERVICE_NAME
13143
- )
13144
- );
13156
+ return err(await serviceHttpError(
13157
+ response,
13158
+ SpaceErrorCodes.NETWORK_ERROR,
13159
+ "Failed to revoke delegation",
13160
+ SERVICE_NAME
13161
+ ));
13145
13162
  }
13146
13163
  return ok(void 0);
13147
13164
  } catch (error) {
13148
13165
  return err(
13149
- serviceError(
13166
+ serviceError2(
13150
13167
  SpaceErrorCodes.NETWORK_ERROR,
13151
13168
  `Network error revoking delegation: ${String(error)}`,
13152
13169
  SERVICE_NAME
@@ -13170,7 +13187,7 @@ var SpaceService = class {
13170
13187
  const result = await self.sharingService.generate(params);
13171
13188
  if (!result.ok) {
13172
13189
  return err(
13173
- serviceError(
13190
+ serviceError2(
13174
13191
  SpaceErrorCodes.NETWORK_ERROR,
13175
13192
  result.error.message || "Failed to generate share link",
13176
13193
  SERVICE_NAME
@@ -13180,7 +13197,7 @@ var SpaceService = class {
13180
13197
  return ok(result.data);
13181
13198
  }
13182
13199
  return err(
13183
- serviceError(
13200
+ serviceError2(
13184
13201
  SpaceErrorCodes.NOT_INITIALIZED,
13185
13202
  "SharingService not configured. V2 sharing requires a SharingService instance.",
13186
13203
  SERVICE_NAME
@@ -13189,7 +13206,7 @@ var SpaceService = class {
13189
13206
  },
13190
13207
  async list() {
13191
13208
  return err(
13192
- serviceError(
13209
+ serviceError2(
13193
13210
  SpaceErrorCodes.NOT_INITIALIZED,
13194
13211
  "Listing share links is not supported in v2. Share links are self-contained tokens that are not tracked on the server.",
13195
13212
  SERVICE_NAME
@@ -13198,7 +13215,7 @@ var SpaceService = class {
13198
13215
  },
13199
13216
  async revoke(token) {
13200
13217
  return err(
13201
- serviceError(
13218
+ serviceError2(
13202
13219
  SpaceErrorCodes.NOT_INITIALIZED,
13203
13220
  "Revoking share links by token is not supported in v2. To revoke access, revoke the underlying delegation using space.delegations.revoke(cid).",
13204
13221
  SERVICE_NAME
@@ -13535,8 +13552,8 @@ var TinyCloud = class _TinyCloud {
13535
13552
  const chainId = this.chainId();
13536
13553
  if (!address || !chainId) {
13537
13554
  return err2(
13538
- serviceError2(
13539
- ErrorCodes2.AUTH_REQUIRED,
13555
+ serviceError3(
13556
+ ErrorCodes3.AUTH_REQUIRED,
13540
13557
  "Must be signed in to ensure public space",
13541
13558
  "public-space"
13542
13559
  )
@@ -13544,8 +13561,8 @@ var TinyCloud = class _TinyCloud {
13544
13561
  }
13545
13562
  if (!this._serviceContext) {
13546
13563
  return err2(
13547
- serviceError2(
13548
- ErrorCodes2.AUTH_REQUIRED,
13564
+ serviceError3(
13565
+ ErrorCodes3.AUTH_REQUIRED,
13549
13566
  "Services not initialized. Call initializeServices() or signIn() first.",
13550
13567
  "public-space"
13551
13568
  )
@@ -13556,8 +13573,8 @@ var TinyCloud = class _TinyCloud {
13556
13573
  const session = this._serviceContext.session;
13557
13574
  if (!session) {
13558
13575
  return err2(
13559
- serviceError2(
13560
- ErrorCodes2.AUTH_REQUIRED,
13576
+ serviceError3(
13577
+ ErrorCodes3.AUTH_REQUIRED,
13561
13578
  "No active session",
13562
13579
  "public-space"
13563
13580
  )
@@ -13595,29 +13612,25 @@ var TinyCloud = class _TinyCloud {
13595
13612
  if (createResponse.status === 409) {
13596
13613
  return ok2(void 0);
13597
13614
  }
13598
- const errorText2 = await createResponse.text();
13599
- return err2(
13600
- serviceError2(
13601
- ErrorCodes2.NETWORK_ERROR,
13602
- `Failed to create public space: ${createResponse.status} - ${errorText2}`,
13603
- "public-space"
13604
- )
13605
- );
13615
+ return err2(await serviceHttpError(
13616
+ createResponse,
13617
+ ErrorCodes3.NETWORK_ERROR,
13618
+ "Failed to create public space",
13619
+ "public-space"
13620
+ ));
13606
13621
  }
13607
13622
  return ok2(void 0);
13608
13623
  }
13609
- const errorText = await response.text();
13610
- return err2(
13611
- serviceError2(
13612
- ErrorCodes2.NETWORK_ERROR,
13613
- `Failed to check public space: ${response.status} - ${errorText}`,
13614
- "public-space"
13615
- )
13616
- );
13624
+ return err2(await serviceHttpError(
13625
+ response,
13626
+ ErrorCodes3.NETWORK_ERROR,
13627
+ "Failed to check public space",
13628
+ "public-space"
13629
+ ));
13617
13630
  } catch (error) {
13618
13631
  return err2(
13619
- serviceError2(
13620
- ErrorCodes2.NETWORK_ERROR,
13632
+ serviceError3(
13633
+ ErrorCodes3.NETWORK_ERROR,
13621
13634
  `Network error ensuring public space: ${String(error)}`,
13622
13635
  "public-space",
13623
13636
  { cause: error instanceof Error ? error : void 0 }
@@ -13684,23 +13697,19 @@ var TinyCloud = class _TinyCloud {
13684
13697
  const response = await doFetch(url, { method: "GET" });
13685
13698
  if (!response.ok) {
13686
13699
  if (response.status === 404) {
13687
- return err2(
13688
- serviceError2(
13689
- ErrorCodes2.NOT_FOUND,
13690
- `Key not found: ${key} in space ${spaceId}`,
13691
- "public-space"
13692
- )
13693
- );
13700
+ return err2(await serviceHttpError(
13701
+ response,
13702
+ ErrorCodes3.NOT_FOUND,
13703
+ `Key not found: ${key} in space ${spaceId}`,
13704
+ "public-space"
13705
+ ));
13694
13706
  }
13695
- const errorText = await response.text();
13696
- return err2(
13697
- serviceError2(
13698
- ErrorCodes2.NETWORK_ERROR,
13699
- `Failed to read public space: ${response.status} - ${errorText}`,
13700
- "public-space",
13701
- { meta: { status: response.status } }
13702
- )
13703
- );
13707
+ return err2(await serviceHttpError(
13708
+ response,
13709
+ ErrorCodes3.NETWORK_ERROR,
13710
+ "Failed to read public space",
13711
+ "public-space"
13712
+ ));
13704
13713
  }
13705
13714
  const contentType = response.headers.get("content-type");
13706
13715
  let data;
@@ -13717,8 +13726,8 @@ var TinyCloud = class _TinyCloud {
13717
13726
  return ok2(data);
13718
13727
  } catch (error) {
13719
13728
  return err2(
13720
- serviceError2(
13721
- ErrorCodes2.NETWORK_ERROR,
13729
+ serviceError3(
13730
+ ErrorCodes3.NETWORK_ERROR,
13722
13731
  `Network error reading public space: ${String(error)}`,
13723
13732
  "public-space",
13724
13733
  { cause: error instanceof Error ? error : void 0 }
@@ -13747,8 +13756,8 @@ var TinyCloud = class _TinyCloud {
13747
13756
  import {
13748
13757
  err as err3,
13749
13758
  ok as ok3,
13750
- serviceError as serviceError3,
13751
- ErrorCodes as ErrorCodes3,
13759
+ serviceError as serviceError4,
13760
+ ErrorCodes as ErrorCodes4,
13752
13761
  isStorageFullError
13753
13762
  } from "@tinycloud/sdk-services";
13754
13763
  import { ACCOUNT_INDEX_SCHEMA } from "@tinycloud/bootstrap";
@@ -13813,7 +13822,7 @@ var AccountService = class {
13813
13822
  const request = composeManifestRequest(manifests);
13814
13823
  if (request.registryRecords.length === 0) {
13815
13824
  return err3(
13816
- serviceError3(
13825
+ serviceError4(
13817
13826
  "INVALID_MANIFEST",
13818
13827
  "Manifest did not produce an account application registry record",
13819
13828
  SERVICE_NAME2
@@ -13942,7 +13951,7 @@ var AccountService = class {
13942
13951
  }
13943
13952
  if (reconcileFailures.length > 0) {
13944
13953
  return err3(
13945
- serviceError3(
13954
+ serviceError4(
13946
13955
  "KV_BATCH_RECONCILE_FAILED",
13947
13956
  `KV batch write for ${items.length} space(s) failed ambiguously (${batchResult.error.message}) and per-space reconciliation also failed for: ${reconcileFailures.join("; ")}`,
13948
13957
  SERVICE_NAME2,
@@ -13973,7 +13982,7 @@ var AccountService = class {
13973
13982
  query: async (options2 = {}) => {
13974
13983
  const manager = this.config.getDelegationManager?.();
13975
13984
  if (!manager) {
13976
- return err3(serviceError3(
13985
+ return err3(serviceError4(
13977
13986
  "NOT_INITIALIZED",
13978
13987
  "Delegation history requires an authenticated delegation manager",
13979
13988
  SERVICE_NAME2
@@ -14024,7 +14033,7 @@ var AccountService = class {
14024
14033
  return revoked2.ok ? ok3(revoked2.data) : accountErr(revoked2.error);
14025
14034
  }
14026
14035
  if (typeof input === "string") {
14027
- return err3(serviceError3(
14036
+ return err3(serviceError4(
14028
14037
  "NOT_INITIALIZED",
14029
14038
  "CID-only revocation requires an authenticated delegation manager",
14030
14039
  SERVICE_NAME2
@@ -14230,7 +14239,7 @@ var AccountService = class {
14230
14239
  const accountSpaceId = this.config.getAccountSpaceId();
14231
14240
  if (!accountSpaceId) {
14232
14241
  return err3(
14233
- serviceError3(
14242
+ serviceError4(
14234
14243
  "ACCOUNT_SPACE_UNAVAILABLE",
14235
14244
  "Account space is unavailable. Sign in with a wallet-backed profile first.",
14236
14245
  SERVICE_NAME2
@@ -14243,7 +14252,7 @@ var AccountService = class {
14243
14252
  const db = this.config.getAccountDb?.();
14244
14253
  if (!db) {
14245
14254
  return err3(
14246
- serviceError3(
14255
+ serviceError4(
14247
14256
  "ACCOUNT_INDEX_UNAVAILABLE",
14248
14257
  "Account index database is unavailable. Sign in with a wallet-backed profile first.",
14249
14258
  SERVICE_NAME2
@@ -14424,7 +14433,7 @@ var AccountService = class {
14424
14433
  const found = listed.data.find((candidate) => candidate.id === space || candidate.name === space);
14425
14434
  if (!found) {
14426
14435
  return err3(
14427
- serviceError3("SPACE_NOT_FOUND", `No account space found for ${JSON.stringify(space)}`, SERVICE_NAME2)
14436
+ serviceError4("SPACE_NOT_FOUND", `No account space found for ${JSON.stringify(space)}`, SERVICE_NAME2)
14428
14437
  );
14429
14438
  }
14430
14439
  return ok3(found);
@@ -14725,17 +14734,17 @@ function mapDelegation(delegation, space, direction) {
14725
14734
  };
14726
14735
  }
14727
14736
  function accountErr(error) {
14728
- return err3(serviceError3(error.code, error.message, SERVICE_NAME2, { cause: error.cause, meta: error.meta }));
14737
+ return err3(serviceError4(error.code, error.message, SERVICE_NAME2, { cause: error.cause, meta: error.meta }));
14729
14738
  }
14730
14739
  function isMissingIndexError(error) {
14731
14740
  return /no such table:/i.test(error.message);
14732
14741
  }
14733
14742
  var AMBIGUOUS_WRITE_STATUSES = /* @__PURE__ */ new Set([500, 502, 503, 504, 520, 522, 524]);
14734
14743
  function isAmbiguousBatchFailure(error) {
14735
- if (error.code === ErrorCodes3.NETWORK_ERROR || error.code === ErrorCodes3.TIMEOUT) {
14744
+ if (error.code === ErrorCodes4.NETWORK_ERROR || error.code === ErrorCodes4.TIMEOUT) {
14736
14745
  return error.meta?.requestMayHaveDispatched === true;
14737
14746
  }
14738
- if (error.code === ErrorCodes3.KV_WRITE_FAILED) {
14747
+ if (error.code === ErrorCodes4.KV_WRITE_FAILED) {
14739
14748
  const status = error.meta?.status;
14740
14749
  return typeof status === "number" && AMBIGUOUS_WRITE_STATUSES.has(status);
14741
14750
  }
@@ -14755,9 +14764,11 @@ import {
14755
14764
  PrefixedKVService,
14756
14765
  ok as ok5,
14757
14766
  err as err5,
14758
- serviceError as serviceError5,
14759
- ErrorCodes as ErrorCodes4,
14760
- authorizationVerdictOf,
14767
+ serviceError as serviceError6,
14768
+ ErrorCodes as ErrorCodes5,
14769
+ authorizationVerdictOf as authorizationVerdictOf2,
14770
+ validatedCapabilityOf,
14771
+ parseCapabilityResource,
14761
14772
  isStorageFullError as isStorageFullError2,
14762
14773
  STORAGE_FULL_MESSAGE,
14763
14774
  STORAGE_WRITE_TOO_LARGE_MESSAGE,
@@ -14836,7 +14847,9 @@ async function fetchPeerId(host, spaceId) {
14836
14847
  );
14837
14848
  if (!res.ok) {
14838
14849
  const error = await res.text().catch(() => res.statusText);
14839
- throw new Error(`Failed to get peer ID: ${res.status} - ${error}`);
14850
+ throw Object.assign(new Error(`Failed to get peer ID: ${res.status} - ${error}`), {
14851
+ status: res.status
14852
+ });
14840
14853
  }
14841
14854
  return res.text();
14842
14855
  }
@@ -14926,7 +14939,7 @@ async function postSessionActivation(host, delegationHeader) {
14926
14939
  }
14927
14940
 
14928
14941
  // src/authorization/CapabilityKeyRegistry.ts
14929
- import { ok as ok4, err as err4, serviceError as serviceError4 } from "@tinycloud/sdk-services";
14942
+ import { ok as ok4, err as err4, serviceError as serviceError5 } from "@tinycloud/sdk-services";
14930
14943
  var SERVICE_NAME3 = "capability-key-registry";
14931
14944
  var CapabilityKeyRegistryErrorCodes = {
14932
14945
  /** Key not found in registry */
@@ -15152,7 +15165,7 @@ var CapabilityKeyRegistry = class {
15152
15165
  const stored = this.store.byCid.get(cid2);
15153
15166
  if (!stored || stored.length === 0) {
15154
15167
  return err4(
15155
- serviceError4(
15168
+ serviceError5(
15156
15169
  CapabilityKeyRegistryErrorCodes.KEY_NOT_FOUND,
15157
15170
  `Delegation not found: ${cid2}`,
15158
15171
  SERVICE_NAME3
@@ -18584,7 +18597,7 @@ export {
18584
18597
  EXPIRY,
18585
18598
  EncryptionService,
18586
18599
  EnsDataSchema,
18587
- ErrorCodes4 as ErrorCodes,
18600
+ ErrorCodes5 as ErrorCodes,
18588
18601
  HOLDER_BINDING_DOMAIN,
18589
18602
  HOLDER_KEY_BINDING_PRESENTATION_SCHEMA,
18590
18603
  HOOKS,
@@ -18709,7 +18722,7 @@ export {
18709
18722
  admitPolicyCredentialV3,
18710
18723
  admitPolicyCredentialV4,
18711
18724
  applyPrefix,
18712
- authorizationVerdictOf,
18725
+ authorizationVerdictOf2 as authorizationVerdictOf,
18713
18726
  bootstrapEncryptionNetworkId,
18714
18727
  bootstrapSpaceId,
18715
18728
  bootstrapSteps,
@@ -18822,6 +18835,7 @@ export {
18822
18835
  hexEncode,
18823
18836
  holderBindingCanonicalBytes,
18824
18837
  holderBindingSigningBytes,
18838
+ httpResponseError,
18825
18839
  httpUrlToMultiaddr,
18826
18840
  importPortableDelegation,
18827
18841
  installTinyCloudDebugGlobals,
@@ -18856,6 +18870,7 @@ export {
18856
18870
  parseCanonicalRecapResource,
18857
18871
  parseCanonicalTinyCloudIdentity,
18858
18872
  parseCanonicalTinyCloudIdentityClaims,
18873
+ parseCapabilityResource,
18859
18874
  parseCompactUcanAuthorization,
18860
18875
  parseExpiry,
18861
18876
  parseNetworkId2 as parseNetworkId,
@@ -18894,7 +18909,7 @@ export {
18894
18909
  revokePolicyRootV3,
18895
18910
  serialize as serializeJcsJson,
18896
18911
  serializePortableDelegation,
18897
- serviceError5 as serviceError,
18912
+ serviceError6 as serviceError,
18898
18913
  sha256Base64Url,
18899
18914
  shareCapabilityAllows,
18900
18915
  signCompactPolicyDescendant,
@@ -18936,6 +18951,7 @@ export {
18936
18951
  validatePolicyUnsigned,
18937
18952
  validateShareDeliveryAuthorizationV3Bytes,
18938
18953
  validateUnifiedPolicyV2,
18954
+ validatedCapabilityOf,
18939
18955
  verifyDecryptResponse,
18940
18956
  verifyDidKeyEd25519Signature,
18941
18957
  verifyEip191MessageSignature,