@tinycloud/cli 1.3.1-beta.0 → 1.3.2-beta.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.js CHANGED
@@ -266,11 +266,11 @@ function warningLine(warnings) {
266
266
  const subject = warnings.length === 1 ? "A stored grant was" : `${warnings.length} stored grants were`;
267
267
  return `${subject} not used (${which}). Approve access again when a command needs it; remove the old grant with ${CLI_NAME2} auth grants remove <cid>.`;
268
268
  }
269
- function outputError(code4, message, hint, details = {}) {
269
+ function outputError(code5, message, hint, details = {}) {
270
270
  const { meta, warnings = [], setup, recovery, progress } = details;
271
271
  if (!shouldOutputJson()) {
272
272
  process.stderr.write(
273
- `${theme.error("\u2717")} ${theme.label(safeInline(code4))}: ${safeBlock(message)}
273
+ `${theme.error("\u2717")} ${theme.label(safeInline(code5))}: ${safeBlock(message)}
274
274
  `
275
275
  );
276
276
  if (hint) {
@@ -283,7 +283,7 @@ function outputError(code4, message, hint, details = {}) {
283
283
  `);
284
284
  } else {
285
285
  const payload = {
286
- error: { code: code4, message }
286
+ error: { code: code5, message }
287
287
  };
288
288
  if (hint) payload.error.hint = hint;
289
289
  if (recovery) payload.error.recovery = recovery;
@@ -305,11 +305,11 @@ function operationWarnings(value) {
305
305
  if (!Array.isArray(value)) return [];
306
306
  return value.flatMap((warning) => {
307
307
  if (warning === null || typeof warning !== "object") return [];
308
- const { code: code4, reason, grantCid } = warning;
309
- if (typeof code4 !== "string" || !WARNING_CODE.test(code4) || typeof reason !== "string" || !WARNING_REASON.test(reason)) {
308
+ const { code: code5, reason, grantCid } = warning;
309
+ if (typeof code5 !== "string" || !WARNING_CODE.test(code5) || typeof reason !== "string" || !WARNING_REASON.test(reason)) {
310
310
  return [];
311
311
  }
312
- return [{ code: code4, reason, ...typeof grantCid === "string" && DELEGATION_CID.test(grantCid) ? { grantCid } : {} }];
312
+ return [{ code: code5, reason, ...typeof grantCid === "string" && DELEGATION_CID.test(grantCid) ? { grantCid } : {} }];
313
313
  });
314
314
  }
315
315
  function isInteractive() {
@@ -340,17 +340,17 @@ function storageRejection(error) {
340
340
  let node = error;
341
341
  for (let depth = 0; depth < MAX_CAUSE_DEPTH && typeof node === "object" && node !== null; depth += 1) {
342
342
  const record2 = node;
343
- let code4;
343
+ let code5;
344
344
  if (record2.code === "STORAGE_QUOTA_EXCEEDED" || record2.code === "STORAGE_LIMIT_REACHED") {
345
- code4 = record2.code;
345
+ code5 = record2.code;
346
346
  } else if (record2.code !== void 0) {
347
347
  return void 0;
348
348
  } else if (isStorageStatus(record2)) {
349
- code4 = storageCodeFromText(record2.message);
349
+ code5 = storageCodeFromText(record2.message);
350
350
  }
351
- if (code4) {
351
+ if (code5) {
352
352
  const account = accountTotals(record2) ?? accountTotals(record2.meta) ?? accountTotals(record2.metadata);
353
- return account ? { code: code4, account } : { code: code4 };
353
+ return account ? { code: code5, account } : { code: code5 };
354
354
  }
355
355
  node = record2.cause;
356
356
  }
@@ -434,22 +434,22 @@ function setActiveProfileName(name) {
434
434
  }
435
435
  function nodeRetryError(error) {
436
436
  if (typeof error !== "object" || error === null) return void 0;
437
- const { code: code4, meta, metadata } = error;
438
- if (code4 !== "NODE_BUSY" && code4 !== "REQUEST_TIMEOUT" && code4 !== "OUTCOME_UNKNOWN") return void 0;
437
+ const { code: code5, meta, metadata } = error;
438
+ if (code5 !== "NODE_BUSY" && code5 !== "REQUEST_TIMEOUT" && code5 !== "OUTCOME_UNKNOWN") return void 0;
439
439
  const details = typeof meta === "object" && meta !== null ? meta : typeof metadata === "object" && metadata !== null ? metadata : {};
440
440
  const retryAfterMs = details.retryAfterMs;
441
441
  const wait = typeof retryAfterMs === "number" && Number.isFinite(retryAfterMs) && retryAfterMs >= 0 ? `in ${Math.max(1, Math.ceil(retryAfterMs / 1e3))} s` : "shortly";
442
- if (code4 === "OUTCOME_UNKNOWN") {
442
+ if (code5 === "OUTCOME_UNKNOWN") {
443
443
  return new CLIError(
444
- code4,
444
+ code5,
445
445
  "Outcome unknown: the node may have applied the write. Check before retrying.",
446
446
  ExitCode.NODE_ERROR,
447
447
  { ...details, hint: "Read the data back before running the command again; repeating a write that already applied can duplicate it." }
448
448
  );
449
449
  }
450
450
  return new CLIError(
451
- code4,
452
- code4 === "NODE_BUSY" ? `The node is busy, try again ${wait}.` : `The node timed out before applying anything, try again ${wait}.`,
451
+ code5,
452
+ code5 === "NODE_BUSY" ? `The node is busy, try again ${wait}.` : `The node timed out before applying anything, try again ${wait}.`,
453
453
  ExitCode.NODE_ERROR,
454
454
  details
455
455
  );
@@ -661,9 +661,9 @@ var init_errors = __esm({
661
661
  init_warnings();
662
662
  GRANT_REVOKED_EXIT_CODE = ExitCode.PERMISSION_DENIED;
663
663
  CLIError = class extends Error {
664
- constructor(code4, message, exitCode = ExitCode.ERROR, metadata) {
664
+ constructor(code5, message, exitCode = ExitCode.ERROR, metadata) {
665
665
  super(message);
666
- this.code = code4;
666
+ this.code = code5;
667
667
  this.exitCode = exitCode;
668
668
  this.metadata = metadata;
669
669
  this.name = "CLIError";
@@ -1182,12 +1182,12 @@ var init_md = __esm({
1182
1182
  _cloneInto(to) {
1183
1183
  to || (to = new this.constructor());
1184
1184
  to.set(...this.get());
1185
- const { blockLen, buffer, length: length4, finished, destroyed, pos } = this;
1185
+ const { blockLen, buffer, length: length5, finished, destroyed, pos } = this;
1186
1186
  to.destroyed = destroyed;
1187
1187
  to.finished = finished;
1188
- to.length = length4;
1188
+ to.length = length5;
1189
1189
  to.pos = pos;
1190
- if (length4 % blockLen)
1190
+ if (length5 % blockLen)
1191
1191
  to.buffer.set(buffer);
1192
1192
  return to;
1193
1193
  }
@@ -1924,13 +1924,13 @@ var init_blake2 = __esm({
1924
1924
  return res;
1925
1925
  }
1926
1926
  _cloneInto(to) {
1927
- const { buffer, length: length4, finished, destroyed, outputLen, pos } = this;
1927
+ const { buffer, length: length5, finished, destroyed, outputLen, pos } = this;
1928
1928
  to || (to = new this.constructor({ dkLen: outputLen }));
1929
1929
  to.set(...this.get());
1930
1930
  to.buffer.set(buffer);
1931
1931
  to.destroyed = destroyed;
1932
1932
  to.finished = finished;
1933
- to.length = length4;
1933
+ to.length = length5;
1934
1934
  to.pos = pos;
1935
1935
  to.outputLen = outputLen;
1936
1936
  return to;
@@ -2165,13 +2165,13 @@ function _abool2(value, title = "") {
2165
2165
  }
2166
2166
  return value;
2167
2167
  }
2168
- function _abytes2(value, length4, title = "") {
2168
+ function _abytes2(value, length5, title = "") {
2169
2169
  const bytes = isBytes(value);
2170
2170
  const len = value?.length;
2171
- const needsLen = length4 !== void 0;
2172
- if (!bytes || needsLen && len !== length4) {
2171
+ const needsLen = length5 !== void 0;
2172
+ if (!bytes || needsLen && len !== length5) {
2173
2173
  const prefix = title && `"${title}" `;
2174
- const ofLen = needsLen ? ` of length ${length4}` : "";
2174
+ const ofLen = needsLen ? ` of length ${length5}` : "";
2175
2175
  const got = bytes ? `length=${len}` : `type=${typeof value}`;
2176
2176
  throw new Error(prefix + "expected Uint8Array" + ofLen + ", got " + got);
2177
2177
  }
@@ -2787,15 +2787,15 @@ var init_curve = __esm({
2787
2787
  const { windows, windowSize } = calcWOpts(W, this.bits);
2788
2788
  const points = [];
2789
2789
  let p = point;
2790
- let base4 = p;
2790
+ let base5 = p;
2791
2791
  for (let window = 0; window < windows; window++) {
2792
- base4 = p;
2793
- points.push(base4);
2792
+ base5 = p;
2793
+ points.push(base5);
2794
2794
  for (let i = 1; i < windowSize; i++) {
2795
- base4 = base4.add(p);
2796
- points.push(base4);
2795
+ base5 = base5.add(p);
2796
+ points.push(base5);
2797
2797
  }
2798
- p = base4.double();
2798
+ p = base5.double();
2799
2799
  }
2800
2800
  return points;
2801
2801
  }
@@ -3770,10 +3770,10 @@ var init_dist = __esm({
3770
3770
  [REPLICA_ERROR] = true;
3771
3771
  code;
3772
3772
  detail;
3773
- constructor(code4, message, detail, options) {
3773
+ constructor(code5, message, detail, options) {
3774
3774
  super(message, options);
3775
3775
  this.name = "ReplicaError";
3776
- this.code = code4;
3776
+ this.code = code5;
3777
3777
  if (detail !== void 0) this.detail = detail;
3778
3778
  }
3779
3779
  };
@@ -4059,10 +4059,10 @@ var init_profile_gate = __esm({
4059
4059
  [REPLICA_ERROR2] = true;
4060
4060
  code;
4061
4061
  detail;
4062
- constructor(code4, message, detail, options) {
4062
+ constructor(code5, message, detail, options) {
4063
4063
  super(message, options);
4064
4064
  this.name = "ReplicaError";
4065
- this.code = code4;
4065
+ this.code = code5;
4066
4066
  if (detail !== void 0) this.detail = detail;
4067
4067
  }
4068
4068
  };
@@ -4083,8 +4083,8 @@ import { dirname as dirname3, join as join22, resolve as resolve2 } from "path";
4083
4083
  import { constants as fsConstants3 } from "fs";
4084
4084
  import { lstat, open as open3, readdir as readdir3, rmdir, unlink } from "fs/promises";
4085
4085
  import { join as join7, parse, resolve, sep } from "path";
4086
- function isReplicaError(error, code4) {
4087
- return typeof error === "object" && error !== null && error[REPLICA_ERROR3] === true && (code4 === void 0 || error.code === code4);
4086
+ function isReplicaError(error, code5) {
4087
+ return typeof error === "object" && error !== null && error[REPLICA_ERROR3] === true && (code5 === void 0 || error.code === code5);
4088
4088
  }
4089
4089
  function assertFolderPrefix3(prefix) {
4090
4090
  const validFolder = typeof prefix === "string" && prefix.length > 0 && !prefix.startsWith("/") && !prefix.includes("//") && prefix.endsWith("/");
@@ -4572,9 +4572,9 @@ function entryOf(row) {
4572
4572
  }
4573
4573
  function storageError(error, action) {
4574
4574
  if (isReplicaError(error)) return error;
4575
- const code4 = errnoOf(error);
4575
+ const code5 = errnoOf(error);
4576
4576
  const message = error instanceof Error ? error.message : String(error);
4577
- if (code4 === "ENOSPC" || code4 === "EDQUOT" || /SQLITE_FULL|database or disk is full/i.test(`${String(code4)} ${message}`)) {
4577
+ if (code5 === "ENOSPC" || code5 === "EDQUOT" || /SQLITE_FULL|database or disk is full/i.test(`${String(code5)} ${message}`)) {
4578
4578
  return new ReplicaError3(ReplicaErrorCode3.STORAGE_FULL, `${action}: the local disk is full.`, void 0, { cause: error });
4579
4579
  }
4580
4580
  return new ReplicaError3(ReplicaErrorCode3.STORAGE_ERROR, `${action}: ${message}`, void 0, { cause: error });
@@ -4748,10 +4748,10 @@ var init_sqlite = __esm({
4748
4748
  [REPLICA_ERROR3] = true;
4749
4749
  code;
4750
4750
  detail;
4751
- constructor(code4, message, detail, options) {
4751
+ constructor(code5, message, detail, options) {
4752
4752
  super(message, options);
4753
4753
  this.name = "ReplicaError";
4754
- this.code = code4;
4754
+ this.code = code5;
4755
4755
  if (detail !== void 0) this.detail = detail;
4756
4756
  }
4757
4757
  };
@@ -5327,8 +5327,8 @@ CREATE TABLE IF NOT EXISTS grant_install (
5327
5327
  if (this.#readonlySnapshot) {
5328
5328
  throw new ReplicaError3(ReplicaErrorCode3.STORAGE_ERROR, "A read-only replica snapshot cannot mutate the shared database.");
5329
5329
  }
5330
- const read4 = activeReadSection.getStore();
5331
- if (read4?.active && read4.controller === this) {
5330
+ const read5 = activeReadSection.getStore();
5331
+ if (read5?.active && read5.controller === this) {
5332
5332
  throw new ReplicaError3(
5333
5333
  ReplicaErrorCode3.STORAGE_ERROR,
5334
5334
  "mutation attempted on the same controller while its readTransaction section is active; this would deadlock"
@@ -6325,7 +6325,7 @@ function assertApprovedEntry(profile, path, actual, recorded) {
6325
6325
  throw refuseUnsafeReplicaPath(profile, `legacy path "${path}" changed since the recorded inventory`);
6326
6326
  }
6327
6327
  }
6328
- function assertRecordedChild(profile, name, layout, inventory, empty4) {
6328
+ function assertRecordedChild(profile, name, layout, inventory, empty5) {
6329
6329
  const prefix = `replicas/${name}/`;
6330
6330
  const root = inventory.roots.get(`replicas/${name}`);
6331
6331
  if (!root || root.dev !== layout.rootIdentity.dev || root.ino !== layout.rootIdentity.ino) {
@@ -6344,7 +6344,7 @@ function assertRecordedChild(profile, name, layout, inventory, empty4) {
6344
6344
  }
6345
6345
  const database = [...layout.knownEntries, ...layout.unknownEntries].some((entry) => entry.path === "replica.db");
6346
6346
  const missingWasApproved = inventory.missingDatabases.has(prefix + "replica.db");
6347
- if (missingWasApproved && database || !database && !empty4 && !missingWasApproved) {
6347
+ if (missingWasApproved && database || !database && !empty5 && !missingWasApproved) {
6348
6348
  throw refuseUnsafeReplicaPath(profile, `replica entry "${name}" has a different database than was approved`);
6349
6349
  }
6350
6350
  }
@@ -6426,8 +6426,8 @@ async function removeProfileReplicas(profile, options = {}) {
6426
6426
  const removed = [];
6427
6427
  const opened = [];
6428
6428
  try {
6429
- for (const { entry, identity, empty: empty4 } of checked) {
6430
- if (!empty4) continue;
6429
+ for (const { entry, identity, empty: empty5 } of checked) {
6430
+ if (!empty5) continue;
6431
6431
  await pinned.assertNamed();
6432
6432
  const current = await safeReplicaEntry(profile, root, entry);
6433
6433
  if (current.identity.dev !== identity.dev || current.identity.ino !== identity.ino) {
@@ -6454,8 +6454,8 @@ async function removeProfileReplicas(profile, options = {}) {
6454
6454
  await removeEmptyRoot(removed);
6455
6455
  return removed;
6456
6456
  }
6457
- for (const { entry, empty: empty4, identity, layout } of checked) {
6458
- if (empty4 || !layout?.knownEntries.some((item) => item.path === "replica.db")) continue;
6457
+ for (const { entry, empty: empty5, identity, layout } of checked) {
6458
+ if (empty5 || !layout?.knownEntries.some((item) => item.path === "replica.db")) continue;
6459
6459
  await pinned.assertNamed();
6460
6460
  const { path: entryPath, identity: expectedDirectory } = await safeReplicaEntry(profile, root, entry);
6461
6461
  if (expectedDirectory.dev !== identity.dev || expectedDirectory.ino !== identity.ino) {
@@ -6488,8 +6488,8 @@ async function removeProfileReplicas(profile, options = {}) {
6488
6488
  }
6489
6489
  opened[opened.length - 1].lease = lease;
6490
6490
  }
6491
- for (const { entry, empty: empty4, path, layout } of checked) {
6492
- if (empty4) continue;
6491
+ for (const { entry, empty: empty5, path, layout } of checked) {
6492
+ if (empty5) continue;
6493
6493
  await pinned.assertNamed();
6494
6494
  const replica = opened.find(({ name }) => name === entry.name);
6495
6495
  try {
@@ -6811,14 +6811,14 @@ async function recoverPendingLogout(name) {
6811
6811
  if (report.failed.length || report.remaining) {
6812
6812
  throw new CLIError(
6813
6813
  "REPLICA_PURGE_FAILED",
6814
- `A durable logout is pending (${report.failed.map(({ code: code4 }) => code4).join(", ") || `${report.remaining} intents remaining`}). Network restore and replica reads remain blocked; retry this command to complete credential and replica cleanup.`,
6814
+ `A durable logout is pending (${report.failed.map(({ code: code5 }) => code5).join(", ") || `${report.remaining} intents remaining`}). Network restore and replica reads remain blocked; retry this command to complete credential and replica cleanup.`,
6815
6815
  ExitCode.ERROR,
6816
6816
  { failed: report.failed, remaining: report.remaining }
6817
6817
  );
6818
6818
  }
6819
6819
  }
6820
6820
  function refuseRestoredGate(report) {
6821
- if (report.failed.some(({ code: code4 }) => code4 === "gate_restored")) {
6821
+ if (report.failed.some(({ code: code5 }) => code5 === "gate_restored")) {
6822
6822
  throw new CLIError("REPLICA_GATED", RESTORED_GATE_MESSAGE, ExitCode.ERROR, { failed: report.failed });
6823
6823
  }
6824
6824
  }
@@ -19891,19 +19891,19 @@ function mailboxCredentialCommitment(target) {
19891
19891
  credentialType: EMAIL_CREDENTIAL_TYPE
19892
19892
  };
19893
19893
  }
19894
- function prepareAddressedShare(request) {
19894
+ function prepareAddressedShare(request2) {
19895
19895
  try {
19896
- canonicalShareFilename2(request.filename);
19896
+ canonicalShareFilename2(request2.filename);
19897
19897
  } catch {
19898
19898
  throw new TypeError("addressed filename is invalid");
19899
19899
  }
19900
- if (request.actions.length === 0 || request.policyActions.length === 0) throw new TypeError("addressed share actions are empty");
19901
- if (request.policyActions.some((action) => !OWNER_SHARE_ACTIONS.has(action))) throw new TypeError("addressed share action is not supported");
19902
- if (request.deliveryEmail !== void 0 && !isEnvelopeDeliveryEmail(request.deliveryEmail)) throw new TypeError("delivery email is not a valid envelope address");
19903
- const target = normalizeShareTarget(request.target);
19900
+ if (request2.actions.length === 0 || request2.policyActions.length === 0) throw new TypeError("addressed share actions are empty");
19901
+ if (request2.policyActions.some((action) => !OWNER_SHARE_ACTIONS.has(action))) throw new TypeError("addressed share action is not supported");
19902
+ if (request2.deliveryEmail !== void 0 && !isEnvelopeDeliveryEmail(request2.deliveryEmail)) throw new TypeError("delivery email is not a valid envelope address");
19903
+ const target = normalizeShareTarget(request2.target);
19904
19904
  if (target.kind === "bearer") throw new TypeError("addressed target is required");
19905
19905
  if (target.kind === "recipientDid") return { target };
19906
- if (target.kind === "emailDomain" && request.deliveryEmail !== void 0 && (request.deliveryEmail !== request.deliveryEmail.toLowerCase() || !request.deliveryEmail.endsWith(`@${target.domain}`))) {
19906
+ if (target.kind === "emailDomain" && request2.deliveryEmail !== void 0 && (request2.deliveryEmail !== request2.deliveryEmail.toLowerCase() || !request2.deliveryEmail.endsWith(`@${target.domain}`))) {
19907
19907
  throw new TypeError("email-domain delivery address must be a lowercase mailbox at the domain");
19908
19908
  }
19909
19909
  return { target, credentialRequirement: mailboxCredentialCommitment(target) };
@@ -20217,9 +20217,9 @@ var cache22 = /* @__PURE__ */ new WeakMap();
20217
20217
  function baseCache22(cid2) {
20218
20218
  const baseCache32 = cache22.get(cid2);
20219
20219
  if (baseCache32 == null) {
20220
- const baseCache4 = /* @__PURE__ */ new Map();
20221
- cache22.set(cid2, baseCache4);
20222
- return baseCache4;
20220
+ const baseCache42 = /* @__PURE__ */ new Map();
20221
+ cache22.set(cid2, baseCache42);
20222
+ return baseCache42;
20223
20223
  }
20224
20224
  return baseCache32;
20225
20225
  }
@@ -20887,6 +20887,9 @@ function parseNativeShareUrl(value) {
20887
20887
  return token;
20888
20888
  }
20889
20889
 
20890
+ // ../share-envelope/dist/index.js
20891
+ init_sha2();
20892
+
20890
20893
  // ../../node_modules/zod/v3/external.js
20891
20894
  var external_exports3 = {};
20892
20895
  __export(external_exports3, {
@@ -21881,8 +21884,8 @@ function isValidJWT3(jwt, alg) {
21881
21884
  const [header] = jwt.split(".");
21882
21885
  if (!header)
21883
21886
  return false;
21884
- const base644 = header.replace(/-/g, "+").replace(/_/g, "/").padEnd(header.length + (4 - header.length % 4) % 4, "=");
21885
- const decoded = JSON.parse(atob(base644));
21887
+ const base645 = header.replace(/-/g, "+").replace(/_/g, "/").padEnd(header.length + (4 - header.length % 4) % 4, "=");
21888
+ const decoded = JSON.parse(atob(base645));
21886
21889
  if (typeof decoded !== "object" || decoded === null)
21887
21890
  return false;
21888
21891
  if ("typ" in decoded && decoded?.typ !== "JWT")
@@ -24536,23 +24539,23 @@ var ZodEffects3 = class extends ZodType3 {
24536
24539
  }
24537
24540
  if (effect.type === "transform") {
24538
24541
  if (ctx.common.async === false) {
24539
- const base4 = this._def.schema._parseSync({
24542
+ const base5 = this._def.schema._parseSync({
24540
24543
  data: ctx.data,
24541
24544
  path: ctx.path,
24542
24545
  parent: ctx
24543
24546
  });
24544
- if (!isValid3(base4))
24547
+ if (!isValid3(base5))
24545
24548
  return INVALID3;
24546
- const result = effect.transform(base4.value, checkCtx);
24549
+ const result = effect.transform(base5.value, checkCtx);
24547
24550
  if (result instanceof Promise) {
24548
24551
  throw new Error(`Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.`);
24549
24552
  }
24550
24553
  return { status: status.value, value: result };
24551
24554
  } else {
24552
- return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((base4) => {
24553
- if (!isValid3(base4))
24555
+ return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((base5) => {
24556
+ if (!isValid3(base5))
24554
24557
  return INVALID3;
24555
- return Promise.resolve(effect.transform(base4.value, checkCtx)).then((result) => ({
24558
+ return Promise.resolve(effect.transform(base5.value, checkCtx)).then((result) => ({
24556
24559
  status: status.value,
24557
24560
  value: result
24558
24561
  }));
@@ -25785,6 +25788,10 @@ function encodeCID3(version2, code22, multihash) {
25785
25788
  var cidSymbol3 = /* @__PURE__ */ Symbol.for("@ipld/js-cid/CID");
25786
25789
  var code3 = 85;
25787
25790
  var SHA256_CODE3 = 18;
25791
+ async function computeCid2(bytes) {
25792
+ const digest = create3(SHA256_CODE3, sha256(new Uint8Array(bytes)));
25793
+ return CID3.create(1, code3, digest).toString();
25794
+ }
25788
25795
  function isCanonicalRawCid3(cidString) {
25789
25796
  let cid;
25790
25797
  try {
@@ -25818,6 +25825,9 @@ var base64urlpad3 = rfc46483({
25818
25825
  alphabet: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_=",
25819
25826
  bitsPerChar: 6
25820
25827
  });
25828
+ function toBase64Url2(bytes) {
25829
+ return base64url3.baseEncode(bytes);
25830
+ }
25821
25831
  function fromBase64Url3(text) {
25822
25832
  const bytes = base64url3.baseDecode(text);
25823
25833
  if (base64url3.baseEncode(bytes) !== text) {
@@ -26315,7 +26325,71 @@ function canonicalMailbox2(value) {
26315
26325
  if (local.length > 64 || !/^[a-z0-9#$&'*+/=?^_`{|}~-]+(?:\.[a-z0-9#$&'*+/=?^_`{|}~-]+)*$/.test(local) || !isCanonicalEmailDomain2(domain)) return void 0;
26316
26326
  return Object.freeze({ email, domain });
26317
26327
  }
26328
+ var KEY_LENGTH22 = 32;
26318
26329
  var MAX_INLINE_BYTES3 = 256 * 1024;
26330
+ function assertCanonicalCid2(cidString) {
26331
+ const cid = CID3.parse(cidString);
26332
+ if (cid.version !== 1 || cid.code !== code3 || cid.multihash.code !== 18 || // sha2-256 (0x12) only, at the link layer too
26333
+ cid.toString() !== cidString) {
26334
+ throw new TypeError(`not a canonical CIDv1 raw sha2-256 base32 CID: ${cidString}`);
26335
+ }
26336
+ }
26337
+ async function encodeSealedInlineShareUrl2(parts) {
26338
+ if (!isCanonicalHttpsOrigin3(parts.origin)) throw new TypeError("origin must be a canonical https origin");
26339
+ if (parts.ciphertext.byteLength === 0 || parts.ciphertext.byteLength > MAX_INLINE_BYTES3) throw new RangeError("inline ciphertext is outside the allowed size");
26340
+ if (parts.key32.byteLength !== KEY_LENGTH22) throw new TypeError("inline key must be 32 bytes");
26341
+ const ciphertextCid = await computeCid2(parts.ciphertext);
26342
+ const payload = canonicalize3({
26343
+ v: 2,
26344
+ c: toBase64Url2(parts.ciphertext),
26345
+ cid: ciphertextCid,
26346
+ k: toBase64Url2(parts.key32)
26347
+ });
26348
+ const payloadBytes = new TextEncoder().encode(payload);
26349
+ if (payloadBytes.byteLength > MAX_INLINE_BYTES3 * 2) throw new RangeError("inline URL is too large");
26350
+ return `${parts.origin}/s/inline#v=2&p=${toBase64Url2(payloadBytes)}`;
26351
+ }
26352
+ async function parseSealedInlineShareUrl2(url, options = {}) {
26353
+ const parsed = new URL(url);
26354
+ if (parsed.protocol !== "https:" || parsed.username !== "" || parsed.password !== "") throw new TypeError("sealed inline share URL must be canonical HTTPS without userinfo");
26355
+ if (!isCanonicalHttpsOrigin3(parsed.origin) || options.expectedOrigin !== void 0 && parsed.origin !== options.expectedOrigin) throw new TypeError("sealed inline share URL origin is not trusted");
26356
+ if (parsed.pathname !== "/s/inline" || parsed.search !== "") throw new TypeError("not a Node sealed-inline share URL");
26357
+ if (url !== `${parsed.origin}/s/inline${parsed.hash}`) throw new TypeError("sealed inline share URL is not lexically canonical");
26358
+ const prefix = "#v=2&p=";
26359
+ if (!parsed.hash.startsWith(prefix)) throw new TypeError("sealed inline URL is missing its canonical fragment");
26360
+ const encoded = parsed.hash.slice(prefix.length);
26361
+ if (encoded.length === 0 || parsed.hash !== `${prefix}${encoded}`) throw new TypeError("sealed inline URL fragment is not canonical");
26362
+ let payloadBytes;
26363
+ try {
26364
+ payloadBytes = fromBase64Url3(encoded);
26365
+ } catch {
26366
+ throw new TypeError("sealed inline payload is not canonical base64url");
26367
+ }
26368
+ if (payloadBytes.byteLength === 0 || payloadBytes.byteLength > MAX_INLINE_BYTES3 * 2) throw new TypeError("sealed inline payload is too large");
26369
+ const payloadText = new TextDecoder("utf-8", { fatal: true }).decode(payloadBytes);
26370
+ let value;
26371
+ try {
26372
+ value = JSON.parse(payloadText);
26373
+ } catch {
26374
+ throw new TypeError("sealed inline payload is not valid JSON");
26375
+ }
26376
+ if (typeof value !== "object" || value === null || Array.isArray(value) || canonicalize3(value) !== payloadText) throw new TypeError("sealed inline payload is not canonical JSON");
26377
+ const record2 = value;
26378
+ if (Object.keys(record2).length !== 4 || record2.v !== 2 || typeof record2.c !== "string" || typeof record2.cid !== "string" || typeof record2.k !== "string") throw new TypeError("sealed inline payload has invalid fields");
26379
+ let ciphertext;
26380
+ let key32;
26381
+ try {
26382
+ ciphertext = fromBase64Url3(record2.c);
26383
+ key32 = fromBase64Url3(record2.k);
26384
+ } catch {
26385
+ throw new TypeError("sealed inline payload has invalid base64url material");
26386
+ }
26387
+ if (ciphertext.byteLength === 0 || ciphertext.byteLength > MAX_INLINE_BYTES3) throw new TypeError("sealed inline ciphertext is outside the allowed size");
26388
+ if (key32.byteLength !== KEY_LENGTH22) throw new TypeError("sealed inline key must be 32 bytes");
26389
+ assertCanonicalCid2(record2.cid);
26390
+ if (await computeCid2(ciphertext) !== record2.cid) throw new TypeError("sealed inline ciphertext does not match its CID");
26391
+ return { kind: "inline", ciphertextCid: record2.cid, ciphertext, key32 };
26392
+ }
26319
26393
 
26320
26394
  // src/commands/share.ts
26321
26395
  import { ProfileLockTimeoutError as ProfileLockTimeoutError2 } from "@tinycloud/operations/state";
@@ -26366,16 +26440,16 @@ function statusOf(error, depth = 0) {
26366
26440
  return direct ?? (depth === 0 ? statusOf(fields.cause, 1) : void 0);
26367
26441
  }
26368
26442
  function codeOf(error) {
26369
- const code4 = record(error)?.code;
26370
- return typeof code4 === "string" && /^[A-Z][A-Z0-9_]{2,63}$/.test(code4) ? code4 : void 0;
26443
+ const code5 = record(error)?.code;
26444
+ return typeof code5 === "string" && /^[A-Z][A-Z0-9_]{2,63}$/.test(code5) ? code5 : void 0;
26371
26445
  }
26372
26446
  function classifyShareFailure(error, loginHint) {
26373
26447
  const status = statusOf(error);
26374
26448
  const verdict = authorizationVerdictOf2(error);
26375
26449
  const message = error instanceof Error ? error.message : "";
26376
- const code4 = codeOf(error);
26450
+ const code5 = codeOf(error);
26377
26451
  const detail = (text) => {
26378
- const parts = [status === void 0 ? void 0 : `HTTP ${status}`, code4].filter((part) => part !== void 0);
26452
+ const parts = [status === void 0 ? void 0 : `HTTP ${status}`, code5].filter((part) => part !== void 0);
26379
26453
  return parts.length === 0 ? text : `${text} (${parts.join(", ")})`;
26380
26454
  };
26381
26455
  if (verdict === "unauthenticated" || status === 401) {
@@ -26414,8 +26488,8 @@ function authorizationRequiredJson(result) {
26414
26488
  next: "complete authorization through the configured authority adapter, then retry with the required proof"
26415
26489
  };
26416
26490
  }
26417
- function publishHuman(result) {
26418
- process.stdout.write(`${result.url}
26491
+ function publishHuman(url) {
26492
+ process.stdout.write(`${url}
26419
26493
  `);
26420
26494
  }
26421
26495
  function inspectHuman(result) {
@@ -26584,10 +26658,10 @@ function kvArtifactStore(kv) {
26584
26658
  throw new ArtifactError("storage", `could not write ${key}: ${errorCode(written.error) ?? "unknown error"}`, { cause: written.error });
26585
26659
  },
26586
26660
  async get(key) {
26587
- const read4 = await kv.get(key, { binary: true });
26588
- if (read4.ok) return new Uint8Array(read4.data.data);
26589
- if (errorCode(read4.error) === "KV_NOT_FOUND") return void 0;
26590
- throw new ArtifactError("storage", `could not read ${key}: ${errorCode(read4.error) ?? "unknown error"}`, { cause: read4.error });
26661
+ const read5 = await kv.get(key, { binary: true });
26662
+ if (read5.ok) return new Uint8Array(read5.data.data);
26663
+ if (errorCode(read5.error) === "KV_NOT_FOUND") return void 0;
26664
+ throw new ArtifactError("storage", `could not read ${key}: ${errorCode(read5.error) ?? "unknown error"}`, { cause: read5.error });
26591
26665
  },
26592
26666
  async list(prefix) {
26593
26667
  const keys = [];
@@ -26605,206 +26679,1904 @@ function kvArtifactStore(kv) {
26605
26679
  };
26606
26680
  }
26607
26681
 
26608
- // src/share/errors.ts
26609
- var SharePublishAuthorityError = class extends Error {
26610
- constructor(failure, options) {
26611
- super(failure.kind, options);
26612
- this.failure = failure;
26613
- this.name = "SharePublishAuthorityError";
26614
- }
26615
- };
26616
- var ShareHistoryRetryError = class extends Error {
26617
- constructor(profile) {
26618
- super("sender history changed during the operation");
26619
- this.profile = profile;
26620
- this.name = "ShareHistoryRetryError";
26682
+ // ../share-envelope/dist/short-link.js
26683
+ init_sha2();
26684
+ var empty4 = new Uint8Array(0);
26685
+ function equals6(aa, bb) {
26686
+ if (aa === bb) {
26687
+ return true;
26621
26688
  }
26622
- code = "SHARE_HISTORY_RETRY";
26623
- };
26624
- var ShareHistoryUnreadableError = class extends Error {
26625
- constructor() {
26626
- super("share history is unavailable");
26627
- this.name = "ShareHistoryUnreadableError";
26689
+ if (aa.byteLength !== bb.byteLength) {
26690
+ return false;
26628
26691
  }
26629
- };
26630
- var ShareHistoryReadError = class extends Error {
26631
- constructor() {
26632
- super("share history could not be read");
26633
- this.name = "ShareHistoryReadError";
26692
+ for (let ii = 0; ii < aa.byteLength; ii++) {
26693
+ if (aa[ii] !== bb[ii]) {
26694
+ return false;
26695
+ }
26634
26696
  }
26635
- };
26636
- var HISTORY_WRITE_ERROR_CODES = { EACCES: true, EPERM: true, EROFS: true, ENOSPC: true, EDQUOT: true, EIO: true };
26637
- function shareHistoryReason(error) {
26638
- if (error instanceof ShareHistoryUnreadableError) return "HISTORY_UNREADABLE";
26639
- if (error instanceof ShareHistoryReadError) return "HISTORY_READ_FAILED";
26640
- const code4 = typeof error === "object" && error !== null && "code" in error ? error.code : void 0;
26641
- return typeof code4 === "string" && HISTORY_WRITE_ERROR_CODES[code4] === true ? "HISTORY_WRITE_FAILED" : "HISTORY_UNAVAILABLE";
26642
- }
26643
-
26644
- // src/share/space-not-ready.ts
26645
- function isSpaceNotFound(error) {
26646
- if (typeof error !== "object" || error === null) return false;
26647
- const message = "message" in error && typeof error.message === "string" ? error.message : "";
26648
- if (!/space not found/i.test(message)) return false;
26649
- const meta = "meta" in error && typeof error.meta === "object" && error.meta !== null ? error.meta : void 0;
26650
- const status = meta !== void 0 && "status" in meta ? meta.status : void 0;
26651
- return status === 404 || /\b404\b/.test(message);
26652
- }
26653
- function spaceNotReadyFailure(cause) {
26654
- return new SharePublishAuthorityError({ kind: "space-not-ready" }, { cause });
26655
- }
26656
- function failIfSpaceNotReady(result) {
26657
- if (!result.ok && isSpaceNotFound(result.error)) throw spaceNotReadyFailure(result.error);
26658
- }
26659
- function artifactSpaceNotReady(error) {
26660
- return error instanceof ArtifactError && isSpaceNotFound(error.cause) ? spaceNotReadyFailure(error.cause) : error;
26661
- }
26662
-
26663
- // src/share/adapters.ts
26664
- init_storage();
26665
- init_profiles();
26666
- init_constants();
26667
- init_errors();
26668
- init_session_expired();
26669
- import { chmod as chmod4, link as link3, open as open8, readFile as readFile7, stat as stat5, unlink as unlink5 } from "fs/promises";
26670
- import { dirname as dirname5, join as join12 } from "path";
26671
- import { createHash } from "crypto";
26672
- import { writeJsonAtomic as writeJsonAtomic2 } from "@tinycloud/operations/state";
26673
- import { withoutBearer } from "@tinycloud/operations/delegation-binding";
26674
- import {
26675
- LocationRecordValidationError,
26676
- LocationRegistryHttpError,
26677
- parseSignedCompactUcanAttenuation,
26678
- parseSignedSiweCacao,
26679
- revokePolicyRootV3,
26680
- signCompactUcanAuthorization
26681
- } from "@tinycloud/sdk-core";
26682
- import { extractSiweExpiration, InvalidRestoredSessionError } from "@tinycloud/node-sdk";
26683
- function requiredKvAction(meta) {
26684
- if (meta === null || typeof meta !== "object" || !("requiredAction" in meta)) return void 0;
26685
- const action = meta.requiredAction;
26686
- return action === "tinycloud.kv/put" || action === "tinycloud.kv/get" || action === "tinycloud.kv/list" ? action : void 0;
26687
- }
26688
- function throwKvUploadFailure(error) {
26689
- const rejection = storageRejection(error);
26690
- if (rejection) throw new SharePublishAuthorityError({ kind: "storage-full", ...rejection });
26691
- throw new SharePublishAuthorityError({ kind: "upload-failed" });
26692
- }
26693
- var DEFAULT_SHARE_ORIGIN = "https://share.tinycloud.xyz";
26694
- var MIN_DOMAIN_DELIVERY_VERSION = "1.17.3";
26695
- function supportsDomainDelivery(version2) {
26696
- if (typeof version2 !== "string") return false;
26697
- const normalized = version2.trim();
26698
- if (normalized.length > 128) return false;
26699
- const match = /^v?(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/.exec(normalized);
26700
- if (match === null) return false;
26701
- if (match[4] !== void 0 && /(?:^|\.)0[0-9]+(?:\.|$)/.test(match[4])) return false;
26702
- const major = Number(match[1]);
26703
- const minor = Number(match[2]);
26704
- const patch = Number(match[3]);
26705
- if (!Number.isSafeInteger(major) || !Number.isSafeInteger(minor) || !Number.isSafeInteger(patch)) return false;
26706
- if (major !== 1) return major > 1;
26707
- if (minor !== 17) return minor > 17;
26708
- if (patch !== 3) return patch > 3;
26709
- return match[4] === void 0;
26710
- }
26711
- function displayedNodeVersion(version2) {
26712
- if (typeof version2 !== "string") return "(unrecognized)";
26713
- const trimmed = version2.trim();
26714
- return /^[A-Za-z0-9.+_-]{1,64}$/.test(trimmed) ? trimmed : "(unrecognized)";
26715
- }
26716
- var URI_SAFE_FILENAME = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
26717
- function safeStorageFilename(filename) {
26718
- if (URI_SAFE_FILENAME.test(filename) && !filename.includes("..")) return filename;
26719
- const dot = filename.lastIndexOf(".");
26720
- const extension = dot >= 0 && /^[A-Za-z0-9]{1,16}$/.test(filename.slice(dot + 1)) ? filename.slice(dot + 1) : "";
26721
- const stem = (extension === "" ? filename : filename.slice(0, dot)).normalize("NFKD").replace(/[\u0300-\u036f]/g, "").replace(extension === "" ? /[^A-Za-z0-9_-]+/g : /[^A-Za-z0-9._-]+/g, "-").replace(/\.{2,}/g, ".").replace(/-{2,}/g, "-").slice(0, 100).replace(/^[^A-Za-z0-9]+|[-.]+$/g, "");
26722
- return `${stem === "" ? "share" : stem}${extension === "" ? "" : `.${extension}`}`;
26723
- }
26724
- function scopeDeniedFromArtifactError(error, capability, authority) {
26725
- const cause = error instanceof ArtifactError ? error.cause : void 0;
26726
- const code4 = typeof cause === "object" && cause !== null && "code" in cause ? cause.code : void 0;
26727
- if (code4 !== "AUTH_UNAUTHORIZED" && code4 !== "PERMISSION_DENIED") return void 0;
26728
- const meta = typeof cause === "object" && cause !== null && "meta" in cause ? cause.meta : void 0;
26729
- const requiredAction = requiredKvAction(meta);
26730
- return new SharePublishAuthorityError({
26731
- kind: "scope-denied",
26732
- capability,
26733
- ...requiredAction === void 0 ? {} : { requiredAction },
26734
- localKey: authority.localKey,
26735
- profileName: authority.profileName
26736
- });
26697
+ return true;
26737
26698
  }
26738
- async function storeArtifactVersion(kv, version2, authority) {
26739
- try {
26740
- return await publishArtifactVersion(kvArtifactStore(kv), version2);
26741
- } catch (error) {
26742
- throw scopeDeniedFromArtifactError(error, "KV upload", authority) ?? artifactSpaceNotReady(error);
26699
+ function coerce6(o) {
26700
+ if (o instanceof Uint8Array && o.constructor.name === "Uint8Array") {
26701
+ return o;
26702
+ }
26703
+ if (o instanceof ArrayBuffer) {
26704
+ return new Uint8Array(o);
26705
+ }
26706
+ if (ArrayBuffer.isView(o)) {
26707
+ return new Uint8Array(o.buffer, o.byteOffset, o.byteLength);
26743
26708
  }
26709
+ throw new Error("Unknown type, must be binary type");
26744
26710
  }
26745
- function createEncryptedSessionHistory() {
26746
- const records = /* @__PURE__ */ new Map();
26747
- let operation = Promise.resolve();
26748
- const serial = (action) => {
26749
- const next = operation.then(action, action);
26750
- operation = next.then(() => void 0, () => void 0);
26751
- return next;
26752
- };
26753
- let keyPromise;
26754
- const key = async () => keyPromise ??= crypto.subtle.generateKey({ name: "AES-GCM", length: 256 }, false, ["encrypt", "decrypt"]);
26755
- const encode6 = async (record2) => {
26756
- const secret = new TextEncoder().encode(JSON.stringify(record2));
26757
- const iv = crypto.getRandomValues(new Uint8Array(12));
26758
- const encrypted = new Uint8Array(await crypto.subtle.encrypt({ name: "AES-GCM", iv }, await key(), secret));
26759
- const value = new Uint8Array(iv.length + encrypted.length);
26760
- value.set(iv);
26761
- value.set(encrypted, iv.length);
26762
- return value;
26763
- };
26764
- const decode10 = async (value) => JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(await crypto.subtle.decrypt({ name: "AES-GCM", iv: value.slice(0, 12) }, await key(), value.slice(12))));
26765
- return {
26766
- async put(record2) {
26767
- return serial(async () => {
26768
- records.set(record2.shareId, await encode6(record2));
26769
- });
26770
- },
26771
- async update(shareId, change) {
26772
- return serial(async () => {
26773
- const value = records.get(shareId);
26774
- if (value === void 0) return void 0;
26775
- const updated = await change(await decode10(value));
26776
- records.set(shareId, await encode6(updated));
26777
- return updated;
26778
- });
26779
- },
26780
- async list() {
26781
- return serial(() => Promise.all([...records.values()].map(decode10)));
26782
- },
26783
- async get(shareId) {
26784
- return serial(async () => {
26785
- const value = records.get(shareId);
26786
- return value === void 0 ? void 0 : decode10(value);
26787
- });
26788
- },
26789
- async delete(shareId) {
26790
- return serial(async () => {
26791
- records.delete(shareId);
26792
- });
26711
+ function base4(ALPHABET, name) {
26712
+ if (ALPHABET.length >= 255) {
26713
+ throw new TypeError("Alphabet too long");
26714
+ }
26715
+ var BASE_MAP = new Uint8Array(256);
26716
+ for (var j = 0; j < BASE_MAP.length; j++) {
26717
+ BASE_MAP[j] = 255;
26718
+ }
26719
+ for (var i = 0; i < ALPHABET.length; i++) {
26720
+ var x = ALPHABET.charAt(i);
26721
+ var xc = x.charCodeAt(0);
26722
+ if (BASE_MAP[xc] !== 255) {
26723
+ throw new TypeError(x + " is ambiguous");
26793
26724
  }
26794
- };
26795
- }
26796
- var SHARE_HISTORY_FILE = "share-history-v2.json";
26797
- var SHARE_HISTORY_LEGACY_FILE = "share-history-v1.bin";
26798
- var PRIVATE_HISTORY_MODE = 384;
26799
- async function signShareHistoryBytes(bytes, profile) {
26800
- const context = await ProfileManager.resolveContext({ profile });
26801
- if (context.profile !== profile) throw new ShareHistoryRetryError(profile);
26802
- const { ensureAuthenticated: ensureAuthenticated2 } = await Promise.resolve().then(() => (init_sdk(), sdk_exports));
26803
- const signer = await ensureAuthenticated2(context);
26804
- return signer.signSessionBytes(bytes);
26805
- }
26806
- function createEncryptedProfileHistory(profileName, sessionSigner) {
26807
- const HISTORY_VERSION = 2;
26725
+ BASE_MAP[xc] = i;
26726
+ }
26727
+ var BASE = ALPHABET.length;
26728
+ var LEADER = ALPHABET.charAt(0);
26729
+ var FACTOR = Math.log(BASE) / Math.log(256);
26730
+ var iFACTOR = Math.log(256) / Math.log(BASE);
26731
+ function encode33(source) {
26732
+ if (source instanceof Uint8Array)
26733
+ ;
26734
+ else if (ArrayBuffer.isView(source)) {
26735
+ source = new Uint8Array(source.buffer, source.byteOffset, source.byteLength);
26736
+ } else if (Array.isArray(source)) {
26737
+ source = Uint8Array.from(source);
26738
+ }
26739
+ if (!(source instanceof Uint8Array)) {
26740
+ throw new TypeError("Expected Uint8Array");
26741
+ }
26742
+ if (source.length === 0) {
26743
+ return "";
26744
+ }
26745
+ var zeroes = 0;
26746
+ var length23 = 0;
26747
+ var pbegin = 0;
26748
+ var pend = source.length;
26749
+ while (pbegin !== pend && source[pbegin] === 0) {
26750
+ pbegin++;
26751
+ zeroes++;
26752
+ }
26753
+ var size = (pend - pbegin) * iFACTOR + 1 >>> 0;
26754
+ var b58 = new Uint8Array(size);
26755
+ while (pbegin !== pend) {
26756
+ var carry = source[pbegin];
26757
+ var i2 = 0;
26758
+ for (var it1 = size - 1; (carry !== 0 || i2 < length23) && it1 !== -1; it1--, i2++) {
26759
+ carry += 256 * b58[it1] >>> 0;
26760
+ b58[it1] = carry % BASE >>> 0;
26761
+ carry = carry / BASE >>> 0;
26762
+ }
26763
+ if (carry !== 0) {
26764
+ throw new Error("Non-zero carry");
26765
+ }
26766
+ length23 = i2;
26767
+ pbegin++;
26768
+ }
26769
+ var it2 = size - length23;
26770
+ while (it2 !== size && b58[it2] === 0) {
26771
+ it2++;
26772
+ }
26773
+ var str = LEADER.repeat(zeroes);
26774
+ for (; it2 < size; ++it2) {
26775
+ str += ALPHABET.charAt(b58[it2]);
26776
+ }
26777
+ return str;
26778
+ }
26779
+ function decodeUnsafe(source) {
26780
+ if (typeof source !== "string") {
26781
+ throw new TypeError("Expected String");
26782
+ }
26783
+ if (source.length === 0) {
26784
+ return new Uint8Array();
26785
+ }
26786
+ var psz = 0;
26787
+ if (source[psz] === " ") {
26788
+ return;
26789
+ }
26790
+ var zeroes = 0;
26791
+ var length23 = 0;
26792
+ while (source[psz] === LEADER) {
26793
+ zeroes++;
26794
+ psz++;
26795
+ }
26796
+ var size = (source.length - psz) * FACTOR + 1 >>> 0;
26797
+ var b256 = new Uint8Array(size);
26798
+ while (source[psz]) {
26799
+ var carry = BASE_MAP[source.charCodeAt(psz)];
26800
+ if (carry === 255) {
26801
+ return;
26802
+ }
26803
+ var i2 = 0;
26804
+ for (var it3 = size - 1; (carry !== 0 || i2 < length23) && it3 !== -1; it3--, i2++) {
26805
+ carry += BASE * b256[it3] >>> 0;
26806
+ b256[it3] = carry % 256 >>> 0;
26807
+ carry = carry / 256 >>> 0;
26808
+ }
26809
+ if (carry !== 0) {
26810
+ throw new Error("Non-zero carry");
26811
+ }
26812
+ length23 = i2;
26813
+ psz++;
26814
+ }
26815
+ if (source[psz] === " ") {
26816
+ return;
26817
+ }
26818
+ var it4 = size - length23;
26819
+ while (it4 !== size && b256[it4] === 0) {
26820
+ it4++;
26821
+ }
26822
+ var vch = new Uint8Array(zeroes + (size - it4));
26823
+ var j2 = zeroes;
26824
+ while (it4 !== size) {
26825
+ vch[j2++] = b256[it4++];
26826
+ }
26827
+ return vch;
26828
+ }
26829
+ function decode53(string) {
26830
+ var buffer = decodeUnsafe(string);
26831
+ if (buffer) {
26832
+ return buffer;
26833
+ }
26834
+ throw new Error(`Non-${name} character`);
26835
+ }
26836
+ return {
26837
+ encode: encode33,
26838
+ decodeUnsafe,
26839
+ decode: decode53
26840
+ };
26841
+ }
26842
+ var src4 = base4;
26843
+ var _brrp__multiformats_scope_baseX4 = src4;
26844
+ var base_x_default4 = _brrp__multiformats_scope_baseX4;
26845
+ var Encoder4 = class {
26846
+ name;
26847
+ prefix;
26848
+ baseEncode;
26849
+ constructor(name, prefix, baseEncode) {
26850
+ this.name = name;
26851
+ this.prefix = prefix;
26852
+ this.baseEncode = baseEncode;
26853
+ }
26854
+ encode(bytes) {
26855
+ if (bytes instanceof Uint8Array) {
26856
+ return `${this.prefix}${this.baseEncode(bytes)}`;
26857
+ } else {
26858
+ throw Error("Unknown type, must be binary type");
26859
+ }
26860
+ }
26861
+ };
26862
+ var Decoder4 = class {
26863
+ name;
26864
+ prefix;
26865
+ baseDecode;
26866
+ prefixCodePoint;
26867
+ constructor(name, prefix, baseDecode) {
26868
+ this.name = name;
26869
+ this.prefix = prefix;
26870
+ const prefixCodePoint = prefix.codePointAt(0);
26871
+ if (prefixCodePoint === void 0) {
26872
+ throw new Error("Invalid prefix character");
26873
+ }
26874
+ this.prefixCodePoint = prefixCodePoint;
26875
+ this.baseDecode = baseDecode;
26876
+ }
26877
+ decode(text) {
26878
+ if (typeof text === "string") {
26879
+ if (text.codePointAt(0) !== this.prefixCodePoint) {
26880
+ throw Error(`Unable to decode multibase string ${JSON.stringify(text)}, ${this.name} decoder only supports inputs prefixed with ${this.prefix}`);
26881
+ }
26882
+ return this.baseDecode(text.slice(this.prefix.length));
26883
+ } else {
26884
+ throw Error("Can only multibase decode strings");
26885
+ }
26886
+ }
26887
+ or(decoder) {
26888
+ return or4(this, decoder);
26889
+ }
26890
+ };
26891
+ var ComposedDecoder4 = class {
26892
+ decoders;
26893
+ constructor(decoders) {
26894
+ this.decoders = decoders;
26895
+ }
26896
+ or(decoder) {
26897
+ return or4(this, decoder);
26898
+ }
26899
+ decode(input) {
26900
+ const prefix = input[0];
26901
+ const decoder = this.decoders[prefix];
26902
+ if (decoder != null) {
26903
+ return decoder.decode(input);
26904
+ } else {
26905
+ throw RangeError(`Unable to decode multibase string ${JSON.stringify(input)}, only inputs prefixed with ${Object.keys(this.decoders)} are supported`);
26906
+ }
26907
+ }
26908
+ };
26909
+ function or4(left, right) {
26910
+ return new ComposedDecoder4({
26911
+ ...left.decoders ?? { [left.prefix]: left },
26912
+ ...right.decoders ?? { [right.prefix]: right }
26913
+ });
26914
+ }
26915
+ var Codec4 = class {
26916
+ name;
26917
+ prefix;
26918
+ baseEncode;
26919
+ baseDecode;
26920
+ encoder;
26921
+ decoder;
26922
+ constructor(name, prefix, baseEncode, baseDecode) {
26923
+ this.name = name;
26924
+ this.prefix = prefix;
26925
+ this.baseEncode = baseEncode;
26926
+ this.baseDecode = baseDecode;
26927
+ this.encoder = new Encoder4(name, prefix, baseEncode);
26928
+ this.decoder = new Decoder4(name, prefix, baseDecode);
26929
+ }
26930
+ encode(input) {
26931
+ return this.encoder.encode(input);
26932
+ }
26933
+ decode(input) {
26934
+ return this.decoder.decode(input);
26935
+ }
26936
+ };
26937
+ function from4({ name, prefix, encode: encode33, decode: decode53 }) {
26938
+ return new Codec4(name, prefix, encode33, decode53);
26939
+ }
26940
+ function baseX4({ name, prefix, alphabet }) {
26941
+ const { encode: encode33, decode: decode53 } = base_x_default4(alphabet, name);
26942
+ return from4({
26943
+ prefix,
26944
+ name,
26945
+ encode: encode33,
26946
+ decode: (text) => coerce6(decode53(text))
26947
+ });
26948
+ }
26949
+ function decode10(string, alphabetIdx, bitsPerChar, name) {
26950
+ let end = string.length;
26951
+ while (string[end - 1] === "=") {
26952
+ --end;
26953
+ }
26954
+ const out = new Uint8Array(end * bitsPerChar / 8 | 0);
26955
+ let bits = 0;
26956
+ let buffer = 0;
26957
+ let written = 0;
26958
+ for (let i = 0; i < end; ++i) {
26959
+ const value = alphabetIdx[string[i]];
26960
+ if (value === void 0) {
26961
+ throw new SyntaxError(`Non-${name} character`);
26962
+ }
26963
+ buffer = buffer << bitsPerChar | value;
26964
+ bits += bitsPerChar;
26965
+ if (bits >= 8) {
26966
+ bits -= 8;
26967
+ out[written++] = 255 & buffer >> bits;
26968
+ }
26969
+ }
26970
+ if (bits >= bitsPerChar || (255 & buffer << 8 - bits) !== 0) {
26971
+ throw new SyntaxError("Unexpected end of data");
26972
+ }
26973
+ return out;
26974
+ }
26975
+ function encode6(data, alphabet, bitsPerChar) {
26976
+ const pad = alphabet[alphabet.length - 1] === "=";
26977
+ const mask = (1 << bitsPerChar) - 1;
26978
+ let out = "";
26979
+ let bits = 0;
26980
+ let buffer = 0;
26981
+ for (let i = 0; i < data.length; ++i) {
26982
+ buffer = buffer << 8 | data[i];
26983
+ bits += 8;
26984
+ while (bits > bitsPerChar) {
26985
+ bits -= bitsPerChar;
26986
+ out += alphabet[mask & buffer >> bits];
26987
+ }
26988
+ }
26989
+ if (bits !== 0) {
26990
+ out += alphabet[mask & buffer << bitsPerChar - bits];
26991
+ }
26992
+ if (pad) {
26993
+ while ((out.length * bitsPerChar & 7) !== 0) {
26994
+ out += "=";
26995
+ }
26996
+ }
26997
+ return out;
26998
+ }
26999
+ function createAlphabetIdx4(alphabet) {
27000
+ const alphabetIdx = {};
27001
+ for (let i = 0; i < alphabet.length; ++i) {
27002
+ alphabetIdx[alphabet[i]] = i;
27003
+ }
27004
+ return alphabetIdx;
27005
+ }
27006
+ function rfc46484({ name, prefix, bitsPerChar, alphabet }) {
27007
+ const alphabetIdx = createAlphabetIdx4(alphabet);
27008
+ return from4({
27009
+ prefix,
27010
+ name,
27011
+ encode(input) {
27012
+ return encode6(input, alphabet, bitsPerChar);
27013
+ },
27014
+ decode(input) {
27015
+ return decode10(input, alphabetIdx, bitsPerChar, name);
27016
+ }
27017
+ });
27018
+ }
27019
+ var base644 = rfc46484({
27020
+ prefix: "m",
27021
+ name: "base64",
27022
+ alphabet: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
27023
+ bitsPerChar: 6
27024
+ });
27025
+ var base64pad4 = rfc46484({
27026
+ prefix: "M",
27027
+ name: "base64pad",
27028
+ alphabet: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
27029
+ bitsPerChar: 6
27030
+ });
27031
+ var base64url4 = rfc46484({
27032
+ prefix: "u",
27033
+ name: "base64url",
27034
+ alphabet: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_",
27035
+ bitsPerChar: 6
27036
+ });
27037
+ var base64urlpad4 = rfc46484({
27038
+ prefix: "U",
27039
+ name: "base64urlpad",
27040
+ alphabet: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_=",
27041
+ bitsPerChar: 6
27042
+ });
27043
+ function toBase64Url3(bytes) {
27044
+ return base64url4.baseEncode(bytes);
27045
+ }
27046
+ function fromBase64Url4(text) {
27047
+ const bytes = base64url4.baseDecode(text);
27048
+ if (base64url4.baseEncode(bytes) !== text) {
27049
+ throw new TypeError("non-canonical base64url input");
27050
+ }
27051
+ return bytes;
27052
+ }
27053
+ var base324 = rfc46484({
27054
+ prefix: "b",
27055
+ name: "base32",
27056
+ alphabet: "abcdefghijklmnopqrstuvwxyz234567",
27057
+ bitsPerChar: 5
27058
+ });
27059
+ var base32upper4 = rfc46484({
27060
+ prefix: "B",
27061
+ name: "base32upper",
27062
+ alphabet: "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567",
27063
+ bitsPerChar: 5
27064
+ });
27065
+ var base32pad4 = rfc46484({
27066
+ prefix: "c",
27067
+ name: "base32pad",
27068
+ alphabet: "abcdefghijklmnopqrstuvwxyz234567=",
27069
+ bitsPerChar: 5
27070
+ });
27071
+ var base32padupper4 = rfc46484({
27072
+ prefix: "C",
27073
+ name: "base32padupper",
27074
+ alphabet: "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=",
27075
+ bitsPerChar: 5
27076
+ });
27077
+ var base32hex4 = rfc46484({
27078
+ prefix: "v",
27079
+ name: "base32hex",
27080
+ alphabet: "0123456789abcdefghijklmnopqrstuv",
27081
+ bitsPerChar: 5
27082
+ });
27083
+ var base32hexupper4 = rfc46484({
27084
+ prefix: "V",
27085
+ name: "base32hexupper",
27086
+ alphabet: "0123456789ABCDEFGHIJKLMNOPQRSTUV",
27087
+ bitsPerChar: 5
27088
+ });
27089
+ var base32hexpad4 = rfc46484({
27090
+ prefix: "t",
27091
+ name: "base32hexpad",
27092
+ alphabet: "0123456789abcdefghijklmnopqrstuv=",
27093
+ bitsPerChar: 5
27094
+ });
27095
+ var base32hexpadupper4 = rfc46484({
27096
+ prefix: "T",
27097
+ name: "base32hexpadupper",
27098
+ alphabet: "0123456789ABCDEFGHIJKLMNOPQRSTUV=",
27099
+ bitsPerChar: 5
27100
+ });
27101
+ var base32z4 = rfc46484({
27102
+ prefix: "h",
27103
+ name: "base32z",
27104
+ alphabet: "ybndrfg8ejkmcpqxot1uwisza345h769",
27105
+ bitsPerChar: 5
27106
+ });
27107
+ var base364 = baseX4({
27108
+ prefix: "k",
27109
+ name: "base36",
27110
+ alphabet: "0123456789abcdefghijklmnopqrstuvwxyz"
27111
+ });
27112
+ var base36upper4 = baseX4({
27113
+ prefix: "K",
27114
+ name: "base36upper",
27115
+ alphabet: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
27116
+ });
27117
+ var base58btc4 = baseX4({
27118
+ name: "base58btc",
27119
+ prefix: "z",
27120
+ alphabet: "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
27121
+ });
27122
+ var base58flickr4 = baseX4({
27123
+ name: "base58flickr",
27124
+ prefix: "Z",
27125
+ alphabet: "123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"
27126
+ });
27127
+ var encode_14 = encode24;
27128
+ var MSB4 = 128;
27129
+ var REST4 = 127;
27130
+ var MSBALL4 = ~REST4;
27131
+ var INT4 = Math.pow(2, 31);
27132
+ function encode24(num, out, offset) {
27133
+ out = out || [];
27134
+ offset = offset || 0;
27135
+ var oldOffset = offset;
27136
+ while (num >= INT4) {
27137
+ out[offset++] = num & 255 | MSB4;
27138
+ num /= 128;
27139
+ }
27140
+ while (num & MSBALL4) {
27141
+ out[offset++] = num & 255 | MSB4;
27142
+ num >>>= 7;
27143
+ }
27144
+ out[offset] = num | 0;
27145
+ encode24.bytes = offset - oldOffset + 1;
27146
+ return out;
27147
+ }
27148
+ var decode24 = read4;
27149
+ var MSB$14 = 128;
27150
+ var REST$14 = 127;
27151
+ function read4(buf, offset) {
27152
+ var res = 0, offset = offset || 0, shift = 0, counter = offset, b, l = buf.length;
27153
+ do {
27154
+ if (counter >= l) {
27155
+ read4.bytes = 0;
27156
+ throw new RangeError("Could not decode varint");
27157
+ }
27158
+ b = buf[counter++];
27159
+ res += shift < 28 ? (b & REST$14) << shift : (b & REST$14) * Math.pow(2, shift);
27160
+ shift += 7;
27161
+ } while (b >= MSB$14);
27162
+ read4.bytes = counter - offset;
27163
+ return res;
27164
+ }
27165
+ var N14 = Math.pow(2, 7);
27166
+ var N24 = Math.pow(2, 14);
27167
+ var N34 = Math.pow(2, 21);
27168
+ var N44 = Math.pow(2, 28);
27169
+ var N54 = Math.pow(2, 35);
27170
+ var N64 = Math.pow(2, 42);
27171
+ var N74 = Math.pow(2, 49);
27172
+ var N84 = Math.pow(2, 56);
27173
+ var N94 = Math.pow(2, 63);
27174
+ var length4 = function(value) {
27175
+ return value < N14 ? 1 : value < N24 ? 2 : value < N34 ? 3 : value < N44 ? 4 : value < N54 ? 5 : value < N64 ? 6 : value < N74 ? 7 : value < N84 ? 8 : value < N94 ? 9 : 10;
27176
+ };
27177
+ var varint4 = {
27178
+ encode: encode_14,
27179
+ decode: decode24,
27180
+ encodingLength: length4
27181
+ };
27182
+ var _brrp_varint4 = varint4;
27183
+ var varint_default4 = _brrp_varint4;
27184
+ function decode34(data, offset = 0) {
27185
+ const code22 = varint_default4.decode(data, offset);
27186
+ return [code22, varint_default4.decode.bytes];
27187
+ }
27188
+ function encodeTo4(int, target, offset = 0) {
27189
+ varint_default4.encode(int, target, offset);
27190
+ return target;
27191
+ }
27192
+ function encodingLength4(int) {
27193
+ return varint_default4.encodingLength(int);
27194
+ }
27195
+ function create4(code22, digest) {
27196
+ const size = digest.byteLength;
27197
+ const sizeOffset = encodingLength4(code22);
27198
+ const digestOffset = sizeOffset + encodingLength4(size);
27199
+ const bytes = new Uint8Array(digestOffset + size);
27200
+ encodeTo4(code22, bytes, 0);
27201
+ encodeTo4(size, bytes, sizeOffset);
27202
+ bytes.set(digest, digestOffset);
27203
+ return new Digest4(code22, size, digest, bytes);
27204
+ }
27205
+ function decode44(multihash) {
27206
+ const bytes = coerce6(multihash);
27207
+ const [code22, sizeOffset] = decode34(bytes);
27208
+ const [size, digestOffset] = decode34(bytes.subarray(sizeOffset));
27209
+ const digest = bytes.subarray(sizeOffset + digestOffset);
27210
+ if (digest.byteLength !== size) {
27211
+ throw new Error("Incorrect length");
27212
+ }
27213
+ return new Digest4(code22, size, digest, bytes);
27214
+ }
27215
+ function equals24(a, b) {
27216
+ if (a === b) {
27217
+ return true;
27218
+ } else {
27219
+ const data = b;
27220
+ return a.code === data.code && a.size === data.size && data.bytes instanceof Uint8Array && equals6(a.bytes, data.bytes);
27221
+ }
27222
+ }
27223
+ var Digest4 = class {
27224
+ code;
27225
+ size;
27226
+ digest;
27227
+ bytes;
27228
+ /**
27229
+ * Creates a multihash digest.
27230
+ */
27231
+ constructor(code22, size, digest, bytes) {
27232
+ this.code = code22;
27233
+ this.size = size;
27234
+ this.digest = digest;
27235
+ this.bytes = bytes;
27236
+ }
27237
+ };
27238
+ function format4(link4, base23) {
27239
+ const { bytes, version: version2 } = link4;
27240
+ switch (version2) {
27241
+ case 0:
27242
+ return toStringV04(bytes, baseCache4(link4), base23 ?? base58btc4.encoder);
27243
+ default:
27244
+ return toStringV14(bytes, baseCache4(link4), base23 ?? base324.encoder);
27245
+ }
27246
+ }
27247
+ var cache4 = /* @__PURE__ */ new WeakMap();
27248
+ function baseCache4(cid) {
27249
+ const baseCache23 = cache4.get(cid);
27250
+ if (baseCache23 == null) {
27251
+ const baseCache32 = /* @__PURE__ */ new Map();
27252
+ cache4.set(cid, baseCache32);
27253
+ return baseCache32;
27254
+ }
27255
+ return baseCache23;
27256
+ }
27257
+ var CID4 = class _CID4 {
27258
+ code;
27259
+ version;
27260
+ multihash;
27261
+ bytes;
27262
+ "/";
27263
+ /**
27264
+ * @param version - Version of the CID
27265
+ * @param code - Code of the codec content is encoded in, see https://github.com/multiformats/multicodec/blob/master/table.csv
27266
+ * @param multihash - (Multi)hash of the of the content.
27267
+ */
27268
+ constructor(version2, code22, multihash, bytes) {
27269
+ this.code = code22;
27270
+ this.version = version2;
27271
+ this.multihash = multihash;
27272
+ this.bytes = bytes;
27273
+ this["/"] = bytes;
27274
+ }
27275
+ /**
27276
+ * Signalling `cid.asCID === cid` has been replaced with `cid['/'] === cid.bytes`
27277
+ * please either use `CID.asCID(cid)` or switch to new signalling mechanism
27278
+ *
27279
+ * @deprecated
27280
+ */
27281
+ get asCID() {
27282
+ return this;
27283
+ }
27284
+ // ArrayBufferView
27285
+ get byteOffset() {
27286
+ return this.bytes.byteOffset;
27287
+ }
27288
+ // ArrayBufferView
27289
+ get byteLength() {
27290
+ return this.bytes.byteLength;
27291
+ }
27292
+ toV0() {
27293
+ switch (this.version) {
27294
+ case 0: {
27295
+ return this;
27296
+ }
27297
+ case 1: {
27298
+ const { code: code22, multihash } = this;
27299
+ if (code22 !== DAG_PB_CODE4) {
27300
+ throw new Error("Cannot convert a non dag-pb CID to CIDv0");
27301
+ }
27302
+ if (multihash.code !== SHA_256_CODE4) {
27303
+ throw new Error("Cannot convert non sha2-256 multihash CID to CIDv0");
27304
+ }
27305
+ return _CID4.createV0(multihash);
27306
+ }
27307
+ default: {
27308
+ throw Error(`Can not convert CID version ${this.version} to version 0. This is a bug please report`);
27309
+ }
27310
+ }
27311
+ }
27312
+ toV1() {
27313
+ switch (this.version) {
27314
+ case 0: {
27315
+ const { code: code22, digest } = this.multihash;
27316
+ const multihash = create4(code22, digest);
27317
+ return _CID4.createV1(this.code, multihash);
27318
+ }
27319
+ case 1: {
27320
+ return this;
27321
+ }
27322
+ default: {
27323
+ throw Error(`Can not convert CID version ${this.version} to version 1. This is a bug please report`);
27324
+ }
27325
+ }
27326
+ }
27327
+ equals(other) {
27328
+ return _CID4.equals(this, other);
27329
+ }
27330
+ static equals(self, other) {
27331
+ const unknown = other;
27332
+ return unknown != null && self.code === unknown.code && self.version === unknown.version && equals24(self.multihash, unknown.multihash);
27333
+ }
27334
+ toString(base23) {
27335
+ return format4(this, base23);
27336
+ }
27337
+ toJSON() {
27338
+ return { "/": format4(this) };
27339
+ }
27340
+ link() {
27341
+ return this;
27342
+ }
27343
+ [Symbol.toStringTag] = "CID";
27344
+ // Legacy
27345
+ [/* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom")]() {
27346
+ return `CID(${this.toString()})`;
27347
+ }
27348
+ /**
27349
+ * Takes any input `value` and returns a `CID` instance if it was
27350
+ * a `CID` otherwise returns `null`. If `value` is instanceof `CID`
27351
+ * it will return value back. If `value` is not instance of this CID
27352
+ * class, but is compatible CID it will return new instance of this
27353
+ * `CID` class. Otherwise returns null.
27354
+ *
27355
+ * This allows two different incompatible versions of CID library to
27356
+ * co-exist and interop as long as binary interface is compatible.
27357
+ */
27358
+ static asCID(input) {
27359
+ if (input == null) {
27360
+ return null;
27361
+ }
27362
+ const value = input;
27363
+ if (value instanceof _CID4) {
27364
+ return value;
27365
+ } else if (value["/"] != null && value["/"] === value.bytes || value.asCID === value) {
27366
+ const { version: version2, code: code22, multihash, bytes } = value;
27367
+ return new _CID4(version2, code22, multihash, bytes ?? encodeCID4(version2, code22, multihash.bytes));
27368
+ } else if (value[cidSymbol4] === true) {
27369
+ const { version: version2, multihash, code: code22 } = value;
27370
+ const digest = decode44(multihash);
27371
+ return _CID4.create(version2, code22, digest);
27372
+ } else {
27373
+ return null;
27374
+ }
27375
+ }
27376
+ /**
27377
+ * @param version - Version of the CID
27378
+ * @param code - Code of the codec content is encoded in, see https://github.com/multiformats/multicodec/blob/master/table.csv
27379
+ * @param digest - (Multi)hash of the of the content.
27380
+ */
27381
+ static create(version2, code22, digest) {
27382
+ if (typeof code22 !== "number") {
27383
+ throw new Error("String codecs are no longer supported");
27384
+ }
27385
+ if (!(digest.bytes instanceof Uint8Array)) {
27386
+ throw new Error("Invalid digest");
27387
+ }
27388
+ switch (version2) {
27389
+ case 0: {
27390
+ if (code22 !== DAG_PB_CODE4) {
27391
+ throw new Error(`Version 0 CID must use dag-pb (code: ${DAG_PB_CODE4}) block encoding`);
27392
+ } else {
27393
+ return new _CID4(version2, code22, digest, digest.bytes);
27394
+ }
27395
+ }
27396
+ case 1: {
27397
+ const bytes = encodeCID4(version2, code22, digest.bytes);
27398
+ return new _CID4(version2, code22, digest, bytes);
27399
+ }
27400
+ default: {
27401
+ throw new Error("Invalid version");
27402
+ }
27403
+ }
27404
+ }
27405
+ /**
27406
+ * Simplified version of `create` for CIDv0.
27407
+ */
27408
+ static createV0(digest) {
27409
+ return _CID4.create(0, DAG_PB_CODE4, digest);
27410
+ }
27411
+ /**
27412
+ * Simplified version of `create` for CIDv1.
27413
+ *
27414
+ * @param code - Content encoding format code.
27415
+ * @param digest - Multihash of the content.
27416
+ */
27417
+ static createV1(code22, digest) {
27418
+ return _CID4.create(1, code22, digest);
27419
+ }
27420
+ /**
27421
+ * Decoded a CID from its binary representation. The byte array must contain
27422
+ * only the CID with no additional bytes.
27423
+ *
27424
+ * An error will be thrown if the bytes provided do not contain a valid
27425
+ * binary representation of a CID.
27426
+ */
27427
+ static decode(bytes) {
27428
+ const [cid, remainder] = _CID4.decodeFirst(bytes);
27429
+ if (remainder.length !== 0) {
27430
+ throw new Error("Incorrect length");
27431
+ }
27432
+ return cid;
27433
+ }
27434
+ /**
27435
+ * Decoded a CID from its binary representation at the beginning of a byte
27436
+ * array.
27437
+ *
27438
+ * Returns an array with the first element containing the CID and the second
27439
+ * element containing the remainder of the original byte array. The remainder
27440
+ * will be a zero-length byte array if the provided bytes only contained a
27441
+ * binary CID representation.
27442
+ */
27443
+ static decodeFirst(bytes) {
27444
+ const specs = _CID4.inspectBytes(bytes);
27445
+ const prefixSize = specs.size - specs.multihashSize;
27446
+ const multihashBytes = coerce6(bytes.subarray(prefixSize, prefixSize + specs.multihashSize));
27447
+ if (multihashBytes.byteLength !== specs.multihashSize) {
27448
+ throw new Error("Incorrect length");
27449
+ }
27450
+ const digestBytes = multihashBytes.subarray(specs.multihashSize - specs.digestSize);
27451
+ const digest = new Digest4(specs.multihashCode, specs.digestSize, digestBytes, multihashBytes);
27452
+ const cid = specs.version === 0 ? _CID4.createV0(digest) : _CID4.createV1(specs.codec, digest);
27453
+ return [cid, bytes.subarray(specs.size)];
27454
+ }
27455
+ /**
27456
+ * Inspect the initial bytes of a CID to determine its properties.
27457
+ *
27458
+ * Involves decoding up to 4 varints. Typically this will require only 4 to 6
27459
+ * bytes but for larger multicodec code values and larger multihash digest
27460
+ * lengths these varints can be quite large. It is recommended that at least
27461
+ * 10 bytes be made available in the `initialBytes` argument for a complete
27462
+ * inspection.
27463
+ */
27464
+ static inspectBytes(initialBytes) {
27465
+ let offset = 0;
27466
+ const next = () => {
27467
+ const [i, length23] = decode34(initialBytes.subarray(offset));
27468
+ offset += length23;
27469
+ return i;
27470
+ };
27471
+ let version2 = next();
27472
+ let codec = DAG_PB_CODE4;
27473
+ if (version2 === 18) {
27474
+ version2 = 0;
27475
+ offset = 0;
27476
+ } else {
27477
+ codec = next();
27478
+ }
27479
+ if (version2 !== 0 && version2 !== 1) {
27480
+ throw new RangeError(`Invalid CID version ${version2}`);
27481
+ }
27482
+ const prefixSize = offset;
27483
+ const multihashCode = next();
27484
+ const digestSize = next();
27485
+ const size = offset + digestSize;
27486
+ const multihashSize = size - prefixSize;
27487
+ return { version: version2, codec, multihashCode, digestSize, multihashSize, size };
27488
+ }
27489
+ /**
27490
+ * Takes cid in a string representation and creates an instance. If `base`
27491
+ * decoder is not provided will use a default from the configuration. It will
27492
+ * throw an error if encoding of the CID is not compatible with supplied (or
27493
+ * a default decoder).
27494
+ */
27495
+ static parse(source, base23) {
27496
+ const [prefix, bytes] = parseCIDtoBytes4(source, base23);
27497
+ const cid = _CID4.decode(bytes);
27498
+ if (cid.version === 0 && source[0] !== "Q") {
27499
+ throw Error("Version 0 CID string must not include multibase prefix");
27500
+ }
27501
+ baseCache4(cid).set(prefix, source);
27502
+ return cid;
27503
+ }
27504
+ };
27505
+ function parseCIDtoBytes4(source, base23) {
27506
+ switch (source[0]) {
27507
+ // CIDv0 is parsed differently
27508
+ case "Q": {
27509
+ const decoder = base23 ?? base58btc4;
27510
+ return [
27511
+ base58btc4.prefix,
27512
+ decoder.decode(`${base58btc4.prefix}${source}`)
27513
+ ];
27514
+ }
27515
+ case base58btc4.prefix: {
27516
+ const decoder = base23 ?? base58btc4;
27517
+ return [base58btc4.prefix, decoder.decode(source)];
27518
+ }
27519
+ case base324.prefix: {
27520
+ const decoder = base23 ?? base324;
27521
+ return [base324.prefix, decoder.decode(source)];
27522
+ }
27523
+ case base364.prefix: {
27524
+ const decoder = base23 ?? base364;
27525
+ return [base364.prefix, decoder.decode(source)];
27526
+ }
27527
+ default: {
27528
+ if (base23 == null) {
27529
+ throw Error("To parse non base32, base36 or base58btc encoded CID multibase decoder must be provided");
27530
+ }
27531
+ return [source[0], base23.decode(source)];
27532
+ }
27533
+ }
27534
+ }
27535
+ function toStringV04(bytes, cache23, base23) {
27536
+ const { prefix } = base23;
27537
+ if (prefix !== base58btc4.prefix) {
27538
+ throw Error(`Cannot string encode V0 in ${base23.name} encoding`);
27539
+ }
27540
+ const cid = cache23.get(prefix);
27541
+ if (cid == null) {
27542
+ const cid2 = base23.encode(bytes).slice(1);
27543
+ cache23.set(prefix, cid2);
27544
+ return cid2;
27545
+ } else {
27546
+ return cid;
27547
+ }
27548
+ }
27549
+ function toStringV14(bytes, cache23, base23) {
27550
+ const { prefix } = base23;
27551
+ const cid = cache23.get(prefix);
27552
+ if (cid == null) {
27553
+ const cid2 = base23.encode(bytes);
27554
+ cache23.set(prefix, cid2);
27555
+ return cid2;
27556
+ } else {
27557
+ return cid;
27558
+ }
27559
+ }
27560
+ var DAG_PB_CODE4 = 112;
27561
+ var SHA_256_CODE4 = 18;
27562
+ function encodeCID4(version2, code22, multihash) {
27563
+ const codeOffset = encodingLength4(version2);
27564
+ const hashOffset = codeOffset + encodingLength4(code22);
27565
+ const bytes = new Uint8Array(hashOffset + multihash.byteLength);
27566
+ encodeTo4(version2, bytes, 0);
27567
+ encodeTo4(code22, bytes, codeOffset);
27568
+ bytes.set(multihash, hashOffset);
27569
+ return bytes;
27570
+ }
27571
+ var cidSymbol4 = /* @__PURE__ */ Symbol.for("@ipld/js-cid/CID");
27572
+ var code4 = 85;
27573
+ var SHA256_CODE4 = 18;
27574
+ async function computeCid3(bytes) {
27575
+ const digest = create4(SHA256_CODE4, sha256(new Uint8Array(bytes)));
27576
+ return CID4.create(1, code4, digest).toString();
27577
+ }
27578
+ function isCanonicalRawCid4(cidString) {
27579
+ let cid;
27580
+ try {
27581
+ cid = CID4.parse(cidString);
27582
+ } catch {
27583
+ return false;
27584
+ }
27585
+ return cid.version === 1 && cid.code === code4 && cid.multihash.code === SHA256_CODE4 && cid.toString() === cidString;
27586
+ }
27587
+ function isPlainRecord4(value) {
27588
+ const proto = Object.getPrototypeOf(value);
27589
+ return proto === Object.prototype || proto === null;
27590
+ }
27591
+ function assertNoLoneSurrogates4(text) {
27592
+ for (let i = 0; i < text.length; i++) {
27593
+ const unit = text.charCodeAt(i);
27594
+ if (unit >= 56320 && unit <= 57343) {
27595
+ throw new TypeError(
27596
+ `cannot canonicalize string with unpaired low surrogate at index ${i}`
27597
+ );
27598
+ }
27599
+ if (unit >= 55296 && unit <= 56319) {
27600
+ const next = text.charCodeAt(i + 1);
27601
+ if (!(next >= 56320 && next <= 57343)) {
27602
+ throw new TypeError(
27603
+ `cannot canonicalize string with unpaired high surrogate at index ${i}`
27604
+ );
27605
+ }
27606
+ i++;
27607
+ }
27608
+ }
27609
+ }
27610
+ function serializeString4(text) {
27611
+ assertNoLoneSurrogates4(text);
27612
+ return JSON.stringify(text);
27613
+ }
27614
+ function serialize4(value) {
27615
+ if (value === null) return "null";
27616
+ switch (typeof value) {
27617
+ case "boolean":
27618
+ return JSON.stringify(value);
27619
+ case "string":
27620
+ return serializeString4(value);
27621
+ case "number":
27622
+ if (!Number.isFinite(value)) {
27623
+ throw new TypeError(`cannot canonicalize non-finite number: ${value}`);
27624
+ }
27625
+ return JSON.stringify(value);
27626
+ case "object":
27627
+ break;
27628
+ default:
27629
+ throw new TypeError(`cannot canonicalize value of type ${typeof value}`);
27630
+ }
27631
+ if (Array.isArray(value)) {
27632
+ return `[${value.map((item) => serialize4(item)).join(",")}]`;
27633
+ }
27634
+ if (!isPlainRecord4(value)) {
27635
+ throw new TypeError("cannot canonicalize non-plain object");
27636
+ }
27637
+ const keys = Object.keys(value).sort();
27638
+ const members = [];
27639
+ for (const key of keys) {
27640
+ const member = value[key];
27641
+ if (member === void 0) continue;
27642
+ members.push(`${serializeString4(key)}:${serialize4(member)}`);
27643
+ }
27644
+ return `{${members.join(",")}}`;
27645
+ }
27646
+ function canonicalize4(value) {
27647
+ return serialize4(value);
27648
+ }
27649
+ function decodeBase64UrlOrNull4(value) {
27650
+ try {
27651
+ return fromBase64Url4(value);
27652
+ } catch {
27653
+ return null;
27654
+ }
27655
+ }
27656
+ var base64UrlString4 = () => external_exports3.string().refine((value) => decodeBase64UrlOrNull4(value) !== null, {
27657
+ message: "expected strictly-decodable unpadded base64url"
27658
+ });
27659
+ function isCanonicalHttpsOrigin4(value) {
27660
+ let url;
27661
+ try {
27662
+ url = new URL(value);
27663
+ } catch {
27664
+ return false;
27665
+ }
27666
+ return url.protocol === "https:" && url.origin === value;
27667
+ }
27668
+ var sessionJwkCommonFields4 = {
27669
+ alg: external_exports3.string().min(1).optional(),
27670
+ use: external_exports3.string().min(1).optional(),
27671
+ key_ops: external_exports3.array(external_exports3.string().min(1)).optional(),
27672
+ kid: external_exports3.string().min(1).optional(),
27673
+ ext: external_exports3.boolean().optional()
27674
+ };
27675
+ var okpPrivateJwkSchema4 = external_exports3.object({
27676
+ kty: external_exports3.literal("OKP"),
27677
+ crv: external_exports3.string().min(1),
27678
+ x: base64UrlString4(),
27679
+ d: base64UrlString4(),
27680
+ ...sessionJwkCommonFields4
27681
+ }).strict();
27682
+ var ecPrivateJwkSchema4 = external_exports3.object({
27683
+ kty: external_exports3.literal("EC"),
27684
+ crv: external_exports3.string().min(1),
27685
+ x: base64UrlString4(),
27686
+ y: base64UrlString4(),
27687
+ d: base64UrlString4(),
27688
+ ...sessionJwkCommonFields4
27689
+ }).strict();
27690
+ var sessionJwkSchema4 = external_exports3.discriminatedUnion("kty", [
27691
+ okpPrivateJwkSchema4,
27692
+ ecPrivateJwkSchema4
27693
+ ]);
27694
+ var policyTargetSchema4 = external_exports3.object({
27695
+ kind: external_exports3.literal("policy"),
27696
+ policyCid: external_exports3.string().min(1),
27697
+ /** Canonical policy bytes, base64url-encoded (bytes are not JSON). */
27698
+ policyBytes: base64UrlString4()
27699
+ }).strict();
27700
+ var bearerKeyTargetSchema4 = external_exports3.object({
27701
+ kind: external_exports3.literal("bearerKey"),
27702
+ sessionJwk: sessionJwkSchema4
27703
+ }).strict();
27704
+ var recipientDidTargetSchema4 = external_exports3.object({
27705
+ kind: external_exports3.literal("recipientDid"),
27706
+ did: external_exports3.string().regex(/^did:[a-z0-9]+:.+$/, "expected a DID")
27707
+ }).strict();
27708
+ var authorizationTargetSchema4 = external_exports3.discriminatedUnion("kind", [
27709
+ policyTargetSchema4,
27710
+ bearerKeyTargetSchema4,
27711
+ recipientDidTargetSchema4
27712
+ ]);
27713
+ function isCanonicalResourcePath4(value) {
27714
+ if (value.length === 0) return false;
27715
+ if (/[\u0000-\u001f\u007f\\]/.test(value)) return false;
27716
+ if (/%2f|%5c|%2e/i.test(value)) return false;
27717
+ return value.split("/").every((segment) => segment.length > 0 && segment !== "." && segment !== "..");
27718
+ }
27719
+ function isCanonicalPathSegment4(value) {
27720
+ return isCanonicalResourcePath4(value) && !value.includes("/");
27721
+ }
27722
+ var resourceSelectorSchema4 = external_exports3.object({
27723
+ kind: external_exports3.union([external_exports3.literal("exact"), external_exports3.literal("prefix")]),
27724
+ path: external_exports3.string().min(1)
27725
+ }).strict().superRefine((selector, ctx) => {
27726
+ const body = selector.kind === "prefix" && selector.path.endsWith("/") ? selector.path.slice(0, -1) : selector.path;
27727
+ if (!isCanonicalResourcePath4(body)) {
27728
+ ctx.addIssue({
27729
+ code: external_exports3.ZodIssueCode.custom,
27730
+ path: ["path"],
27731
+ message: "expected a canonical resource path (non-empty segments, no . or .. segments, no //, no backslash, no %2f/%5c/%2e, no control chars)"
27732
+ });
27733
+ }
27734
+ });
27735
+ var targetSchema4 = external_exports3.object({
27736
+ origin: external_exports3.string().refine(isCanonicalHttpsOrigin4, {
27737
+ message: "expected a canonical https origin (https://host[:port], nothing else)"
27738
+ }),
27739
+ nodeAudience: external_exports3.string().min(1),
27740
+ spaceId: external_exports3.string().refine(isCanonicalPathSegment4, {
27741
+ message: "expected a single canonical path segment (spaceId joins the resource URI; separators/traversal would alias grants)"
27742
+ }),
27743
+ resource: resourceSelectorSchema4
27744
+ }).strict();
27745
+ var displaySchema4 = external_exports3.object({
27746
+ senderName: external_exports3.string().optional(),
27747
+ filename: external_exports3.string().optional(),
27748
+ recipientHint: external_exports3.string().optional(),
27749
+ /**
27750
+ * Presentation preference only (viewer spec §1): may narrow, never widen;
27751
+ * capabilities always win.
27752
+ */
27753
+ mode: external_exports3.union([external_exports3.literal("document"), external_exports3.literal("source"), external_exports3.literal("folder")]).optional()
27754
+ }).strict();
27755
+ var contentPointerSchema4 = external_exports3.object({
27756
+ cid: external_exports3.string().refine(isCanonicalRawCid4, {
27757
+ message: "expected a canonical CIDv1 raw sha2-256 base32 CID"
27758
+ }),
27759
+ key: external_exports3.string().refine((value) => decodeBase64UrlOrNull4(value)?.length === 32, {
27760
+ message: "expected base64url decoding to exactly 32 bytes"
27761
+ })
27762
+ }).strict();
27763
+ var signatureSchema4 = external_exports3.object({
27764
+ /** did:key of the sender's ed25519 signing key. */
27765
+ signerDid: external_exports3.string().regex(/^did:key:z[1-9A-HJ-NP-Za-km-z]+$/, "expected a did:key"),
27766
+ algorithm: external_exports3.literal("Ed25519"),
27767
+ /** base64url-encoded ed25519 signature over the JCS bytes of all other fields. */
27768
+ value: external_exports3.string().refine((value) => decodeBase64UrlOrNull4(value)?.length === 64, {
27769
+ message: "expected base64url decoding to exactly 64 bytes"
27770
+ })
27771
+ }).strict();
27772
+ var unsignedShareEnvelopeSchema4 = external_exports3.object({
27773
+ version: external_exports3.literal(1),
27774
+ shareId: external_exports3.string().min(1),
27775
+ /** Full signed delegation chain, opaque serialized form. */
27776
+ delegation: external_exports3.string().min(1),
27777
+ authorizationTarget: authorizationTargetSchema4,
27778
+ target: targetSchema4,
27779
+ display: displaySchema4,
27780
+ /** ISO 8601 UTC datetime. Advisory here; enforcement is the delegation's. */
27781
+ expiry: external_exports3.string().datetime(),
27782
+ /** Bearer-slice sealed-content pointer (see contentPointerSchema). */
27783
+ content: contentPointerSchema4.optional()
27784
+ }).strict();
27785
+ var shareEnvelopeSchema4 = unsignedShareEnvelopeSchema4.extend({ signature: signatureSchema4 }).strict();
27786
+ var recipientMatcherSchema4 = external_exports3.discriminatedUnion("kind", [
27787
+ external_exports3.object({ kind: external_exports3.literal("exactEmail"), value: external_exports3.string().min(3).regex(/^[^@\s]+@[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$/) }).strict(),
27788
+ external_exports3.object({ kind: external_exports3.literal("emailDomain"), value: external_exports3.string().regex(/^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$/) }).strict(),
27789
+ external_exports3.object({ kind: external_exports3.literal("recipientDid"), value: external_exports3.string().regex(/^did:[a-z0-9]+:.+$/) }).strict(),
27790
+ external_exports3.object({ kind: external_exports3.literal("policyDigest"), value: external_exports3.string().regex(/^[A-Za-z0-9_-]{43}$/) }).strict(),
27791
+ external_exports3.object({ kind: external_exports3.literal("bearer") }).strict()
27792
+ ]);
27793
+ var shareActionSchema4 = external_exports3.union([external_exports3.literal("read"), external_exports3.literal("list"), external_exports3.literal("edit")]);
27794
+ var kvContentSourceSchema4 = external_exports3.object({
27795
+ kind: external_exports3.literal("kv"),
27796
+ space: external_exports3.string().min(1),
27797
+ path: external_exports3.string().min(1),
27798
+ action: external_exports3.literal("tinycloud.kv/get")
27799
+ }).strict();
27800
+ var sqlContentSourceSchema4 = external_exports3.object({
27801
+ kind: external_exports3.literal("sql"),
27802
+ space: external_exports3.string().min(1),
27803
+ database: external_exports3.string().min(1),
27804
+ path: external_exports3.string().min(1),
27805
+ statement: external_exports3.string().min(1),
27806
+ arguments: external_exports3.record(external_exports3.string(), external_exports3.number().int()),
27807
+ argumentsDigest: external_exports3.string().regex(/^[A-Za-z0-9_-]{43}$/),
27808
+ action: external_exports3.literal("tinycloud.sql/read")
27809
+ }).strict();
27810
+ var contentSourceSchema4 = external_exports3.discriminatedUnion("kind", [kvContentSourceSchema4, sqlContentSourceSchema4]);
27811
+ var v2TargetSchema4 = external_exports3.object({
27812
+ origin: external_exports3.string().refine(isCanonicalHttpsOrigin4, { message: "expected a canonical https origin" }),
27813
+ nodeAudience: external_exports3.string().min(1),
27814
+ spaceId: external_exports3.string().refine(isCanonicalPathSegment4, { message: "expected a canonical space id" })
27815
+ }).strict();
27816
+ var shareDecryptionSchema4 = external_exports3.object({
27817
+ networkId: external_exports3.string().min(1),
27818
+ action: external_exports3.literal("tinycloud.encryption/decrypt")
27819
+ }).strict();
27820
+ var ownerAuthoritySchema4 = external_exports3.object({
27821
+ registrationCid: external_exports3.string().min(1),
27822
+ shareCid: external_exports3.string().min(1),
27823
+ envelopeCid: external_exports3.string().min(1),
27824
+ enforcementDelegation: external_exports3.record(external_exports3.string(), external_exports3.unknown()),
27825
+ outerEnvelope: external_exports3.record(external_exports3.string(), external_exports3.unknown()),
27826
+ /** Node-signed registration evidence; required by trusted policy adapters. */
27827
+ registrationReceipt: external_exports3.object({
27828
+ registration: external_exports3.record(external_exports3.string(), external_exports3.unknown()),
27829
+ proof: external_exports3.record(external_exports3.string(), external_exports3.unknown())
27830
+ }).strict().optional()
27831
+ }).strict();
27832
+ var contentMetadataSchema4 = external_exports3.object({
27833
+ mediaType: external_exports3.string().min(1).max(128).optional(),
27834
+ byteLength: external_exports3.number().int().nonnegative().max(100 * 1024 * 1024).optional(),
27835
+ filename: external_exports3.string().min(1).max(255).optional(),
27836
+ encoding: external_exports3.literal("utf-8").optional(),
27837
+ /** Encrypted presentation discriminator. The fixed entry point is index.html. */
27838
+ artifact: external_exports3.literal("html").optional()
27839
+ }).strict();
27840
+ var deliveryEmailSchema4 = external_exports3.string().email();
27841
+ var unsignedShareEnvelopeV2BaseSchema4 = external_exports3.object({
27842
+ version: external_exports3.literal(2),
27843
+ shareId: external_exports3.string().min(1),
27844
+ recipientMatcher: recipientMatcherSchema4,
27845
+ deliveryEmail: deliveryEmailSchema4.optional(),
27846
+ actions: external_exports3.array(shareActionSchema4).min(1).max(3),
27847
+ resource: resourceSelectorSchema4,
27848
+ target: v2TargetSchema4,
27849
+ delegationCid: external_exports3.string().min(1),
27850
+ authorityMaterialHandle: external_exports3.string().min(1),
27851
+ authorityMaterialDigest: external_exports3.string().regex(/^[A-Za-z0-9_-]{43}$/),
27852
+ decryption: shareDecryptionSchema4.optional(),
27853
+ contentSource: contentSourceSchema4,
27854
+ contentSourceDigest: external_exports3.string().regex(/^[A-Za-z0-9_-]{43}$/),
27855
+ authorizationTarget: authorizationTargetSchema4,
27856
+ display: displaySchema4,
27857
+ expiry: external_exports3.string().datetime(),
27858
+ encrypted: external_exports3.boolean(),
27859
+ content: contentPointerSchema4.optional(),
27860
+ metadata: contentMetadataSchema4,
27861
+ ownerAuthority: ownerAuthoritySchema4.optional()
27862
+ }).strict();
27863
+ function validateV2Invariants4(value, ctx) {
27864
+ const actions = [...value.actions];
27865
+ if (new Set(actions).size !== actions.length) ctx.addIssue({ code: external_exports3.ZodIssueCode.custom, path: ["actions"], message: "actions must be unique" });
27866
+ if (actions.some((action, index) => action !== ["read", "list", "edit"].filter((candidate) => actions.includes(candidate))[index])) ctx.addIssue({ code: external_exports3.ZodIssueCode.custom, path: ["actions"], message: "actions must be canonically ordered" });
27867
+ if (!value.encrypted && value.recipientMatcher.kind !== "policyDigest") ctx.addIssue({ code: external_exports3.ZodIssueCode.custom, path: ["recipientMatcher"], message: "safe plaintext must carry only a matcher digest" });
27868
+ if (!value.encrypted && value.authorizationTarget.kind !== "policy") ctx.addIssue({ code: external_exports3.ZodIssueCode.custom, path: ["encrypted"], message: "unencrypted content requires a policy target" });
27869
+ if (!value.encrypted && value.content !== void 0) ctx.addIssue({ code: external_exports3.ZodIssueCode.custom, path: ["content"], message: "policy-only plaintext cannot carry content" });
27870
+ if (value.encrypted && (value.metadata.mediaType === void 0 || value.metadata.filename === void 0 || value.metadata.byteLength === void 0)) ctx.addIssue({ code: external_exports3.ZodIssueCode.custom, path: ["metadata"], message: "encrypted shares must describe their content" });
27871
+ if (!value.encrypted && Object.keys(value.metadata).length !== 0) ctx.addIssue({ code: external_exports3.ZodIssueCode.custom, path: ["metadata"], message: "policy-only plaintext cannot describe content" });
27872
+ if (!value.encrypted && value.metadata.encoding !== void 0) ctx.addIssue({ code: external_exports3.ZodIssueCode.custom, path: ["metadata", "encoding"], message: "policy-only plaintext cannot carry content encoding" });
27873
+ if (value.metadata.artifact === "html" && (!value.encrypted || value.resource.kind !== "prefix" || !value.actions.includes("read") || !value.actions.includes("list"))) ctx.addIssue({ code: external_exports3.ZodIssueCode.custom, path: ["metadata", "artifact"], message: "html artifacts require an encrypted readable prefix" });
27874
+ if (!value.encrypted && (value.display.senderName !== void 0 || value.display.filename !== void 0 || value.display.recipientHint !== void 0)) ctx.addIssue({ code: external_exports3.ZodIssueCode.custom, path: ["display"], message: "policy-only plaintext cannot carry display metadata" });
27875
+ if (!value.encrypted && value.deliveryEmail !== void 0) ctx.addIssue({ code: external_exports3.ZodIssueCode.custom, path: ["deliveryEmail"], message: "policy-only plaintext cannot carry delivery metadata" });
27876
+ if (value.recipientMatcher.kind === "exactEmail" && value.deliveryEmail !== void 0 && value.deliveryEmail !== value.recipientMatcher.value) ctx.addIssue({ code: external_exports3.ZodIssueCode.custom, path: ["deliveryEmail"], message: "delivery email must match the exact matcher" });
27877
+ if (value.recipientMatcher.kind === "emailDomain" && value.deliveryEmail !== void 0 && value.deliveryEmail.toLowerCase().endsWith(`@${value.recipientMatcher.value}`) === false) ctx.addIssue({ code: external_exports3.ZodIssueCode.custom, path: ["deliveryEmail"], message: "delivery email must belong to the matcher domain" });
27878
+ if (value.contentSource.kind === "kv" && value.contentSource.action !== "tinycloud.kv/get") ctx.addIssue({ code: external_exports3.ZodIssueCode.custom, path: ["contentSource"], message: "source action mismatch" });
27879
+ if (value.contentSource.kind === "sql" && value.contentSource.action !== "tinycloud.sql/read") ctx.addIssue({ code: external_exports3.ZodIssueCode.custom, path: ["contentSource"], message: "source action mismatch" });
27880
+ }
27881
+ var unsignedShareEnvelopeV2Schema4 = unsignedShareEnvelopeV2BaseSchema4.superRefine(validateV2Invariants4);
27882
+ var shareEnvelopeV2Schema4 = unsignedShareEnvelopeV2BaseSchema4.extend({ signature: signatureSchema4 }).strict().superRefine(validateV2Invariants4);
27883
+ var unifiedResourceSchema4 = external_exports3.string().refine((value) => {
27884
+ const marker = value.indexOf("/kv/");
27885
+ if (marker < 1) return false;
27886
+ const space = value.slice(0, marker);
27887
+ const legacy = space.startsWith("tinycloud://");
27888
+ if (legacy ? /[:/?#%]/.test(space.slice("tinycloud://".length)) : !space.startsWith("tinycloud:") || /[/?#%]/.test(space)) return false;
27889
+ const path = value.slice(marker + 4);
27890
+ return !path.startsWith("/") && !path.endsWith("/") && !path.includes("//") && path.split("/").every((segment) => segment.length > 0 && segment !== "." && segment !== "..");
27891
+ }, { message: "expected canonical TinyCloud KV resource" });
27892
+ var unifiedEncryptionNetworkSchema4 = external_exports3.string().refine((value) => {
27893
+ if (!value.startsWith("urn:tinycloud:encryption:")) return false;
27894
+ const rest = value.slice("urn:tinycloud:encryption:".length);
27895
+ const separator = rest.lastIndexOf(":");
27896
+ const owner = separator < 0 ? "" : rest.slice(0, separator);
27897
+ const network = separator < 0 ? "" : rest.slice(separator + 1);
27898
+ return owner.startsWith("did:") && owner.length > 4 && network.length > 0 && !/[:/%?#\s]/.test(network);
27899
+ }, { message: "expected canonical TinyCloud encryption network" });
27900
+ var unifiedKvCapabilitySchema4 = external_exports3.object({
27901
+ kind: external_exports3.literal("kv"),
27902
+ resource: unifiedResourceSchema4,
27903
+ selector: external_exports3.union([external_exports3.literal("exact"), external_exports3.literal("prefix")]),
27904
+ actions: external_exports3.array(external_exports3.union([
27905
+ external_exports3.literal("tinycloud.kv/get"),
27906
+ external_exports3.literal("tinycloud.kv/list"),
27907
+ external_exports3.literal("tinycloud.kv/metadata"),
27908
+ external_exports3.literal("tinycloud.kv/put")
27909
+ ])).min(1)
27910
+ }).strict();
27911
+ var unifiedEncryptionCapabilitySchema4 = external_exports3.object({
27912
+ kind: external_exports3.literal("encryption"),
27913
+ resource: unifiedEncryptionNetworkSchema4,
27914
+ action: external_exports3.literal("tinycloud.encryption/decrypt")
27915
+ }).strict();
27916
+ var unifiedCapabilitySchema4 = external_exports3.union([unifiedKvCapabilitySchema4, unifiedEncryptionCapabilitySchema4]);
27917
+ var unifiedContentSourceSchema4 = external_exports3.object({
27918
+ shareId: external_exports3.string().min(1),
27919
+ kvResource: unifiedResourceSchema4,
27920
+ selector: external_exports3.union([external_exports3.literal("exact"), external_exports3.literal("prefix")]),
27921
+ encryptionNetwork: unifiedEncryptionNetworkSchema4,
27922
+ encryptedSymmetricKeyDigestHex: external_exports3.string().regex(/^[0-9a-f]{64}$/),
27923
+ keyVersion: external_exports3.number().int().positive(),
27924
+ mode: external_exports3.union([external_exports3.literal("mutable"), external_exports3.literal("immutable")]),
27925
+ initialCiphertextDigestHex: external_exports3.string().regex(/^[0-9a-f]{64}$/).optional()
27926
+ }).strict();
27927
+ var unifiedPolicyV1Schema4 = external_exports3.object({
27928
+ schema: external_exports3.literal("xyz.tinycloud.policy/policy/v1"),
27929
+ policyId: external_exports3.string().regex(/^pol_[a-z2-7]+$/),
27930
+ ownerDid: external_exports3.string().min(1),
27931
+ createdAt: external_exports3.string().datetime({ offset: true }),
27932
+ expiresAt: external_exports3.string().datetime({ offset: true }).optional(),
27933
+ contentSource: unifiedContentSourceSchema4,
27934
+ capabilityCeiling: external_exports3.array(unifiedCapabilitySchema4).min(2),
27935
+ signature: external_exports3.object({ suite: external_exports3.string().min(1), signerDid: external_exports3.string().min(1), value: external_exports3.string().min(1) }).strict()
27936
+ }).strict();
27937
+ var policyCredentialRequirementV1Schema4 = external_exports3.object({
27938
+ type: external_exports3.literal("TinyCloudPolicyCredentialRequirement"),
27939
+ version: external_exports3.literal(1),
27940
+ requirementDigest: external_exports3.string().regex(/^[A-Za-z0-9_-]{43}$/),
27941
+ descriptorDigest: external_exports3.string().regex(/^[A-Za-z0-9_-]{43}$/),
27942
+ issuerDid: external_exports3.string().min(1),
27943
+ issuerKid: external_exports3.string().min(1),
27944
+ profile: external_exports3.object({ id: external_exports3.string().min(1), version: external_exports3.literal(1) }).strict(),
27945
+ credentialType: external_exports3.object({ id: external_exports3.string().min(1), version: external_exports3.literal(1) }).strict()
27946
+ }).strict();
27947
+ var unifiedPolicyV2Schema4 = external_exports3.object({
27948
+ schema: external_exports3.literal("xyz.tinycloud.policy/policy/v2"),
27949
+ policyId: external_exports3.string().regex(/^pol_[a-z2-7]+$/),
27950
+ ownerDid: external_exports3.string().min(1),
27951
+ createdAt: external_exports3.string().datetime({ offset: true }),
27952
+ expiresAt: external_exports3.string().datetime({ offset: true }).optional(),
27953
+ contentSource: unifiedContentSourceSchema4,
27954
+ capabilityCeiling: external_exports3.array(unifiedCapabilitySchema4).min(2),
27955
+ credentialRequirement: policyCredentialRequirementV1Schema4,
27956
+ signature: external_exports3.object({ suite: external_exports3.literal("Ed25519"), signerDid: external_exports3.string().min(1), value: external_exports3.string().min(1) }).strict()
27957
+ }).strict();
27958
+ var unifiedPolicySchema4 = external_exports3.discriminatedUnion("schema", [
27959
+ unifiedPolicyV1Schema4,
27960
+ unifiedPolicyV2Schema4
27961
+ ]);
27962
+ var unifiedRootSchema4 = external_exports3.object({
27963
+ cid: external_exports3.string().min(1),
27964
+ authorization: external_exports3.string().regex(/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/),
27965
+ role: external_exports3.union([external_exports3.literal("policy-authority"), external_exports3.literal("policy-enforcement")])
27966
+ }).strict();
27967
+ var attestedEnforcerBindingV2Schema4 = external_exports3.object({
27968
+ schema: external_exports3.literal("xyz.tinycloud.policy/attested-enforcer/v2"),
27969
+ enforcerDid: external_exports3.string().regex(/^did:key:z[1-9A-HJ-NP-Za-km-z]+$/),
27970
+ nodeAudience: external_exports3.string().min(1),
27971
+ attestationBindingDigestHex: external_exports3.string().regex(/^[0-9a-f]{64}$/),
27972
+ issuedAt: external_exports3.string().datetime({ offset: true }),
27973
+ expiresAt: external_exports3.string().datetime({ offset: true }),
27974
+ signature: external_exports3.object({ suite: external_exports3.literal("Ed25519"), signerDid: external_exports3.string().min(1), value: base64UrlString4() }).strict()
27975
+ }).strict();
27976
+ var v3TargetSchema4 = external_exports3.object({
27977
+ origin: external_exports3.string().refine(isCanonicalHttpsOrigin4, { message: "expected a canonical https origin" }),
27978
+ nodeAudience: external_exports3.string().min(1),
27979
+ spaceId: external_exports3.string().refine(isCanonicalPathSegment4, { message: "expected a canonical space id" })
27980
+ }).strict();
27981
+ var ARTIFACT_ID_PATTERN4 = /^[a-z0-9][a-z0-9_-]{2,62}$/;
27982
+ var artifactPinSchema4 = external_exports3.object({
27983
+ v: external_exports3.literal(1),
27984
+ artifactId: external_exports3.string().regex(ARTIFACT_ID_PATTERN4),
27985
+ version: external_exports3.number().int().min(1).max(Number.MAX_SAFE_INTEGER),
27986
+ /** SHA-256 (lowercase hex) of the exact `manifest.json` bytes. The manifest itself stays an owner-side record. */
27987
+ manifestSha256: external_exports3.string().regex(/^[0-9a-f]{64}$/),
27988
+ /** An addressed share reads one exact file, so exactly one entry: the stored bytes (ciphertext) it will fetch. */
27989
+ files: external_exports3.array(external_exports3.object({
27990
+ path: external_exports3.string().min(1).max(255),
27991
+ sha256: external_exports3.string().regex(/^[0-9a-f]{64}$/),
27992
+ bytes: external_exports3.number().int().nonnegative()
27993
+ }).strict()).length(1)
27994
+ }).strict();
27995
+ var unsignedShareEnvelopeV3BaseSchema4 = external_exports3.object({
27996
+ version: external_exports3.literal(3),
27997
+ shareId: external_exports3.string().min(1),
27998
+ recipientMatcher: recipientMatcherSchema4,
27999
+ deliveryEmail: deliveryEmailSchema4.optional(),
28000
+ actions: external_exports3.array(shareActionSchema4).min(1).max(3),
28001
+ resource: resourceSelectorSchema4,
28002
+ target: v3TargetSchema4,
28003
+ policy: unifiedPolicySchema4,
28004
+ policyCid: external_exports3.string().min(1),
28005
+ policyRoot: unifiedRootSchema4,
28006
+ enforcementRoot: unifiedRootSchema4,
28007
+ attestedEnforcerBinding: attestedEnforcerBindingV2Schema4,
28008
+ contentSource: unifiedContentSourceSchema4,
28009
+ contentSourceDigestHex: external_exports3.string().regex(/^[0-9a-f]{64}$/),
28010
+ encryptionNetwork: unifiedEncryptionNetworkSchema4,
28011
+ expiry: external_exports3.string().datetime({ offset: true }),
28012
+ display: displaySchema4,
28013
+ encrypted: external_exports3.literal(true),
28014
+ metadata: contentMetadataSchema4,
28015
+ /**
28016
+ * TC-1428: an owner-signed statement that this share reads one write-once artifact version. Additive: absent on
28017
+ * every other share, and covered by the envelope signature because the signature spans the whole unsigned object.
28018
+ * The shape is checked here; its binding to the content source is `verifyArtifactShare` in share-sdk.
28019
+ */
28020
+ artifactPin: artifactPinSchema4.optional()
28021
+ }).strict();
28022
+ function validateV3Invariants4(value, ctx) {
28023
+ const actions = [...value.actions];
28024
+ if (new Set(actions).size !== actions.length || actions.some((action, index) => action !== ["read", "list", "edit"].filter((candidate) => actions.includes(candidate))[index])) {
28025
+ ctx.addIssue({ code: external_exports3.ZodIssueCode.custom, path: ["actions"], message: "actions must be unique and canonically ordered" });
28026
+ }
28027
+ if (value.policyRoot.role !== "policy-authority" || value.enforcementRoot.role !== "policy-enforcement") {
28028
+ ctx.addIssue({ code: external_exports3.ZodIssueCode.custom, path: ["policyRoot", "role"], message: "root roles are fixed" });
28029
+ }
28030
+ if (value.policyCid.length === 0 || value.policyCid === value.policyRoot.cid || value.policyCid === value.enforcementRoot.cid) {
28031
+ ctx.addIssue({ code: external_exports3.ZodIssueCode.custom, path: ["policyCid"], message: "policy CID must be distinct from both roots" });
28032
+ }
28033
+ if (value.contentSource.encryptionNetwork !== value.encryptionNetwork) {
28034
+ ctx.addIssue({ code: external_exports3.ZodIssueCode.custom, path: ["encryptionNetwork"], message: "encryption network is not bound to the source" });
28035
+ }
28036
+ if (value.attestedEnforcerBinding.nodeAudience !== value.target.nodeAudience || value.attestedEnforcerBinding.signature.signerDid !== value.attestedEnforcerBinding.nodeAudience || Date.parse(value.attestedEnforcerBinding.expiresAt) < Date.parse(value.expiry)) {
28037
+ ctx.addIssue({ code: external_exports3.ZodIssueCode.custom, path: ["attestedEnforcerBinding"], message: "enforcer binding does not cover the target and share lifetime" });
28038
+ }
28039
+ if (value.policy.contentSource.shareId !== value.contentSource.shareId || value.policy.contentSource.kvResource !== value.contentSource.kvResource || value.policy.contentSource.selector !== value.contentSource.selector || value.policy.contentSource.encryptionNetwork !== value.encryptionNetwork || value.policy.contentSource.encryptedSymmetricKeyDigestHex !== value.contentSource.encryptedSymmetricKeyDigestHex || value.policy.contentSource.keyVersion !== value.contentSource.keyVersion || value.policy.contentSource.mode !== value.contentSource.mode || value.policy.contentSource.initialCiphertextDigestHex !== value.contentSource.initialCiphertextDigestHex) {
28040
+ ctx.addIssue({ code: external_exports3.ZodIssueCode.custom, path: ["contentSource"], message: "content source is not bound to policy" });
28041
+ }
28042
+ if (value.policy.signature.suite !== "Ed25519" || value.policy.signature.signerDid !== value.policy.ownerDid) {
28043
+ ctx.addIssue({ code: external_exports3.ZodIssueCode.custom, path: ["policy", "signature"], message: "policy must be signed by its owner" });
28044
+ }
28045
+ const kvCapabilities = value.policy.capabilityCeiling.filter((capability) => capability.kind === "kv");
28046
+ const decryptCapabilities = value.policy.capabilityCeiling.filter((capability) => capability.kind === "encryption" && capability.resource === value.encryptionNetwork && capability.action === "tinycloud.encryption/decrypt");
28047
+ if (value.policy.capabilityCeiling.length !== 2 || kvCapabilities.length !== 1 || decryptCapabilities.length !== 1 || kvCapabilities[0]?.resource !== value.contentSource.kvResource || kvCapabilities[0]?.selector !== value.contentSource.selector) {
28048
+ ctx.addIssue({ code: external_exports3.ZodIssueCode.custom, path: ["policy", "capabilityCeiling"], message: "policy ceiling must contain exact decrypt network" });
28049
+ }
28050
+ }
28051
+ var unsignedShareEnvelopeV3Schema4 = unsignedShareEnvelopeV3BaseSchema4.superRefine(validateV3Invariants4);
28052
+ var shareEnvelopeV3Schema4 = unsignedShareEnvelopeV3BaseSchema4.extend({ signature: signatureSchema4 }).strict().superRefine(validateV3Invariants4);
28053
+ var KEY_LENGTH3 = 32;
28054
+ var MAX_INLINE_BYTES4 = 256 * 1024;
28055
+ function assertCanonicalCid3(cidString) {
28056
+ const cid = CID4.parse(cidString);
28057
+ if (cid.version !== 1 || cid.code !== code4 || cid.multihash.code !== 18 || // sha2-256 (0x12) only, at the link layer too
28058
+ cid.toString() !== cidString) {
28059
+ throw new TypeError(`not a canonical CIDv1 raw sha2-256 base32 CID: ${cidString}`);
28060
+ }
28061
+ }
28062
+ async function parseSealedInlineShareUrl3(url, options = {}) {
28063
+ const parsed = new URL(url);
28064
+ if (parsed.protocol !== "https:" || parsed.username !== "" || parsed.password !== "") throw new TypeError("sealed inline share URL must be canonical HTTPS without userinfo");
28065
+ if (!isCanonicalHttpsOrigin4(parsed.origin) || options.expectedOrigin !== void 0 && parsed.origin !== options.expectedOrigin) throw new TypeError("sealed inline share URL origin is not trusted");
28066
+ if (parsed.pathname !== "/s/inline" || parsed.search !== "") throw new TypeError("not a Node sealed-inline share URL");
28067
+ if (url !== `${parsed.origin}/s/inline${parsed.hash}`) throw new TypeError("sealed inline share URL is not lexically canonical");
28068
+ const prefix = "#v=2&p=";
28069
+ if (!parsed.hash.startsWith(prefix)) throw new TypeError("sealed inline URL is missing its canonical fragment");
28070
+ const encoded = parsed.hash.slice(prefix.length);
28071
+ if (encoded.length === 0 || parsed.hash !== `${prefix}${encoded}`) throw new TypeError("sealed inline URL fragment is not canonical");
28072
+ let payloadBytes;
28073
+ try {
28074
+ payloadBytes = fromBase64Url4(encoded);
28075
+ } catch {
28076
+ throw new TypeError("sealed inline payload is not canonical base64url");
28077
+ }
28078
+ if (payloadBytes.byteLength === 0 || payloadBytes.byteLength > MAX_INLINE_BYTES4 * 2) throw new TypeError("sealed inline payload is too large");
28079
+ const payloadText = new TextDecoder("utf-8", { fatal: true }).decode(payloadBytes);
28080
+ let value;
28081
+ try {
28082
+ value = JSON.parse(payloadText);
28083
+ } catch {
28084
+ throw new TypeError("sealed inline payload is not valid JSON");
28085
+ }
28086
+ if (typeof value !== "object" || value === null || Array.isArray(value) || canonicalize4(value) !== payloadText) throw new TypeError("sealed inline payload is not canonical JSON");
28087
+ const record2 = value;
28088
+ if (Object.keys(record2).length !== 4 || record2.v !== 2 || typeof record2.c !== "string" || typeof record2.cid !== "string" || typeof record2.k !== "string") throw new TypeError("sealed inline payload has invalid fields");
28089
+ let ciphertext;
28090
+ let key32;
28091
+ try {
28092
+ ciphertext = fromBase64Url4(record2.c);
28093
+ key32 = fromBase64Url4(record2.k);
28094
+ } catch {
28095
+ throw new TypeError("sealed inline payload has invalid base64url material");
28096
+ }
28097
+ if (ciphertext.byteLength === 0 || ciphertext.byteLength > MAX_INLINE_BYTES4) throw new TypeError("sealed inline ciphertext is outside the allowed size");
28098
+ if (key32.byteLength !== KEY_LENGTH3) throw new TypeError("sealed inline key must be 32 bytes");
28099
+ assertCanonicalCid3(record2.cid);
28100
+ if (await computeCid3(ciphertext) !== record2.cid) throw new TypeError("sealed inline ciphertext does not match its CID");
28101
+ return { kind: "inline", ciphertextCid: record2.cid, ciphertext, key32 };
28102
+ }
28103
+ var SHORT_LINK_ID_PATTERN = /^[a-z2-7]{26}$/;
28104
+ function assertShortLinkId(id) {
28105
+ if (!SHORT_LINK_ID_PATTERN.test(id)) throw new TypeError("short link id must be 26 lowercase base32 characters");
28106
+ }
28107
+ function parseShortShareUrl(url, options = {}) {
28108
+ let parsed;
28109
+ try {
28110
+ parsed = new URL(url);
28111
+ } catch {
28112
+ throw new TypeError("short share URL is not a URL");
28113
+ }
28114
+ if (parsed.protocol !== "https:" || parsed.username !== "" || parsed.password !== "") throw new TypeError("short share URL must be canonical HTTPS without userinfo");
28115
+ if (!isCanonicalHttpsOrigin4(parsed.origin) || options.expectedOrigin !== void 0 && parsed.origin !== options.expectedOrigin) throw new TypeError("short share URL origin is not trusted");
28116
+ if (parsed.search !== "") throw new TypeError("short share URL must not have a query string");
28117
+ const match = /^\/s\/([A-Za-z2-7]{26})$/.exec(parsed.pathname);
28118
+ if (match === null) throw new TypeError("not a short share URL path");
28119
+ const id = match[1].toLowerCase();
28120
+ const fragment = /^#v=3&k=([A-Za-z0-9_-]{43})&c=([a-z2-7]+)$/.exec(parsed.hash);
28121
+ if (fragment === null) throw new TypeError("short share URL fragment is not canonical");
28122
+ const k = fragment[1];
28123
+ const ciphertextCid = fragment[2];
28124
+ if (url !== `${parsed.origin}${parsed.pathname}${parsed.hash}`) throw new TypeError("short share URL is not lexically canonical");
28125
+ let key32;
28126
+ try {
28127
+ key32 = fromBase64Url4(k);
28128
+ } catch {
28129
+ throw new TypeError("short share URL key is not canonical base64url");
28130
+ }
28131
+ if (key32.byteLength !== KEY_LENGTH3) throw new TypeError("short share URL key must be 32 bytes");
28132
+ try {
28133
+ assertCanonicalCid3(ciphertextCid);
28134
+ } catch {
28135
+ throw new TypeError("short share URL CID is not canonical");
28136
+ }
28137
+ return { kind: "short", origin: parsed.origin, id, k, key32, ciphertextCid };
28138
+ }
28139
+ async function splitInlineToShort(inlineUrl, id) {
28140
+ assertShortLinkId(id);
28141
+ const inline = await parseSealedInlineShareUrl3(inlineUrl);
28142
+ const origin = new URL(inlineUrl).origin;
28143
+ return `${origin}/s/${id}#v=3&k=${toBase64Url3(inline.key32)}&c=${inline.ciphertextCid}`;
28144
+ }
28145
+ async function rebuildInlineFromShort(shortUrl, ciphertextB64Url) {
28146
+ const short = parseShortShareUrl(shortUrl);
28147
+ let ciphertext;
28148
+ try {
28149
+ ciphertext = fromBase64Url4(ciphertextB64Url);
28150
+ } catch {
28151
+ throw new TypeError("short link ciphertext is not canonical base64url");
28152
+ }
28153
+ if (ciphertext.byteLength === 0 || ciphertext.byteLength > MAX_INLINE_BYTES4) throw new TypeError("short link ciphertext is outside the allowed size");
28154
+ if (await computeCid3(ciphertext) !== short.ciphertextCid) throw new TypeError("short link ciphertext does not match the link's CID");
28155
+ return { v: 2, c: ciphertextB64Url, cid: short.ciphertextCid, k: short.k };
28156
+ }
28157
+
28158
+ // src/share/short-links.ts
28159
+ var MAX_SHORT_LINK_BYTES = 128 * 1024;
28160
+ var REQUEST_TIMEOUT_MS = 1e4;
28161
+ var DELETE_TOKEN = /^[A-Za-z0-9_-]{43}$/;
28162
+ var ShortLinkError = class extends Error {
28163
+ constructor(code5, message, options) {
28164
+ super(message, options);
28165
+ this.code = code5;
28166
+ this.name = "ShortLinkError";
28167
+ }
28168
+ };
28169
+ function shortLinkTokenKey(shareId) {
28170
+ return `xyz.tinycloud.share/shares/${shareId}/.short-link.json`;
28171
+ }
28172
+ async function readCapped(response, max) {
28173
+ if (response.body === null) return new Uint8Array(0);
28174
+ const reader = response.body.getReader();
28175
+ const chunks = [];
28176
+ let total = 0;
28177
+ for (; ; ) {
28178
+ const { done, value } = await reader.read();
28179
+ if (done) break;
28180
+ total += value.byteLength;
28181
+ if (total > max) {
28182
+ await reader.cancel().catch(() => void 0);
28183
+ throw new ShortLinkError("too-large", "the short-link service returned too many bytes");
28184
+ }
28185
+ chunks.push(value);
28186
+ }
28187
+ const bytes = new Uint8Array(total);
28188
+ let offset = 0;
28189
+ for (const chunk of chunks) {
28190
+ bytes.set(chunk, offset);
28191
+ offset += chunk.byteLength;
28192
+ }
28193
+ return bytes;
28194
+ }
28195
+ function parseShortLinkRecord(bytes) {
28196
+ let value;
28197
+ try {
28198
+ value = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes));
28199
+ } catch {
28200
+ return void 0;
28201
+ }
28202
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
28203
+ const record2 = value;
28204
+ if (typeof record2.id !== "string" || !SHORT_LINK_ID_PATTERN.test(record2.id)) return void 0;
28205
+ if (typeof record2.deleteToken !== "string" || !DELETE_TOKEN.test(record2.deleteToken)) return void 0;
28206
+ return { id: record2.id, deleteToken: record2.deleteToken };
28207
+ }
28208
+ function serializeShortLinkRecord(record2) {
28209
+ return new TextEncoder().encode(JSON.stringify({ id: record2.id, deleteToken: record2.deleteToken }));
28210
+ }
28211
+ function request(init, timeoutMs) {
28212
+ return { ...init, credentials: "omit", redirect: "error", referrerPolicy: "no-referrer", signal: AbortSignal.timeout(timeoutMs) };
28213
+ }
28214
+ async function send(fetchFn, url, init, timeoutMs) {
28215
+ try {
28216
+ return await fetchFn(url, request(init, timeoutMs));
28217
+ } catch (error) {
28218
+ throw new ShortLinkError("unavailable", "the short-link service could not be reached", { cause: error });
28219
+ }
28220
+ }
28221
+ function statusError(response) {
28222
+ if (response.status === 429) return new ShortLinkError("rate-limited", "the short-link service is rate limiting this client");
28223
+ if (response.status === 503) return new ShortLinkError("capacity", "the short-link service is at capacity");
28224
+ if (response.status === 404) return new ShortLinkError("not-found", "the short link has expired, was revoked, or never existed");
28225
+ if (response.status >= 400 && response.status < 500) return new ShortLinkError("rejected", `the short-link service rejected the request (HTTP ${response.status})`);
28226
+ return new ShortLinkError("unavailable", `the short-link service failed (HTTP ${response.status})`);
28227
+ }
28228
+ function createShortLinkClient(origin, fetchFn = globalThis.fetch, timeoutMs = REQUEST_TIMEOUT_MS) {
28229
+ const base5 = `${origin}/api/share-links`;
28230
+ return {
28231
+ async create(ciphertext, expiresAt) {
28232
+ if (ciphertext.byteLength === 0 || ciphertext.byteLength > MAX_SHORT_LINK_BYTES) throw new ShortLinkError("too-large", "the sealed share is too large for a short link");
28233
+ const expectedCid = await computeCid2(ciphertext);
28234
+ const response = await send(fetchFn, base5, {
28235
+ method: "POST",
28236
+ headers: { "content-type": "application/json", accept: "application/json" },
28237
+ body: JSON.stringify({ ciphertext: toBase64Url2(ciphertext), expiresAt: expiresAt.toISOString() })
28238
+ }, timeoutMs);
28239
+ if (response.status !== 201) throw statusError(response);
28240
+ let value;
28241
+ try {
28242
+ value = await response.json();
28243
+ } catch {
28244
+ throw new ShortLinkError("invalid-response", "the short-link service returned an unreadable response");
28245
+ }
28246
+ const body = typeof value === "object" && value !== null && !Array.isArray(value) ? value : {};
28247
+ if (typeof body.id !== "string" || !SHORT_LINK_ID_PATTERN.test(body.id)) throw new ShortLinkError("invalid-response", "the short-link service returned an invalid id");
28248
+ if (typeof body.deleteToken !== "string" || !DELETE_TOKEN.test(body.deleteToken) || fromBase64Url3(body.deleteToken).byteLength !== 32) {
28249
+ throw new ShortLinkError("invalid-response", "the short-link service returned an invalid delete token");
28250
+ }
28251
+ if (body.cid !== expectedCid) throw new ShortLinkError("invalid-response", "the short-link service stored different bytes than were sent");
28252
+ return { id: body.id, deleteToken: body.deleteToken };
28253
+ },
28254
+ async fetchCiphertext(id) {
28255
+ if (!SHORT_LINK_ID_PATTERN.test(id)) throw new ShortLinkError("not-found", "the short link has expired, was revoked, or never existed");
28256
+ const response = await send(fetchFn, `${base5}/${id}`, { method: "GET", headers: { accept: "application/octet-stream" } }, timeoutMs);
28257
+ if (response.status !== 200) throw statusError(response);
28258
+ if ((response.headers.get("content-type") ?? "").split(";", 1)[0].trim().toLowerCase() !== "application/octet-stream") {
28259
+ await response.body?.cancel().catch(() => void 0);
28260
+ throw new ShortLinkError("invalid-response", "the short-link service did not return sealed bytes");
28261
+ }
28262
+ const declared = Number(response.headers.get("content-length") ?? "0");
28263
+ if (declared > MAX_SHORT_LINK_BYTES) {
28264
+ await response.body?.cancel().catch(() => void 0);
28265
+ throw new ShortLinkError("too-large", "the short-link service returned too many bytes");
28266
+ }
28267
+ const bytes = await readCapped(response, MAX_SHORT_LINK_BYTES);
28268
+ if (bytes.byteLength === 0) throw new ShortLinkError("invalid-response", "the short-link service returned no bytes");
28269
+ return bytes;
28270
+ },
28271
+ async delete(record2) {
28272
+ const response = await send(fetchFn, `${base5}/${record2.id}`, { method: "DELETE", headers: { authorization: `Bearer ${record2.deleteToken}` } }, timeoutMs);
28273
+ if (response.status === 204) return "deleted";
28274
+ if (response.status === 404) return "absent";
28275
+ throw statusError(response);
28276
+ }
28277
+ };
28278
+ }
28279
+ async function shortenInlineLink(input) {
28280
+ const inline = await parseSealedInlineShareUrl2(input.inlineUrl);
28281
+ const record2 = await input.client.create(inline.ciphertext, input.expiresAt);
28282
+ try {
28283
+ await input.tokens.write(input.shareId, record2);
28284
+ } catch (error) {
28285
+ await input.client.delete(record2).catch(() => void 0);
28286
+ throw new ShortLinkError("token-store-failed", "the short link's delete token could not be saved", { cause: error });
28287
+ }
28288
+ return splitInlineToShort(input.inlineUrl, record2.id);
28289
+ }
28290
+ async function resolveShortLink(link4, options) {
28291
+ let short;
28292
+ try {
28293
+ short = parseShortShareUrl(link4);
28294
+ } catch {
28295
+ return link4;
28296
+ }
28297
+ if (short.origin !== options.expectedOrigin) throw new ShortLinkError("rejected", "the short link is not from the trusted Share origin");
28298
+ const ciphertext = await createShortLinkClient(options.expectedOrigin, options.fetchFn).fetchCiphertext(short.id);
28299
+ let payload;
28300
+ try {
28301
+ payload = await rebuildInlineFromShort(link4, toBase64Url2(ciphertext));
28302
+ } catch (error) {
28303
+ throw new ShortLinkError("invalid-response", "the short-link service returned bytes that do not match the link", { cause: error });
28304
+ }
28305
+ return encodeSealedInlineShareUrl2({ origin: short.origin, ciphertext: fromBase64Url3(payload.c), key32: fromBase64Url3(payload.k) });
28306
+ }
28307
+ function kvErrorCode(error) {
28308
+ return typeof error === "object" && error !== null && "code" in error && typeof error.code === "string" ? error.code : void 0;
28309
+ }
28310
+ function kvShortLinkTokenStore(kv) {
28311
+ return {
28312
+ async read(shareId) {
28313
+ const read5 = await (await kv()).get(shortLinkTokenKey(shareId), { binary: true });
28314
+ if (read5.ok) return parseShortLinkRecord(new Uint8Array(read5.data.data));
28315
+ if (kvErrorCode(read5.error) === "KV_NOT_FOUND") return void 0;
28316
+ throw new Error(`could not read the short-link token (${kvErrorCode(read5.error) ?? "unknown error"})`);
28317
+ },
28318
+ async write(shareId, record2) {
28319
+ const written = await (await kv()).put(shortLinkTokenKey(shareId), serializeShortLinkRecord(record2), { contentType: "application/json" });
28320
+ if (!written.ok) throw new Error(`could not write the short-link token (${kvErrorCode(written.error) ?? "unknown error"})`);
28321
+ },
28322
+ async remove(shareId) {
28323
+ const removed = await (await kv()).delete(shortLinkTokenKey(shareId));
28324
+ if (!removed.ok && kvErrorCode(removed.error) !== "KV_NOT_FOUND") throw new Error(`could not remove the short-link token (${kvErrorCode(removed.error) ?? "unknown error"})`);
28325
+ }
28326
+ };
28327
+ }
28328
+ function isInlineLink(link4) {
28329
+ if (link4 === void 0) return false;
28330
+ try {
28331
+ return new URL(link4).pathname === "/s/inline";
28332
+ } catch {
28333
+ return false;
28334
+ }
28335
+ }
28336
+ function createShareShortLinks(input) {
28337
+ const tokens = (spaceId) => kvShortLinkTokenStore(() => input.kvForSpace(spaceId));
28338
+ const client = (inlineUrl) => createShortLinkClient(new URL(inlineUrl).origin, input.fetchFn, input.timeoutMs);
28339
+ return {
28340
+ async shorten(published) {
28341
+ if (published.link.kind !== "policy" || !isInlineLink(published.url)) throw new ShortLinkError("rejected", "only addressed shares get a short link");
28342
+ return shortenInlineLink({
28343
+ inlineUrl: published.url,
28344
+ shareId: published.metadata.shareId,
28345
+ expiresAt: new Date(published.metadata.expiresAt),
28346
+ client: client(published.url),
28347
+ tokens: tokens(published.metadata.target.spaceId)
28348
+ });
28349
+ },
28350
+ async linkFor(record2) {
28351
+ if (!isInlineLink(record2.link)) return void 0;
28352
+ const inlineUrl = record2.link;
28353
+ const stored = await tokens(record2.target.spaceId).read(record2.shareId).catch(() => void 0);
28354
+ return stored === void 0 ? void 0 : splitInlineToShort(inlineUrl, stored.id).catch(() => void 0);
28355
+ },
28356
+ async discard(record2) {
28357
+ if (!isInlineLink(record2.link)) return "none";
28358
+ return discardShortLink(record2.shareId, client(record2.link), tokens(record2.target.spaceId));
28359
+ },
28360
+ resolve: (link4, expectedOrigin) => resolveShortLink(link4, { expectedOrigin, ...input.fetchFn === void 0 ? {} : { fetchFn: input.fetchFn } })
28361
+ };
28362
+ }
28363
+ async function discardShortLink(shareId, client, tokens) {
28364
+ let record2;
28365
+ try {
28366
+ record2 = await tokens.read(shareId);
28367
+ } catch {
28368
+ return "failed";
28369
+ }
28370
+ if (record2 === void 0) return "none";
28371
+ try {
28372
+ await client.delete(record2);
28373
+ } catch {
28374
+ return "failed";
28375
+ }
28376
+ await tokens.remove(shareId).catch(() => void 0);
28377
+ return "deleted";
28378
+ }
28379
+
28380
+ // src/share/errors.ts
28381
+ var SharePublishAuthorityError = class extends Error {
28382
+ constructor(failure, options) {
28383
+ super(failure.kind, options);
28384
+ this.failure = failure;
28385
+ this.name = "SharePublishAuthorityError";
28386
+ }
28387
+ };
28388
+ var ShareHistoryRetryError = class extends Error {
28389
+ constructor(profile) {
28390
+ super("sender history changed during the operation");
28391
+ this.profile = profile;
28392
+ this.name = "ShareHistoryRetryError";
28393
+ }
28394
+ code = "SHARE_HISTORY_RETRY";
28395
+ };
28396
+ var ShareHistoryUnreadableError = class extends Error {
28397
+ constructor() {
28398
+ super("share history is unavailable");
28399
+ this.name = "ShareHistoryUnreadableError";
28400
+ }
28401
+ };
28402
+ var ShareHistoryReadError = class extends Error {
28403
+ constructor() {
28404
+ super("share history could not be read");
28405
+ this.name = "ShareHistoryReadError";
28406
+ }
28407
+ };
28408
+ var HISTORY_WRITE_ERROR_CODES = { EACCES: true, EPERM: true, EROFS: true, ENOSPC: true, EDQUOT: true, EIO: true };
28409
+ function shareHistoryReason(error) {
28410
+ if (error instanceof ShareHistoryUnreadableError) return "HISTORY_UNREADABLE";
28411
+ if (error instanceof ShareHistoryReadError) return "HISTORY_READ_FAILED";
28412
+ const code5 = typeof error === "object" && error !== null && "code" in error ? error.code : void 0;
28413
+ return typeof code5 === "string" && HISTORY_WRITE_ERROR_CODES[code5] === true ? "HISTORY_WRITE_FAILED" : "HISTORY_UNAVAILABLE";
28414
+ }
28415
+
28416
+ // src/share/space-not-ready.ts
28417
+ function isSpaceNotFound(error) {
28418
+ if (typeof error !== "object" || error === null) return false;
28419
+ const message = "message" in error && typeof error.message === "string" ? error.message : "";
28420
+ if (!/space not found/i.test(message)) return false;
28421
+ const meta = "meta" in error && typeof error.meta === "object" && error.meta !== null ? error.meta : void 0;
28422
+ const status = meta !== void 0 && "status" in meta ? meta.status : void 0;
28423
+ return status === 404 || /\b404\b/.test(message);
28424
+ }
28425
+ function spaceNotReadyFailure(cause) {
28426
+ return new SharePublishAuthorityError({ kind: "space-not-ready" }, { cause });
28427
+ }
28428
+ function failIfSpaceNotReady(result) {
28429
+ if (!result.ok && isSpaceNotFound(result.error)) throw spaceNotReadyFailure(result.error);
28430
+ }
28431
+ function artifactSpaceNotReady(error) {
28432
+ return error instanceof ArtifactError && isSpaceNotFound(error.cause) ? spaceNotReadyFailure(error.cause) : error;
28433
+ }
28434
+
28435
+ // src/share/adapters.ts
28436
+ init_storage();
28437
+ init_profiles();
28438
+ init_constants();
28439
+ init_errors();
28440
+ init_session_expired();
28441
+ import { chmod as chmod4, link as link3, open as open8, readFile as readFile7, stat as stat5, unlink as unlink5 } from "fs/promises";
28442
+ import { dirname as dirname5, join as join12 } from "path";
28443
+ import { createHash } from "crypto";
28444
+ import { writeJsonAtomic as writeJsonAtomic2 } from "@tinycloud/operations/state";
28445
+ import { withoutBearer } from "@tinycloud/operations/delegation-binding";
28446
+ import {
28447
+ LocationRecordValidationError,
28448
+ LocationRegistryHttpError,
28449
+ parseSignedCompactUcanAttenuation,
28450
+ parseSignedSiweCacao,
28451
+ revokePolicyRootV3,
28452
+ signCompactUcanAuthorization
28453
+ } from "@tinycloud/sdk-core";
28454
+ import { extractSiweExpiration, InvalidRestoredSessionError } from "@tinycloud/node-sdk";
28455
+ function requiredKvAction(meta) {
28456
+ if (meta === null || typeof meta !== "object" || !("requiredAction" in meta)) return void 0;
28457
+ const action = meta.requiredAction;
28458
+ return action === "tinycloud.kv/put" || action === "tinycloud.kv/get" || action === "tinycloud.kv/list" ? action : void 0;
28459
+ }
28460
+ function throwKvUploadFailure(error) {
28461
+ const rejection = storageRejection(error);
28462
+ if (rejection) throw new SharePublishAuthorityError({ kind: "storage-full", ...rejection });
28463
+ throw new SharePublishAuthorityError({ kind: "upload-failed" });
28464
+ }
28465
+ var DEFAULT_SHARE_ORIGIN = "https://share.tinycloud.xyz";
28466
+ var MIN_DOMAIN_DELIVERY_VERSION = "1.17.3";
28467
+ function supportsDomainDelivery(version2) {
28468
+ if (typeof version2 !== "string") return false;
28469
+ const normalized = version2.trim();
28470
+ if (normalized.length > 128) return false;
28471
+ const match = /^v?(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/.exec(normalized);
28472
+ if (match === null) return false;
28473
+ if (match[4] !== void 0 && /(?:^|\.)0[0-9]+(?:\.|$)/.test(match[4])) return false;
28474
+ const major = Number(match[1]);
28475
+ const minor = Number(match[2]);
28476
+ const patch = Number(match[3]);
28477
+ if (!Number.isSafeInteger(major) || !Number.isSafeInteger(minor) || !Number.isSafeInteger(patch)) return false;
28478
+ if (major !== 1) return major > 1;
28479
+ if (minor !== 17) return minor > 17;
28480
+ if (patch !== 3) return patch > 3;
28481
+ return match[4] === void 0;
28482
+ }
28483
+ function displayedNodeVersion(version2) {
28484
+ if (typeof version2 !== "string") return "(unrecognized)";
28485
+ const trimmed = version2.trim();
28486
+ return /^[A-Za-z0-9.+_-]{1,64}$/.test(trimmed) ? trimmed : "(unrecognized)";
28487
+ }
28488
+ var URI_SAFE_FILENAME = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
28489
+ function safeStorageFilename(filename) {
28490
+ if (URI_SAFE_FILENAME.test(filename) && !filename.includes("..")) return filename;
28491
+ const dot = filename.lastIndexOf(".");
28492
+ const extension = dot >= 0 && /^[A-Za-z0-9]{1,16}$/.test(filename.slice(dot + 1)) ? filename.slice(dot + 1) : "";
28493
+ const stem = (extension === "" ? filename : filename.slice(0, dot)).normalize("NFKD").replace(/[\u0300-\u036f]/g, "").replace(extension === "" ? /[^A-Za-z0-9_-]+/g : /[^A-Za-z0-9._-]+/g, "-").replace(/\.{2,}/g, ".").replace(/-{2,}/g, "-").slice(0, 100).replace(/^[^A-Za-z0-9]+|[-.]+$/g, "");
28494
+ return `${stem === "" ? "share" : stem}${extension === "" ? "" : `.${extension}`}`;
28495
+ }
28496
+ function scopeDeniedFromArtifactError(error, capability, authority) {
28497
+ const cause = error instanceof ArtifactError ? error.cause : void 0;
28498
+ const code5 = typeof cause === "object" && cause !== null && "code" in cause ? cause.code : void 0;
28499
+ if (code5 !== "AUTH_UNAUTHORIZED" && code5 !== "PERMISSION_DENIED") return void 0;
28500
+ const meta = typeof cause === "object" && cause !== null && "meta" in cause ? cause.meta : void 0;
28501
+ const requiredAction = requiredKvAction(meta);
28502
+ return new SharePublishAuthorityError({
28503
+ kind: "scope-denied",
28504
+ capability,
28505
+ ...requiredAction === void 0 ? {} : { requiredAction },
28506
+ localKey: authority.localKey,
28507
+ profileName: authority.profileName
28508
+ });
28509
+ }
28510
+ async function storeArtifactVersion(kv, version2, authority) {
28511
+ try {
28512
+ return await publishArtifactVersion(kvArtifactStore(kv), version2);
28513
+ } catch (error) {
28514
+ throw scopeDeniedFromArtifactError(error, "KV upload", authority) ?? artifactSpaceNotReady(error);
28515
+ }
28516
+ }
28517
+ function createEncryptedSessionHistory() {
28518
+ const records = /* @__PURE__ */ new Map();
28519
+ let operation = Promise.resolve();
28520
+ const serial = (action) => {
28521
+ const next = operation.then(action, action);
28522
+ operation = next.then(() => void 0, () => void 0);
28523
+ return next;
28524
+ };
28525
+ let keyPromise;
28526
+ const key = async () => keyPromise ??= crypto.subtle.generateKey({ name: "AES-GCM", length: 256 }, false, ["encrypt", "decrypt"]);
28527
+ const encode7 = async (record2) => {
28528
+ const secret = new TextEncoder().encode(JSON.stringify(record2));
28529
+ const iv = crypto.getRandomValues(new Uint8Array(12));
28530
+ const encrypted = new Uint8Array(await crypto.subtle.encrypt({ name: "AES-GCM", iv }, await key(), secret));
28531
+ const value = new Uint8Array(iv.length + encrypted.length);
28532
+ value.set(iv);
28533
+ value.set(encrypted, iv.length);
28534
+ return value;
28535
+ };
28536
+ const decode11 = async (value) => JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(await crypto.subtle.decrypt({ name: "AES-GCM", iv: value.slice(0, 12) }, await key(), value.slice(12))));
28537
+ return {
28538
+ async put(record2) {
28539
+ return serial(async () => {
28540
+ records.set(record2.shareId, await encode7(record2));
28541
+ });
28542
+ },
28543
+ async update(shareId, change) {
28544
+ return serial(async () => {
28545
+ const value = records.get(shareId);
28546
+ if (value === void 0) return void 0;
28547
+ const updated = await change(await decode11(value));
28548
+ records.set(shareId, await encode7(updated));
28549
+ return updated;
28550
+ });
28551
+ },
28552
+ async list() {
28553
+ return serial(() => Promise.all([...records.values()].map(decode11)));
28554
+ },
28555
+ async get(shareId) {
28556
+ return serial(async () => {
28557
+ const value = records.get(shareId);
28558
+ return value === void 0 ? void 0 : decode11(value);
28559
+ });
28560
+ },
28561
+ async delete(shareId) {
28562
+ return serial(async () => {
28563
+ records.delete(shareId);
28564
+ });
28565
+ }
28566
+ };
28567
+ }
28568
+ var SHARE_HISTORY_FILE = "share-history-v2.json";
28569
+ var SHARE_HISTORY_LEGACY_FILE = "share-history-v1.bin";
28570
+ var PRIVATE_HISTORY_MODE = 384;
28571
+ async function signShareHistoryBytes(bytes, profile) {
28572
+ const context = await ProfileManager.resolveContext({ profile });
28573
+ if (context.profile !== profile) throw new ShareHistoryRetryError(profile);
28574
+ const { ensureAuthenticated: ensureAuthenticated2 } = await Promise.resolve().then(() => (init_sdk(), sdk_exports));
28575
+ const signer = await ensureAuthenticated2(context);
28576
+ return signer.signSessionBytes(bytes);
28577
+ }
28578
+ function createEncryptedProfileHistory(profileName, sessionSigner) {
28579
+ const HISTORY_VERSION = 2;
26808
28580
  const identityChanged = new Error("share history profile or key changed");
26809
28581
  const saltChanged = new Error("share history salt changed");
26810
28582
  let operation = Promise.resolve();
@@ -26880,7 +28652,7 @@ function createEncryptedProfileHistory(profileName, sessionSigner) {
26880
28652
  if (salt.length < 16) throw new ShareHistoryUnreadableError();
26881
28653
  return salt;
26882
28654
  };
26883
- const read4 = async (profile, ready) => {
28655
+ const read5 = async (profile, ready) => {
26884
28656
  const file = await readIfPresent(await path(profile));
26885
28657
  if (file === void 0) {
26886
28658
  const legacy = await readIfPresent(await legacyPath(profile));
@@ -26969,7 +28741,7 @@ function createEncryptedProfileHistory(profileName, sessionSigner) {
26969
28741
  false,
26970
28742
  ["encrypt", "decrypt"]
26971
28743
  );
26972
- await read4(profile, { salt, key, legacyKey: keys.legacyKey });
28744
+ await read5(profile, { salt, key, legacyKey: keys.legacyKey });
26973
28745
  return true;
26974
28746
  } catch (error) {
26975
28747
  if (error instanceof ShareHistoryUnreadableError) return false;
@@ -27008,7 +28780,7 @@ function createEncryptedProfileHistory(profileName, sessionSigner) {
27008
28780
  return {
27009
28781
  async put(record2) {
27010
28782
  return locked(async (profile, ready) => {
27011
- const values = await read4(profile, ready);
28783
+ const values = await read5(profile, ready);
27012
28784
  const index = values.findIndex((value) => value.shareId === record2.shareId);
27013
28785
  if (index >= 0) values[index] = record2;
27014
28786
  else values.push(record2);
@@ -27017,7 +28789,7 @@ function createEncryptedProfileHistory(profileName, sessionSigner) {
27017
28789
  },
27018
28790
  async update(shareId, change) {
27019
28791
  return locked(async (profile, ready) => {
27020
- const values = await read4(profile, ready);
28792
+ const values = await read5(profile, ready);
27021
28793
  const index = values.findIndex((record2) => record2.shareId === shareId);
27022
28794
  if (index < 0) return void 0;
27023
28795
  const updated = await change(values[index]);
@@ -27027,14 +28799,14 @@ function createEncryptedProfileHistory(profileName, sessionSigner) {
27027
28799
  }, true);
27028
28800
  },
27029
28801
  async list() {
27030
- return locked((profile, ready) => read4(profile, ready));
28802
+ return locked((profile, ready) => read5(profile, ready));
27031
28803
  },
27032
28804
  async get(shareId) {
27033
- return locked(async (profile, ready) => (await read4(profile, ready)).find((record2) => record2.shareId === shareId));
28805
+ return locked(async (profile, ready) => (await read5(profile, ready)).find((record2) => record2.shareId === shareId));
27034
28806
  },
27035
28807
  async delete(shareId) {
27036
28808
  return locked(async (profile, ready) => {
27037
- await write(profile, (await read4(profile, ready)).filter((record2) => record2.shareId !== shareId), ready);
28809
+ await write(profile, (await read5(profile, ready)).filter((record2) => record2.shareId !== shareId), ready);
27038
28810
  }, true);
27039
28811
  },
27040
28812
  quarantineUnreadable
@@ -27057,13 +28829,19 @@ function createShareAuthorityAdapters(input = {}) {
27057
28829
  };
27058
28830
  let configPromise;
27059
28831
  const publicConfig = async () => configPromise ??= (async () => {
27060
- const response = await fetchFn(`${origin}/.well-known/tinycloud-share/config.json`, {
27061
- headers: { accept: "application/json" },
27062
- credentials: "omit",
27063
- redirect: "error",
27064
- referrerPolicy: "no-referrer"
27065
- });
27066
- if (!response.ok) throw new Error("share public config is unavailable");
28832
+ let response;
28833
+ try {
28834
+ response = await fetchFn(`${origin}/.well-known/tinycloud-share/config.json`, {
28835
+ headers: { accept: "application/json" },
28836
+ credentials: "omit",
28837
+ redirect: "error",
28838
+ referrerPolicy: "no-referrer",
28839
+ signal: AbortSignal.timeout(1e4)
28840
+ });
28841
+ } catch (error) {
28842
+ throw new SharePublishAuthorityError({ kind: "share-service-unavailable", origin }, { cause: error });
28843
+ }
28844
+ if (!response.ok) throw new SharePublishAuthorityError({ kind: "share-service-unavailable", origin });
27067
28845
  const value = await response.json();
27068
28846
  if (typeof value !== "object" || value === null || Array.isArray(value)) throw new Error("share public config is invalid");
27069
28847
  const object3 = value;
@@ -27085,8 +28863,8 @@ function createShareAuthorityAdapters(input = {}) {
27085
28863
  return await ensureAuthenticated2(context);
27086
28864
  } catch (error) {
27087
28865
  const profileConfig = await ProfileManager.getProfile(profile).catch(() => void 0);
27088
- const code4 = typeof error === "object" && error !== null && "code" in error ? error.code : void 0;
27089
- if (error instanceof InvalidRestoredSessionError || code4 === "AUTH_EXPIRED" || isSessionExpiredError(error)) {
28866
+ const code5 = typeof error === "object" && error !== null && "code" in error ? error.code : void 0;
28867
+ if (error instanceof InvalidRestoredSessionError || code5 === "AUTH_EXPIRED" || isSessionExpiredError(error)) {
27090
28868
  throw new SharePublishAuthorityError({
27091
28869
  kind: "owner-space-unresolved",
27092
28870
  localKey: profileConfig?.authMethod === "local",
@@ -27213,8 +28991,8 @@ function createShareAuthorityAdapters(input = {}) {
27213
28991
  });
27214
28992
  failIfSpaceNotReady(written);
27215
28993
  if (!written.ok) {
27216
- const code4 = typeof written.error === "object" && written.error !== null && "code" in written.error ? written.error.code : void 0;
27217
- if (code4 === "AUTH_UNAUTHORIZED" || code4 === "PERMISSION_DENIED") {
28994
+ const code5 = typeof written.error === "object" && written.error !== null && "code" in written.error ? written.error.code : void 0;
28995
+ if (code5 === "AUTH_UNAUTHORIZED" || code5 === "PERMISSION_DENIED") {
27218
28996
  const requiredAction = requiredKvAction(written.error.meta);
27219
28997
  throw new SharePublishAuthorityError({
27220
28998
  kind: "scope-denied",
@@ -27235,8 +29013,8 @@ function createShareAuthorityAdapters(input = {}) {
27235
29013
  viewerOrigin: config.shareOrigin
27236
29014
  });
27237
29015
  } catch (error) {
27238
- const code4 = typeof error === "object" && error !== null && "code" in error ? error.code : void 0;
27239
- if (code4 === "AUTH_UNAUTHORIZED" || code4 === "PERMISSION_DENIED") {
29016
+ const code5 = typeof error === "object" && error !== null && "code" in error ? error.code : void 0;
29017
+ if (code5 === "AUTH_UNAUTHORIZED" || code5 === "PERMISSION_DENIED") {
27240
29018
  throw new SharePublishAuthorityError({
27241
29019
  kind: "scope-denied",
27242
29020
  capability: "sharing delegation",
@@ -27313,8 +29091,8 @@ function createShareAuthorityAdapters(input = {}) {
27313
29091
  const stored = await node.kvForSpace(ownerSpaceId).put(resourcePath, storedBytes, { contentType: "application/vnd.tinycloud.encrypted-envelope+json" });
27314
29092
  failIfSpaceNotReady(stored);
27315
29093
  if (!stored.ok) {
27316
- const code4 = typeof stored.error === "object" && stored.error !== null && "code" in stored.error ? stored.error.code : void 0;
27317
- if (code4 === "AUTH_UNAUTHORIZED" || code4 === "PERMISSION_DENIED") {
29094
+ const code5 = typeof stored.error === "object" && stored.error !== null && "code" in stored.error ? stored.error.code : void 0;
29095
+ if (code5 === "AUTH_UNAUTHORIZED" || code5 === "PERMISSION_DENIED") {
27318
29096
  const requiredAction = requiredKvAction(stored.error.meta);
27319
29097
  throw new SharePublishAuthorityError({
27320
29098
  kind: "scope-denied",
@@ -27366,9 +29144,9 @@ function createShareAuthorityAdapters(input = {}) {
27366
29144
  // transport hop, so the CLI supplies only owner signing material.
27367
29145
  authority: {
27368
29146
  ownerDid: node.credentialHolderDid,
27369
- createOwnerRoot: (request) => node.createUnifiedOwnerRoot(request),
29147
+ createOwnerRoot: (request2) => node.createUnifiedOwnerRoot(request2),
27370
29148
  sign: (bytes) => node.signSessionBytes(bytes),
27371
- registerPolicy: (request) => node.registerPolicy(request)
29149
+ registerPolicy: (request2) => node.registerPolicy(request2)
27372
29150
  }
27373
29151
  });
27374
29152
  if (expiryClamped) Object.defineProperty(published.metadata, "expiryClamped", { value: true, enumerable: true });
@@ -27377,9 +29155,9 @@ function createShareAuthorityAdapters(input = {}) {
27377
29155
  }
27378
29156
  return published;
27379
29157
  } };
27380
- const delivery = { deliver: input.deliver ?? (async (request) => {
27381
- const record2 = request.record;
27382
- if (record2 === void 0 || record2.link === void 0 || record2.deliveryMaterial === void 0 || request.idempotencyKey === void 0) throw new Error("share delivery history is incomplete");
29158
+ const delivery = { deliver: input.deliver ?? (async (request2) => {
29159
+ const record2 = request2.record;
29160
+ if (record2 === void 0 || record2.link === void 0 || record2.deliveryMaterial === void 0 || request2.idempotencyKey === void 0) throw new Error("share delivery history is incomplete");
27383
29161
  const expiry = shareDeliveryWindowExpiresAt(record2);
27384
29162
  if (expiry <= Date.now()) throw new ShareNotifyError("share delivery authorization window has expired", "delivery-window-expired");
27385
29163
  const authorizationExpiresAt = new Date(expiry).toISOString();
@@ -27390,19 +29168,19 @@ function createShareAuthorityAdapters(input = {}) {
27390
29168
  envelopeKey: record2.deliveryMaterial.envelopeKey,
27391
29169
  shareCid: record2.deliveryMaterial.shareCid,
27392
29170
  resourcePath: record2.resource.path,
27393
- recipientEmail: request.recipient,
29171
+ recipientEmail: request2.recipient,
27394
29172
  shareUrl: record2.link,
27395
29173
  documentName: record2.filename ?? "share.md",
27396
29174
  expiresAt: authorizationExpiresAt,
27397
29175
  deliveryAudience: config.credentialsOrigin,
27398
- idempotencyKey: request.idempotencyKey
29176
+ idempotencyKey: request2.idempotencyKey
27399
29177
  });
27400
29178
  await deliverCredentialInvitation({
27401
29179
  credentialsOrigin: config.credentialsOrigin,
27402
29180
  receipt,
27403
29181
  shareUrl: record2.link,
27404
29182
  fetchFn,
27405
- signal: request.signal
29183
+ signal: request2.signal
27406
29184
  });
27407
29185
  return "delivered";
27408
29186
  }) };
@@ -27482,16 +29260,16 @@ function createShareAuthorityAdapters(input = {}) {
27482
29260
  { status: response.status }
27483
29261
  );
27484
29262
  }),
27485
- revokePolicyRoot: input.revokePolicyRoot ?? (async (request) => {
29263
+ revokePolicyRoot: input.revokePolicyRoot ?? (async (request2) => {
27486
29264
  const node = await authenticatedNode();
27487
29265
  const activeNode = await node.activeNodeIdentity();
27488
- if (request.nodeOrigin !== activeNode.origin || request.nodeAudience !== activeNode.nodeDid || request.ownerDid !== node.credentialHolderDid) {
29266
+ if (request2.nodeOrigin !== activeNode.origin || request2.nodeAudience !== activeNode.nodeDid || request2.ownerDid !== node.credentialHolderDid) {
27489
29267
  throw new Error("share Policy/v3 revocation is not bound to the active owner node");
27490
29268
  }
27491
29269
  await revokePolicyRootV3({
27492
29270
  nodeOrigin: activeNode.origin,
27493
- rootCid: request.rootCid,
27494
- targetRole: request.targetRole,
29271
+ rootCid: request2.rootCid,
29272
+ targetRole: request2.targetRole,
27495
29273
  ownerDid: node.credentialHolderDid,
27496
29274
  issuerDid: node.credentialHolderDid,
27497
29275
  nodeAudience: activeNode.nodeDid,
@@ -27535,6 +29313,10 @@ function createShareAuthorityAdapters(input = {}) {
27535
29313
  list: (prefix) => mapped(() => store.list(prefix))
27536
29314
  };
27537
29315
  };
29316
+ const shortLinks = createShareShortLinks({
29317
+ kvForSpace: async (spaceId) => (await authenticatedNode()).kvForSpace(spaceId),
29318
+ fetchFn
29319
+ });
27538
29320
  return {
27539
29321
  targetAdapter,
27540
29322
  records: input.profileName === void 0 ? createEncryptedSessionHistory() : createEncryptedProfileHistory(profileName, signShareHistoryBytes),
@@ -27542,7 +29324,8 @@ function createShareAuthorityAdapters(input = {}) {
27542
29324
  revocation,
27543
29325
  assertDomainDelivery,
27544
29326
  nativeReader,
27545
- artifactStore
29327
+ artifactStore,
29328
+ shortLinks
27546
29329
  };
27547
29330
  }
27548
29331
  async function selectedProfileName() {
@@ -27898,7 +29681,7 @@ var SCRIPT_END = /<\/script/gi;
27898
29681
  var STYLE_END = /<\/style/gi;
27899
29682
  function scanMarkup(html, options) {
27900
29683
  const checkReferences = options.references;
27901
- const length4 = html.length;
29684
+ const length5 = html.length;
27902
29685
  let index = 0;
27903
29686
  let comments = 0;
27904
29687
  const malformed = (detail) => {
@@ -27909,7 +29692,7 @@ function scanMarkup(html, options) {
27909
29692
  comments += 1;
27910
29693
  if (comments > MAX_ARTIFACT_COMMENTS) fail("limit", "artifact page has too many comments");
27911
29694
  };
27912
- while (index < length4) {
29695
+ while (index < length5) {
27913
29696
  const open10 = html.indexOf("<", index);
27914
29697
  if (open10 === -1) return;
27915
29698
  index = open10 + 1;
@@ -27953,8 +29736,8 @@ function scanMarkup(html, options) {
27953
29736
  const attributes = /* @__PURE__ */ new Map();
27954
29737
  let attributeCount = 0;
27955
29738
  for (; ; ) {
27956
- while (index < length4 && SKIPPED.test(html[index])) index += 1;
27957
- if (index >= length4) {
29739
+ while (index < length5 && SKIPPED.test(html[index])) index += 1;
29740
+ if (index >= length5) {
27958
29741
  if (malformed("artifact output has an unterminated tag")) return;
27959
29742
  return;
27960
29743
  }
@@ -27965,11 +29748,11 @@ function scanMarkup(html, options) {
27965
29748
  ATTRIBUTE_NAME.lastIndex = index;
27966
29749
  const rawName = ATTRIBUTE_NAME.exec(html)[0];
27967
29750
  index = ATTRIBUTE_NAME.lastIndex;
27968
- while (index < length4 && SPACE.test(html[index])) index += 1;
29751
+ while (index < length5 && SPACE.test(html[index])) index += 1;
27969
29752
  let rawValue = "";
27970
29753
  if (html[index] === "=") {
27971
29754
  index += 1;
27972
- while (index < length4 && SPACE.test(html[index])) index += 1;
29755
+ while (index < length5 && SPACE.test(html[index])) index += 1;
27973
29756
  const quote = html[index];
27974
29757
  if (quote === '"' || quote === "'") {
27975
29758
  const close = html.indexOf(quote, index + 1);
@@ -27994,7 +29777,7 @@ function scanMarkup(html, options) {
27994
29777
  checkAttribute(name, decoded);
27995
29778
  if (isHrefAnimation(tag, name, decoded)) unsupportedOutput("artifact svg animates a resource reference");
27996
29779
  if (!attributes.has(name)) attributes.set(name, decoded);
27997
- } else if (index < length4 && html[index] !== ">" && !SKIPPED.test(html[index])) {
29780
+ } else if (index < length5 && html[index] !== ">" && !SKIPPED.test(html[index])) {
27998
29781
  index += 1;
27999
29782
  }
28000
29783
  }
@@ -28017,7 +29800,7 @@ function scanMarkup(html, options) {
28017
29800
  } else if (tag === "style" && checkReferences) {
28018
29801
  STYLE_END.lastIndex = index;
28019
29802
  const close = STYLE_END.exec(html);
28020
- assertOnlyInlineCssReferences(html.slice(index, close === null ? length4 : close.index));
29803
+ assertOnlyInlineCssReferences(html.slice(index, close === null ? length5 : close.index));
28021
29804
  }
28022
29805
  }
28023
29806
  }
@@ -28121,26 +29904,26 @@ function requiredFile(context, basePath, reference) {
28121
29904
  return { file, resolved };
28122
29905
  }
28123
29906
  var CSS_REFERENCE_NAMES = /* @__PURE__ */ new Set(["url", "image-set", "-webkit-image-set", "src", "import"]);
28124
- function isCssIdentifierCode(code4) {
28125
- return code4 >= 128 || code4 >= 48 && code4 <= 57 || code4 >= 65 && code4 <= 90 || code4 >= 97 && code4 <= 122 || code4 === 95 || code4 === 45;
29907
+ function isCssIdentifierCode(code5) {
29908
+ return code5 >= 128 || code5 >= 48 && code5 <= 57 || code5 >= 65 && code5 <= 90 || code5 >= 97 && code5 <= 122 || code5 === 95 || code5 === 45;
28126
29909
  }
28127
29910
  function normalizeCssEscapes(source) {
28128
29911
  let output = "";
28129
29912
  let index = 0;
28130
- const length4 = source.length;
28131
- while (index < length4) {
29913
+ const length5 = source.length;
29914
+ while (index < length5) {
28132
29915
  const char = source[index];
28133
29916
  if (char === "/" && source[index + 1] === "*") {
28134
29917
  const end = source.indexOf("*/", index + 2);
28135
- const stop = end === -1 ? length4 : end + 2;
29918
+ const stop = end === -1 ? length5 : end + 2;
28136
29919
  output += source.slice(index, stop);
28137
29920
  index = stop;
28138
29921
  continue;
28139
29922
  }
28140
29923
  if (char === '"' || char === "'") {
28141
29924
  let cursor = index + 1;
28142
- while (cursor < length4 && source[cursor] !== char && source[cursor] !== "\n") cursor += source[cursor] === "\\" ? 2 : 1;
28143
- const stop = Math.min(source[cursor] === char ? cursor + 1 : cursor, length4);
29925
+ while (cursor < length5 && source[cursor] !== char && source[cursor] !== "\n") cursor += source[cursor] === "\\" ? 2 : 1;
29926
+ const stop = Math.min(source[cursor] === char ? cursor + 1 : cursor, length5);
28144
29927
  output += source.slice(index, stop);
28145
29928
  index = stop;
28146
29929
  continue;
@@ -28149,7 +29932,7 @@ function normalizeCssEscapes(source) {
28149
29932
  let cursor = index;
28150
29933
  let decoded = "";
28151
29934
  let escaped = false;
28152
- while (cursor < length4) {
29935
+ while (cursor < length5) {
28153
29936
  if (source[cursor] === "\\") {
28154
29937
  const next = source[cursor + 1];
28155
29938
  if (next === void 0) {
@@ -28193,15 +29976,15 @@ function assertOnlyInlineCssReferences(css) {
28193
29976
  if (/@import/i.test(text)) fail("unsupported", "artifact css still imports a stylesheet");
28194
29977
  if (/(?:^|[^\w-])(?:-webkit-)?image-set\s*\(/i.test(text) || /(?:^|[^\w-])src\s*\(/i.test(text)) fail("unsupported", "artifact css uses an unsupported resource function");
28195
29978
  const opened = text.match(/url\(/gi)?.length ?? 0;
28196
- let read4 = 0;
29979
+ let read5 = 0;
28197
29980
  for (const match of text.matchAll(/url\([ \t\n\r\f]*(?:"([^"]*)"|'([^']*)'|([^)"' \t\n\r\f]*))[ \t\n\r\f]*\)/gi)) {
28198
- read4 += 1;
29981
+ read5 += 1;
28199
29982
  const value = match[1] ?? match[2] ?? match[3] ?? "";
28200
29983
  if (!isInlineReference(value) || value.includes("\\")) {
28201
29984
  throw new ArtifactBundleError("unsupported", "artifact css references a resource", void 0, value);
28202
29985
  }
28203
29986
  }
28204
- if (read4 !== opened) fail("unsupported", "artifact css has a url() that cannot be read");
29987
+ if (read5 !== opened) fail("unsupported", "artifact css has a url() that cannot be read");
28205
29988
  }
28206
29989
  async function transformCss(sourceText, basePath, context) {
28207
29990
  if (context.cssStack.length > MAX_ARTIFACT_CSS_IMPORT_DEPTH) fail("limit", "artifact stylesheet import depth exceeded");
@@ -28487,8 +30270,8 @@ function isWithinFolder(root, candidate) {
28487
30270
  }
28488
30271
  var CHANGED = "changed while it was read";
28489
30272
  function isRaceError(error) {
28490
- const code4 = error?.code;
28491
- return code4 === "ENOENT" || code4 === "ENOTDIR" || code4 === "ELOOP";
30273
+ const code5 = error?.code;
30274
+ return code5 === "ENOENT" || code5 === "ENOTDIR" || code5 === "ELOOP";
28492
30275
  }
28493
30276
  var PROC_FD = "/proc/self/fd";
28494
30277
  async function linuxDescriptorPath(fd) {
@@ -28645,11 +30428,11 @@ async function readHtmlFolder(directory, limit) {
28645
30428
  continue;
28646
30429
  }
28647
30430
  if (files.length >= MAX_ARTIFACT_FILES) throw limitError(`folder has more than ${MAX_ARTIFACT_FILES} files`);
28648
- const read4 = await readRegularFile(root, child, path, limit - total, limit);
28649
- if (read4 instanceof Uint8Array) {
28650
- total += read4.byteLength;
28651
- files.push({ path: path.normalize("NFC"), bytes: read4 });
28652
- } else problems.push(read4);
30431
+ const read5 = await readRegularFile(root, child, path, limit - total, limit);
30432
+ if (read5 instanceof Uint8Array) {
30433
+ total += read5.byteLength;
30434
+ files.push({ path: path.normalize("NFC"), bytes: read5 });
30435
+ } else problems.push(read5);
28653
30436
  }
28654
30437
  }
28655
30438
  };
@@ -28762,9 +30545,9 @@ function shareHistoryRecoverError(error) {
28762
30545
  if (error instanceof ShareHistoryReadError) {
28763
30546
  return new CLIError("SHARE_HISTORY_RECOVER_FAILED", "could not read the unreadable sender history to move it aside", 1, { hint: "The original history file was not deleted. Check read permission on the history file, then retry." });
28764
30547
  }
28765
- const code4 = error instanceof Error ? error.code : void 0;
28766
- if (code4 !== void 0 && SHARE_HISTORY_RECOVER_FS_ERRNO[code4] === true) {
28767
- return new CLIError("SHARE_HISTORY_RECOVER_FAILED", `could not move the unreadable sender history aside (${code4})`, 1, { hint: "The original history file was not deleted. Check write permission on the profile directory, then retry." });
30548
+ const code5 = error instanceof Error ? error.code : void 0;
30549
+ if (code5 !== void 0 && SHARE_HISTORY_RECOVER_FS_ERRNO[code5] === true) {
30550
+ return new CLIError("SHARE_HISTORY_RECOVER_FAILED", `could not move the unreadable sender history aside (${code5})`, 1, { hint: "The original history file was not deleted. Check write permission on the profile directory, then retry." });
28768
30551
  }
28769
30552
  return shareCliError(error);
28770
30553
  }
@@ -28833,6 +30616,10 @@ function shareCliError(error, operation = "publish") {
28833
30616
  if (failure.kind === "registry-unavailable") {
28834
30617
  return new CLIError("UNAVAILABLE", "the TinyCloud location registry could not be reached, so nothing was shared; try again shortly", 4);
28835
30618
  }
30619
+ if (failure.kind === "share-service-unavailable") {
30620
+ const outcome = operation === "publish" ? "nothing was shared" : "no invitation was sent";
30621
+ return new CLIError("SHARE_SERVICE_UNAVAILABLE", `the Share service at ${failure.origin} could not be reached, so ${outcome}; try again shortly`, 4);
30622
+ }
28836
30623
  if (failure.kind === "node-info-unavailable") {
28837
30624
  const outcome = operation === "publish" ? "nothing was shared and no invitation was sent" : "no invitation was sent";
28838
30625
  return new CLIError("UNAVAILABLE", `could not verify TinyCloud node 1.17.3 domain delivery support; ${outcome}. Check the node and retry`, 4);
@@ -28858,19 +30645,26 @@ function shareCliError(error, operation = "publish") {
28858
30645
  return new CLIError("UPLOAD_FAILED", "share source upload failed; nothing was shared", 4);
28859
30646
  }
28860
30647
  }
30648
+ if (error instanceof ShortLinkError) {
30649
+ if (error.code === "not-found") return new CLIError("NOT_FOUND", "this short link has expired, was revoked, or never existed", 4);
30650
+ if (error.code === "rejected") return new CLIError("ORIGIN_MISMATCH", "this short link is not from the trusted Share origin", 5);
30651
+ if (error.code === "too-large") return new CLIError("MAX_BYTES_EXCEEDED", "the Share short-link service returned too many bytes", 7);
30652
+ if (error.code === "invalid-response") return new CLIError("CID_MISMATCH", "the Share short-link service returned content that does not match the link", 5);
30653
+ return new CLIError("UNAVAILABLE", "the Share short-link service is unavailable; try again shortly", 4);
30654
+ }
28861
30655
  if (error instanceof ShareNotifyError) {
28862
30656
  return new CLIError("INVALID_ARGUMENT", error.message, 2);
28863
30657
  }
28864
30658
  if (error instanceof SharePublishError) {
28865
30659
  const exit = error.code === "authority-required" ? 3 : error.code === "max-bytes-exceeded" ? 7 : 2;
28866
- const code4 = error.code === "authority-required" ? "AUTH_REQUIRED" : error.code === "max-bytes-exceeded" ? "MAX_BYTES_EXCEEDED" : "INVALID_ARGUMENT";
28867
- return new CLIError(code4, error.message, exit);
30660
+ const code5 = error.code === "authority-required" ? "AUTH_REQUIRED" : error.code === "max-bytes-exceeded" ? "MAX_BYTES_EXCEEDED" : "INVALID_ARGUMENT";
30661
+ return new CLIError(code5, error.message, exit);
28868
30662
  }
28869
30663
  if (error instanceof ShareReceiveError) {
28870
30664
  const verification = /* @__PURE__ */ new Set(["cid-mismatch", "decrypt-failed", "envelope-invalid", "origin-mismatch", "signature-invalid", "capability-invalid", "content-integrity-failed"]);
28871
30665
  const exit = error.code === "max-bytes-exceeded" ? 7 : verification.has(error.code) ? 5 : error.code === "expired" || error.code === "fetch-failed" ? 4 : error.code === "invalid-link" || error.code === "unsupported-target" ? 2 : 2;
28872
- const code4 = error.code === "fetch-failed" ? "NOT_FOUND" : error.code.replaceAll("-", "_").toUpperCase();
28873
- return new CLIError(code4, error.message, exit);
30666
+ const code5 = error.code === "fetch-failed" ? "NOT_FOUND" : error.code.replaceAll("-", "_").toUpperCase();
30667
+ return new CLIError(code5, error.message, exit);
28874
30668
  }
28875
30669
  const storageFull = storageFullError(error);
28876
30670
  if (storageFull) return storageFull;
@@ -28898,12 +30692,36 @@ function inputUrl(value, stdin) {
28898
30692
  if (value === void 0 || value.length === 0) throw new CLIError("INVALID_ARGUMENT", "a share URL or - is required", 2);
28899
30693
  return Promise.resolve(value);
28900
30694
  }
30695
+ function resolveLink(link4, expectedOrigin) {
30696
+ return shareServices.shortLinks?.resolve(link4, expectedOrigin) ?? resolveShortLink(link4, { expectedOrigin });
30697
+ }
30698
+ var SHORT_LINK_WARNING = {
30699
+ "rate-limited": "the short-link service is rate limiting this client",
30700
+ capacity: "the short-link service is at capacity",
30701
+ rejected: "the short-link service refused this share",
30702
+ unavailable: "the short-link service could not be reached",
30703
+ "invalid-response": "the short-link service answered incorrectly",
30704
+ "not-found": "the short-link service lost the link",
30705
+ "too-large": "this share is too large for a short link",
30706
+ "token-store-failed": "the short link's delete token could not be saved"
30707
+ };
30708
+ async function linkToShow(result, longLink) {
30709
+ if (longLink || result.link.kind !== "policy" || shareServices.shortLinks === void 0) return { url: result.url };
30710
+ try {
30711
+ return { url: await shareServices.shortLinks.shorten(result) };
30712
+ } catch (error) {
30713
+ const code5 = error instanceof ShortLinkError ? error.code : "unavailable";
30714
+ process.stderr.write(`Warning: no short link (${SHORT_LINK_WARNING[code5]}); printing the long link instead. It works, but it is long and some mail clients may break it.
30715
+ `);
30716
+ return { url: result.url, shortLinkError: code5 };
30717
+ }
30718
+ }
28901
30719
  async function inspectShareInputOnce(value, stdin, expectedOrigin, dependencies = {}) {
28902
30720
  const link4 = stdin || value === "-" ? await (dependencies.read ?? readBoundedUrlStdin)() : await inputUrl(value, false);
28903
30721
  try {
28904
30722
  parseNativeShareUrl(link4);
28905
30723
  } catch {
28906
- return (dependencies.inspect ?? inspectShare)(link4, { expectedOrigin });
30724
+ return (dependencies.inspect ?? inspectShare)(await resolveLink(link4, expectedOrigin), { expectedOrigin });
28907
30725
  }
28908
30726
  throw new CLIError("UNSUPPORTED_LINK", "native bearer links are opaque; receive the link to verify access", 2);
28909
30727
  }
@@ -28977,7 +30795,7 @@ function assertAggregateInputLimit(inputs, maxBytes) {
28977
30795
  }
28978
30796
  function registerShareCommand(program2) {
28979
30797
  const share = program2.command("share").description("Publish and consume TinyCloud Share links");
28980
- share.command("publish <files...>").description("Publish one or more bounded files as a Share, or a folder with an index.html as one self-contained page (anyone links only)").option("--name <filename>", "Filename for stdin input, or the published .html name of a folder").option("--to <target>", "Share target", "anyone").option("--notify", "Email an exact-email recipient, or a domain mailbox on node 1.17.3+").option("--notify-to <address>", "Mailbox to invite for --to domain:<name> --notify (node 1.17.3+)").option("--expires <duration>", "Share lifetime").option("--max-bytes <bytes>", "Bound input bytes").option("--media-type <type>", "Media type for a single input").option("--action <actions...>", "Addressed permission: read, list, or edit").option("--prefix", "Publish multiple inputs beneath one addressed prefix").option("--binary", "Allow non-UTF-8 bearer content").option("--artifact <id>", 'Publish as the next write-once version of an artifact ("new" starts one); the share is pinned to that version').addOption(new Option("--ongoing").hideHelp()).option("--note <text>", "Note stored with the artifact version").option("--json", "Print versioned redacted JSON").option("--viewer-origin <origin>", "Canonical HTTPS viewer origin", SHARE_ORIGIN).action(async (files, options, command) => {
30798
+ share.command("publish <files...>").description("Publish one or more bounded files as a Share, or a folder with an index.html as one self-contained page (anyone links only)").option("--name <filename>", "Filename for stdin input, or the published .html name of a folder").option("--to <target>", "Share target", "anyone").option("--notify", "Email an exact-email recipient, or a domain mailbox on node 1.17.3+").option("--notify-to <address>", "Mailbox to invite for --to domain:<name> --notify (node 1.17.3+)").option("--expires <duration>", "Share lifetime").option("--max-bytes <bytes>", "Bound input bytes").option("--media-type <type>", "Media type for a single input").option("--action <actions...>", "Addressed permission: read, list, or edit").option("--prefix", "Publish multiple inputs beneath one addressed prefix").option("--binary", "Allow non-UTF-8 bearer content").option("--artifact <id>", 'Publish as the next write-once version of an artifact ("new" starts one); the share is pinned to that version').addOption(new Option("--ongoing").hideHelp()).option("--note <text>", "Note stored with the artifact version").option("--json", "Print versioned redacted JSON").option("--long-link", "Print the long self-contained link instead of a short link (addressed shares)").option("--viewer-origin <origin>", "Canonical HTTPS viewer origin", SHARE_ORIGIN).action(async (files, options, command) => {
28981
30799
  try {
28982
30800
  const json = jsonOutput(options, command);
28983
30801
  if (options.ongoing === true) throw new CLIError("UNSUPPORTED_TARGET", ONGOING_UNAVAILABLE, 2);
@@ -29038,7 +30856,7 @@ function registerShareCommand(program2) {
29038
30856
  notify: options.notify === true,
29039
30857
  // The artifact request rides on the adapter call rather than through `publishTargetShare`, whose code is part of
29040
30858
  // the browser bundles (the web-sdk size ceiling counts every byte it carries).
29041
- targetAdapter: artifact === void 0 || shareServices.targetAdapter === void 0 ? shareServices.targetAdapter : { publish: (request) => shareServices.targetAdapter.publish({ ...request, artifact }) }
30859
+ targetAdapter: artifact === void 0 || shareServices.targetAdapter === void 0 ? shareServices.targetAdapter : { publish: (request2) => shareServices.targetAdapter.publish({ ...request2, artifact }) }
29042
30860
  });
29043
30861
  if ("state" in result) {
29044
30862
  if (json) {
@@ -29058,11 +30876,12 @@ function registerShareCommand(program2) {
29058
30876
  }
29059
30877
  if (result.metadata.expiryClamped === true) process.stderr.write(`Share expiry clamped to session expiry (${result.metadata.expiresAt}).
29060
30878
  `);
29061
- if (json) writeJson2({ ...redactPublishedShare(result), history: history2, expiryClamped: result.metadata.expiryClamped === true, ...artifact === void 0 || result.metadata.artifact === void 0 ? {} : { artifactId: result.metadata.artifact.id, version: result.metadata.artifact.version, mode: result.metadata.artifact.mode }, ...notification === void 0 ? {} : { notification } });
30879
+ const shown = await linkToShow(result, options.longLink === true);
30880
+ if (json) writeJson2({ ...redactPublishedShare(result), history: history2, expiryClamped: result.metadata.expiryClamped === true, ...artifact === void 0 || result.metadata.artifact === void 0 ? {} : { artifactId: result.metadata.artifact.id, version: result.metadata.artifact.version, mode: result.metadata.artifact.mode }, ...notification === void 0 ? {} : { notification }, ...shown.shortLinkError === void 0 ? {} : { shortLinkError: shown.shortLinkError } });
29062
30881
  else {
29063
30882
  if (result.metadata.artifact !== void 0) process.stderr.write(`Artifact ${result.metadata.artifact.id} v${result.metadata.artifact.version} (${result.metadata.artifact.mode})
29064
30883
  `);
29065
- publishHuman(result);
30884
+ publishHuman(shown.url);
29066
30885
  }
29067
30886
  } catch (error) {
29068
30887
  return handleError(shareCliError(error));
@@ -29138,7 +30957,7 @@ function registerShareCommand(program2) {
29138
30957
  else receiveHuman(output2);
29139
30958
  return;
29140
30959
  }
29141
- const result = await receiveShare(link4, {
30960
+ const result = await receiveShare(await resolveLink(link4, options.viewerOrigin), {
29142
30961
  expectedOrigin: options.viewerOrigin,
29143
30962
  ...maxBytes === void 0 ? {} : { maxContentBlobBytes: maxBytes }
29144
30963
  });
@@ -29177,7 +30996,9 @@ function registerShareCommand(program2) {
29177
30996
  const json = jsonOutput(options, command);
29178
30997
  if (options.revealLink && json) throw new CLIError("INVALID_ARGUMENT", "--reveal-link cannot be combined with --json", 2);
29179
30998
  if (shareServices.records === void 0) throw new CLIError("AUTH_REQUIRED", "sender history storage is not configured", 3);
29180
- const result = await showShare({ storage: shareServices.records, shareId: id, revealLink: options.revealLink === true, link: options.revealLink ? await shareServices.linkFor?.(id) : void 0 });
30999
+ const record2 = options.revealLink === true ? await shareServices.records.get(id) : void 0;
31000
+ const link4 = record2 === void 0 ? void 0 : await shareServices.shortLinks?.linkFor(record2);
31001
+ const result = await showShare({ storage: shareServices.records, shareId: id, revealLink: options.revealLink === true, ...link4 === void 0 ? {} : { link: link4 } });
29181
31002
  if (json) writeJson2({ protocol: "tinycloud-share", version: 1, share: result });
29182
31003
  else writeJson2(result);
29183
31004
  } catch (error) {
@@ -29221,7 +31042,9 @@ function registerShareCommand(program2) {
29221
31042
  if (result.state === "unsupported") {
29222
31043
  throw new CLIError("UNSUPPORTED_TARGET", result.reason, 2);
29223
31044
  }
29224
- if (json) writeJson2({ protocol: "tinycloud-share", version: 1, result });
31045
+ const shortLink = await shareServices.shortLinks?.discard(record2) ?? "none";
31046
+ if (shortLink === "failed") process.stderr.write("Warning: the share is revoked, but its short link could not be removed; it stops resolving when the share expires.\n");
31047
+ if (json) writeJson2({ protocol: "tinycloud-share", version: 1, result, ...shortLink === "none" ? {} : { shortLink } });
29225
31048
  else process.stdout.write(`${result.state}
29226
31049
  `);
29227
31050
  } catch (error) {
@@ -29309,7 +31132,8 @@ configureShareCommandServices({
29309
31132
  assertDomainDelivery: shareAuthority.assertDomainDelivery,
29310
31133
  revocation: shareAuthority.revocation,
29311
31134
  nativeReader: shareAuthority.nativeReader,
29312
- artifactStore: shareAuthority.artifactStore
31135
+ artifactStore: shareAuthority.artifactStore,
31136
+ shortLinks: shareAuthority.shortLinks
29313
31137
  });
29314
31138
  var argv = process.argv.slice(2);
29315
31139
  var globalLongOptionsWithValues = { "--profile": true, "--host": true };
@@ -29355,8 +31179,8 @@ ${theme.muted("Repo:")} ${theme.accent("https://github.com/tinycloudlabs/web-sdk
29355
31179
  });
29356
31180
  var commandToken = firstCommandToken(argv);
29357
31181
  if (argv[0] === "courier") {
29358
- const code4 = await (await loadCourierEntry()).runCourier(argv.slice(1));
29359
- if (code4 !== 0) process.exit(code4);
31182
+ const code5 = await (await loadCourierEntry()).runCourier(argv.slice(1));
31183
+ if (code5 !== 0) process.exit(code5);
29360
31184
  } else if (commandToken === "courier") {
29361
31185
  process.stderr.write(`${TC_OPTIONS_BEFORE_COURIER}
29362
31186
  `);