@browsercore/testing 0.1.3 → 0.2.1

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.
Files changed (201) hide show
  1. package/README.md +5 -0
  2. package/bin/coverage-md.mjs +99 -0
  3. package/captures/DIVERGENCE_REPORT.md +325 -0
  4. package/captures/IMPERSIONATION_GAPS_REPORT.md +367 -0
  5. package/captures/README.md +56 -0
  6. package/captures/REVIEW_FINDINGS.md +71 -0
  7. package/captures/_probe/analyze.py +67 -0
  8. package/captures/_probe/capture_bytes.py +127 -0
  9. package/captures/_probe/chrome131_determinism.py +32 -0
  10. package/captures/_probe/diagnose_capture.py +59 -0
  11. package/captures/_probe/golden_analysis.py +91 -0
  12. package/captures/_probe/inspect_golden.py +55 -0
  13. package/captures/_probe/inspect_sv.py +16 -0
  14. package/captures/_probe/make_golden.py +170 -0
  15. package/captures/_probe/output/chrome100.json +219 -0
  16. package/captures/_probe/output/chrome101.json +219 -0
  17. package/captures/_probe/output/chrome104.json +219 -0
  18. package/captures/_probe/output/chrome107.json +220 -0
  19. package/captures/_probe/output/chrome110.json +220 -0
  20. package/captures/_probe/output/chrome116.json +220 -0
  21. package/captures/_probe/output/chrome119.json +219 -0
  22. package/captures/_probe/output/chrome120.json +219 -0
  23. package/captures/_probe/output/chrome123.json +223 -0
  24. package/captures/_probe/output/chrome124.json +224 -0
  25. package/captures/_probe/output/chrome131.json +224 -0
  26. package/captures/_probe/output/chrome131_fresh.json +224 -0
  27. package/captures/_probe/output/chrome133a.json +224 -0
  28. package/captures/_probe/output/chrome136.json +224 -0
  29. package/captures/_probe/output/chrome99.json +219 -0
  30. package/captures/_probe/output/edge101.json +219 -0
  31. package/captures/_probe/output/edge99.json +219 -0
  32. package/captures/_probe/output/firefox133.json +227 -0
  33. package/captures/_probe/output/firefox135.json +230 -0
  34. package/captures/_probe/output/safari155.json +210 -0
  35. package/captures/_probe/output/safari170.json +214 -0
  36. package/captures/_probe/output/safari170_fresh.json +214 -0
  37. package/captures/_probe/output/safari180.json +216 -0
  38. package/captures/_probe/output/safari180_ios.json +216 -0
  39. package/captures/_probe/output/safari184.json +215 -0
  40. package/captures/_probe/output/safari260.json +211 -0
  41. package/captures/_probe/output/summary.json +2520 -0
  42. package/captures/_probe/parse_existing_settings.py +15 -0
  43. package/captures/_probe/peetprint.py +39 -0
  44. package/captures/_probe/probe.py +137 -0
  45. package/captures/_probe/raw_bytes/chrome-131_client_hello.bin +0 -0
  46. package/captures/_probe/raw_bytes/chrome-131_client_hello.hex +32 -0
  47. package/captures/_probe/raw_bytes/firefox-133_client_hello.bin +0 -0
  48. package/captures/_probe/raw_bytes/firefox-133_client_hello.hex +32 -0
  49. package/captures/_probe/raw_bytes/safari-17_client_hello.bin +0 -0
  50. package/captures/_probe/raw_bytes/safari-17_client_hello.hex +32 -0
  51. package/captures/_probe/relay_capture.py +137 -0
  52. package/captures/_probe/socks_capture.py +138 -0
  53. package/captures/_probe/validate_fresh.py +66 -0
  54. package/captures/_probe/validate_golden.py +97 -0
  55. package/captures/_probe/verify_capture.py +68 -0
  56. package/captures/chrome-131/http2/settings.bin +0 -0
  57. package/captures/chrome-131/http2/settings.meta.json +9 -0
  58. package/captures/chrome-131/oracle_capture.reference.json +224 -0
  59. package/captures/chrome-131/tls/client_hello.bin +0 -0
  60. package/captures/chrome-131/tls/client_hello.meta.json +20 -0
  61. package/captures/chrome-140/http2/settings.bin +0 -0
  62. package/captures/chrome-140/http2/settings.meta.json +9 -0
  63. package/captures/chrome-140/tls/client_hello.bin +0 -0
  64. package/captures/chrome-140/tls/client_hello.meta.json +12 -0
  65. package/captures/firefox-128/tls/client_hello.bin +0 -0
  66. package/captures/firefox-128/tls/client_hello.meta.json +12 -0
  67. package/captures/firefox-133/http2/settings.bin +0 -0
  68. package/captures/firefox-133/http2/settings.meta.json +9 -0
  69. package/captures/firefox-133/oracle_capture.reference.json +227 -0
  70. package/captures/firefox-133/tls/client_hello.bin +0 -0
  71. package/captures/firefox-133/tls/client_hello.meta.json +20 -0
  72. package/captures/safari-17/http2/settings.bin +0 -0
  73. package/captures/safari-17/http2/settings.meta.json +9 -0
  74. package/captures/safari-17/oracle_capture.reference.json +214 -0
  75. package/captures/safari-17/tls/client_hello.bin +0 -0
  76. package/captures/safari-17/tls/client_hello.meta.json +20 -0
  77. package/captures/test-malformed/http2/settings.bin +0 -0
  78. package/captures/test-malformed/http2/settings.meta.json +9 -0
  79. package/captures/test-no-extensions/tls/client_hello.bin +0 -0
  80. package/captures/test-no-extensions/tls/client_hello.meta.json +9 -0
  81. package/captures/test-wrong-type/http2/settings.bin +0 -0
  82. package/captures/test-wrong-type/http2/settings.meta.json +9 -0
  83. package/dist/bench/bench.d.ts +24 -6
  84. package/dist/bench/bench.d.ts.map +1 -1
  85. package/dist/bench/bench.js +110 -10
  86. package/dist/bench/bench.js.map +1 -1
  87. package/dist/captures/manifest.d.ts.map +1 -1
  88. package/dist/captures/manifest.js +7 -7
  89. package/dist/captures/manifest.js.map +1 -1
  90. package/dist/categories/compression.d.ts +6 -4
  91. package/dist/categories/compression.d.ts.map +1 -1
  92. package/dist/categories/compression.js +56 -6
  93. package/dist/categories/compression.js.map +1 -1
  94. package/dist/categories/cookies.d.ts +3 -2
  95. package/dist/categories/cookies.d.ts.map +1 -1
  96. package/dist/categories/cookies.js +216 -11
  97. package/dist/categories/cookies.js.map +1 -1
  98. package/dist/categories/redirects.d.ts +8 -2
  99. package/dist/categories/redirects.d.ts.map +1 -1
  100. package/dist/categories/redirects.js +97 -12
  101. package/dist/categories/redirects.js.map +1 -1
  102. package/dist/e2e/cert-gen.d.ts +31 -0
  103. package/dist/e2e/cert-gen.d.ts.map +1 -0
  104. package/dist/e2e/cert-gen.js +158 -0
  105. package/dist/e2e/cert-gen.js.map +1 -0
  106. package/dist/e2e/parse-clienthello.d.ts +177 -0
  107. package/dist/e2e/parse-clienthello.d.ts.map +1 -0
  108. package/dist/e2e/parse-clienthello.js +343 -0
  109. package/dist/e2e/parse-clienthello.js.map +1 -0
  110. package/dist/e2e/sink-server.d.ts +109 -0
  111. package/dist/e2e/sink-server.d.ts.map +1 -0
  112. package/dist/e2e/sink-server.js +292 -0
  113. package/dist/e2e/sink-server.js.map +1 -0
  114. package/dist/e2e/traffic-server.d.ts +48 -0
  115. package/dist/e2e/traffic-server.d.ts.map +1 -0
  116. package/dist/e2e/traffic-server.js +162 -0
  117. package/dist/e2e/traffic-server.js.map +1 -0
  118. package/dist/errors.d.ts.map +1 -1
  119. package/dist/errors.js.map +1 -1
  120. package/dist/fingerprint/index.d.ts +5 -2
  121. package/dist/fingerprint/index.d.ts.map +1 -1
  122. package/dist/fingerprint/index.js +3 -2
  123. package/dist/fingerprint/index.js.map +1 -1
  124. package/dist/fingerprint/ja3.d.ts.map +1 -1
  125. package/dist/fingerprint/ja3.js +33 -4
  126. package/dist/fingerprint/ja3.js.map +1 -1
  127. package/dist/fingerprint/ja4-errors.d.ts +17 -0
  128. package/dist/fingerprint/ja4-errors.d.ts.map +1 -0
  129. package/dist/fingerprint/ja4-errors.js +20 -0
  130. package/dist/fingerprint/ja4-errors.js.map +1 -0
  131. package/dist/fingerprint/ja4-reader.d.ts +44 -0
  132. package/dist/fingerprint/ja4-reader.d.ts.map +1 -0
  133. package/dist/fingerprint/ja4-reader.js +112 -0
  134. package/dist/fingerprint/ja4-reader.js.map +1 -0
  135. package/dist/fingerprint/ja4.d.ts +11 -43
  136. package/dist/fingerprint/ja4.d.ts.map +1 -1
  137. package/dist/fingerprint/ja4.js +54 -141
  138. package/dist/fingerprint/ja4.js.map +1 -1
  139. package/dist/fingerprint/ja4h.d.ts +46 -0
  140. package/dist/fingerprint/ja4h.d.ts.map +1 -0
  141. package/dist/fingerprint/ja4h.js +50 -0
  142. package/dist/fingerprint/ja4h.js.map +1 -0
  143. package/dist/golden/golden.d.ts +15 -1
  144. package/dist/golden/golden.d.ts.map +1 -1
  145. package/dist/golden/golden.js +42 -28
  146. package/dist/golden/golden.js.map +1 -1
  147. package/dist/index.d.ts +21 -1
  148. package/dist/index.d.ts.map +1 -1
  149. package/dist/index.js +36 -1
  150. package/dist/index.js.map +1 -1
  151. package/dist/node-provider.d.ts +42 -0
  152. package/dist/node-provider.d.ts.map +1 -0
  153. package/dist/node-provider.js +53 -0
  154. package/dist/node-provider.js.map +1 -0
  155. package/dist/provider.d.ts +52 -0
  156. package/dist/provider.d.ts.map +1 -0
  157. package/dist/provider.js +14 -0
  158. package/dist/provider.js.map +1 -0
  159. package/dist/reference/browser-provider.d.ts +33 -0
  160. package/dist/reference/browser-provider.d.ts.map +1 -0
  161. package/dist/reference/browser-provider.js +61 -0
  162. package/dist/reference/browser-provider.js.map +1 -0
  163. package/dist/reference/curl-provider.d.ts +40 -0
  164. package/dist/reference/curl-provider.d.ts.map +1 -0
  165. package/dist/reference/curl-provider.js +96 -0
  166. package/dist/reference/curl-provider.js.map +1 -0
  167. package/dist/reference/dump.d.ts +42 -0
  168. package/dist/reference/dump.d.ts.map +1 -0
  169. package/dist/reference/dump.js +102 -0
  170. package/dist/reference/dump.js.map +1 -0
  171. package/dist/reference/node-crypto-provider.d.ts +31 -0
  172. package/dist/reference/node-crypto-provider.d.ts.map +1 -0
  173. package/dist/reference/node-crypto-provider.js +199 -0
  174. package/dist/reference/node-crypto-provider.js.map +1 -0
  175. package/dist/reference/node-reference.d.ts.map +1 -1
  176. package/dist/reference/node-reference.js +2 -5
  177. package/dist/reference/node-reference.js.map +1 -1
  178. package/dist/reference/reference-errors.d.ts +36 -0
  179. package/dist/reference/reference-errors.d.ts.map +1 -0
  180. package/dist/reference/reference-errors.js +43 -0
  181. package/dist/reference/reference-errors.js.map +1 -0
  182. package/dist/reference/reference-types.d.ts +33 -0
  183. package/dist/reference/reference-types.d.ts.map +1 -0
  184. package/dist/reference/reference-types.js +9 -0
  185. package/dist/reference/reference-types.js.map +1 -0
  186. package/dist/reference/reference.d.ts +14 -77
  187. package/dist/reference/reference.d.ts.map +1 -1
  188. package/dist/reference/reference.js +43 -207
  189. package/dist/reference/reference.js.map +1 -1
  190. package/dist/rfc/rfcTests.d.ts +46 -8
  191. package/dist/rfc/rfcTests.d.ts.map +1 -1
  192. package/dist/rfc/rfcTests.js +203 -16
  193. package/dist/rfc/rfcTests.js.map +1 -1
  194. package/dist/types.d.ts +2 -1
  195. package/dist/types.d.ts.map +1 -1
  196. package/dist/types.js.map +1 -1
  197. package/dist/utils.d.ts +3 -0
  198. package/dist/utils.d.ts.map +1 -1
  199. package/dist/utils.js +11 -5
  200. package/dist/utils.js.map +1 -1
  201. package/package.json +68 -55
@@ -0,0 +1,46 @@
1
+ /**
2
+ * JA4H — the HTTP-layer sibling of JA4 (docs/TEST-SUITE.md, Category 4).
3
+ *
4
+ * JA4H fingerprints an HTTP request from its method, version, header order,
5
+ * cookies, and Accept-Language prefix. It is the HTTP analogue computed by the
6
+ * reference provider to fingerprint a captured request. Independent of the TLS
7
+ * ClientHello parsing in `ja4.ts`.
8
+ *
9
+ * Reference: https://github.com/FoxIO-LLC/JA4
10
+ */
11
+ /** The four computed JA4H parts. */
12
+ export interface Ja4hFingerprint {
13
+ readonly a: string;
14
+ readonly b: string;
15
+ readonly c: string;
16
+ readonly d: string;
17
+ /** Canonical `JA4H_a_JA4H_b_JA4H_c_JA4H_d` tag. */
18
+ readonly tag: string;
19
+ }
20
+ /**
21
+ * HTTP request fields needed to compute a JA4H fingerprint.
22
+ *
23
+ * Only the parts JA4H inspects are required — method, HTTP version, header
24
+ * names (in order), cookies, and the Accept-Language prefix.
25
+ */
26
+ export interface Ja4hRequest {
27
+ readonly method: "GET" | "POST" | "HEAD" | "PUT" | "DELETE" | "OPTIONS" | "PATCH";
28
+ readonly httpVersion: "1.1" | "2" | "3";
29
+ /** Header names in the order they are serialized (lowercased). */
30
+ readonly headerNames: readonly string[];
31
+ /** Cookie name=value pairs (as they appear in the Cookie header). */
32
+ readonly cookies: readonly string[];
33
+ /** The Accept-Language header value (only its 4-char prefix is used). */
34
+ readonly acceptLanguage?: string;
35
+ }
36
+ /**
37
+ * Compute the four-part JA4H HTTP fingerprint from a captured request.
38
+ *
39
+ * Format: `JA4H_a_JA4H_b_JA4H_c_JA4H_d` where:
40
+ * - JA4H_a: `{method:02s}{version}{has_cookies:d}{has_referer:d}{header_count:02d}{lang_prefix}`
41
+ * - JA4H_b: sorted cookie name=value pairs, SHA-256, first 12 hex.
42
+ * - JA4H_c: sorted cookie names, SHA-256, first 12 hex.
43
+ * - JA4H_d: sorted header names (excluding cookie), SHA-256, first 12 hex.
44
+ */
45
+ export declare function computeJa4h(request: Ja4hRequest): Ja4hFingerprint;
46
+ //# sourceMappingURL=ja4h.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ja4h.d.ts","sourceRoot":"","sources":["../../src/fingerprint/ja4h.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,oCAAoC;AACpC,MAAM,WAAW,eAAe;IAC5B,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACxB;AAED;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IACxB,QAAQ,CAAC,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAC;IAClF,QAAQ,CAAC,WAAW,EAAE,KAAK,GAAG,GAAG,GAAG,GAAG,CAAC;IACxC,kEAAkE;IAClE,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,qEAAqE;IACrE,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,yEAAyE;IACzE,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CACpC;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,eAAe,CAkCjE"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * JA4H — the HTTP-layer sibling of JA4 (docs/TEST-SUITE.md, Category 4).
3
+ *
4
+ * JA4H fingerprints an HTTP request from its method, version, header order,
5
+ * cookies, and Accept-Language prefix. It is the HTTP analogue computed by the
6
+ * reference provider to fingerprint a captured request. Independent of the TLS
7
+ * ClientHello parsing in `ja4.ts`.
8
+ *
9
+ * Reference: https://github.com/FoxIO-LLC/JA4
10
+ */
11
+ import { sha256First12 } from "./ja4.js";
12
+ /**
13
+ * Compute the four-part JA4H HTTP fingerprint from a captured request.
14
+ *
15
+ * Format: `JA4H_a_JA4H_b_JA4H_c_JA4H_d` where:
16
+ * - JA4H_a: `{method:02s}{version}{has_cookies:d}{has_referer:d}{header_count:02d}{lang_prefix}`
17
+ * - JA4H_b: sorted cookie name=value pairs, SHA-256, first 12 hex.
18
+ * - JA4H_c: sorted cookie names, SHA-256, first 12 hex.
19
+ * - JA4H_d: sorted header names (excluding cookie), SHA-256, first 12 hex.
20
+ */
21
+ export function computeJa4h(request) {
22
+ const methodCode = request.method.slice(0, 2).toLowerCase();
23
+ const versionCode = request.httpVersion === "1.1"
24
+ ? "11"
25
+ : request.httpVersion === "2"
26
+ ? "02"
27
+ : request.httpVersion === "3"
28
+ ? "03"
29
+ : "00";
30
+ const hasCookies = request.cookies.length > 0 ? "c" : "n";
31
+ const hasReferer = request.headerNames.some((h) => h === "referer") ? "r" : "n";
32
+ const headerCount = request.headerNames.length.toString().padStart(2, "0");
33
+ const langPrefix = (request.acceptLanguage ?? "").slice(0, 4).padEnd(4, "0").toLowerCase();
34
+ const a = `${methodCode}${versionCode}${hasCookies}${hasReferer}${headerCount}${langPrefix}`;
35
+ const sortedCookies = [...request.cookies].sort().join(",");
36
+ const b = sortedCookies.length > 0 ? sha256First12(sortedCookies) : "000000000000";
37
+ const sortedCookieNames = [...request.cookies]
38
+ .map((c) => c.split("=")[0] ?? "")
39
+ .filter((n) => n.length > 0)
40
+ .sort()
41
+ .join(",");
42
+ const c = sortedCookieNames.length > 0 ? sha256First12(sortedCookieNames) : "000000000000";
43
+ const sortedHeaders = [...request.headerNames]
44
+ .filter((h) => h !== "cookie")
45
+ .sort()
46
+ .join(",");
47
+ const d = sortedHeaders.length > 0 ? sha256First12(sortedHeaders) : "000000000000";
48
+ return { a, b, c, d, tag: `${a}_${b}_${c}_${d}` };
49
+ }
50
+ //# sourceMappingURL=ja4h.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ja4h.js","sourceRoot":"","sources":["../../src/fingerprint/ja4h.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AA6BzC;;;;;;;;GAQG;AACH,MAAM,UAAU,WAAW,CAAC,OAAoB;IAC5C,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IAC5D,MAAM,WAAW,GACb,OAAO,CAAC,WAAW,KAAK,KAAK;QACzB,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,OAAO,CAAC,WAAW,KAAK,GAAG;YAC3B,CAAC,CAAC,IAAI;YACN,CAAC,CAAC,OAAO,CAAC,WAAW,KAAK,GAAG;gBAC3B,CAAC,CAAC,IAAI;gBACN,CAAC,CAAC,IAAI,CAAC;IACnB,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IAC1D,MAAM,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IAChF,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC3E,MAAM,UAAU,GAAG,CAAC,OAAO,CAAC,cAAc,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;IAE3F,MAAM,CAAC,GAAG,GAAG,UAAU,GAAG,WAAW,GAAG,UAAU,GAAG,UAAU,GAAG,WAAW,GAAG,UAAU,EAAE,CAAC;IAE7F,MAAM,aAAa,GAAG,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC5D,MAAM,CAAC,GAAG,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC;IAEnF,MAAM,iBAAiB,GAAG,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;SACzC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACjC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;SAC3B,IAAI,EAAE;SACN,IAAI,CAAC,GAAG,CAAC,CAAC;IACf,MAAM,CAAC,GAAG,iBAAiB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC;IAE3F,MAAM,aAAa,GAAG,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC;SACzC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,QAAQ,CAAC;SAC7B,IAAI,EAAE;SACN,IAAI,CAAC,GAAG,CAAC,CAAC;IACf,MAAM,CAAC,GAAG,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC;IAEnF,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;AACtD,CAAC"}
@@ -11,7 +11,21 @@
11
11
  * (e.g. `chrome-140/tls/client_hello`) that maps directly onto the
12
12
  * `captures/<profile>/<protocol>/<record>.{bin,meta.json}` layout.
13
13
  */
14
- import type { CaptureId, CaptureMeta, ComparisonResult, ComparisonResultWithIgnore, GoldenCapture } from "../types.js";
14
+ import type { CaptureId, CaptureMeta, ComparisonResult, ComparisonResultWithIgnore, GoldenCapture, RandomizedField } from "../types.js";
15
+ /**
16
+ * Validate unknown JSON data as a {@link CaptureMeta} (no zod dep here).
17
+ *
18
+ * Exported for unit testing the validation branches — the error paths are only
19
+ * reachable with a malformed sidecar, which the on-disk captures are not.
20
+ */
21
+ export declare function parseCaptureMeta(raw: unknown, captureId: string): CaptureMeta;
22
+ /**
23
+ * Validate unknown data as a list of {@link RandomizedField}.
24
+ *
25
+ * Exported for unit testing the validation branches — the error paths are only
26
+ * reachable with a malformed sidecar, which the on-disk captures are not.
27
+ */
28
+ export declare function parseRandomizedFields(raw: unknown, captureId: string): readonly RandomizedField[];
15
29
  /**
16
30
  * Load a golden capture by id.
17
31
  *
@@ -1 +1 @@
1
- {"version":3,"file":"golden.d.ts","sourceRoot":"","sources":["../../src/golden/golden.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,OAAO,KAAK,EACR,SAAS,EACT,WAAW,EACX,gBAAgB,EAChB,0BAA0B,EAC1B,aAAa,EAEhB,MAAM,aAAa,CAAC;AA6HrB;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,SAAS,EAAE,SAAS,GAAG,aAAa,CA2B9D;AAYD,0DAA0D;AAC1D,wBAAgB,eAAe,CAAC,SAAS,EAAE,SAAS,GAAG,WAAW,CAUjE;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,GAAG,gBAAgB,CAa/F;AAED;;;;;;;;GAQG;AACH,wBAAgB,8BAA8B,CAC1C,MAAM,EAAE,UAAU,EAClB,SAAS,EAAE,SAAS,GACrB,0BAA0B,CAe5B"}
1
+ {"version":3,"file":"golden.d.ts","sourceRoot":"","sources":["../../src/golden/golden.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EACR,SAAS,EACT,WAAW,EACX,gBAAgB,EAChB,0BAA0B,EAC1B,aAAa,EACb,eAAe,EAClB,MAAM,aAAa,CAAC;AAkCrB;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,WAAW,CAgD7E;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,eAAe,EAAE,CA+BjG;AAYD;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,SAAS,EAAE,SAAS,GAAG,aAAa,CA2B9D;AAoBD,0DAA0D;AAC1D,wBAAgB,eAAe,CAAC,SAAS,EAAE,SAAS,GAAG,WAAW,CAUjE;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,GAAG,gBAAgB,CAa/F;AAED;;;;;;;;GAQG;AACH,wBAAgB,8BAA8B,CAC1C,MAAM,EAAE,UAAU,EAClB,SAAS,EAAE,SAAS,GACrB,0BAA0B,CAe5B"}
@@ -11,17 +11,17 @@
11
11
  * (e.g. `chrome-140/tls/client_hello`) that maps directly onto the
12
12
  * `captures/<profile>/<protocol>/<record>.{bin,meta.json}` layout.
13
13
  */
14
- import { readFileSync } from "node:fs";
15
- import { fileURLToPath } from "node:url";
16
- import { dirname, join } from "node:path";
17
14
  import { compareBytes, compareBytesWithIgnore } from "../utils.js";
18
15
  import { GoldenMismatchError, TestingError } from "../errors.js";
19
- const here = dirname(fileURLToPath(import.meta.url));
16
+ import { createFileSystem, createPath } from "../node-provider.js";
17
+ const fileSystem = createFileSystem();
18
+ const path = createPath();
19
+ const here = import.meta.dirname;
20
20
  // src/golden -> package root -> captures/
21
- const capturesDir = join(here, "..", "..", "captures");
21
+ const capturesDir = path.join(here, "..", "..", "captures");
22
22
  /** Parse a CaptureId of the form `${profile}/${protocol}/${record}`. */
23
23
  function parseCaptureId(captureId) {
24
- const EXPECTED_FORMAT = "${profile}/${protocol}/${record}";
24
+ const EXPECTED_FORMAT = `\${profile}/\${protocol}/\${record}`;
25
25
  const parts = captureId.split("/");
26
26
  if (parts.length !== 3) {
27
27
  throw new TestingError(`Malformed CaptureId "${captureId}" — expected ${EXPECTED_FORMAT}`);
@@ -32,39 +32,44 @@ function parseCaptureId(captureId) {
32
32
  }
33
33
  return { profile, protocol, record };
34
34
  }
35
- /** Validate unknown JSON data as a {@link CaptureMeta} (no zod dep here). */
36
- function parseCaptureMeta(raw, captureId) {
35
+ /**
36
+ * Validate unknown JSON data as a {@link CaptureMeta} (no zod dep here).
37
+ *
38
+ * Exported for unit testing the validation branches — the error paths are only
39
+ * reachable with a malformed sidecar, which the on-disk captures are not.
40
+ */
41
+ export function parseCaptureMeta(raw, captureId) {
37
42
  if (typeof raw !== "object" || raw === null) {
38
43
  throw new TestingError(`Capture meta for ${captureId} is not an object`);
39
44
  }
40
45
  const obj = raw;
41
- const source = obj.source;
46
+ const source = obj["source"];
42
47
  if (source !== "curl-impersonate" && source !== "real-browser") {
43
48
  throw new TestingError(`Capture meta for ${captureId} has invalid source: ${String(source)}`);
44
49
  }
45
- const protocol = obj.protocol;
50
+ const protocol = obj["protocol"];
46
51
  if (protocol !== "tls" && protocol !== "http2" && protocol !== "http1" && protocol !== "tcp") {
47
52
  throw new TestingError(`Capture meta for ${captureId} has invalid protocol: ${String(protocol)}`);
48
53
  }
49
- const record = obj.record;
54
+ const record = obj["record"];
50
55
  if (record !== "client_hello" &&
51
56
  record !== "settings" &&
52
57
  record !== "headers" &&
53
58
  record !== "server_hello") {
54
59
  throw new TestingError(`Capture meta for ${captureId} has invalid record: ${String(record)}`);
55
60
  }
56
- const description = obj.description;
61
+ const description = obj["description"];
57
62
  if (typeof description !== "string") {
58
63
  throw new TestingError(`Capture meta for ${captureId} has non-string description`);
59
64
  }
60
- const createdAt = obj.createdAt;
65
+ const createdAt = obj["createdAt"];
61
66
  if (typeof createdAt !== "string") {
62
67
  throw new TestingError(`Capture meta for ${captureId} has non-string createdAt`);
63
68
  }
64
- const randomizedFields = parseRandomizedFields(obj.randomizedFields, captureId);
69
+ const randomizedFields = parseRandomizedFields(obj["randomizedFields"], captureId);
65
70
  return {
66
71
  source,
67
- profile: obj.profile,
72
+ profile: obj["profile"],
68
73
  protocol,
69
74
  record,
70
75
  description,
@@ -72,8 +77,13 @@ function parseCaptureMeta(raw, captureId) {
72
77
  createdAt,
73
78
  };
74
79
  }
75
- /** Validate unknown data as a list of {@link RandomizedField}. */
76
- function parseRandomizedFields(raw, captureId) {
80
+ /**
81
+ * Validate unknown data as a list of {@link RandomizedField}.
82
+ *
83
+ * Exported for unit testing the validation branches — the error paths are only
84
+ * reachable with a malformed sidecar, which the on-disk captures are not.
85
+ */
86
+ export function parseRandomizedFields(raw, captureId) {
77
87
  if (!Array.isArray(raw)) {
78
88
  throw new TestingError(`Capture meta for ${captureId} has non-array randomizedFields`);
79
89
  }
@@ -82,15 +92,15 @@ function parseRandomizedFields(raw, captureId) {
82
92
  throw new TestingError(`Capture meta for ${captureId} randomizedFields[${i}] is not an object`);
83
93
  }
84
94
  const obj = item;
85
- const byteOffset = obj.byteOffset;
95
+ const byteOffset = obj["byteOffset"];
86
96
  if (typeof byteOffset !== "number" || byteOffset < 0) {
87
97
  throw new TestingError(`Capture meta for ${captureId} randomizedFields[${i}].byteOffset invalid`);
88
98
  }
89
- const length = obj.length;
99
+ const length = obj["length"];
90
100
  if (typeof length !== "number" || length < 0) {
91
101
  throw new TestingError(`Capture meta for ${captureId} randomizedFields[${i}].length invalid`);
92
102
  }
93
- const reason = obj.reason;
103
+ const reason = obj["reason"];
94
104
  if (reason !== "ephemeral_key" && reason !== "nonce" && reason !== "grease" && reason !== "random") {
95
105
  throw new TestingError(`Capture meta for ${captureId} randomizedFields[${i}].reason invalid: ${String(reason)}`);
96
106
  }
@@ -100,7 +110,7 @@ function parseRandomizedFields(raw, captureId) {
100
110
  /** Resolve a CaptureId to its on-disk `.bin` + `.meta.json` paths. */
101
111
  function resolveCapturePaths(captureId) {
102
112
  const { profile, protocol, record } = parseCaptureId(captureId);
103
- const base = join(capturesDir, profile, protocol, record);
113
+ const base = path.join(capturesDir, profile, protocol, record);
104
114
  return { binPath: `${base}.bin`, metaPath: `${base}.meta.json` };
105
115
  }
106
116
  /**
@@ -115,7 +125,7 @@ export function loadGolden(captureId) {
115
125
  const { binPath, metaPath } = resolveCapturePaths(captureId);
116
126
  let bytes;
117
127
  try {
118
- bytes = readFileSync(binPath);
128
+ bytes = fileSystem.readFileSync(binPath);
119
129
  }
120
130
  catch (e) {
121
131
  const cause = e instanceof Error ? e : new Error(String(e));
@@ -123,7 +133,7 @@ export function loadGolden(captureId) {
123
133
  }
124
134
  let meta;
125
135
  try {
126
- meta = JSON.parse(readFileSync(metaPath, "utf8"));
136
+ meta = JSON.parse(fileSystem.readFileText(metaPath));
127
137
  }
128
138
  catch (e) {
129
139
  const cause = e instanceof Error ? e : new Error(String(e));
@@ -141,14 +151,18 @@ export function loadGolden(captureId) {
141
151
  /** Derive a {@link CaptureSource} from a profile id (best-effort). */
142
152
  function parseSource(profile) {
143
153
  const p = String(profile);
144
- if (p.startsWith("chrome"))
154
+ if (p.startsWith("chrome")) {
145
155
  return "chrome-140";
146
- if (p.startsWith("firefox"))
156
+ }
157
+ if (p.startsWith("firefox")) {
147
158
  return "firefox-135";
148
- if (p.startsWith("safari"))
159
+ }
160
+ if (p.startsWith("safari")) {
149
161
  return "safari-18";
150
- if (p.startsWith("edge"))
162
+ }
163
+ if (p.startsWith("edge")) {
151
164
  return "edge-140";
165
+ }
152
166
  return "chrome-140";
153
167
  }
154
168
  /** Load the {@link CaptureMeta} sidecar for a capture. */
@@ -156,7 +170,7 @@ export function loadCaptureMeta(captureId) {
156
170
  const { metaPath } = resolveCapturePaths(captureId);
157
171
  let raw;
158
172
  try {
159
- raw = JSON.parse(readFileSync(metaPath, "utf8"));
173
+ raw = JSON.parse(fileSystem.readFileText(metaPath));
160
174
  }
161
175
  catch (e) {
162
176
  const cause = e instanceof Error ? e : new Error(String(e));
@@ -1 +1 @@
1
- {"version":3,"file":"golden.js","sourceRoot":"","sources":["../../src/golden/golden.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAS1C,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjE,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AACrD,0CAA0C;AAC1C,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;AAEvD,wEAAwE;AACxE,SAAS,cAAc,CAAC,SAAoB;IAKxC,MAAM,eAAe,GAAG,kCAAkC,CAAC;IAC3D,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACnC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrB,MAAM,IAAI,YAAY,CAClB,wBAAwB,SAAS,gBAAgB,eAAe,EAAE,CACrE,CAAC;IACN,CAAC;IACD,MAAM,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC;IAC1C,IAAI,OAAO,KAAK,SAAS,IAAI,QAAQ,KAAK,SAAS,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QAC1E,MAAM,IAAI,YAAY,CAClB,wBAAwB,SAAS,gBAAgB,eAAe,EAAE,CACrE,CAAC;IACN,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;AACzC,CAAC;AAED,6EAA6E;AAC7E,SAAS,gBAAgB,CAAC,GAAY,EAAE,SAAiB;IACrD,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QAC1C,MAAM,IAAI,YAAY,CAAC,oBAAoB,SAAS,mBAAmB,CAAC,CAAC;IAC7E,CAAC;IACD,MAAM,GAAG,GAAG,GAA8B,CAAC;IAE3C,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;IAC1B,IAAI,MAAM,KAAK,kBAAkB,IAAI,MAAM,KAAK,cAAc,EAAE,CAAC;QAC7D,MAAM,IAAI,YAAY,CAClB,oBAAoB,SAAS,wBAAwB,MAAM,CAAC,MAAM,CAAC,EAAE,CACxE,CAAC;IACN,CAAC;IACD,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC;IAC9B,IAAI,QAAQ,KAAK,KAAK,IAAI,QAAQ,KAAK,OAAO,IAAI,QAAQ,KAAK,OAAO,IAAI,QAAQ,KAAK,KAAK,EAAE,CAAC;QAC3F,MAAM,IAAI,YAAY,CAClB,oBAAoB,SAAS,0BAA0B,MAAM,CAAC,QAAQ,CAAC,EAAE,CAC5E,CAAC;IACN,CAAC;IACD,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;IAC1B,IACI,MAAM,KAAK,cAAc;QACzB,MAAM,KAAK,UAAU;QACrB,MAAM,KAAK,SAAS;QACpB,MAAM,KAAK,cAAc,EAC3B,CAAC;QACC,MAAM,IAAI,YAAY,CAClB,oBAAoB,SAAS,wBAAwB,MAAM,CAAC,MAAM,CAAC,EAAE,CACxE,CAAC;IACN,CAAC;IACD,MAAM,WAAW,GAAG,GAAG,CAAC,WAAW,CAAC;IACpC,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;QAClC,MAAM,IAAI,YAAY,CAAC,oBAAoB,SAAS,6BAA6B,CAAC,CAAC;IACvF,CAAC;IACD,MAAM,SAAS,GAAG,GAAG,CAAC,SAAS,CAAC;IAChC,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;QAChC,MAAM,IAAI,YAAY,CAAC,oBAAoB,SAAS,2BAA2B,CAAC,CAAC;IACrF,CAAC;IACD,MAAM,gBAAgB,GAAG,qBAAqB,CAAC,GAAG,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC;IAEhF,OAAO;QACH,MAAM;QACN,OAAO,EAAE,GAAG,CAAC,OAAiC;QAC9C,QAAQ;QACR,MAAM;QACN,WAAW;QACX,gBAAgB;QAChB,SAAS;KACZ,CAAC;AACN,CAAC;AAED,kEAAkE;AAClE,SAAS,qBAAqB,CAAC,GAAY,EAAE,SAAiB;IAC1D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,YAAY,CAAC,oBAAoB,SAAS,iCAAiC,CAAC,CAAC;IAC3F,CAAC;IACD,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;QACvB,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAC5C,MAAM,IAAI,YAAY,CAClB,oBAAoB,SAAS,qBAAqB,CAAC,oBAAoB,CAC1E,CAAC;QACN,CAAC;QACD,MAAM,GAAG,GAAG,IAA+B,CAAC;QAC5C,MAAM,UAAU,GAAG,GAAG,CAAC,UAAU,CAAC;QAClC,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;YACnD,MAAM,IAAI,YAAY,CAClB,oBAAoB,SAAS,qBAAqB,CAAC,sBAAsB,CAC5E,CAAC;QACN,CAAC;QACD,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;QAC1B,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3C,MAAM,IAAI,YAAY,CAClB,oBAAoB,SAAS,qBAAqB,CAAC,kBAAkB,CACxE,CAAC;QACN,CAAC;QACD,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;QAC1B,IAAI,MAAM,KAAK,eAAe,IAAI,MAAM,KAAK,OAAO,IAAI,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;YACjG,MAAM,IAAI,YAAY,CAClB,oBAAoB,SAAS,qBAAqB,CAAC,qBAAqB,MAAM,CAAC,MAAM,CAAC,EAAE,CAC3F,CAAC;QACN,CAAC;QACD,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IAC1C,CAAC,CAAC,CAAC;AACP,CAAC;AAED,sEAAsE;AACtE,SAAS,mBAAmB,CAAC,SAAoB;IAI7C,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;IAChE,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC1D,OAAO,EAAE,OAAO,EAAE,GAAG,IAAI,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,YAAY,EAAE,CAAC;AACrE,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CAAC,SAAoB;IAC3C,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC;IAE7D,IAAI,KAAiB,CAAC;IACtB,IAAI,CAAC;QACD,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;IAClC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACT,MAAM,KAAK,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5D,MAAM,IAAI,YAAY,CAAC,mCAAmC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IACpF,CAAC;IAED,IAAI,IAAa,CAAC;IAClB,IAAI,CAAC;QACD,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAY,CAAC;IACjE,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACT,MAAM,KAAK,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5D,MAAM,IAAI,YAAY,CAAC,wCAAwC,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IAC1F,CAAC;IAED,MAAM,MAAM,GAAG,gBAAgB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACjD,OAAO;QACH,EAAE,EAAE,SAAS;QACb,MAAM,EAAE,MAAM,CAAC,MAAM,KAAK,kBAAkB,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,YAAY;QACzF,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,KAAK;QACL,WAAW,EAAE,MAAM,CAAC,WAAW;KAClC,CAAC;AACN,CAAC;AAED,sEAAsE;AACtE,SAAS,WAAW,CAAC,OAA+B;IAChD,MAAM,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IAC1B,IAAI,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,YAAY,CAAC;IAChD,IAAI,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,aAAa,CAAC;IAClD,IAAI,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,WAAW,CAAC;IAC/C,IAAI,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,UAAU,CAAC;IAC5C,OAAO,YAAY,CAAC;AACxB,CAAC;AAED,0DAA0D;AAC1D,MAAM,UAAU,eAAe,CAAC,SAAoB;IAChD,MAAM,EAAE,QAAQ,EAAE,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC;IACpD,IAAI,GAAY,CAAC;IACjB,IAAI,CAAC;QACD,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAY,CAAC;IAChE,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACT,MAAM,KAAK,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5D,MAAM,IAAI,YAAY,CAAC,wCAAwC,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IAC1F,CAAC;IACD,OAAO,gBAAgB,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;AAC5C,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAkB,EAAE,SAAoB;IACzE,IAAI,QAAoB,CAAC;IACzB,IAAI,CAAC;QACD,QAAQ,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC;IAC3C,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACT,MAAM,KAAK,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5D,MAAM,IAAI,YAAY,CAAC,yBAAyB,SAAS,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IAC5E,CAAC;IACD,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC9C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QAClB,MAAM,IAAI,mBAAmB,CAAC,SAAS,EAAE,MAAM,CAAC,mBAAmB,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC;IAC1F,CAAC;IACD,OAAO,MAAM,CAAC;AAClB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,8BAA8B,CAC1C,MAAkB,EAClB,SAAoB;IAEpB,IAAI,QAAoB,CAAC;IACzB,IAAI,IAAiB,CAAC;IACtB,IAAI,CAAC;QACD,QAAQ,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC;QACvC,IAAI,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;IACtC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACT,MAAM,KAAK,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5D,MAAM,IAAI,YAAY,CAAC,yBAAyB,SAAS,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IAC5E,CAAC;IACD,MAAM,MAAM,GAAG,sBAAsB,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAC/E,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QAClB,MAAM,IAAI,mBAAmB,CAAC,SAAS,EAAE,MAAM,CAAC,mBAAmB,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC;IAC1F,CAAC;IACD,OAAO,MAAM,CAAC;AAClB,CAAC"}
1
+ {"version":3,"file":"golden.js","sourceRoot":"","sources":["../../src/golden/golden.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -4,6 +4,7 @@
4
4
  * Protocol verification: RFC compliance tests, browser golden packet captures,
5
5
  * integration tests, and benchmarking.
6
6
  */
7
+ import type { CaptureEntry } from "./captures/manifest.js";
7
8
  export { loadGolden, compareAgainstGolden } from "./golden/golden.js";
8
9
  export { runTlsCompliance, runHttp2Compliance, runHttp1Compliance } from "./rfc/rfcTests.js";
9
10
  export { benchmarkTlsHandshake, benchmarkHttp2Request } from "./bench/bench.js";
@@ -15,11 +16,30 @@ export type { SpecTestCase, TestCategoryId, TestRun, TestStatus } from "./types.
15
16
  export * as categories from "./categories/index.js";
16
17
  export { compareBytesWithIgnore } from "./utils.js";
17
18
  export type { CaptureMeta, ComparisonResultWithIgnore, RandomizedField } from "./types.js";
18
- export { captures, type CaptureEntry } from "./captures/manifest.js";
19
+ export type { CaptureEntry } from "./captures/manifest.js";
20
+ /**
21
+ * Lazily load the golden-capture manifest.
22
+ *
23
+ * The manifest reads each `.bin` from disk, so it is NOT eagerly evaluated at
24
+ * import time (an eager re-export would force every consumer to pay the read
25
+ * cost — and crash if the tarball lacked `captures/`). Call this only when you
26
+ * actually need the captures.
27
+ */
28
+ export declare function loadCaptures(): Promise<readonly CaptureEntry[]>;
19
29
  export { createReferenceProvider, CurlImpersonateProvider, RealBrowserCaptureProvider, } from "./reference/reference.js";
20
30
  export type { CurlImpersonateOptions, Fingerprint, RealBrowserOptions, ReferenceProvider, ReferenceProviderKind, } from "./reference/reference.js";
21
31
  export { computeJa3, computeJa4, Ja3ParseError, parseClientHello } from "./fingerprint/index.js";
22
32
  export type { Ja3Segments } from "./fingerprint/index.js";
23
33
  export { nodeCrypto, nodeDns, nodeZlib, nodeHttp, toError, compareBytesOutcome, } from "./reference/node-reference.js";
24
34
  export type { CompareOutcome, HashAlgorithm } from "./reference/node-reference.js";
35
+ export { TlsSinkServer } from "./e2e/sink-server.js";
36
+ export type { ClientHelloCapture, HandshakeResult } from "./e2e/sink-server.js";
37
+ export { generateSelfSignedCert } from "./e2e/cert-gen.js";
38
+ export type { SelfSignedCert } from "./e2e/cert-gen.js";
39
+ export { TrafficServer } from "./e2e/traffic-server.js";
40
+ export type { TrafficResult } from "./e2e/traffic-server.js";
41
+ export { parseClientHelloWire, peekRecordHeader, findExtension, parseSniHostname, parseAlpnProtocols, parseSupportedVersions, decodeSni, decodeAlpn, decodeSupportedVersions, isGrease, nonGreaseCipherSuites, nonGreaseExtensionTypes, EXT, GREASE_SENTINELS, ClientHelloParseError, } from "./e2e/parse-clienthello.js";
42
+ export type { ParsedClientHello, ParsedExtension, ExtensionTypeValue, } from "./e2e/parse-clienthello.js";
43
+ export { createFileSystem, createPath, NodeFileSystemProvider, NodePathProvider } from "./node-provider.js";
44
+ export type { FileSystemProvider, PathProvider } from "./provider.js";
25
45
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC7F,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAEhF,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhE,YAAY,EACR,UAAU,EACV,SAAS,EACT,eAAe,EACf,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,QAAQ,EACR,UAAU,EACV,UAAU,GACb,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAG7E,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACpF,OAAO,KAAK,UAAU,MAAM,uBAAuB,CAAC;AAGpD,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AACpD,YAAY,EAAE,WAAW,EAAE,0BAA0B,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC3F,OAAO,EAAE,QAAQ,EAAE,KAAK,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAGrE,OAAO,EACH,uBAAuB,EACvB,uBAAuB,EACvB,0BAA0B,GAC7B,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACR,sBAAsB,EACtB,WAAW,EACX,kBAAkB,EAClB,iBAAiB,EACjB,qBAAqB,GACxB,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AACjG,YAAY,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAI1D,OAAO,EACH,UAAU,EACV,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,mBAAmB,GACtB,MAAM,+BAA+B,CAAC;AACvC,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAE3D,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC7F,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAEhF,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhE,YAAY,EACR,UAAU,EACV,SAAS,EACT,eAAe,EACf,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,QAAQ,EACR,UAAU,EACV,UAAU,GACb,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAG7E,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACpF,OAAO,KAAK,UAAU,MAAM,uBAAuB,CAAC;AAGpD,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AACpD,YAAY,EAAE,WAAW,EAAE,0BAA0B,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC3F,YAAY,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAE3D;;;;;;;GAOG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,SAAS,YAAY,EAAE,CAAC,CAGrE;AAGD,OAAO,EACH,uBAAuB,EACvB,uBAAuB,EACvB,0BAA0B,GAC7B,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACR,sBAAsB,EACtB,WAAW,EACX,kBAAkB,EAClB,iBAAiB,EACjB,qBAAqB,GACxB,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AACjG,YAAY,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAI1D,OAAO,EACH,UAAU,EACV,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,mBAAmB,GACtB,MAAM,+BAA+B,CAAC;AACvC,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAOnF,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,YAAY,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAGhF,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAOxD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,YAAY,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAO7D,OAAO,EACH,oBAAoB,EACpB,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,kBAAkB,EAClB,sBAAsB,EACtB,SAAS,EACT,UAAU,EACV,uBAAuB,EACvB,QAAQ,EACR,qBAAqB,EACrB,uBAAuB,EACvB,GAAG,EACH,gBAAgB,EAChB,qBAAqB,GACxB,MAAM,4BAA4B,CAAC;AACpC,YAAY,EACR,iBAAiB,EACjB,eAAe,EACf,kBAAkB,GACrB,MAAM,4BAA4B,CAAC;AAKpC,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC5G,YAAY,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC"}
package/dist/index.js CHANGED
@@ -14,7 +14,18 @@ export { TestCategory } from "./types.js";
14
14
  export * as categories from "./categories/index.js";
15
15
  // Randomized-field comparison (Cat 14 core) + capture manifest.
16
16
  export { compareBytesWithIgnore } from "./utils.js";
17
- export { captures } from "./captures/manifest.js";
17
+ /**
18
+ * Lazily load the golden-capture manifest.
19
+ *
20
+ * The manifest reads each `.bin` from disk, so it is NOT eagerly evaluated at
21
+ * import time (an eager re-export would force every consumer to pay the read
22
+ * cost — and crash if the tarball lacked `captures/`). Call this only when you
23
+ * actually need the captures.
24
+ */
25
+ export async function loadCaptures() {
26
+ const manifest = await import("./captures/manifest.js");
27
+ return manifest.captures;
28
+ }
18
29
  // Pluggable layered reference provider.
19
30
  export { createReferenceProvider, CurlImpersonateProvider, RealBrowserCaptureProvider, } from "./reference/reference.js";
20
31
  // Fingerprint computation (JA3 / JA4) for Cat 4.
@@ -22,4 +33,28 @@ export { computeJa3, computeJa4, Ja3ParseError, parseClientHello } from "./finge
22
33
  // Node.js reference oracle — deterministic comparison target for the primitive
23
34
  // layers (crypto, dns, zlib, wire format). See src/reference/node-reference.ts.
24
35
  export { nodeCrypto, nodeDns, nodeZlib, nodeHttp, toError, compareBytesOutcome, } from "./reference/node-reference.js";
36
+ // E2E TLS sink server — live handshake verification oracle (plan
37
+ // docs/E2E_TEST_PLAN.md). The sink performs a real TLS 1.3 handshake and
38
+ // returns the raw ClientHello bytes it saw on the wire, plus parsed handshake
39
+ // inspection (protocol, cipher, ALPN, SNI). Reusable by any package that
40
+ // wants to verify its TLS stack against a real server.
41
+ export { TlsSinkServer } from "./e2e/sink-server.js";
42
+ // Self-signed ECDSA P-256 certificate generator (runtime, no openssl).
43
+ export { generateSelfSignedCert } from "./e2e/cert-gen.js";
44
+ // E2E HTTPS traffic server — local TLS termination oracle for the traffic
45
+ // gate. Spins up a real HTTPS server with a throwaway self-signed cert and
46
+ // returns a known body + marker header so a client test can assert the full
47
+ // request path (TCP → TLS → HTTP) worked. Reusable by any package that wants
48
+ // to verify its HTTP stack against a real local server.
49
+ export { TrafficServer } from "./e2e/traffic-server.js";
50
+ // Minimal ClientHello wire parser — structural assertions for the e2e matrix.
51
+ // (Distinct from the JA3 `parseClientHello` re-exported from fingerprint.)
52
+ // Note: `parseClientHello` is intentionally NOT re-exported here to avoid
53
+ // colliding with the JA3 `parseClientHello` from ./fingerprint/index.js.
54
+ // Consumers of the e2e parser import it directly from ./e2e/parse-clienthello.js.
55
+ export { parseClientHelloWire, peekRecordHeader, findExtension, parseSniHostname, parseAlpnProtocols, parseSupportedVersions, decodeSni, decodeAlpn, decodeSupportedVersions, isGrease, nonGreaseCipherSuites, nonGreaseExtensionTypes, EXT, GREASE_SENTINELS, ClientHelloParseError, } from "./e2e/parse-clienthello.js";
56
+ // Provider interfaces + Node-backed factories (Rule 21 — runtime independence).
57
+ // Higher layers depend on the interfaces; the factories return the production
58
+ // defaults. Tests inject fakes through the interfaces.
59
+ export { createFileSystem, createPath, NodeFileSystemProvider, NodePathProvider } from "./node-provider.js";
25
60
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC7F,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAEhF,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAchE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE7E,sEAAsE;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,OAAO,KAAK,UAAU,MAAM,uBAAuB,CAAC;AAEpD,gEAAgE;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAEpD,OAAO,EAAE,QAAQ,EAAqB,MAAM,wBAAwB,CAAC;AAErE,wCAAwC;AACxC,OAAO,EACH,uBAAuB,EACvB,uBAAuB,EACvB,0BAA0B,GAC7B,MAAM,0BAA0B,CAAC;AASlC,iDAAiD;AACjD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAGjG,+EAA+E;AAC/E,gFAAgF;AAChF,OAAO,EACH,UAAU,EACV,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,mBAAmB,GACtB,MAAM,+BAA+B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC7F,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAEhF,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAchE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE7E,sEAAsE;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,OAAO,KAAK,UAAU,MAAM,uBAAuB,CAAC;AAEpD,gEAAgE;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAIpD;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY;IAC9B,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,wBAAwB,CAAC,CAAC;IACxD,OAAO,QAAQ,CAAC,QAAQ,CAAC;AAC7B,CAAC;AAED,wCAAwC;AACxC,OAAO,EACH,uBAAuB,EACvB,uBAAuB,EACvB,0BAA0B,GAC7B,MAAM,0BAA0B,CAAC;AASlC,iDAAiD;AACjD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAGjG,+EAA+E;AAC/E,gFAAgF;AAChF,OAAO,EACH,UAAU,EACV,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,mBAAmB,GACtB,MAAM,+BAA+B,CAAC;AAGvC,iEAAiE;AACjE,yEAAyE;AACzE,8EAA8E;AAC9E,yEAAyE;AACzE,uDAAuD;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAGrD,uEAAuE;AACvE,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAG3D,0EAA0E;AAC1E,2EAA2E;AAC3E,4EAA4E;AAC5E,6EAA6E;AAC7E,wDAAwD;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAGxD,8EAA8E;AAC9E,2EAA2E;AAC3E,0EAA0E;AAC1E,yEAAyE;AACzE,kFAAkF;AAClF,OAAO,EACH,oBAAoB,EACpB,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,kBAAkB,EAClB,sBAAsB,EACtB,SAAS,EACT,UAAU,EACV,uBAAuB,EACvB,QAAQ,EACR,qBAAqB,EACrB,uBAAuB,EACvB,GAAG,EACH,gBAAgB,EAChB,qBAAqB,GACxB,MAAM,4BAA4B,CAAC;AAOpC,gFAAgF;AAChF,8EAA8E;AAC9E,uDAAuD;AACvD,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Node.js-backed implementations of the testing package's provider interfaces.
3
+ *
4
+ * This is the ONLY module in @browsercore/testing that may import `node:fs`
5
+ * and `node:path` directly — the provider boundary that isolates the runtime
6
+ * per Rule 21 (CODING_STANDARDS.md "Runtime independence & dependency
7
+ * injection"). Every other module depends on the
8
+ * {@link FileSystemProvider}/{@link PathProvider} interfaces and never touches
9
+ * the runtime built-ins.
10
+ *
11
+ * Higher layers call the provider methods here, never `node:fs`/`node:path`
12
+ * directly, so the backend stays replaceable. Factories return a fresh
13
+ * instance so consumers can call `createFileSystem().readFileSync(...)` without
14
+ * threading a provider through every constructor.
15
+ */
16
+ import type { FileSystemProvider, PathProvider } from "./provider.js";
17
+ /**
18
+ * `node:fs`-backed implementation of {@link FileSystemProvider}.
19
+ *
20
+ * Production code calls the factory (`createFileSystem()`) — it never
21
+ * constructs this class directly. Tests inject a fake provider through the
22
+ * `FileSystemProvider` interface.
23
+ */
24
+ export declare class NodeFileSystemProvider implements FileSystemProvider {
25
+ readFileSync(path: string): Uint8Array;
26
+ readFileText(path: string): string;
27
+ }
28
+ /**
29
+ * `node:path`-backed implementation of {@link PathProvider}.
30
+ *
31
+ * Production code calls the factory (`createPath()`) — it never constructs
32
+ * this class directly. Tests inject a fake provider through the
33
+ * `PathProvider` interface.
34
+ */
35
+ export declare class NodePathProvider implements PathProvider {
36
+ join(...parts: string[]): string;
37
+ }
38
+ /** Factory that returns the default {@link FileSystemProvider}. */
39
+ export declare function createFileSystem(): FileSystemProvider;
40
+ /** Factory that returns the default {@link PathProvider}. */
41
+ export declare function createPath(): PathProvider;
42
+ //# sourceMappingURL=node-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-provider.d.ts","sourceRoot":"","sources":["../src/node-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,KAAK,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAEtE;;;;;;GAMG;AACH,qBAAa,sBAAuB,YAAW,kBAAkB;IACtD,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAE5C;IAEM,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAExC;CACJ;AAED;;;;;;GAMG;AACH,qBAAa,gBAAiB,YAAW,YAAY;IAC1C,IAAI,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAEtC;CACJ;AAED,mEAAmE;AACnE,wBAAgB,gBAAgB,IAAI,kBAAkB,CAErD;AAED,6DAA6D;AAC7D,wBAAgB,UAAU,IAAI,YAAY,CAEzC"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Node.js-backed implementations of the testing package's provider interfaces.
3
+ *
4
+ * This is the ONLY module in @browsercore/testing that may import `node:fs`
5
+ * and `node:path` directly — the provider boundary that isolates the runtime
6
+ * per Rule 21 (CODING_STANDARDS.md "Runtime independence & dependency
7
+ * injection"). Every other module depends on the
8
+ * {@link FileSystemProvider}/{@link PathProvider} interfaces and never touches
9
+ * the runtime built-ins.
10
+ *
11
+ * Higher layers call the provider methods here, never `node:fs`/`node:path`
12
+ * directly, so the backend stays replaceable. Factories return a fresh
13
+ * instance so consumers can call `createFileSystem().readFileSync(...)` without
14
+ * threading a provider through every constructor.
15
+ */
16
+ import { readFileSync } from "node:fs";
17
+ import { join } from "node:path";
18
+ /**
19
+ * `node:fs`-backed implementation of {@link FileSystemProvider}.
20
+ *
21
+ * Production code calls the factory (`createFileSystem()`) — it never
22
+ * constructs this class directly. Tests inject a fake provider through the
23
+ * `FileSystemProvider` interface.
24
+ */
25
+ export class NodeFileSystemProvider {
26
+ readFileSync(path) {
27
+ return readFileSync(path);
28
+ }
29
+ readFileText(path) {
30
+ return readFileSync(path, "utf8");
31
+ }
32
+ }
33
+ /**
34
+ * `node:path`-backed implementation of {@link PathProvider}.
35
+ *
36
+ * Production code calls the factory (`createPath()`) — it never constructs
37
+ * this class directly. Tests inject a fake provider through the
38
+ * `PathProvider` interface.
39
+ */
40
+ export class NodePathProvider {
41
+ join(...parts) {
42
+ return join(...parts);
43
+ }
44
+ }
45
+ /** Factory that returns the default {@link FileSystemProvider}. */
46
+ export function createFileSystem() {
47
+ return new NodeFileSystemProvider();
48
+ }
49
+ /** Factory that returns the default {@link PathProvider}. */
50
+ export function createPath() {
51
+ return new NodePathProvider();
52
+ }
53
+ //# sourceMappingURL=node-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-provider.js","sourceRoot":"","sources":["../src/node-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC;;;;;;GAMG;AACH,MAAM,OAAO,sBAAsB;IACxB,YAAY,CAAC,IAAY;QAC5B,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IAEM,YAAY,CAAC,IAAY;QAC5B,OAAO,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACtC,CAAC;CACJ;AAED;;;;;;GAMG;AACH,MAAM,OAAO,gBAAgB;IAClB,IAAI,CAAC,GAAG,KAAe;QAC1B,OAAO,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC;IAC1B,CAAC;CACJ;AAED,mEAAmE;AACnE,MAAM,UAAU,gBAAgB;IAC5B,OAAO,IAAI,sBAAsB,EAAE,CAAC;AACxC,CAAC;AAED,6DAA6D;AAC7D,MAAM,UAAU,UAAU;IACtB,OAAO,IAAI,gBAAgB,EAAE,CAAC;AAClC,CAAC"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Provider interfaces for the @browsercore/testing package.
3
+ *
4
+ * Protocol/test infrastructure layers isolate runtime-specific dependencies
5
+ * (node:fs, node:path) behind these interfaces per Rule 21
6
+ * (CODING_STANDARDS.md "Runtime independence & dependency injection").
7
+ * Higher layers depend on the interfaces — never on a concrete provider — so
8
+ * the backend is replaceable (in-memory fake for tests, Deno/Bun, ...).
9
+ *
10
+ * @see {@link NodeFileSystemProvider} for the default `node:fs` backend.
11
+ * @see {@link NodePathProvider} for the default `node:path` backend.
12
+ */
13
+ /**
14
+ * File-system read operations.
15
+ *
16
+ * Higher layers depend on this interface, never on `node:fs` directly, so the
17
+ * backend is replaceable. All methods take and return `Uint8Array` or
18
+ * `string` — never Node `Buffer` — so the interface is portable across
19
+ * runtimes.
20
+ */
21
+ export interface FileSystemProvider {
22
+ /**
23
+ * Read a file's raw bytes.
24
+ *
25
+ * @param path Absolute or relative file path.
26
+ * @returns The file's contents as raw bytes.
27
+ */
28
+ readFileSync(path: string): Uint8Array;
29
+ /**
30
+ * Read a file's text content (utf8).
31
+ *
32
+ * @param path Absolute or relative file path.
33
+ * @returns The file's contents as a utf8 string.
34
+ */
35
+ readFileText(path: string): string;
36
+ }
37
+ /**
38
+ * Path manipulation operations.
39
+ *
40
+ * Higher layers depend on this interface, never on `node:path` directly, so
41
+ * path resolution is replaceable and testable against synthetic layouts.
42
+ */
43
+ export interface PathProvider {
44
+ /**
45
+ * Join path segments into a single path.
46
+ *
47
+ * @param parts Path segments to join.
48
+ * @returns The joined path.
49
+ */
50
+ join(...parts: string[]): string;
51
+ }
52
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;;;;;;GAOG;AACH,MAAM,WAAW,kBAAkB;IAC/B;;;;;OAKG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAAC;IAEvC;;;;;OAKG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;CACtC;AAED;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IACzB;;;;;OAKG;IACH,IAAI,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;CACpC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Provider interfaces for the @browsercore/testing package.
3
+ *
4
+ * Protocol/test infrastructure layers isolate runtime-specific dependencies
5
+ * (node:fs, node:path) behind these interfaces per Rule 21
6
+ * (CODING_STANDARDS.md "Runtime independence & dependency injection").
7
+ * Higher layers depend on the interfaces — never on a concrete provider — so
8
+ * the backend is replaceable (in-memory fake for tests, Deno/Bun, ...).
9
+ *
10
+ * @see {@link NodeFileSystemProvider} for the default `node:fs` backend.
11
+ * @see {@link NodePathProvider} for the default `node:path` backend.
12
+ */
13
+ export {};
14
+ //# sourceMappingURL=provider.js.map