@telorun/analyzer 0.35.0 → 0.36.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.d.ts CHANGED
@@ -30,7 +30,7 @@ export { parseModuleRef, isRegistryRef } from "./sources/module-ref.js";
30
30
  export type { ParsedModuleRef } from "./sources/module-ref.js";
31
31
  export { OCI_SCHEME, isOciRef, parseOciRef } from "./sources/oci-ref.js";
32
32
  export type { ParsedOciRef } from "./sources/oci-ref.js";
33
- export { MANIFEST_CACHE_BASE_URL, ManifestCacheSource, manifestCacheKey, manifestCacheUrl, ociManifestCacheCoords, } from "./sources/manifest-cache.js";
33
+ export { MANIFEST_CACHE_BASE_URL, ManifestCacheSource, isHttpsModuleRef, manifestCacheKey, manifestCacheUrl, ociManifestCacheCoords, urlManifestCacheCoords, } from "./sources/manifest-cache.js";
34
34
  export type { ManifestCacheCoords } from "./sources/manifest-cache.js";
35
35
  export { withSyntheticPositions } from "./with-synthetic-positions.js";
36
36
  export { DEFAULT_MANIFEST_FILENAME, DiagnosticSeverity } from "./types.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -18,6 +18,6 @@ export { defaultSources } from "./sources/default-sources.js";
18
18
  export { splitIntegrity, foldIntegrity, verifyIntegrity, verifiedFetch, sha256Base64Url, IntegrityError, } from "./sources/integrity.js";
19
19
  export { parseModuleRef, isRegistryRef } from "./sources/module-ref.js";
20
20
  export { OCI_SCHEME, isOciRef, parseOciRef } from "./sources/oci-ref.js";
21
- export { MANIFEST_CACHE_BASE_URL, ManifestCacheSource, manifestCacheKey, manifestCacheUrl, ociManifestCacheCoords, } from "./sources/manifest-cache.js";
21
+ export { MANIFEST_CACHE_BASE_URL, ManifestCacheSource, isHttpsModuleRef, manifestCacheKey, manifestCacheUrl, ociManifestCacheCoords, urlManifestCacheCoords, } from "./sources/manifest-cache.js";
22
22
  export { withSyntheticPositions } from "./with-synthetic-positions.js";
23
23
  export { DEFAULT_MANIFEST_FILENAME, DiagnosticSeverity } from "./types.js";
@@ -23,6 +23,21 @@ export declare function manifestCacheKey(coords: ManifestCacheCoords): string |
23
23
  * not addressable — the cache is keyed by the human version tag the tracker
24
24
  * enumerated). The inline `#sha256-…` fragment is tolerated and ignored. */
25
25
  export declare function ociManifestCacheCoords(ref: string): ManifestCacheCoords | null;
26
+ /** True for a direct `https://` module manifest ref. Plaintext `http://` is
27
+ * deliberately excluded — the hub serves cached third-party manifests onward,
28
+ * so it never ingests over an unauthenticated channel. */
29
+ export declare function isHttpsModuleRef(ref: string): boolean;
30
+ /** Cache coordinates for a direct `https://host/path/telo.yaml` ref.
31
+ *
32
+ * Unlike OCI, a URL carries no version — a URL addresses one file whose
33
+ * version lives *inside* it (`metadata.version`) — so the caller passes the
34
+ * version it read from the manifest. Returns `null` for a non-https ref, a
35
+ * URL that carries a query or userinfo (both would let two distinct URLs
36
+ * collide onto one key, or smuggle a host), or an unparseable URL.
37
+ *
38
+ * A trailing `telo.yaml` segment is dropped: the key appends the manifest
39
+ * filename itself, so carrying it in `path` would duplicate it. */
40
+ export declare function urlManifestCacheCoords(ref: string, version: string): ManifestCacheCoords | null;
26
41
  /** Full cache URL for a ref or coordinates, or `null` when not addressable. */
27
42
  export declare function manifestCacheUrl(refOrCoords: string | ManifestCacheCoords, baseUrl?: string): string | null;
28
43
  /** Resolves `oci://` module refs against the hub's static manifest cache with a
@@ -1 +1 @@
1
- {"version":3,"file":"manifest-cache.d.ts","sourceRoot":"","sources":["../../src/sources/manifest-cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAKlD;;iFAEiF;AACjF,eAAO,MAAM,uBAAuB,8BAA8B,CAAC;AAEnE;;;;+BAI+B;AAC/B,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAOD;;kEAEkE;AAClE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,mBAAmB,GAAG,MAAM,GAAG,IAAI,CAO3E;AAED;;;6EAG6E;AAC7E,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI,CAY9E;AAID,+EAA+E;AAC/E,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,MAAM,GAAG,mBAAmB,EACzC,OAAO,GAAE,MAAgC,GACxC,MAAM,GAAG,IAAI,CAKf;AAED;;;;;+DAK+D;AAC/D,qBAAa,mBAAoB,YAAW,cAAc;IAC5C,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,GAAE,MAAgC;IAEtE,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAQxB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAalE;;;iEAG6D;IAC7D,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;CAOxD"}
1
+ {"version":3,"file":"manifest-cache.d.ts","sourceRoot":"","sources":["../../src/sources/manifest-cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAKlD;;iFAEiF;AACjF,eAAO,MAAM,uBAAuB,8BAA8B,CAAC;AAEnE;;;;+BAI+B;AAC/B,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAOD;;kEAEkE;AAClE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,mBAAmB,GAAG,MAAM,GAAG,IAAI,CAO3E;AAED;;;6EAG6E;AAC7E,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI,CAY9E;AAID;;2DAE2D;AAC3D,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAErD;AAED;;;;;;;;;oEASoE;AACpE,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI,CAuB/F;AAED,+EAA+E;AAC/E,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,MAAM,GAAG,mBAAmB,EACzC,OAAO,GAAE,MAAgC,GACxC,MAAM,GAAG,IAAI,CAKf;AAED;;;;;+DAK+D;AAC/D,qBAAa,mBAAoB,YAAW,cAAc;IAC5C,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,GAAE,MAAgC;IAEtE,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAQxB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAalE;;;iEAG6D;IAC7D,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;CAOxD"}
@@ -40,6 +40,49 @@ export function ociManifestCacheCoords(ref) {
40
40
  return null;
41
41
  return { transport: "oci", host: parsed.host, path: parsed.repo, version: parsed.reference };
42
42
  }
43
+ /** True for a direct `https://` module manifest ref. Plaintext `http://` is
44
+ * deliberately excluded — the hub serves cached third-party manifests onward,
45
+ * so it never ingests over an unauthenticated channel. */
46
+ export function isHttpsModuleRef(ref) {
47
+ return splitIntegrity(ref).base.startsWith("https://");
48
+ }
49
+ /** Cache coordinates for a direct `https://host/path/telo.yaml` ref.
50
+ *
51
+ * Unlike OCI, a URL carries no version — a URL addresses one file whose
52
+ * version lives *inside* it (`metadata.version`) — so the caller passes the
53
+ * version it read from the manifest. Returns `null` for a non-https ref, a
54
+ * URL that carries a query or userinfo (both would let two distinct URLs
55
+ * collide onto one key, or smuggle a host), or an unparseable URL.
56
+ *
57
+ * A trailing `telo.yaml` segment is dropped: the key appends the manifest
58
+ * filename itself, so carrying it in `path` would duplicate it. */
59
+ export function urlManifestCacheCoords(ref, version) {
60
+ const { base } = splitIntegrity(ref);
61
+ if (!isHttpsModuleRef(base))
62
+ return null;
63
+ let parsed;
64
+ try {
65
+ parsed = new URL(base);
66
+ }
67
+ catch {
68
+ return null;
69
+ }
70
+ // `username`/`password` would mean the authority is not what it looks like
71
+ // (`https://evil.com@internal/…`); a query would make the key ambiguous.
72
+ if (parsed.search !== "" || parsed.username !== "" || parsed.password !== "")
73
+ return null;
74
+ const segments = parsed.pathname.split("/").filter((s) => s !== "");
75
+ if (segments[segments.length - 1] === DEFAULT_MANIFEST_FILENAME)
76
+ segments.pop();
77
+ if (segments.length === 0 || parsed.hostname === "")
78
+ return null;
79
+ return {
80
+ transport: "url",
81
+ host: parsed.host,
82
+ path: segments.map((s) => decodeURIComponent(s)).join("/"),
83
+ version,
84
+ };
85
+ }
43
86
  /** Full cache URL for a ref or coordinates, or `null` when not addressable. */
44
87
  export function manifestCacheUrl(refOrCoords, baseUrl = MANIFEST_CACHE_BASE_URL) {
45
88
  const coords = typeof refOrCoords === "string" ? ociManifestCacheCoords(refOrCoords) : refOrCoords;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@telorun/analyzer",
3
- "version": "0.35.0",
3
+ "version": "0.36.0",
4
4
  "description": "Telo Analyzer - Static manifest validator for Telo manifests.",
5
5
  "keywords": [
6
6
  "telo",
package/src/index.ts CHANGED
@@ -80,9 +80,11 @@ export type { ParsedOciRef } from "./sources/oci-ref.js";
80
80
  export {
81
81
  MANIFEST_CACHE_BASE_URL,
82
82
  ManifestCacheSource,
83
+ isHttpsModuleRef,
83
84
  manifestCacheKey,
84
85
  manifestCacheUrl,
85
86
  ociManifestCacheCoords,
87
+ urlManifestCacheCoords,
86
88
  } from "./sources/manifest-cache.js";
87
89
  export type { ManifestCacheCoords } from "./sources/manifest-cache.js";
88
90
  export { withSyntheticPositions } from "./with-synthetic-positions.js";
@@ -57,6 +57,48 @@ export function ociManifestCacheCoords(ref: string): ManifestCacheCoords | null
57
57
 
58
58
  type ParsedOciRefShape = ReturnType<typeof parseOciRef>;
59
59
 
60
+ /** True for a direct `https://` module manifest ref. Plaintext `http://` is
61
+ * deliberately excluded — the hub serves cached third-party manifests onward,
62
+ * so it never ingests over an unauthenticated channel. */
63
+ export function isHttpsModuleRef(ref: string): boolean {
64
+ return splitIntegrity(ref).base.startsWith("https://");
65
+ }
66
+
67
+ /** Cache coordinates for a direct `https://host/path/telo.yaml` ref.
68
+ *
69
+ * Unlike OCI, a URL carries no version — a URL addresses one file whose
70
+ * version lives *inside* it (`metadata.version`) — so the caller passes the
71
+ * version it read from the manifest. Returns `null` for a non-https ref, a
72
+ * URL that carries a query or userinfo (both would let two distinct URLs
73
+ * collide onto one key, or smuggle a host), or an unparseable URL.
74
+ *
75
+ * A trailing `telo.yaml` segment is dropped: the key appends the manifest
76
+ * filename itself, so carrying it in `path` would duplicate it. */
77
+ export function urlManifestCacheCoords(ref: string, version: string): ManifestCacheCoords | null {
78
+ const { base } = splitIntegrity(ref);
79
+ if (!isHttpsModuleRef(base)) return null;
80
+ let parsed: URL;
81
+ try {
82
+ parsed = new URL(base);
83
+ } catch {
84
+ return null;
85
+ }
86
+ // `username`/`password` would mean the authority is not what it looks like
87
+ // (`https://evil.com@internal/…`); a query would make the key ambiguous.
88
+ if (parsed.search !== "" || parsed.username !== "" || parsed.password !== "") return null;
89
+
90
+ const segments = parsed.pathname.split("/").filter((s) => s !== "");
91
+ if (segments[segments.length - 1] === DEFAULT_MANIFEST_FILENAME) segments.pop();
92
+ if (segments.length === 0 || parsed.hostname === "") return null;
93
+
94
+ return {
95
+ transport: "url",
96
+ host: parsed.host,
97
+ path: segments.map((s) => decodeURIComponent(s)).join("/"),
98
+ version,
99
+ };
100
+ }
101
+
60
102
  /** Full cache URL for a ref or coordinates, or `null` when not addressable. */
61
103
  export function manifestCacheUrl(
62
104
  refOrCoords: string | ManifestCacheCoords,