@fastls/fastls 0.13.0 → 0.15.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/README.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Fastls Node.js SDK
2
2
 
3
+ Python 0.6.0 / Node 0.15.0 支持显式 H3 与可信 Session 地址策略组合,需原生 `http3_address_policy_v1`;默认校验证书,旧库在分配资源前拒绝。详见 [组合契约](https://github.com/FastTLS/fastls-ffi/blob/main/H3_POLICY.zh-CN.md)。
4
+
5
+ Node 0.14.0 增加完整 Spec 的 H2 首流编号与初始流窗口配置,并导出 `HTTP2StreamConfig` 类型。省略保持旧行为,需要 `http2.stream.v1` 和原生 `http2_stream_v1`;转换、Bundle/Store、Session/fetch 共用契约。旧原生库明确拒绝,窗口预算及候选采用边界见 [中文契约](https://github.com/FastTLS/fastls-ffi/blob/main/FINGERPRINTS.zh-CN.md)。
6
+
3
7
  Node 0.11.0 起支持 Session `addressPolicy`、`profileSpec: new ProfileSpec(...)` 和
4
8
  `httpVersion: "h3"`;Session/fetch 可选择完整 Spec 或显式协议。
5
9
  `addressPolicy` 只能创建可信 owner,不能由 `session.fetch()` 或请求替换。
@@ -37,7 +41,7 @@ Node.js 22+ 的 Fastls C ABI v1 绑定,提供 Promise API、TypeScript 声明
37
41
  安装指定版本:
38
42
 
39
43
  ```sh
40
- npm install @fastls/fastls@0.13.0
44
+ npm install @fastls/fastls@0.15.0
41
45
  ```
42
46
 
43
47
  主包通过同版本的可选依赖自动安装当前平台的 Fastls 原生库。保留 optional dependencies;支持 Windows x64、Linux glibc x64/arm64、macOS x64/arm64。Linux musl 和其它架构没有内置包。具体系统最低版本见原生包的 `native/manifest.json`。
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@ export { RetryPolicy } from "./retry.js";
3
3
  export { ProfileBundle, ProfileStore } from "./profile-store.js";
4
4
  export type { RetryOptions } from "./retry.js";
5
5
  export { ProfileSpec } from "./profiles.js";
6
- export type { AddressPolicy } from "./profiles.js";
6
+ export type { AddressPolicy, HTTP2StreamConfig } from "./profiles.js";
7
7
  export { fetch } from "./fetch.js";
8
8
  export type { FetchOptions, FetchResponse } from "./fetch.js";
9
9
  export type { SessionOptions, RequestOptions, DuplexOptions, Stats } from "./session.js";
@@ -6,6 +6,13 @@ export interface AddressPolicy {
6
6
  readonly allow_cidrs?: readonly string[];
7
7
  readonly deny_cidrs?: readonly string[];
8
8
  }
9
+ /** Optional stream settings within a complete schema-v1 profile. */
10
+ export interface HTTP2StreamConfig {
11
+ /** 0 or omitted selects stream 1; other values are odd, up to 2^31-1. */
12
+ readonly first_stream_id?: number;
13
+ /** Receive credit sent once after initial request HEADERS; 0 disables it. */
14
+ readonly stream_window_increment?: number;
15
+ }
9
16
  /** Explicit snapshot of a complete schema-v1 profile, validated by the core. */
10
17
  export declare class ProfileSpec {
11
18
  private readonly snapshot;
@@ -16,4 +23,6 @@ export declare class ProfileSpec {
16
23
  library?: string;
17
24
  }): ProfileSpec;
18
25
  toJSON(): Record<string, unknown>;
26
+ /** @internal Capability negotiation happens before allocating a session. */
27
+ nativeCapabilities(): string[];
19
28
  }
package/dist/profiles.js CHANGED
@@ -20,8 +20,17 @@ class ProfileSpec {
20
20
  throw new TypeError("ja3 and h2 must be strings");
21
21
  if (Object.keys(options).some(key => !["ja3", "h2", "library"].includes(key)))
22
22
  throw new TypeError("unknown fingerprint option");
23
- return new ProfileSpec(native_js_1.Native.load(library).adaptProfile({ schema_version: 1, base: base.toJSON(), ja3, h2 }));
23
+ const native = native_js_1.Native.load(library);
24
+ native.requireCapabilities(base.nativeCapabilities());
25
+ return new ProfileSpec(native.adaptProfile({ schema_version: 1, base: base.toJSON(), ja3, h2 }));
24
26
  }
25
27
  toJSON() { return JSON.parse(this.snapshot); }
28
+ /** @internal Capability negotiation happens before allocating a session. */
29
+ nativeCapabilities() {
30
+ const value = this.toJSON();
31
+ const stream = value.http2?.first_stream_id || value.http2?.stream_window_increment ||
32
+ (Array.isArray(value.capabilities?.required_features) && value.capabilities.required_features.includes("http2.stream.v1"));
33
+ return stream ? ["profile_spec_v1", "http2_stream_v1"] : ["profile_spec_v1"];
34
+ }
26
35
  }
27
36
  exports.ProfileSpec = ProfileSpec;
package/dist/session.d.ts CHANGED
@@ -75,6 +75,7 @@ export declare class Session {
75
75
  static open(options?: SessionOptions): Promise<Session>;
76
76
  readonly notificationMode: "async-events" | "poll";
77
77
  readonly cookies: Cookies;
78
+ private readonly hasAddressPolicy;
78
79
  private readonly native;
79
80
  private readonly handle;
80
81
  private readonly profile;
package/dist/session.js CHANGED
@@ -66,6 +66,7 @@ class Session {
66
66
  }
67
67
  notificationMode;
68
68
  cookies;
69
+ hasAddressPolicy;
69
70
  native;
70
71
  handle;
71
72
  profile;
@@ -87,6 +88,7 @@ class Session {
87
88
  constructor(options = {}) {
88
89
  if (options.retry !== undefined && !(options.retry instanceof retry_js_1.RetryPolicy))
89
90
  throw new TypeError("retry must be RetryPolicy");
91
+ this.hasAddressPolicy = options.addressPolicy !== undefined;
90
92
  this.retry = options.retry;
91
93
  this.proxy = proxyValue(options.proxy);
92
94
  this.proxyCaPem = proxyTrust(options.proxyCaFile);
@@ -129,11 +131,13 @@ class Session {
129
131
  }
130
132
  if (options.profileSpec !== undefined) {
131
133
  configuration.profile_spec = options.profileSpec.toJSON();
132
- required.push("profile_spec_v1");
134
+ required.push(...options.profileSpec.nativeCapabilities());
133
135
  }
134
136
  if (options.httpVersion === "h3") {
135
137
  configuration.http_version = "h3";
136
138
  required.push("http3_v1");
139
+ if (this.hasAddressPolicy && options.httpVersion === "h3")
140
+ required.push("http3_address_policy_v1");
137
141
  }
138
142
  if (required.length) {
139
143
  this.native.requireCapabilities(required);
@@ -267,11 +271,13 @@ class Session {
267
271
  throw new TypeError("profile and profileSpec are mutually exclusive");
268
272
  const required = [];
269
273
  if (options.profileSpec !== undefined)
270
- required.push("profile_spec_v1");
274
+ required.push(...options.profileSpec.nativeCapabilities());
271
275
  if (options.httpVersion !== undefined) {
272
276
  if (!["auto", "h3"].includes(options.httpVersion))
273
277
  throw new TypeError("httpVersion must be auto or h3");
274
278
  required.push("http3_v1");
279
+ if (this.hasAddressPolicy && options.httpVersion === "h3")
280
+ required.push("http3_address_policy_v1");
275
281
  }
276
282
  if (required.length)
277
283
  this.native.requireCapabilities(required);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fastls/fastls",
3
- "version": "0.13.0",
3
+ "version": "0.15.0",
4
4
  "description": "Node.js bindings for the Fastls C ABI",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -35,10 +35,10 @@
35
35
  "registry": "https://registry.npmjs.org/"
36
36
  },
37
37
  "optionalDependencies": {
38
- "@fastls/fastls-win32-x64": "0.13.0",
39
- "@fastls/fastls-linux-x64-glibc": "0.13.0",
40
- "@fastls/fastls-linux-arm64-glibc": "0.13.0",
41
- "@fastls/fastls-darwin-x64": "0.13.0",
42
- "@fastls/fastls-darwin-arm64": "0.13.0"
38
+ "@fastls/fastls-win32-x64": "0.15.0",
39
+ "@fastls/fastls-linux-x64-glibc": "0.15.0",
40
+ "@fastls/fastls-linux-arm64-glibc": "0.15.0",
41
+ "@fastls/fastls-darwin-x64": "0.15.0",
42
+ "@fastls/fastls-darwin-arm64": "0.15.0"
43
43
  }
44
44
  }