superbee 0.4.4-pre.1 → 0.4.4-pre.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -30978,6 +30978,13 @@ function assertSafeConceptId(id) {
30978
30978
  }
30979
30979
  var FORMAT_AT_EDGE = new RegExp("^\\p{Cf}|\\p{Cf}$", "u");
30980
30980
  var FORMAT_INSIDE = new RegExp("(?![\\u200c\\u200d])\\p{Cf}", "u");
30981
+ function nonCanonicalDocumentId(id) {
30982
+ const segments = id.split("/");
30983
+ if (segments.some((segment) => segment !== segment.trim())) return "segment_whitespace";
30984
+ if (segments.some((segment) => FORMAT_AT_EDGE.test(segment) || FORMAT_INSIDE.test(segment))) return "format_character";
30985
+ if (id !== id.normalize("NFC")) return "not_nfc";
30986
+ return null;
30987
+ }
30981
30988
  function assertSafeBlobKey(key) {
30982
30989
  if (typeof key !== "string" || key.trim() === "") {
30983
30990
  throw new InvalidInputError("Blob key must be a non-empty string.");
@@ -31351,6 +31358,11 @@ function stringifyDoc(frontmatter2, body) {
31351
31358
  return stringifyWithData(frontmatter2, body);
31352
31359
  }
31353
31360
 
31361
+ // ../core/src/code-unit-order.ts
31362
+ function compareCodeUnits(a, b) {
31363
+ return a < b ? -1 : a > b ? 1 : 0;
31364
+ }
31365
+
31354
31366
  // ../core/src/links.ts
31355
31367
  function normalizeSegments(segments) {
31356
31368
  const out = [];
@@ -31372,6 +31384,13 @@ function isExternalHref(href) {
31372
31384
  return /^[a-z][a-z0-9+.-]*:\/\//i.test(h) || h.startsWith("mailto:") || h.startsWith("#");
31373
31385
  }
31374
31386
  function extractMarkdownLinks(source, options = {}) {
31387
+ const out = [];
31388
+ for (const span of extractMarkdownLinkSpans(source, options)) {
31389
+ if (!span.image) out.push({ text: span.text, href: span.href });
31390
+ }
31391
+ return out;
31392
+ }
31393
+ function extractMarkdownLinkSpans(source, options = {}) {
31375
31394
  const body = options.skipCode ? maskMarkdownCode(source) : source;
31376
31395
  const out = [];
31377
31396
  let textOpen = -1;
@@ -31382,12 +31401,16 @@ function extractMarkdownLinks(source, options = {}) {
31382
31401
  const char = body[cursor];
31383
31402
  if (hrefRest) {
31384
31403
  if (char === ")") {
31385
- if (hrefRest.open === 0 || body[hrefRest.open - 1] !== "!") {
31386
- out.push({
31387
- text: source.slice(hrefRest.open + 1, hrefRest.close),
31388
- href: source.slice(hrefRest.hrefStart, cursor)
31389
- });
31390
- }
31404
+ const image = hrefRest.open > 0 && body[hrefRest.open - 1] === "!";
31405
+ out.push({
31406
+ text: source.slice(hrefRest.open + 1, hrefRest.close),
31407
+ href: source.slice(hrefRest.hrefStart, cursor),
31408
+ start: image ? hrefRest.open - 1 : hrefRest.open,
31409
+ end: cursor + 1,
31410
+ hrefStart: hrefRest.hrefStart,
31411
+ hrefEnd: cursor,
31412
+ image
31413
+ });
31391
31414
  textOpen = -1;
31392
31415
  afterClose = void 0;
31393
31416
  hrefFirst = void 0;
@@ -31767,12 +31790,13 @@ async function readDocVersioned(backend, id) {
31767
31790
  function isEnoent(err) {
31768
31791
  return typeof err === "object" && err !== null && err.code === "ENOENT";
31769
31792
  }
31770
- async function readManyExisting(backend, ids, onMalformed) {
31793
+ async function readManyExisting(backend, ids, onMalformed, onAliased) {
31771
31794
  try {
31772
31795
  return await backend.readMany(ids);
31773
31796
  } catch (err) {
31774
- const malformed = err instanceof MalformedDocumentError;
31775
- if (!isEnoent(err) && !(malformed && onMalformed)) throw err;
31797
+ const malformed = err instanceof MalformedDocumentError && onMalformed !== void 0;
31798
+ const aliased = err instanceof FilesystemIdentityAliasError && onAliased !== void 0;
31799
+ if (!isEnoent(err) && !malformed && !aliased) throw err;
31776
31800
  const out = [];
31777
31801
  for (const id of ids) {
31778
31802
  try {
@@ -31783,6 +31807,10 @@ async function readManyExisting(backend, ids, onMalformed) {
31783
31807
  onMalformed({ id, reason: candidate.detail });
31784
31808
  continue;
31785
31809
  }
31810
+ if (candidate instanceof FilesystemIdentityAliasError && onAliased) {
31811
+ onAliased({ id, reason: candidate.message });
31812
+ continue;
31813
+ }
31786
31814
  throw candidate;
31787
31815
  }
31788
31816
  }
@@ -31795,7 +31823,7 @@ async function scanMatching(backend, filter, onSkip) {
31795
31823
  for (const result of await readManyExisting(backend, ids, onSkip)) {
31796
31824
  if (matchesFilter(result.doc, filter)) results.push(result);
31797
31825
  }
31798
- results.sort((a, b) => a.doc.id.localeCompare(b.doc.id));
31826
+ results.sort((a, b) => compareCodeUnits(a.doc.id, b.doc.id));
31799
31827
  return results;
31800
31828
  }
31801
31829
  async function query(backend, filter = {}, options = {}) {
@@ -31804,7 +31832,7 @@ async function query(backend, filter = {}, options = {}) {
31804
31832
  async function queryHeads(backend, filter = {}, options = {}) {
31805
31833
  if (backend.queryHeads) {
31806
31834
  const rows = (await backend.queryHeads(filter, options.onSkip ? { onSkip: options.onSkip } : void 0)).filter((row) => matchesFilter(row, filter));
31807
- rows.sort((a, b) => a.id.localeCompare(b.id));
31835
+ rows.sort((a, b) => compareCodeUnits(a.id, b.id));
31808
31836
  return rows;
31809
31837
  }
31810
31838
  return (await scanMatching(backend, filter, options.onSkip)).map(({ doc, version: version2 }) => ({
@@ -31844,7 +31872,7 @@ async function queryEdges(backend, filter = {}, options = {}) {
31844
31872
  edges.push(link);
31845
31873
  }
31846
31874
  }
31847
- edges.sort((a, b) => a.from.localeCompare(b.from) || a.to.localeCompare(b.to) || a.text.localeCompare(b.text));
31875
+ edges.sort((a, b) => compareCodeUnits(a.from, b.from) || compareCodeUnits(a.to, b.to) || compareCodeUnits(a.text, b.text));
31848
31876
  return edges;
31849
31877
  }
31850
31878
 
@@ -32053,14 +32081,14 @@ async function readOwnerRecord(lockPath) {
32053
32081
  }
32054
32082
  async function resolveOwnerRecord(lockPath, started, waitMs, pollMs) {
32055
32083
  while (true) {
32056
- const record2 = await readOwnerRecord(lockPath);
32057
- if (record2.state !== "unreadable" || Date.now() - started >= waitMs) return record2;
32084
+ const record3 = await readOwnerRecord(lockPath);
32085
+ if (record3.state !== "unreadable" || Date.now() - started >= waitMs) return record3;
32058
32086
  await delay(pollMs);
32059
32087
  }
32060
32088
  }
32061
32089
  async function readOwner(lockPath) {
32062
- const record2 = await readOwnerRecord(lockPath);
32063
- return record2.state === "record" ? record2.owner : null;
32090
+ const record3 = await readOwnerRecord(lockPath);
32091
+ return record3.state === "record" ? record3.owner : null;
32064
32092
  }
32065
32093
  function processExists(pid) {
32066
32094
  try {
@@ -32255,12 +32283,12 @@ async function claimLockPath(lockPath, owner, waitMs, pollMs, policy) {
32255
32283
  }
32256
32284
  async function rollBackOwnClaim(lockPath, owner, claimed, waitMs, pollMs, policy) {
32257
32285
  const started = Date.now();
32258
- const record2 = await resolveOwnerRecord(lockPath, started, waitMs, pollMs);
32259
- if (record2.state === "record") {
32260
- if (record2.owner.token === owner.token) await removeReleasedLock(lockPath, owner, started, waitMs, pollMs, policy);
32286
+ const record3 = await resolveOwnerRecord(lockPath, started, waitMs, pollMs);
32287
+ if (record3.state === "record") {
32288
+ if (record3.owner.token === owner.token) await removeReleasedLock(lockPath, owner, started, waitMs, pollMs, policy);
32261
32289
  return;
32262
32290
  }
32263
- if (record2.state === "unreadable" || !await isClaimedDirectory(lockPath, claimed)) return;
32291
+ if (record3.state === "unreadable" || !await isClaimedDirectory(lockPath, claimed)) return;
32264
32292
  const remnant = releasedLockRemnantPath(lockPath, owner);
32265
32293
  await fs.rename(lockPath, remnant);
32266
32294
  await fs.rm(remnant, { recursive: true, force: true });
@@ -32360,6 +32388,11 @@ async function acquireFilesystemIdentityLock(key, identity, options = {}) {
32360
32388
  return claimLockPath(path.join(lockRoot, `${key}.lock`), owner, waitMs, pollMs, policy);
32361
32389
  }
32362
32390
 
32391
+ // ../core/src/identity-fold.ts
32392
+ function foldSegment(segment) {
32393
+ return segment.normalize("NFKD").toLowerCase().toUpperCase().toLowerCase();
32394
+ }
32395
+
32363
32396
  // ../core/src/filesystem-identity.ts
32364
32397
  async function replaceExistingLeaf(port, tmp, target, rel) {
32365
32398
  try {
@@ -32405,9 +32438,6 @@ function relSegments(rel) {
32405
32438
  }
32406
32439
  return segments;
32407
32440
  }
32408
- function foldSegment(segment) {
32409
- return segment.normalize("NFKD").toLowerCase().toUpperCase().toLowerCase();
32410
- }
32411
32441
  async function existingAnchor(resolved) {
32412
32442
  const tail = [];
32413
32443
  let candidate = resolved;
@@ -33639,11 +33669,11 @@ function isPlainObject(value) {
33639
33669
  const prototype = Object.getPrototypeOf(value);
33640
33670
  return prototype === Object.prototype || prototype === null;
33641
33671
  }
33642
- function hasOwn(record2, key) {
33643
- return Object.prototype.hasOwnProperty.call(record2, key);
33672
+ function hasOwn(record3, key) {
33673
+ return Object.prototype.hasOwnProperty.call(record3, key);
33644
33674
  }
33645
- function setOwn(record2, key, value) {
33646
- Object.defineProperty(record2, key, { value, enumerable: true, configurable: true, writable: true });
33675
+ function setOwn(record3, key, value) {
33676
+ Object.defineProperty(record3, key, { value, enumerable: true, configurable: true, writable: true });
33647
33677
  }
33648
33678
  function isScalar(value) {
33649
33679
  return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
@@ -43199,6 +43229,22 @@ function resolveBound(requested, max) {
43199
43229
  if (requested === void 0 || !Number.isFinite(requested) || requested < 1) return max;
43200
43230
  return Math.min(Math.floor(requested), max);
43201
43231
  }
43232
+ var MAX_STATIC_IMAGE_ASSETS = 4096;
43233
+ var STATIC_IMAGE_PATH = /^\/assets\/(?:[A-Za-z0-9][A-Za-z0-9._-]*\/)*[A-Za-z0-9][A-Za-z0-9._-]*\.(?:png|jpe?g|gif|webp|avif|svg)$/;
43234
+ function staticImageLookup(options) {
43235
+ const lookup = /* @__PURE__ */ new Map();
43236
+ if (options.profile !== "inert" || options.imageAssets === void 0) return lookup;
43237
+ if (!Array.isArray(options.imageAssets) || options.imageAssets.length > MAX_STATIC_IMAGE_ASSETS) {
43238
+ throw new TypeError("static image asset inventory must be a bounded array");
43239
+ }
43240
+ for (const path6 of options.imageAssets) {
43241
+ if (typeof path6 !== "string" || path6.length > 2048 || path6.trim() !== path6 || !STATIC_IMAGE_PATH.test(path6)) {
43242
+ throw new TypeError("static image asset paths must be canonical local image paths");
43243
+ }
43244
+ lookup.set(path6, path6);
43245
+ }
43246
+ return lookup;
43247
+ }
43202
43248
  function textOf(node2) {
43203
43249
  if (node2.type === "text" || node2.type === "inlineCode" || node2.type === "html") {
43204
43250
  return node2.value ?? "";
@@ -43380,7 +43426,21 @@ function renderNode(node2, state, depth, index2) {
43380
43426
  index2
43381
43427
  );
43382
43428
  }
43383
- case "image":
43429
+ case "image": {
43430
+ const source = state.imageAssets.get(node2.url ?? "");
43431
+ if (source !== void 0) {
43432
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
43433
+ "img",
43434
+ {
43435
+ src: source,
43436
+ alt: node2.alt ?? "",
43437
+ loading: "lazy",
43438
+ decoding: "async",
43439
+ referrerPolicy: "no-referrer"
43440
+ },
43441
+ index2
43442
+ );
43443
+ }
43384
43444
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
43385
43445
  "span",
43386
43446
  {
@@ -43394,6 +43454,7 @@ function renderNode(node2, state, depth, index2) {
43394
43454
  },
43395
43455
  index2
43396
43456
  );
43457
+ }
43397
43458
  case "table": {
43398
43459
  const align = node2.align ?? [];
43399
43460
  const rows = node2.children;
@@ -43463,7 +43524,7 @@ function renderMarkdown(body, options) {
43463
43524
  extensions: [gfm()],
43464
43525
  mdastExtensions: [gfmFromMarkdown()]
43465
43526
  });
43466
- const state = { count: 0, bounded: false, options, maxNodes };
43527
+ const state = { count: 0, bounded: false, options, maxNodes, imageAssets: staticImageLookup(options) };
43467
43528
  const children = tree.children;
43468
43529
  const nodes = [];
43469
43530
  let i = 0;
@@ -43543,7 +43604,7 @@ function compareByMeaningfulChange(a, b) {
43543
43604
  } else if (b.timestampMs !== null) {
43544
43605
  return 1;
43545
43606
  }
43546
- return a.id < b.id ? -1 : a.id > b.id ? 1 : 0;
43607
+ return compareCodeUnits(a.id, b.id);
43547
43608
  }
43548
43609
  function sortByMeaningfulChange(rows, okfVersion) {
43549
43610
  return rows.map((row) => ({ row, key: meaningfulChangeOrderKey(row.id, row.frontmatter, okfVersion) })).sort((a, b) => compareByMeaningfulChange(a.key, b.key)).map(({ row }) => row);
@@ -43790,7 +43851,7 @@ function replyWithinLimit(reply) {
43790
43851
  }
43791
43852
  function skippedReply(skipped) {
43792
43853
  if (skipped.length === 0) return {};
43793
- return { skipped: [...skipped].sort((a, b) => a.id.localeCompare(b.id)).slice(0, MAX_QUERY_ROWS) };
43854
+ return { skipped: [...skipped].sort((a, b) => compareCodeUnits(a.id, b.id)).slice(0, MAX_QUERY_ROWS) };
43794
43855
  }
43795
43856
  function boundedRows(rows, params, kinds) {
43796
43857
  const requested = params.limit === 0 || params.limit === void 0 ? MAX_QUERY_ROWS : Math.min(params.limit, MAX_QUERY_ROWS);
@@ -43905,7 +43966,7 @@ var BridgeService = class {
43905
43966
  for (const id of subscription.baseline.keys()) {
43906
43967
  if (!next.has(id)) removed.push(id);
43907
43968
  }
43908
- changes.sort((a, b) => a.id.localeCompare(b.id));
43969
+ changes.sort((a, b) => compareCodeUnits(a.id, b.id));
43909
43970
  removed.sort();
43910
43971
  if (changes.length === 0 && removed.length === 0) return { status: "unchanged" };
43911
43972
  if (changes.length > MAX_CHANGE_ROWS || removed.length > MAX_CHANGE_ROWS) {
@@ -43934,7 +43995,7 @@ var BridgeService = class {
43934
43995
  throw new Error("the bundle is too large for the experimental View polling snapshot");
43935
43996
  }
43936
43997
  return new Map(
43937
- [...rows].sort((a, b) => a.id.localeCompare(b.id)).map((row) => [row.id, row.version])
43998
+ [...rows].sort((a, b) => compareCodeUnits(a.id, b.id)).map((row) => [row.id, row.version])
43938
43999
  );
43939
44000
  }
43940
44001
  /**
@@ -44537,22 +44598,22 @@ function buildSnapshot(first) {
44537
44598
  });
44538
44599
  relationships.push(...parseLinksFromDoc(doc).map((link) => ({ ...link })));
44539
44600
  }
44540
- documents.sort((a, b) => a.id.localeCompare(b.id));
44541
- relationships.sort((a, b) => a.from.localeCompare(b.from) || a.to.localeCompare(b.to) || a.text.localeCompare(b.text) || a.href.localeCompare(b.href));
44601
+ documents.sort((a, b) => compareCodeUnits(a.id, b.id));
44602
+ relationships.sort((a, b) => compareCodeUnits(a.from, b.from) || compareCodeUnits(a.to, b.to) || compareCodeUnits(a.text, b.text) || compareCodeUnits(a.href, b.href));
44542
44603
  const reserved = first.reserved.map((row) => ({
44543
44604
  dir: row.dir,
44544
44605
  name: row.name,
44545
44606
  version: row.version,
44546
44607
  object: addObject(objects, row.bytes, "text/markdown; charset=utf-8", "exact")
44547
44608
  }));
44548
- reserved.sort((a, b) => `${a.dir}/${a.name}`.localeCompare(`${b.dir}/${b.name}`));
44609
+ reserved.sort((a, b) => compareCodeUnits(`${a.dir}/${a.name}`, `${b.dir}/${b.name}`));
44549
44610
  const blobs = first.blobs.map((row) => ({
44550
44611
  key: row.key,
44551
44612
  version: row.version,
44552
44613
  contentType: row.contentType,
44553
44614
  object: addObject(objects, row.bytes, row.contentType, "exact")
44554
44615
  }));
44555
- blobs.sort((a, b) => a.key.localeCompare(b.key));
44616
+ blobs.sort((a, b) => compareCodeUnits(a.key, b.key));
44556
44617
  const blobsByKey = new Map(blobs.map((row) => [row.key, row]));
44557
44618
  const views = [];
44558
44619
  for (const { doc, version: version2 } of parsedDocs.values()) {
@@ -44561,15 +44622,15 @@ function buildSnapshot(first) {
44561
44622
  if (!registration) {
44562
44623
  throw new PublicationError("INVALID_VIEW_REGISTRATION", "a View registration is invalid", { subject: doc.id });
44563
44624
  }
44564
- const blob = blobsByKey.get(registration.entry);
44565
- if (!blob) {
44625
+ const blob2 = blobsByKey.get(registration.entry);
44626
+ if (!blob2) {
44566
44627
  throw new PublicationError("VIEW_ENTRY_MISSING", "a registered View entry is missing", { subject: doc.id });
44567
44628
  }
44568
- if (registration.entryVersion && registration.entryVersion !== blob.version) {
44629
+ if (registration.entryVersion && registration.entryVersion !== blob2.version) {
44569
44630
  throw new PublicationError("VIEW_ENTRY_VERSION_MISMATCH", "a registered View entry no longer matches its pin", {
44570
44631
  subject: doc.id,
44571
44632
  expected: registration.entryVersion,
44572
- actual: blob.version
44633
+ actual: blob2.version
44573
44634
  });
44574
44635
  }
44575
44636
  const rawBlob = first.blobs.find((candidate) => candidate.key === registration.entry);
@@ -44590,11 +44651,11 @@ function buildSnapshot(first) {
44590
44651
  ...presentation === "workspace" || presentation === "inline" || presentation === "adaptive" ? { presentation } : {},
44591
44652
  access: resolveDeclaredAccess(doc.frontmatter),
44592
44653
  entry: registration.entry,
44593
- entryVersion: blob.version,
44594
- entryObject: blob.object
44654
+ entryVersion: blob2.version,
44655
+ entryObject: blob2.object
44595
44656
  });
44596
44657
  }
44597
- views.sort((a, b) => a.id.localeCompare(b.id));
44658
+ views.sort((a, b) => compareCodeUnits(a.id, b.id));
44598
44659
  const withoutDigest = {
44599
44660
  schema: PUBLICATION_SNAPSHOT_V1,
44600
44661
  schemaVersion: 1,
@@ -45020,18 +45081,157 @@ function assertPublicationSourceExclusions(source, exclusions) {
45020
45081
  return slash > 0 && directories.has(fold(path6.slice(0, slash)));
45021
45082
  };
45022
45083
  const excludedType = (type) => type !== void 0 && type !== null && (types.has(kind(type)) || Array.isArray(type) && type.flat(Infinity).some((value) => types.has(kind(value))));
45023
- const count = source.documents.filter((document3) => excludedPath(document3.id) || excludedType(document3.frontmatter.type)).length + source.reserved.filter((file) => excludedPath(`${file.dir}/${file.name}`)).length + source.blobs.filter((blob) => excludedPath(blob.key)).length;
45084
+ const count = source.documents.filter((document3) => excludedPath(document3.id) || excludedType(document3.frontmatter.type)).length + source.reserved.filter((file) => excludedPath(`${file.dir}/${file.name}`)).length + source.blobs.filter((blob2) => excludedPath(blob2.key)).length;
45024
45085
  if (count > 0) throw new PublicationError("INVALID_BUNDLE", "the publication source contains excluded content", { details: { excludedEntries: count } });
45025
45086
  }
45087
+
45088
+ // ../core/src/json-data.ts
45089
+ function isJsonData(value, depth = 0) {
45090
+ if (depth > 32) return false;
45091
+ if (value === null || typeof value === "string" || typeof value === "boolean") return true;
45092
+ if (typeof value === "number") return Number.isFinite(value);
45093
+ if (Array.isArray(value)) return value.every((item) => isJsonData(item, depth + 1));
45094
+ if (value === null || typeof value !== "object") return false;
45095
+ const proto = Object.getPrototypeOf(value);
45096
+ if (proto !== null && Object.getPrototypeOf(proto) !== null) return false;
45097
+ return Object.values(value).every((item) => item !== void 0 && isJsonData(item, depth + 1));
45098
+ }
45099
+
45100
+ // ../core/src/site-manifest.ts
45101
+ var SITE_TYPE = "Site";
45102
+ var SITES_PREFIX = "sites/";
45103
+ var SITE_LABEL = /^[a-z][a-z0-9-]{1,30}[a-z0-9]$/;
45104
+ var isSiteLabel = (value) => typeof value === "string" && SITE_LABEL.test(value) && !value.includes("--");
45105
+ var SITE_DOCUMENT_KEYS = ["type", "title", "description", "presentation", "landing", "views", "audience", "capabilities", "options", "brand"];
45106
+ var record2 = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
45107
+ var packageName = /^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*$/;
45108
+ var exactVersion = /^(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-]+)*))?$/;
45109
+ var encoder2 = new TextEncoder();
45110
+ function presentationReference(raw) {
45111
+ if (typeof raw !== "string" || raw.length > 512) return void 0;
45112
+ if (raw.startsWith("repo:")) {
45113
+ const repository = raw.slice(5);
45114
+ return /^[A-Za-z0-9][A-Za-z0-9-]{0,38}\/[A-Za-z0-9][A-Za-z0-9._-]{0,99}$/.test(repository) && !repository.endsWith(".git") ? { kind: "repository", repository } : void 0;
45115
+ }
45116
+ const at = raw.lastIndexOf("@");
45117
+ if (at < 1) return void 0;
45118
+ const name = raw.slice(0, at), version2 = raw.slice(at + 1), match = exactVersion.exec(version2);
45119
+ if (name.length > 214 || !packageName.test(name) || !match || !match.slice(1, 4).every((part) => Number.isSafeInteger(Number(part))) || match[4]?.split(".").some((part) => /^\d+$/.test(part) && (part.length > 1 && part.startsWith("0") || !Number.isSafeInteger(Number(part))))) return void 0;
45120
+ return { kind: "package", name, version: version2 };
45121
+ }
45122
+ var concept = (raw) => {
45123
+ if (typeof raw !== "string") return false;
45124
+ try {
45125
+ assertSafeConceptId(raw);
45126
+ return nonCanonicalDocumentId(raw) === null;
45127
+ } catch {
45128
+ return false;
45129
+ }
45130
+ };
45131
+ var blob = (raw) => {
45132
+ if (typeof raw !== "string") return false;
45133
+ try {
45134
+ assertSafeBlobKey(raw);
45135
+ return true;
45136
+ } catch {
45137
+ return false;
45138
+ }
45139
+ };
45140
+ function parseSiteManifestDoc(doc) {
45141
+ const errors = [];
45142
+ const fail2 = (path6, message) => {
45143
+ errors.push({ code: "SITE_MANIFEST_INVALID", path: path6, message });
45144
+ };
45145
+ const fm = record2(doc?.frontmatter) ? doc.frontmatter : {};
45146
+ const site = typeof doc?.id === "string" && doc.id.startsWith(SITES_PREFIX) ? doc.id.slice(SITES_PREFIX.length) : "";
45147
+ if (!isSiteLabel(site)) fail2("/id", "a Site lives at sites/<site>, using one site label");
45148
+ if (fm.type !== SITE_TYPE) fail2("/type", "type must be Site");
45149
+ if (Object.keys(fm).some((key) => !SITE_DOCUMENT_KEYS.includes(key) && !isOkfStandardField(key) && !isManagedDocumentMetadataField(key)))
45150
+ fail2("", "unrecognized Site fields");
45151
+ if (typeof fm.title !== "string" || fm.title.trim() === "" || encoder2.encode(fm.title).byteLength > 512)
45152
+ fail2("/title", "title must be a nonempty string of at most 512 bytes");
45153
+ if (fm.description !== void 0 && (typeof fm.description !== "string" || encoder2.encode(fm.description).byteLength > 8192))
45154
+ fail2("/description", "description must be a string of at most 8192 bytes");
45155
+ const presentation = presentationReference(fm.presentation);
45156
+ if (!presentation) fail2("/presentation", "presentation must name an exact npm version or repo:owner/name");
45157
+ if (fm.audience !== "restricted") fail2("/audience", "only the restricted audience is supported");
45158
+ const list3 = (raw, path6, maximum, valid) => {
45159
+ if (!Array.isArray(raw) || raw.length > maximum || !raw.every(valid) || new Set(raw).size !== raw.length) {
45160
+ fail2(path6, "expected a bounded list of unique valid references");
45161
+ return [];
45162
+ }
45163
+ return [...raw];
45164
+ };
45165
+ const views = list3(fm.views, "/views", 64, concept);
45166
+ const capability = (v) => typeof v === "string" && /^[a-z][a-z0-9-]{0,63}$/.test(v);
45167
+ const capabilities = list3(fm.capabilities ?? [], "/capabilities", 16, capability);
45168
+ if (fm.landing !== void 0 && !concept(fm.landing)) fail2("/landing", "landing must be a canonical document or View id");
45169
+ const options = fm.options ?? {};
45170
+ if (!record2(options) || !isJsonData(options) || encoder2.encode(JSON.stringify(options)).byteLength > 16384)
45171
+ fail2("/options", "options must be JSON data of at most 16384 bytes");
45172
+ let brand;
45173
+ if (fm.brand !== void 0) {
45174
+ if (!record2(fm.brand) || Object.keys(fm.brand).some((key) => key !== "logo" && key !== "fonts")) fail2("/brand", "brand may only name a logo and fonts");
45175
+ else {
45176
+ if (fm.brand.logo !== void 0 && !blob(fm.brand.logo)) fail2("/brand/logo", "logo must be a bundle blob reference");
45177
+ const fonts = fm.brand.fonts === void 0 ? void 0 : list3(fm.brand.fonts, "/brand/fonts", 16, blob);
45178
+ brand = { ...typeof fm.brand.logo === "string" ? { logo: fm.brand.logo } : {}, ...fonts ? { fonts } : {} };
45179
+ }
45180
+ }
45181
+ if (errors.length) return { ok: false, errors };
45182
+ return { ok: true, manifest: {
45183
+ id: doc.id,
45184
+ site,
45185
+ title: fm.title,
45186
+ presentation,
45187
+ audience: "restricted",
45188
+ views,
45189
+ capabilities,
45190
+ options: JSON.parse(JSON.stringify(options)),
45191
+ ...fm.description === void 0 ? {} : { description: fm.description },
45192
+ ...fm.landing === void 0 ? {} : { landing: fm.landing },
45193
+ ...brand ? { brand } : {}
45194
+ } };
45195
+ }
45196
+
45197
+ // ../publication/src/site-manifest.ts
45198
+ function readPublicationSiteManifest(snapshot, site) {
45199
+ const declarations = snapshot.documents.filter((doc) => doc.frontmatter.type === SITE_TYPE);
45200
+ if (declarations.length !== 1 || declarations[0].id !== `${SITES_PREFIX}${site}`)
45201
+ return { ok: false, errors: [{ code: "SITE_MANIFEST_INVALID", path: "/id", message: "the publication requires exactly one Site at sites/<site>" }] };
45202
+ const parsed = parseSiteManifestDoc(declarations[0]);
45203
+ if (!parsed.ok) return parsed;
45204
+ const { manifest } = parsed;
45205
+ const views = new Set(snapshot.views.map((view) => view.id));
45206
+ const documents = new Set(snapshot.documents.map((doc) => doc.id));
45207
+ const blobs = new Set(snapshot.blobs.map((blob2) => blob2.key));
45208
+ const errors = [];
45209
+ const fail2 = (path6, message) => {
45210
+ errors.push({ code: "SITE_MANIFEST_INVALID", path: path6, message });
45211
+ };
45212
+ if (manifest.views.some((id) => !views.has(id))) fail2("/views", "every declared View must be registered in this publication");
45213
+ if (manifest.landing !== void 0 && !documents.has(manifest.landing)) fail2("/landing", "landing must name a document or View in this publication");
45214
+ if (manifest.landing !== void 0 && views.has(manifest.landing) && !manifest.views.includes(manifest.landing)) fail2("/landing", "a landing View must be declared by this Site");
45215
+ if (manifest.brand?.logo !== void 0 && !blobs.has(manifest.brand.logo)) fail2("/brand/logo", "the logo must be a blob in this publication");
45216
+ if (manifest.brand?.fonts?.some((key) => !blobs.has(key))) fail2("/brand/fonts", "every font must be a blob in this publication");
45217
+ return errors.length ? { ok: false, errors } : parsed;
45218
+ }
45026
45219
  export {
45027
45220
  PUBLICATION_BRIDGE_V0,
45028
45221
  PUBLICATION_SNAPSHOT_SCHEMA_V1,
45029
45222
  PUBLICATION_SNAPSHOT_V1,
45030
45223
  PublicationError,
45224
+ SITES_PREFIX,
45225
+ SITE_DOCUMENT_KEYS,
45226
+ SITE_LABEL,
45227
+ SITE_TYPE,
45031
45228
  assertPublicationSourceExclusions,
45032
45229
  capturePublicationSnapshot,
45033
45230
  createPublicationBridge,
45034
- isPublicationError
45231
+ isPublicationError,
45232
+ isSiteLabel,
45233
+ parseSiteManifestDoc,
45234
+ readPublicationSiteManifest
45035
45235
  };
45036
45236
  /*! Bundled license information:
45037
45237