@geekmidas/manifest 10.0.0-alpha.166 → 10.0.0-alpha.167

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.cjs CHANGED
@@ -76,7 +76,7 @@ const DERIVES_FROM = {
76
76
  * can legitimately use any of them. A bucket's `url` presigns and stays private.
77
77
  */
78
78
  const PUBLIC = {
79
- objects: [],
79
+ objects: ["signedOrigin"],
80
80
  "file-server": ["url"],
81
81
  email: ["inboxUrl"],
82
82
  inbox: [],
@@ -875,8 +875,32 @@ function cookieDomain(urls) {
875
875
  function providedKeyFor(id, kind, role) {
876
876
  if (kind === "secret") return environmentCase(id);
877
877
  if (kind === "telemetry") return "OTEL_EXPORTER_OTLP_ENDPOINT";
878
+ if (kind === "file-server") return provideKey(fileServerName(id), role);
878
879
  return provideKey(id, role);
879
880
  }
881
+ /**
882
+ * What a file server's surface node adds to the construct's id. The bucket
883
+ * keeps the plain id, so serving a bucket you already have adds a node rather
884
+ * than renaming the one holding the data.
885
+ */
886
+ const FILE_SERVER_SUFFIX = "Server";
887
+ /**
888
+ * A file server's surface node id, from the construct's id.
889
+ *
890
+ * @example fileServerSurfaceId('Assets') // 'AssetsServer'
891
+ */
892
+ function fileServerSurfaceId(id) {
893
+ return `${id}${FILE_SERVER_SUFFIX}`;
894
+ }
895
+ /**
896
+ * The construct's id, from its surface node's: what its key and its host are
897
+ * named after.
898
+ *
899
+ * @example fileServerName('AssetsServer') // 'Assets'
900
+ */
901
+ function fileServerName(surfaceId) {
902
+ return surfaceId.endsWith("Server") && surfaceId.length > 6 ? surfaceId.slice(0, -6) : surfaceId;
903
+ }
880
904
  //#endregion
881
905
  //#region src/derive.ts
882
906
  /** Whether a declaration names a parent. */
@@ -1013,16 +1037,74 @@ function publicEnvFor(declaration, manifest) {
1013
1037
  const key = provideKey(declaration.id, role);
1014
1038
  keys[`${prefix}${key}`] = key;
1015
1039
  }
1040
+ const inline = (id, target) => {
1041
+ for (const role of PUBLIC[target.kind] ?? []) {
1042
+ const key = providedKeyFor(id, target.kind, role);
1043
+ keys[`${prefix}${key}`] = key;
1044
+ }
1045
+ };
1016
1046
  for (const edge of declaration.dependencies) {
1017
1047
  const target = manifest[edge.target];
1018
1048
  if (!target) continue;
1019
- for (const role of PUBLIC[target.kind] ?? []) {
1020
- const key = provideKey(edge.target, role);
1021
- keys[`${prefix}${key}`] = key;
1049
+ inline(edge.target, target);
1050
+ if (target.kind === "objects") {
1051
+ for (const [id, other] of Object.entries(manifest)) if (other.kind === "file-server" && other.of === edge.target) inline(id, other);
1052
+ }
1053
+ if (target.kind === "file-server") {
1054
+ const bucket = manifest[target.of];
1055
+ if (bucket) inline(target.of, bucket);
1022
1056
  }
1023
1057
  }
1024
1058
  return keys;
1025
1059
  }
1060
+ /**
1061
+ * The key, under a site's public prefix, that lists every origin its pages
1062
+ * load files from: `NEXT_PUBLIC_GKM_IMAGE_ORIGINS`. Comma-separated.
1063
+ *
1064
+ * One composed key rather than a rule over names, because a file server's
1065
+ * `<ID>_URL` and an API's look the same: which of a bundle's addresses serve
1066
+ * files is a fact about the graph, so the graph says it.
1067
+ */
1068
+ const IMAGE_ORIGINS_KEY = "GKM_IMAGE_ORIGINS";
1069
+ /**
1070
+ * The keys whose values are the origins a site's pages load files from: each
1071
+ * file server it reaches, and where each bucket it reaches signs its links —
1072
+ * by either edge, the same walk {@link publicEnvFor} makes. Sorted, so the
1073
+ * value composed from them does not churn.
1074
+ */
1075
+ function imageOriginSources(declaration, manifest) {
1076
+ const sources = /* @__PURE__ */ new Set();
1077
+ const bucket = (id) => sources.add(providedKeyFor(id, "objects", "signedOrigin"));
1078
+ const server = (id) => sources.add(providedKeyFor(id, "file-server", "url"));
1079
+ for (const edge of declaration.dependencies) {
1080
+ const target = manifest[edge.target];
1081
+ if (target?.kind === "objects") {
1082
+ bucket(edge.target);
1083
+ for (const [id, other] of Object.entries(manifest)) if (other.kind === "file-server" && other.of === edge.target) server(id);
1084
+ }
1085
+ if (target?.kind === "file-server") {
1086
+ server(edge.target);
1087
+ if (manifest[target.of]?.kind === "objects") bucket(target.of);
1088
+ }
1089
+ }
1090
+ return [...sources].sort();
1091
+ }
1092
+ /**
1093
+ * {@link IMAGE_ORIGINS_KEY}'s value: the origin of each source that resolved,
1094
+ * de-duplicated and comma-separated. `undefined` when none did, so a site
1095
+ * that shows no files is built without the key at all.
1096
+ */
1097
+ function imageOrigins(sources, resolve) {
1098
+ const origins = /* @__PURE__ */ new Set();
1099
+ for (const source of sources) {
1100
+ const value = resolve(source);
1101
+ if (!value) continue;
1102
+ try {
1103
+ origins.add(new URL(value).origin);
1104
+ } catch {}
1105
+ }
1106
+ return origins.size > 0 ? [...origins].sort().join(",") : void 0;
1107
+ }
1026
1108
  //#endregion
1027
1109
  //#region src/derived.ts
1028
1110
  /** Where a processor keeps what it made, in the bucket it reads. */
@@ -1451,6 +1533,8 @@ exports.DERIVED_PREFIX = DERIVED_PREFIX;
1451
1533
  exports.DERIVES_FROM = DERIVES_FROM;
1452
1534
  exports.EDGE_TOKEN_HEADER = EDGE_TOKEN_HEADER;
1453
1535
  exports.EDGE_TOKEN_KEY = EDGE_TOKEN_KEY;
1536
+ exports.FILE_SERVER_SUFFIX = FILE_SERVER_SUFFIX;
1537
+ exports.IMAGE_ORIGINS_KEY = IMAGE_ORIGINS_KEY;
1454
1538
  exports.INBOX_EVENT = INBOX_EVENT;
1455
1539
  exports.INBOX_MESSAGES_PREFIX = INBOX_MESSAGES_PREFIX;
1456
1540
  exports.IllegalDerivation = IllegalDerivation;
@@ -1479,6 +1563,10 @@ exports.dependentsOf = dependentsOf;
1479
1563
  exports.drawSecret = drawSecret;
1480
1564
  exports.environmentCase = environmentCase;
1481
1565
  exports.externalApiUrl = externalApiUrl;
1566
+ exports.fileServerName = fileServerName;
1567
+ exports.fileServerSurfaceId = fileServerSurfaceId;
1568
+ exports.imageOriginSources = imageOriginSources;
1569
+ exports.imageOrigins = imageOrigins;
1482
1570
  exports.inboxRecipient = inboxRecipient;
1483
1571
  exports.isDerived = isDerived;
1484
1572
  exports.isWebOrigin = isWebOrigin;