@tinycloud/sdk-core 3.0.1-beta.0 → 3.1.0-beta.10

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.
@@ -3191,6 +3191,23 @@ import { sha256 as sha2564 } from "@noble/hashes/sha256";
3191
3191
  import { blake3 } from "@noble/hashes/blake3";
3192
3192
  import { ed25519 as ed255192 } from "@noble/curves/ed25519";
3193
3193
  import { z } from "zod";
3194
+
3195
+ // src/http-error.ts
3196
+ import { ErrorCodes, serviceError } from "@tinycloud/sdk-services";
3197
+ async function httpResponseError(response, context) {
3198
+ let body;
3199
+ try {
3200
+ body = await response.text();
3201
+ } catch {
3202
+ body = response.statusText;
3203
+ }
3204
+ body = body.trim().slice(0, 512);
3205
+ return Object.assign(new Error(`${context}: HTTP ${response.status}${body ? ` - ${body}` : ""}`), {
3206
+ status: response.status
3207
+ });
3208
+ }
3209
+
3210
+ // src/policy/unified.ts
3194
3211
  var POLICY_V1_SCHEMA = "xyz.tinycloud.policy/policy/v1";
3195
3212
  var POLICY_CAPABILITY_V1_SCHEMA = "xyz.tinycloud.policy/capability/v1";
3196
3213
  var POLICY_ENFORCEMENT_DELEGATION_V2_SCHEMA = "xyz.tinycloud.policy/enforcement-delegation/v2";
@@ -3218,7 +3235,7 @@ async function requestPolicyChallengeV3(input) {
3218
3235
  headers: { accept: "application/json", "content-type": "application/json" },
3219
3236
  body: JSON.stringify({ policyCid: input.policyCid, recipientDid: input.recipientDid, requestedCapabilities: input.requestedCapabilities.map(normalizeUnifiedPolicyCapability) })
3220
3237
  });
3221
- if (!response.ok) throw new Error(`policy challenge rejected (${response.status})`);
3238
+ if (!response.ok) throw await httpResponseError(response, "policy challenge rejected");
3222
3239
  const value = object(await response.json(), "policy challenge");
3223
3240
  if (typeof value.challengeId !== "string" || typeof value.nonce !== "string" || value.policyCid !== input.policyCid || value.recipientDid !== input.recipientDid)
3224
3241
  throw new Error("policy challenge binding is invalid");
@@ -3243,7 +3260,7 @@ async function mintPolicySessionV3(input) {
3243
3260
  headers: { accept: "application/json", "content-type": "application/json" },
3244
3261
  body: JSON.stringify({ policyCid: input.policyCid, challengeId: challenge.challengeId, nonce: challenge.nonce, claim: input.claim, presentation: input.presentation })
3245
3262
  });
3246
- if (!response.ok) throw new Error(`policy delegation rejected (${response.status})`);
3263
+ if (!response.ok) throw await httpResponseError(response, "policy delegation rejected");
3247
3264
  const value = object(await response.json(), "policy delegation");
3248
3265
  if (value.admitted !== true || typeof value.sessionCid !== "string" || typeof value.authorization !== "string")
3249
3266
  throw new Error("policy delegation response is invalid");
@@ -3303,7 +3320,7 @@ async function getPolicyRootStatusV3(input) {
3303
3320
  redirect: "error",
3304
3321
  headers: { accept: "application/json" }
3305
3322
  });
3306
- if (!response.ok) throw new Error(`policy root status rejected (${response.status})`);
3323
+ if (!response.ok) throw await httpResponseError(response, "policy root status rejected");
3307
3324
  const value = object(await response.json(), "policy root status");
3308
3325
  const checkpoint = object(value.checkpoint, "policy root checkpoint");
3309
3326
  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 }))
@@ -3363,9 +3380,12 @@ async function renewPolicyRootStatusV3(input) {
3363
3380
  headers: { accept: "application/json", "content-type": "application/json" },
3364
3381
  body: JSON.stringify({ rootCid: input.rootCid, renewal: { ...unsigned, signature: { suite: "Ed25519", signerDid: input.ownerDid, value: encodeBase64Url(signature) } } })
3365
3382
  });
3366
- if (!response.ok) throw new Error(`policy root renewal rejected (${response.status})`);
3383
+ if (!response.ok) throw await httpResponseError(response, "policy root renewal rejected");
3367
3384
  return object(await response.json(), "policy root renewal");
3368
3385
  }
3386
+ function rfc3339Seconds(value) {
3387
+ return new Date(Math.floor(value.getTime() / 1e3) * 1e3).toISOString().replace(/\.000Z$/, "Z");
3388
+ }
3369
3389
  async function revokePolicyRootV3(input) {
3370
3390
  if (input.reason.length === 0) throw new Error("policy root revocation reason is required");
3371
3391
  const unsigned = {
@@ -3374,7 +3394,7 @@ async function revokePolicyRootV3(input) {
3374
3394
  targetRole: input.targetRole,
3375
3395
  ownerDid: input.ownerDid,
3376
3396
  nodeAudience: input.nodeAudience,
3377
- revokedAt: (input.now ?? /* @__PURE__ */ new Date()).toISOString(),
3397
+ revokedAt: rfc3339Seconds(input.now ?? /* @__PURE__ */ new Date()),
3378
3398
  reason: input.reason,
3379
3399
  issuerDid: input.issuerDid
3380
3400
  };
@@ -3387,7 +3407,7 @@ async function revokePolicyRootV3(input) {
3387
3407
  headers: { accept: "application/json", "content-type": "application/json" },
3388
3408
  body: JSON.stringify({ revocation: { ...unsigned, signature: { suite: "Ed25519", signerDid: input.issuerDid, value: encodeBase64Url(signature) } } })
3389
3409
  });
3390
- if (!response.ok) throw new Error(`policy root revocation rejected (${response.status})`);
3410
+ if (!response.ok) throw await httpResponseError(response, "policy root revocation rejected");
3391
3411
  return object(await response.json(), "policy root revocation");
3392
3412
  }
3393
3413
  var POLICY_SESSION_FACT_KEYS = [
@@ -3656,7 +3676,7 @@ async function registerPolicyV3(input) {
3656
3676
  }
3657
3677
  );
3658
3678
  if (!bindingResponse.ok) {
3659
- throw new Error(`policy enforcer binding rejected (${bindingResponse.status})`);
3679
+ throw await httpResponseError(bindingResponse, "policy enforcer binding rejected");
3660
3680
  }
3661
3681
  const binding = exactObject(
3662
3682
  await bindingResponse.json(),
@@ -3722,7 +3742,7 @@ async function registerPolicyV3(input) {
3722
3742
  }
3723
3743
  );
3724
3744
  if (!response.ok) {
3725
- throw new Error(`policy registration rejected (${response.status})`);
3745
+ throw await httpResponseError(response, "policy registration rejected");
3726
3746
  }
3727
3747
  const receipt = exactObject(
3728
3748
  await response.json(),
@@ -4196,7 +4216,7 @@ function date(value, label) {
4196
4216
  if (!Number.isFinite(Date.parse(text))) throw new Error(`${label} is invalid`);
4197
4217
  return text;
4198
4218
  }
4199
- function rfc3339Seconds(value) {
4219
+ function rfc3339Seconds2(value) {
4200
4220
  return new Date(Math.floor(value.getTime() / 1e3) * 1e3).toISOString().replace(/\.000Z$/, "Z");
4201
4221
  }
4202
4222
  function validateUnifiedPolicyV2(value, expectedPolicyCid) {
@@ -4361,8 +4381,8 @@ async function buildPolicyCredentialPresentationV4(input) {
4361
4381
  requirementDigest,
4362
4382
  descriptorDigest: input.credential.descriptorDigest,
4363
4383
  requestedCapabilities: Object.freeze(requestedCapabilities),
4364
- issuedAt: rfc3339Seconds(now),
4365
- expiresAt: rfc3339Seconds(new Date(expiresAtMs))
4384
+ issuedAt: rfc3339Seconds2(now),
4385
+ expiresAt: rfc3339Seconds2(new Date(expiresAtMs))
4366
4386
  }), input.sign);
4367
4387
  }
4368
4388
  async function buildPolicyCredentialPresentationV3(input) {
@@ -4416,8 +4436,8 @@ async function buildPolicyCredentialPresentationV3(input) {
4416
4436
  requirementDigest,
4417
4437
  descriptorDigest: input.credential.descriptorDigest,
4418
4438
  requestedCapabilities: Object.freeze(requestedCapabilities),
4419
- issuedAt: rfc3339Seconds(now),
4420
- expiresAt: rfc3339Seconds(new Date(expiresAtMs))
4439
+ issuedAt: rfc3339Seconds2(now),
4440
+ expiresAt: rfc3339Seconds2(new Date(expiresAtMs))
4421
4441
  });
4422
4442
  const digest2 = sha2565(
4423
4443
  new TextEncoder().encode(
@@ -4479,7 +4499,7 @@ async function admitPolicyCredentialV3(input) {
4479
4499
  requestedSessionExpiry(input.requestedExpiresAt, policy),
4480
4500
  input.signal
4481
4501
  );
4482
- if (!response.ok) throw new Error(`policy delegation rejected (${response.status})`);
4502
+ if (!response.ok) throw await httpResponseError(response, "policy delegation rejected");
4483
4503
  const value = record(await response.json(), "policy delegation");
4484
4504
  if (value.admitted !== true || typeof value.sessionCid !== "string" || typeof value.authorization !== "string") {
4485
4505
  throw new Error("policy delegation response is invalid");
@@ -4532,7 +4552,7 @@ async function admitPolicyCredentialV4(input) {
4532
4552
  requestedSessionExpiry(input.requestedExpiresAt, policy),
4533
4553
  input.signal
4534
4554
  );
4535
- if (!response.ok) throw new Error(`policy delegation rejected (${response.status})`);
4555
+ if (!response.ok) throw await httpResponseError(response, "policy delegation rejected");
4536
4556
  const value = record(await response.json(), "policy delegation");
4537
4557
  if (value.admitted !== true || typeof value.sessionCid !== "string" || typeof value.authorization !== "string") throw new Error("policy delegation response is invalid");
4538
4558
  const session = parsePolicySessionUcan(value.authorization, [
@@ -4551,7 +4571,7 @@ async function admitPolicyCredentialV4(input) {
4551
4571
  signal: input.signal,
4552
4572
  headers: { Authorization: session.authorization }
4553
4573
  });
4554
- if (!importResponse.ok) throw new Error(`delegation import rejected (${importResponse.status})`);
4574
+ if (!importResponse.ok) throw await httpResponseError(importResponse, "delegation import rejected");
4555
4575
  input.signal?.throwIfAborted();
4556
4576
  return Object.freeze({ challenge, presentation, session, delegationImported: true });
4557
4577
  }