@apifuse/provider-sdk 2.2.0-beta.61 → 2.2.0-beta.63
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/AUTHORING.md +268 -9
- package/CHANGELOG.md +8 -0
- package/README.md +1 -0
- package/bin/apifuse-check.ts +84 -2
- package/bin/apifuse-dev.ts +11 -31
- package/bin/apifuse-migrate-deployment.ts +200 -0
- package/bin/apifuse-pack-check.ts +11 -4
- package/bin/apifuse-pack-types.ts +191 -4
- package/bin/apifuse-record.ts +44 -32
- package/bin/apifuse-test.ts +3 -1
- package/dist/cli/commands.d.ts +1 -1
- package/dist/cli/commands.js +11 -0
- package/dist/cli/deployment-intent.d.ts +178 -0
- package/dist/cli/deployment-intent.js +277 -0
- package/dist/cli/migrate-deployment-intent.d.ts +132 -0
- package/dist/cli/migrate-deployment-intent.js +1552 -0
- package/dist/cli/migrate-provider-shape.d.ts +5 -1
- package/dist/cli/migrate-provider-shape.js +4 -2
- package/dist/cli/resolver-runtime.d.ts +21 -0
- package/dist/cli/resolver-runtime.js +31 -0
- package/dist/define.d.ts +3 -0
- package/dist/define.js +5 -0
- package/dist/dev.d.ts +3 -1
- package/dist/dev.js +6 -1
- package/dist/engine.d.ts +35 -1
- package/dist/engine.js +21 -2
- package/dist/error-resolution.d.ts +1 -0
- package/dist/error-resolution.js +54 -0
- package/dist/errors.d.ts +39 -1
- package/dist/errors.js +50 -0
- package/dist/handle-meta.d.ts +18 -2
- package/dist/handle-meta.js +30 -2
- package/dist/handle.d.ts +33 -12
- package/dist/handle.js +69 -24
- package/dist/i18n/error-messages.d.ts +86 -0
- package/dist/i18n/error-messages.js +192 -0
- package/dist/i18n/index.d.ts +1 -0
- package/dist/i18n/index.js +1 -0
- package/dist/i18n/keys.d.ts +12 -0
- package/dist/i18n/keys.js +76 -5
- package/dist/index.d.ts +10 -2
- package/dist/index.js +9 -1
- package/dist/lint.d.ts +10 -0
- package/dist/lint.js +440 -57
- package/dist/provider.d.ts +7 -5
- package/dist/provider.js +4 -2
- package/dist/runtime/browser-telemetry-binding.d.ts +5 -0
- package/dist/runtime/browser-telemetry-binding.js +83 -0
- package/dist/runtime/browser-telemetry.d.ts +76 -0
- package/dist/runtime/browser-telemetry.js +165 -0
- package/dist/runtime/browser.d.ts +3 -0
- package/dist/runtime/browser.js +208 -47
- package/dist/runtime/cache-telemetry.d.ts +71 -0
- package/dist/runtime/cache-telemetry.js +177 -0
- package/dist/runtime/cache.js +67 -7
- package/dist/runtime/capability-response.d.ts +3 -0
- package/dist/runtime/capability-response.js +56 -0
- package/dist/runtime/capability-telemetry.d.ts +46 -0
- package/dist/runtime/capability-telemetry.js +68 -0
- package/dist/runtime/diagnostic-env.d.ts +3 -0
- package/dist/runtime/diagnostic-env.js +10 -1
- package/dist/runtime/engine-mode.d.ts +74 -0
- package/dist/runtime/engine-mode.js +152 -0
- package/dist/runtime/handle.js +15 -10
- package/dist/runtime/http-telemetry-binding.d.ts +10 -0
- package/dist/runtime/http-telemetry-binding.js +152 -0
- package/dist/runtime/http-telemetry-guard.d.ts +16 -0
- package/dist/runtime/http-telemetry-guard.js +202 -0
- package/dist/runtime/http-telemetry.d.ts +104 -0
- package/dist/runtime/http-telemetry.js +190 -0
- package/dist/runtime/http.d.ts +31 -0
- package/dist/runtime/http.js +356 -174
- package/dist/runtime/instrumentation.js +92 -13
- package/dist/runtime/ocr-telemetry.d.ts +82 -0
- package/dist/runtime/ocr-telemetry.js +192 -0
- package/dist/runtime/ocr.js +30 -8
- package/dist/runtime/request-telemetry.d.ts +2 -0
- package/dist/runtime/request-telemetry.js +2 -1
- package/dist/runtime/resolver-runtime-options.d.ts +14 -0
- package/dist/runtime/resolver-runtime-options.js +33 -0
- package/dist/runtime/resolver-shared.d.ts +3 -2
- package/dist/runtime/resolver-shared.js +4 -4
- package/dist/runtime/resolver-telemetry.d.ts +1 -0
- package/dist/runtime/resolver-telemetry.js +1 -1
- package/dist/runtime/resolver-vendors/browser.d.ts +2 -0
- package/dist/runtime/resolver-vendors/browser.js +46 -0
- package/dist/runtime/resolver-vendors/hosts.d.ts +21 -0
- package/dist/runtime/resolver-vendors/hosts.js +35 -0
- package/dist/runtime/resolver-vendors/hypersolutions.js +2 -2
- package/dist/runtime/resolver-vendors/types.d.ts +5 -4
- package/dist/runtime/resolver.d.ts +4 -1
- package/dist/runtime/resolver.js +46 -13
- package/dist/runtime/state-telemetry.d.ts +79 -0
- package/dist/runtime/state-telemetry.js +194 -0
- package/dist/runtime/state.d.ts +3 -0
- package/dist/runtime/state.js +26 -7
- package/dist/runtime/stealth-cookies.d.ts +5 -1
- package/dist/runtime/stealth-cookies.js +21 -1
- package/dist/runtime/stealth-owned-headers.d.ts +26 -0
- package/dist/runtime/stealth-owned-headers.js +37 -0
- package/dist/runtime/stealth-telemetry.d.ts +92 -0
- package/dist/runtime/stealth-telemetry.js +179 -0
- package/dist/runtime/stealth.d.ts +4 -1
- package/dist/runtime/stealth.js +228 -85
- package/dist/runtime/stt-telemetry.d.ts +77 -0
- package/dist/runtime/stt-telemetry.js +176 -0
- package/dist/runtime/stt.js +15 -6
- package/dist/server/error-stack-frames.d.ts +35 -0
- package/dist/server/error-stack-frames.js +219 -0
- package/dist/server/index.d.ts +9 -0
- package/dist/server/index.js +5 -0
- package/dist/server/sdk-version.d.ts +3 -0
- package/dist/server/sdk-version.js +19 -0
- package/dist/server/self-test.js +1 -18
- package/dist/server/sensitive-values.d.ts +1 -1
- package/dist/server/sensitive-values.js +9 -0
- package/dist/server/serve-implementation.d.ts +53 -2
- package/dist/server/serve-implementation.js +369 -123
- package/dist/server/types.d.ts +1 -0
- package/dist/server/types.js +7 -0
- package/dist/stateful/stateful-provider-owner-forwarder.js +22 -0
- package/dist/stateful/stateful-provider-runtime-context.d.ts +3 -0
- package/dist/stateful/stateful-provider-runtime-context.js +1 -0
- package/dist/types.d.ts +94 -1
- package/package.json +6 -1
- package/src/cli/commands.ts +14 -0
- package/src/cli/deployment-intent.ts +364 -0
- package/src/cli/migrate-deployment-intent.ts +1908 -0
- package/src/cli/migrate-provider-shape.ts +10 -4
- package/src/cli/resolver-runtime.ts +72 -0
- package/src/define.ts +13 -0
- package/src/dev.ts +9 -2
- package/src/engine.ts +38 -2
- package/src/error-resolution.ts +58 -0
- package/src/errors.ts +77 -1
- package/src/handle-meta.ts +39 -4
- package/src/handle.ts +121 -38
- package/src/i18n/error-messages.ts +255 -0
- package/src/i18n/index.ts +1 -0
- package/src/i18n/keys.ts +80 -6
- package/src/index.ts +91 -0
- package/src/lint.ts +552 -57
- package/src/provider.ts +20 -0
- package/src/runtime/browser-telemetry-binding.ts +92 -0
- package/src/runtime/browser-telemetry.ts +289 -0
- package/src/runtime/browser.ts +249 -65
- package/src/runtime/cache-telemetry.ts +247 -0
- package/src/runtime/cache.ts +68 -17
- package/src/runtime/capability-response.ts +53 -0
- package/src/runtime/capability-telemetry.ts +101 -0
- package/src/runtime/diagnostic-env.ts +11 -1
- package/src/runtime/engine-mode.ts +233 -0
- package/src/runtime/handle.ts +20 -10
- package/src/runtime/http-telemetry-binding.ts +162 -0
- package/src/runtime/http-telemetry-guard.ts +208 -0
- package/src/runtime/http-telemetry.ts +292 -0
- package/src/runtime/http.ts +457 -204
- package/src/runtime/instrumentation.ts +105 -16
- package/src/runtime/ocr-telemetry.ts +308 -0
- package/src/runtime/ocr.ts +109 -74
- package/src/runtime/request-telemetry.ts +2 -1
- package/src/runtime/resolver-runtime-options.ts +50 -0
- package/src/runtime/resolver-shared.ts +9 -4
- package/src/runtime/resolver-telemetry.ts +1 -1
- package/src/runtime/resolver-vendors/browser.ts +65 -7
- package/src/runtime/resolver-vendors/hosts.ts +43 -0
- package/src/runtime/resolver-vendors/hypersolutions.ts +2 -2
- package/src/runtime/resolver-vendors/types.ts +5 -4
- package/src/runtime/resolver.ts +64 -21
- package/src/runtime/state-telemetry.ts +298 -0
- package/src/runtime/state.ts +46 -45
- package/src/runtime/stealth-cookies.ts +24 -1
- package/src/runtime/stealth-owned-headers.ts +41 -0
- package/src/runtime/stealth-telemetry.ts +304 -0
- package/src/runtime/stealth.ts +355 -150
- package/src/runtime/stt-telemetry.ts +282 -0
- package/src/runtime/stt.ts +93 -71
- package/src/server/error-stack-frames.ts +214 -0
- package/src/server/index.ts +66 -0
- package/src/server/sdk-version.ts +22 -0
- package/src/server/self-test.ts +1 -21
- package/src/server/sensitive-values.ts +14 -0
- package/src/server/serve-implementation.ts +601 -157
- package/src/server/types.ts +7 -0
- package/src/stateful/stateful-provider-owner-forwarder.ts +23 -0
- package/src/stateful/stateful-provider-runtime-context.ts +4 -0
- package/src/types.ts +99 -1
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/approval-override.ts.txt +0 -6
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/codemod-syntax.ts.txt +0 -3
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/connection-precedence.ts.txt +0 -10
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-ambiguous-a.ts.txt +0 -3
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-ambiguous-b.ts.txt +0 -3
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-ambiguous-barrel.ts.txt +0 -2
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-ambiguous-index.ts.txt +0 -3
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-computed.ts.txt +0 -6
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-cycle-a.ts.txt +0 -1
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-cycle-b.ts.txt +0 -1
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-cycle-index.ts.txt +0 -3
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-barrel.ts.txt +0 -7
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-catalog.ts.txt +0 -19
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-docs.ts.txt +0 -6
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-index.ts.txt +0 -3
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-stores.ts.txt +0 -8
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-indirect-config.ts.txt +0 -5
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-nonstatic.ts.txt +0 -4
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-package-index.ts.txt +0 -3
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-reexport-index.ts.txt +0 -3
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-reexport-leaf.ts.txt +0 -10
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-reexport-one.ts.txt +0 -1
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-reexport-two.ts.txt +0 -1
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-composed-index.ts.txt +0 -3
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-composed-one.ts.txt +0 -6
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-composed-two.ts.txt +0 -6
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-mixed-index.ts.txt +0 -14
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-registry.ts.txt +0 -3
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-star-package-barrel.ts.txt +0 -2
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-star-package-index.ts.txt +0 -3
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-star-package-leaf.ts.txt +0 -3
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/docs-conflict.ts.txt +0 -8
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-hoisted-array-spread.ts.txt +0 -15
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-imported-array-spread.ts.txt +0 -9
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-kebab-operation-id.ts.txt +0 -17
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-map.ts.txt +0 -5
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-mixed-array-spread.ts.txt +0 -24
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-operation.ts.txt +0 -16
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-snake-operation-id.ts.txt +0 -21
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-duplicate-provider.ts.txt +0 -11
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-id-unresolved.ts.txt +0 -7
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-map.ts.txt +0 -3
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-one-to-many.ts.txt +0 -18
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-one-to-one.ts.txt +0 -13
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/hoist-all.ts.txt +0 -31
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/hoisted-const.ts.txt +0 -11
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/imported-spread.ts.txt +0 -11
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-map.ts.txt +0 -11
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-cast-tail.ts.txt +0 -21
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-ekitan.ts.txt +0 -11
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-override.ts.txt +0 -14
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/locale-canonical-en.json +0 -1
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/locale-canonical-ja.json +0 -1
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/locale-canonical-ko.json +0 -1
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/locale-existing-operation-namespace-en.json +0 -8
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/missing-english-locale.ts.txt +0 -7
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/no-safety.ts.txt +0 -6
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/non-literal.ts.txt +0 -7
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/redundant-approval.ts.txt +0 -6
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-binding-ambiguous.ts.txt +0 -12
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-imported-other.ts.txt +0 -7
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-imported.ts.txt +0 -5
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-key-ambiguous.ts.txt +0 -19
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-shorthand.ts.txt +0 -9
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-typed.ts.txt +0 -11
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-unrelated.ts.txt +0 -13
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/safety-conflict.ts.txt +0 -7
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/stream.ts.txt +0 -7
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/tool-router-spread.ts.txt +0 -15
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/unparseable.ts.txt +0 -4
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/verbatim-template.ts.txt +0 -12
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { createTelemetryObserver } from "./http-telemetry-guard.js";
|
|
2
|
+
import { closedEnum, } from "./request-telemetry.js";
|
|
3
|
+
import { getStateViolation, isStateRedisNoop } from "./state.js";
|
|
4
|
+
const MAX_SAMPLES = 24;
|
|
5
|
+
const MAX_TEXT = 300;
|
|
6
|
+
const STATE_TELEMETRY_INSTRUMENTED = Symbol.for("@apifuse/provider-sdk/state-telemetry-instrumented");
|
|
7
|
+
function integer(value) {
|
|
8
|
+
return Number.isFinite(value)
|
|
9
|
+
? Math.min(Number.MAX_SAFE_INTEGER, Math.max(0, Math.floor(value)))
|
|
10
|
+
: Number.MAX_SAFE_INTEGER;
|
|
11
|
+
}
|
|
12
|
+
function add(a, b) {
|
|
13
|
+
return Math.min(Number.MAX_SAFE_INTEGER, integer(a) + integer(b));
|
|
14
|
+
}
|
|
15
|
+
function keyText(value, redact) {
|
|
16
|
+
if (value === undefined)
|
|
17
|
+
return undefined;
|
|
18
|
+
let result;
|
|
19
|
+
try {
|
|
20
|
+
result = redact?.(value) ?? value;
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
result = "[REDACTION_FAILED]";
|
|
24
|
+
}
|
|
25
|
+
const length = Math.min(result.length, MAX_TEXT);
|
|
26
|
+
const units = new Uint16Array(length);
|
|
27
|
+
for (let index = 0; index < length; index += 1)
|
|
28
|
+
units[index] = result.charCodeAt(index);
|
|
29
|
+
return String.fromCharCode(...units);
|
|
30
|
+
}
|
|
31
|
+
export class StateTelemetryCollector {
|
|
32
|
+
key = "state";
|
|
33
|
+
#redact;
|
|
34
|
+
#telemetryFailed = false;
|
|
35
|
+
#ops = { list: 0, get: 0, set: 0, patch: 0, delete: 0, cas: 0, increment: 0 };
|
|
36
|
+
#conflicts = 0;
|
|
37
|
+
#violations = { quota: 0, ttl: 0, size: 0, unsupported: 0, error: 0 };
|
|
38
|
+
#backend = "unsupported";
|
|
39
|
+
#redisFallbacks = 0;
|
|
40
|
+
#configured = "not_configured";
|
|
41
|
+
#redisRoundTrips = 0;
|
|
42
|
+
#ms = 0;
|
|
43
|
+
#samples = [];
|
|
44
|
+
#dropped = 0;
|
|
45
|
+
constructor(options = {}) {
|
|
46
|
+
this.#redact = options.redact;
|
|
47
|
+
}
|
|
48
|
+
markTelemetryFailed() {
|
|
49
|
+
this.#telemetryFailed = true;
|
|
50
|
+
}
|
|
51
|
+
setRedisConfigured(configured) {
|
|
52
|
+
if (configured && this.#configured === "not_configured")
|
|
53
|
+
this.#configured = "configured";
|
|
54
|
+
}
|
|
55
|
+
record(event) {
|
|
56
|
+
if (!["list", "get", "set", "patch", "delete", "cas", "increment"].includes(event.op) ||
|
|
57
|
+
!["redis", "memory", "unsupported"].includes(event.backend) ||
|
|
58
|
+
(event.violation !== undefined &&
|
|
59
|
+
!["quota", "ttl", "size", "unsupported", "error"].includes(event.violation))) {
|
|
60
|
+
this.#telemetryFailed = true;
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
this.#ops[event.op] = add(this.#ops[event.op], 1);
|
|
64
|
+
this.#backend = event.backend;
|
|
65
|
+
if (event.backend === "redis" && this.#configured === "not_configured")
|
|
66
|
+
this.#configured = "configured";
|
|
67
|
+
if (event.backend === "redis" && event.ok && event.redisTouched !== false)
|
|
68
|
+
this.#redisRoundTrips = add(this.#redisRoundTrips, 1);
|
|
69
|
+
if (event.backend === "redis" && !event.ok)
|
|
70
|
+
this.#configured = "degraded";
|
|
71
|
+
this.#ms = add(this.#ms, event.ms);
|
|
72
|
+
if (event.conflict)
|
|
73
|
+
this.#conflicts = add(this.#conflicts, 1);
|
|
74
|
+
if (event.violation)
|
|
75
|
+
this.#violations[event.violation] = add(this.#violations[event.violation], 1);
|
|
76
|
+
if (this.#samples.length < MAX_SAMPLES)
|
|
77
|
+
this.#samples.push({
|
|
78
|
+
key: keyText(event.key, this.#redact) ?? "",
|
|
79
|
+
op: event.op,
|
|
80
|
+
ms: integer(event.ms),
|
|
81
|
+
backend: event.backend,
|
|
82
|
+
});
|
|
83
|
+
else
|
|
84
|
+
this.#dropped = add(this.#dropped, 1);
|
|
85
|
+
}
|
|
86
|
+
toLogPayload(_spans) {
|
|
87
|
+
if (Object.values(this.#ops).every((value) => value === 0) && !this.#telemetryFailed)
|
|
88
|
+
return undefined;
|
|
89
|
+
return {
|
|
90
|
+
...(this.#telemetryFailed ? { telemetryFailed: true } : {}),
|
|
91
|
+
ops: { ...this.#ops },
|
|
92
|
+
casConflicts: this.#conflicts,
|
|
93
|
+
violations: { ...this.#violations },
|
|
94
|
+
backend: closedEnum(this.#backend),
|
|
95
|
+
redisFallbacks: this.#redisFallbacks,
|
|
96
|
+
redisMode: closedEnum(this.#configured),
|
|
97
|
+
redisRoundTrips: this.#redisRoundTrips,
|
|
98
|
+
ms: this.#ms,
|
|
99
|
+
samples: this.#samples.map((sample) => ({ ...sample })),
|
|
100
|
+
dropped: this.#dropped,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
toHeaderPayload(log) {
|
|
104
|
+
return {
|
|
105
|
+
ops: log.ops,
|
|
106
|
+
casConflicts: log.casConflicts,
|
|
107
|
+
violations: log.violations,
|
|
108
|
+
backend: log.backend,
|
|
109
|
+
redisFallbacks: log.redisFallbacks,
|
|
110
|
+
redisMode: log.redisMode,
|
|
111
|
+
redisRoundTrips: log.redisRoundTrips,
|
|
112
|
+
ms: log.ms,
|
|
113
|
+
dropped: log.dropped,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
function backendOf(state) {
|
|
118
|
+
try {
|
|
119
|
+
const name = state.constructor?.name;
|
|
120
|
+
return name?.includes("Redis") ? "redis" : name?.includes("Memory") ? "memory" : "unsupported";
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
return "unsupported";
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
function violationOf(error) {
|
|
127
|
+
return getStateViolation(error) ?? "error";
|
|
128
|
+
}
|
|
129
|
+
function wrapNamespace(namespace, sink, backend) {
|
|
130
|
+
// Compare-and-set records one event per attempt; a three-attempt loop therefore
|
|
131
|
+
// reports cas: 3 and casConflicts: 2 when the first two attempts conflict.
|
|
132
|
+
const observe = createTelemetryObserver(sink);
|
|
133
|
+
return new Proxy(namespace, {
|
|
134
|
+
get(target, property, receiver) {
|
|
135
|
+
const value = Reflect.get(target, property, receiver);
|
|
136
|
+
if (typeof value !== "function" || property === "constructor")
|
|
137
|
+
return value;
|
|
138
|
+
const op = property === "compareAndSet" ? "cas" : String(property);
|
|
139
|
+
if (!(op in { list: 1, get: 1, set: 1, patch: 1, delete: 1, cas: 1, increment: 1 }))
|
|
140
|
+
return value;
|
|
141
|
+
return async (...args) => {
|
|
142
|
+
const started = Date.now();
|
|
143
|
+
const key = typeof args[0] === "string" ? args[0] : undefined;
|
|
144
|
+
try {
|
|
145
|
+
const result = await Reflect.apply(value, target, args);
|
|
146
|
+
observe(() => sink.record({
|
|
147
|
+
op,
|
|
148
|
+
key,
|
|
149
|
+
ms: Date.now() - started,
|
|
150
|
+
backend,
|
|
151
|
+
ok: true,
|
|
152
|
+
redisTouched: !isStateRedisNoop(result),
|
|
153
|
+
conflict: op === "cas" &&
|
|
154
|
+
!!result &&
|
|
155
|
+
typeof result === "object" &&
|
|
156
|
+
"ok" in result &&
|
|
157
|
+
result.ok === false,
|
|
158
|
+
}));
|
|
159
|
+
return result;
|
|
160
|
+
}
|
|
161
|
+
catch (error) {
|
|
162
|
+
observe(() => sink.record({
|
|
163
|
+
op,
|
|
164
|
+
key,
|
|
165
|
+
ms: Date.now() - started,
|
|
166
|
+
backend,
|
|
167
|
+
ok: false,
|
|
168
|
+
violation: violationOf(error),
|
|
169
|
+
}));
|
|
170
|
+
throw error;
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
},
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
export function instrumentProviderRuntimeState(state, sink, redact) {
|
|
177
|
+
if (state[STATE_TELEMETRY_INSTRUMENTED])
|
|
178
|
+
return state;
|
|
179
|
+
const backend = backendOf(state);
|
|
180
|
+
const observe = createTelemetryObserver(sink);
|
|
181
|
+
observe(() => sink.setRedisConfigured?.(backend === "redis"));
|
|
182
|
+
return new Proxy(state, {
|
|
183
|
+
get(target, property, receiver) {
|
|
184
|
+
if (property === STATE_TELEMETRY_INSTRUMENTED)
|
|
185
|
+
return true;
|
|
186
|
+
const value = Reflect.get(target, property, receiver);
|
|
187
|
+
if (property === "forConnection" && typeof value === "function")
|
|
188
|
+
return (id) => instrumentProviderRuntimeState(value.call(target, id), sink, redact);
|
|
189
|
+
if (property === "namespace" && typeof value === "function")
|
|
190
|
+
return (name, options) => wrapNamespace(value.call(target, name, options), sink, backend);
|
|
191
|
+
return value;
|
|
192
|
+
},
|
|
193
|
+
});
|
|
194
|
+
}
|
package/dist/runtime/state.d.ts
CHANGED
|
@@ -10,6 +10,9 @@ type RedisProviderRuntimeStateOptions = {
|
|
|
10
10
|
export declare class UnsupportedProviderStateError extends ProviderError {
|
|
11
11
|
constructor(message?: string);
|
|
12
12
|
}
|
|
13
|
+
export declare function isStateRedisNoop(result: unknown): boolean;
|
|
14
|
+
type StateViolationKind = "quota" | "ttl" | "size" | "unsupported";
|
|
15
|
+
export declare function getStateViolation(error: unknown): StateViolationKind | undefined;
|
|
13
16
|
export declare function createRedisProviderRuntimeState(options: RedisProviderRuntimeStateOptions): ProviderRuntimeState;
|
|
14
17
|
export declare function createProviderRuntimeStateFromEnv(options?: {
|
|
15
18
|
readonly providerId?: string;
|
package/dist/runtime/state.js
CHANGED
|
@@ -247,17 +247,17 @@ class RedisProviderStateNamespace {
|
|
|
247
247
|
enforceValueSize(value) {
|
|
248
248
|
const bytes = Buffer.byteLength(JSON.stringify(value), "utf8");
|
|
249
249
|
if (bytes > this.options.maxValueBytes) {
|
|
250
|
-
throw
|
|
250
|
+
throw stateViolationError(`Provider runtime state value exceeds maxValueBytes (${bytes} > ${this.options.maxValueBytes})`, "size");
|
|
251
251
|
}
|
|
252
252
|
}
|
|
253
253
|
quotaExceeded() {
|
|
254
|
-
return
|
|
254
|
+
return stateViolationError(`Provider runtime state namespace quota exceeded (${this.options.maxEntries + 1} > ${this.options.maxEntries})`, "quota");
|
|
255
255
|
}
|
|
256
256
|
writeTiming(ttl) {
|
|
257
257
|
const ttlMs = parseStateDurationMs(ttl ?? this.options.defaultTtl);
|
|
258
258
|
const maxTtlMs = parseStateDurationMs(this.options.maxTtl);
|
|
259
259
|
if (ttlMs > maxTtlMs) {
|
|
260
|
-
throw
|
|
260
|
+
throw stateViolationError(`Provider runtime state ttl exceeds maxTtl (${ttlMs} > ${maxTtlMs})`, "ttl");
|
|
261
261
|
}
|
|
262
262
|
const expiresAtMs = Date.now() + ttlMs;
|
|
263
263
|
return {
|
|
@@ -269,7 +269,7 @@ class RedisProviderStateNamespace {
|
|
|
269
269
|
async list(options) {
|
|
270
270
|
const requestedLimit = Math.max(0, options?.limit ?? this.options.maxEntries);
|
|
271
271
|
if (requestedLimit === 0)
|
|
272
|
-
return [];
|
|
272
|
+
return recordStateRedisNoop([]);
|
|
273
273
|
const keys = await this.indexedKeys(this.options.maxEntries);
|
|
274
274
|
if (keys.length === 0)
|
|
275
275
|
return [];
|
|
@@ -376,8 +376,27 @@ export class UnsupportedProviderStateError extends ProviderError {
|
|
|
376
376
|
constructor(message = "Provider runtime state is not available in this runtime") {
|
|
377
377
|
super(message, { code: "PROVIDER_STATE_UNSUPPORTED" });
|
|
378
378
|
this.name = "UnsupportedProviderStateError";
|
|
379
|
+
stateViolationKinds.set(this, "unsupported");
|
|
379
380
|
}
|
|
380
381
|
}
|
|
382
|
+
// Keep the exact no-command result out of band, without inspecting caller options twice.
|
|
383
|
+
const stateRedisNoopResults = new WeakSet();
|
|
384
|
+
function recordStateRedisNoop(result) {
|
|
385
|
+
stateRedisNoopResults.add(result);
|
|
386
|
+
return result;
|
|
387
|
+
}
|
|
388
|
+
export function isStateRedisNoop(result) {
|
|
389
|
+
return result !== null && typeof result === "object" && stateRedisNoopResults.has(result);
|
|
390
|
+
}
|
|
391
|
+
const stateViolationKinds = new WeakMap();
|
|
392
|
+
function stateViolationError(message, kind) {
|
|
393
|
+
const error = new UnsupportedProviderStateError(message);
|
|
394
|
+
stateViolationKinds.set(error, kind);
|
|
395
|
+
return error;
|
|
396
|
+
}
|
|
397
|
+
export function getStateViolation(error) {
|
|
398
|
+
return error !== null && typeof error === "object" ? stateViolationKinds.get(error) : undefined;
|
|
399
|
+
}
|
|
381
400
|
class UnsupportedProviderStateNamespace {
|
|
382
401
|
async list(_options) {
|
|
383
402
|
throw new UnsupportedProviderStateError();
|
|
@@ -421,7 +440,7 @@ class MemoryProviderStateNamespace {
|
|
|
421
440
|
enforceValueSize(value) {
|
|
422
441
|
const bytes = Buffer.byteLength(JSON.stringify(value), "utf8");
|
|
423
442
|
if (bytes > this.options.maxValueBytes) {
|
|
424
|
-
throw
|
|
443
|
+
throw stateViolationError(`Provider runtime state value exceeds maxValueBytes (${bytes} > ${this.options.maxValueBytes})`, "size");
|
|
425
444
|
}
|
|
426
445
|
}
|
|
427
446
|
enforceWritePolicy(key, value, ttl) {
|
|
@@ -429,10 +448,10 @@ class MemoryProviderStateNamespace {
|
|
|
429
448
|
const ttlMs = parseStateDurationMs(ttl ?? this.options.defaultTtl);
|
|
430
449
|
const maxTtlMs = parseStateDurationMs(this.options.maxTtl);
|
|
431
450
|
if (ttlMs > maxTtlMs) {
|
|
432
|
-
throw
|
|
451
|
+
throw stateViolationError(`Provider runtime state ttl exceeds maxTtl (${ttlMs} > ${maxTtlMs})`, "ttl");
|
|
433
452
|
}
|
|
434
453
|
if (!this.values.has(key) && this.values.size >= this.options.maxEntries) {
|
|
435
|
-
throw
|
|
454
|
+
throw stateViolationError(`Provider runtime state namespace quota exceeded (${this.options.maxEntries + 1} > ${this.options.maxEntries})`, "quota");
|
|
436
455
|
}
|
|
437
456
|
}
|
|
438
457
|
pruneExpired(nowMs = this.now()) {
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import type { CookieJar, StealthCookieStore, StealthCookieStoreV1, StealthSessionCookies } from "../types.js";
|
|
2
|
+
/** Extract cookie values from Set-Cookie/header strings for request-scoped registration. */
|
|
3
|
+
export declare function cookieValuesFromHeaders(headers: string | readonly string[]): string[];
|
|
2
4
|
export declare class StealthCookieJar implements CookieJar, StealthSessionCookies {
|
|
3
5
|
private cookies;
|
|
4
6
|
private readonly defaultUrl;
|
|
5
|
-
|
|
7
|
+
private readonly register;
|
|
8
|
+
constructor(cookieStrings: readonly string[], defaultUrl?: string, register?: (value: string) => void);
|
|
6
9
|
setFromCookieStrings(cookieStrings: readonly string[], url?: string): void;
|
|
7
10
|
get(name: string, url?: string): string | undefined;
|
|
8
11
|
getAll(url?: string): Record<string, string>;
|
|
@@ -15,6 +18,7 @@ export declare class StealthCookieJar implements CookieJar, StealthSessionCookie
|
|
|
15
18
|
deserialize(state: StealthCookieStore): void;
|
|
16
19
|
clear(): void;
|
|
17
20
|
find(predicate: (cookie: string) => boolean, url?: string): string | undefined;
|
|
21
|
+
names(url?: string): string[];
|
|
18
22
|
private normalizeUrl;
|
|
19
23
|
private getUniqueCookies;
|
|
20
24
|
}
|
|
@@ -4,15 +4,27 @@ function isRecord(value) {
|
|
|
4
4
|
return typeof value === "object" && value !== null;
|
|
5
5
|
}
|
|
6
6
|
const LEGACY_COOKIE_ORIGIN = "https://legacy-cookie.invalid/";
|
|
7
|
+
/** Extract cookie values from Set-Cookie/header strings for request-scoped registration. */
|
|
8
|
+
export function cookieValuesFromHeaders(headers) {
|
|
9
|
+
const values = [];
|
|
10
|
+
for (const header of typeof headers === "string" ? [headers] : headers) {
|
|
11
|
+
const cookie = Cookie.parse(header);
|
|
12
|
+
if (cookie?.value)
|
|
13
|
+
values.push(cookie.value);
|
|
14
|
+
}
|
|
15
|
+
return values;
|
|
16
|
+
}
|
|
7
17
|
export class StealthCookieJar {
|
|
8
18
|
cookies;
|
|
9
19
|
defaultUrl;
|
|
10
|
-
|
|
20
|
+
register;
|
|
21
|
+
constructor(cookieStrings, defaultUrl = LEGACY_COOKIE_ORIGIN, register) {
|
|
11
22
|
this.cookies = new ToughCookieJar(undefined, {
|
|
12
23
|
allowSecureOnLocal: false,
|
|
13
24
|
rejectPublicSuffixes: true,
|
|
14
25
|
});
|
|
15
26
|
this.defaultUrl = this.normalizeUrl(defaultUrl) ?? LEGACY_COOKIE_ORIGIN;
|
|
27
|
+
this.register = register;
|
|
16
28
|
this.setFromCookieStrings(cookieStrings);
|
|
17
29
|
}
|
|
18
30
|
setFromCookieStrings(cookieStrings, url = this.defaultUrl) {
|
|
@@ -20,6 +32,8 @@ export class StealthCookieJar {
|
|
|
20
32
|
if (!cookieUrl)
|
|
21
33
|
return;
|
|
22
34
|
for (const cookieString of cookieStrings) {
|
|
35
|
+
for (const value of cookieValuesFromHeaders(cookieString))
|
|
36
|
+
this.register?.(value);
|
|
23
37
|
this.cookies.setCookieSync(cookieString, cookieUrl, { ignoreError: true });
|
|
24
38
|
}
|
|
25
39
|
}
|
|
@@ -54,6 +68,7 @@ export class StealthCookieJar {
|
|
|
54
68
|
for (const [name, value] of Object.entries(cookies)) {
|
|
55
69
|
if (!name)
|
|
56
70
|
continue;
|
|
71
|
+
this.register?.(value);
|
|
57
72
|
this.cookies.setCookieSync(new Cookie({ key: name, path: "/", value }), this.defaultUrl, {
|
|
58
73
|
ignoreError: true,
|
|
59
74
|
});
|
|
@@ -88,6 +103,9 @@ export class StealthCookieJar {
|
|
|
88
103
|
}
|
|
89
104
|
return undefined;
|
|
90
105
|
}
|
|
106
|
+
names(url) {
|
|
107
|
+
return this.getUniqueCookies(url ?? this.defaultUrl).map((cookie) => cookie.key);
|
|
108
|
+
}
|
|
91
109
|
normalizeUrl(url) {
|
|
92
110
|
try {
|
|
93
111
|
return new URL(url).toString();
|
|
@@ -102,6 +120,8 @@ export class StealthCookieJar {
|
|
|
102
120
|
return [];
|
|
103
121
|
const names = new Set();
|
|
104
122
|
return this.cookies.getCookiesSync(cookieUrl).filter((cookie) => {
|
|
123
|
+
if (cookie.value)
|
|
124
|
+
this.register?.(cookie.value);
|
|
105
125
|
if (names.has(cookie.key))
|
|
106
126
|
return false;
|
|
107
127
|
names.add(cookie.key);
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Header names the stealth transport owns.
|
|
3
|
+
*
|
|
4
|
+
* `ctx.stealth` composes these from the Chrome emulation and the request class,
|
|
5
|
+
* so a caller value is rejected at request time with `SDKError` code
|
|
6
|
+
* `STEALTH_HEADER_OVERRIDE_UNSUPPORTED` (`assertCallerHeadersSupported` in
|
|
7
|
+
* stealth.ts). The `browser-version-literal` lint reports a subset of these
|
|
8
|
+
* names — the `sec-fetch-*` and `sec-ch-ua*` families — in files that use
|
|
9
|
+
* `ctx.stealth` (`isReportedOwnedHeaderName` in lint.ts). Both read this
|
|
10
|
+
* module, so the lint cannot claim a rejection the runtime does not perform;
|
|
11
|
+
* it reports deliberately less than the runtime rejects (host, connection,
|
|
12
|
+
* accept-encoding and a non-literal user-agent stay silent — see that
|
|
13
|
+
* predicate for why), so a green `apifuse check` is not proof that no owned
|
|
14
|
+
* header is set.
|
|
15
|
+
*
|
|
16
|
+
* Leaf module by design: no imports, so the lazily loaded CLI lint path does
|
|
17
|
+
* not pull the stealth runtime in.
|
|
18
|
+
*/
|
|
19
|
+
export declare const SDK_OWNED_EXACT_CHROME_HEADERS: ReadonlySet<string>;
|
|
20
|
+
export declare const SDK_OWNED_CHROME_HEADER_PREFIX = "sec-fetch-";
|
|
21
|
+
/**
|
|
22
|
+
* True when `ctx.stealth` rejects a caller value for `name` (case-insensitive):
|
|
23
|
+
* an exact member of {@link SDK_OWNED_EXACT_CHROME_HEADERS} or any
|
|
24
|
+
* `sec-fetch-*` name.
|
|
25
|
+
*/
|
|
26
|
+
export declare function isStealthOwnedHeaderName(name: string): boolean;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Header names the stealth transport owns.
|
|
3
|
+
*
|
|
4
|
+
* `ctx.stealth` composes these from the Chrome emulation and the request class,
|
|
5
|
+
* so a caller value is rejected at request time with `SDKError` code
|
|
6
|
+
* `STEALTH_HEADER_OVERRIDE_UNSUPPORTED` (`assertCallerHeadersSupported` in
|
|
7
|
+
* stealth.ts). The `browser-version-literal` lint reports a subset of these
|
|
8
|
+
* names — the `sec-fetch-*` and `sec-ch-ua*` families — in files that use
|
|
9
|
+
* `ctx.stealth` (`isReportedOwnedHeaderName` in lint.ts). Both read this
|
|
10
|
+
* module, so the lint cannot claim a rejection the runtime does not perform;
|
|
11
|
+
* it reports deliberately less than the runtime rejects (host, connection,
|
|
12
|
+
* accept-encoding and a non-literal user-agent stay silent — see that
|
|
13
|
+
* predicate for why), so a green `apifuse check` is not proof that no owned
|
|
14
|
+
* header is set.
|
|
15
|
+
*
|
|
16
|
+
* Leaf module by design: no imports, so the lazily loaded CLI lint path does
|
|
17
|
+
* not pull the stealth runtime in.
|
|
18
|
+
*/
|
|
19
|
+
export const SDK_OWNED_EXACT_CHROME_HEADERS = new Set([
|
|
20
|
+
"host",
|
|
21
|
+
"connection",
|
|
22
|
+
"user-agent",
|
|
23
|
+
"sec-ch-ua",
|
|
24
|
+
"sec-ch-ua-mobile",
|
|
25
|
+
"sec-ch-ua-platform",
|
|
26
|
+
"accept-encoding",
|
|
27
|
+
]);
|
|
28
|
+
export const SDK_OWNED_CHROME_HEADER_PREFIX = "sec-fetch-";
|
|
29
|
+
/**
|
|
30
|
+
* True when `ctx.stealth` rejects a caller value for `name` (case-insensitive):
|
|
31
|
+
* an exact member of {@link SDK_OWNED_EXACT_CHROME_HEADERS} or any
|
|
32
|
+
* `sec-fetch-*` name.
|
|
33
|
+
*/
|
|
34
|
+
export function isStealthOwnedHeaderName(name) {
|
|
35
|
+
const lower = name.toLowerCase();
|
|
36
|
+
return (SDK_OWNED_EXACT_CHROME_HEADERS.has(lower) || lower.startsWith(SDK_OWNED_CHROME_HEADER_PREFIX));
|
|
37
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import type { StealthBrowser, StealthChallengeClassification, StealthOS, StealthProfileDescriptor } from "../types.js";
|
|
2
|
+
import { type ClosedEnum, type TelemetryContributor } from "./request-telemetry.js";
|
|
3
|
+
export type StealthTelemetryErrorCode = "transport_network_error" | "transport_timeout" | "transport_cancelled" | "upstream_http_error" | "response_too_large" | "proxy_connect_failed" | "PROXY_POOL_STALE" | "PROXY_EDGE_AUTH_REJECTED" | "PROXY_AUTH_IP_DENIED" | "PROXY_EDGE_TLS_REJECTED" | "PROXY_REQUIRED" | "other";
|
|
4
|
+
export type StealthTelemetryRequestClass = "navigation" | "script_navigation" | "xhr" | "post";
|
|
5
|
+
export type StealthTelemetryAttemptKind = "request" | "resolver" | "proxy_diagnostic";
|
|
6
|
+
export type StealthTelemetrySbsdOutcome = StealthChallengeClassification["outcome"] | "detected" | "refetch_clear";
|
|
7
|
+
export type StealthTelemetryDiagnostics = {
|
|
8
|
+
readonly name?: string;
|
|
9
|
+
readonly message?: string;
|
|
10
|
+
readonly code?: string;
|
|
11
|
+
};
|
|
12
|
+
export type StealthTelemetryAttemptEvent = {
|
|
13
|
+
readonly ms: number;
|
|
14
|
+
readonly status?: number;
|
|
15
|
+
readonly errorCode?: StealthTelemetryErrorCode;
|
|
16
|
+
readonly diagnostics?: StealthTelemetryDiagnostics;
|
|
17
|
+
readonly profileId: StealthProfileDescriptor;
|
|
18
|
+
readonly proxyUsed: boolean;
|
|
19
|
+
readonly requestClass: StealthTelemetryRequestClass;
|
|
20
|
+
readonly kind?: StealthTelemetryAttemptKind;
|
|
21
|
+
};
|
|
22
|
+
export type StealthTelemetrySbsdEvent = {
|
|
23
|
+
readonly detected: boolean;
|
|
24
|
+
readonly outcome?: StealthTelemetrySbsdOutcome;
|
|
25
|
+
};
|
|
26
|
+
export interface StealthTelemetrySink {
|
|
27
|
+
recordAttempt(event: StealthTelemetryAttemptEvent): void;
|
|
28
|
+
recordPoolRefresh(): void;
|
|
29
|
+
recordRedirectHop(): void;
|
|
30
|
+
recordSbsd(event?: StealthTelemetrySbsdEvent | StealthTelemetrySbsdOutcome): void;
|
|
31
|
+
recordSafeRefetch(): void;
|
|
32
|
+
}
|
|
33
|
+
export type StealthTelemetryAttemptSample = {
|
|
34
|
+
n: number;
|
|
35
|
+
ms: number;
|
|
36
|
+
status?: number;
|
|
37
|
+
e?: StealthTelemetryErrorCode;
|
|
38
|
+
kind?: StealthTelemetryAttemptKind;
|
|
39
|
+
diagnostics?: StealthTelemetryDiagnostics;
|
|
40
|
+
};
|
|
41
|
+
export type StealthTelemetryLogPayload = {
|
|
42
|
+
attempts: number;
|
|
43
|
+
poolRefreshes: number;
|
|
44
|
+
redirectHops: number;
|
|
45
|
+
profileId?: StealthProfileDescriptor;
|
|
46
|
+
proxyUsed: boolean;
|
|
47
|
+
requestClass?: StealthTelemetryRequestClass;
|
|
48
|
+
sbsdDetected?: boolean;
|
|
49
|
+
sbsdOutcome?: StealthTelemetrySbsdOutcome;
|
|
50
|
+
safeRefetch: number;
|
|
51
|
+
lastStatus?: number;
|
|
52
|
+
ms: number;
|
|
53
|
+
attemptSamples?: StealthTelemetryAttemptSample[];
|
|
54
|
+
attemptSamplesDropped?: number;
|
|
55
|
+
};
|
|
56
|
+
export type StealthTelemetryHeaderPayload = {
|
|
57
|
+
attempts: number;
|
|
58
|
+
poolRefreshes: number;
|
|
59
|
+
redirectHops: number;
|
|
60
|
+
profileId?: {
|
|
61
|
+
browser: ClosedEnum<StealthBrowser>;
|
|
62
|
+
os: ClosedEnum<StealthOS>;
|
|
63
|
+
};
|
|
64
|
+
proxyUsed: boolean;
|
|
65
|
+
requestClass?: ClosedEnum<StealthTelemetryRequestClass>;
|
|
66
|
+
sbsdDetected?: boolean;
|
|
67
|
+
sbsdOutcome?: ClosedEnum<StealthTelemetrySbsdOutcome>;
|
|
68
|
+
safeRefetch: number;
|
|
69
|
+
lastStatus?: number;
|
|
70
|
+
ms: number;
|
|
71
|
+
attemptSamples?: {
|
|
72
|
+
n: number;
|
|
73
|
+
ms: number;
|
|
74
|
+
status?: number;
|
|
75
|
+
e?: ClosedEnum<StealthTelemetryErrorCode>;
|
|
76
|
+
kind?: ClosedEnum<StealthTelemetryAttemptKind>;
|
|
77
|
+
}[];
|
|
78
|
+
};
|
|
79
|
+
export declare class StealthTelemetryCollector implements StealthTelemetrySink, TelemetryContributor<StealthTelemetryLogPayload, StealthTelemetryHeaderPayload> {
|
|
80
|
+
#private;
|
|
81
|
+
readonly key: "stealth";
|
|
82
|
+
constructor(options?: {
|
|
83
|
+
redact?: (text: string) => string;
|
|
84
|
+
});
|
|
85
|
+
recordAttempt(event: StealthTelemetryAttemptEvent): void;
|
|
86
|
+
recordPoolRefresh(): void;
|
|
87
|
+
recordRedirectHop(): void;
|
|
88
|
+
recordSbsd(event?: StealthTelemetrySbsdEvent | StealthTelemetrySbsdOutcome): void;
|
|
89
|
+
recordSafeRefetch(): void;
|
|
90
|
+
toLogPayload(): StealthTelemetryLogPayload | undefined;
|
|
91
|
+
toHeaderPayload(log: StealthTelemetryLogPayload): StealthTelemetryHeaderPayload;
|
|
92
|
+
}
|