@apifuse/provider-sdk 2.2.0-beta.5 → 2.2.0-beta.50
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 +537 -33
- package/CHANGELOG.md +201 -1
- package/README.md +83 -22
- package/SUBMISSION.md +2 -2
- package/bin/apifuse-check.ts +165 -11
- package/bin/apifuse-dev.ts +57 -13
- package/bin/apifuse-migrate-operation-declaration.ts +55 -0
- package/bin/apifuse-migrate-shape.ts +202 -0
- package/bin/apifuse-pack-check.ts +22 -2
- package/bin/apifuse-pack-smoke.ts +57 -2
- package/bin/apifuse-pack-types.ts +357 -38
- package/bin/apifuse-perf.ts +14 -13
- package/bin/apifuse-record.ts +709 -72
- package/bin/apifuse-submit-check.ts +2344 -324
- package/bin/apifuse-sync-assets.ts +117 -0
- package/bin/submit-check-delimited-text.ts +50 -0
- package/dist/auth-turn/index.d.ts +3 -3
- package/dist/auth-turn/index.js +1 -1
- package/dist/auth.d.ts +14 -0
- package/dist/auth.js +67 -0
- package/dist/ceremonies/index.d.ts +16 -0
- package/dist/ceremonies/index.js +141 -36
- package/dist/cli/commands.d.ts +1 -1
- package/dist/cli/commands.js +27 -0
- package/dist/cli/create.d.ts +4 -1
- package/dist/cli/create.js +42 -37
- package/dist/cli/migrate-operation-declaration.d.ts +59 -0
- package/dist/cli/migrate-operation-declaration.js +1178 -0
- package/dist/cli/migrate-operation-shape.d.ts +44 -0
- package/dist/cli/migrate-operation-shape.js +113 -0
- package/dist/cli/migrate-provider-shape.d.ts +52 -0
- package/dist/cli/migrate-provider-shape.js +578 -0
- package/dist/cli/prompt-assets.d.ts +80 -0
- package/dist/cli/prompt-assets.js +743 -0
- package/dist/cli/templates/provider/AGENTS.md.tpl +17 -8
- package/dist/cli/templates/provider/Dockerfile.tpl +1 -1
- package/dist/cli/templates/provider/README.md.tpl +5 -5
- package/dist/cli/templates/provider/index.ts.tpl +6 -3
- package/dist/cli/templates/provider/operations/ping.ts.tpl +4 -1
- package/dist/cli/templates/provider/provider.json.tpl +6 -0
- package/dist/config/loader.d.ts +179 -16
- package/dist/config/loader.js +435 -127
- package/dist/contract-serialization.js +4 -8
- package/dist/contract-types.d.ts +12 -5
- package/dist/contract.js +24 -10
- package/dist/declaration-validation.d.ts +33 -0
- package/dist/declaration-validation.js +266 -0
- package/dist/define.d.ts +66 -29
- package/dist/define.js +778 -69
- package/dist/dev.d.ts +3 -0
- package/dist/dev.js +1 -1
- package/dist/engine.d.ts +78 -0
- package/dist/engine.js +133 -0
- package/dist/error-observability.d.ts +7 -0
- package/dist/error-observability.js +61 -0
- package/dist/error-resolution.d.ts +4 -0
- package/dist/error-resolution.js +122 -0
- package/dist/errors.d.ts +33 -0
- package/dist/errors.js +40 -0
- package/dist/fixture-sanitization.d.ts +28 -0
- package/dist/fixture-sanitization.js +227 -0
- package/dist/health-scenario.d.ts +1842 -0
- package/dist/health-scenario.js +624 -0
- package/dist/index.d.ts +21 -10
- package/dist/index.js +12 -7
- package/dist/lint.d.ts +23 -11
- package/dist/lint.js +572 -69
- package/dist/native-address.d.ts +43 -0
- package/dist/native-address.js +281 -0
- package/dist/native-egress-policy.d.ts +31 -0
- package/dist/native-egress-policy.js +288 -0
- package/dist/observability.d.ts +5 -2
- package/dist/observability.js +48 -1
- package/dist/provider.d.ts +10 -2
- package/dist/provider.js +4 -1
- package/dist/runtime/auth-flow.d.ts +5 -1
- package/dist/runtime/auth-flow.js +6 -0
- package/dist/runtime/browser.d.ts +1 -0
- package/dist/runtime/browser.js +492 -49
- package/dist/runtime/cache.d.ts +1 -0
- package/dist/runtime/cache.js +169 -15
- package/dist/runtime/choice-wordlist.d.ts +9 -0
- package/dist/runtime/choice-wordlist.js +138 -0
- package/dist/runtime/choice.d.ts +13 -1
- package/dist/runtime/choice.js +490 -102
- package/dist/runtime/chrome149-header-order.d.ts +58 -0
- package/dist/runtime/chrome149-header-order.js +289 -0
- package/dist/runtime/env.js +12 -0
- package/dist/runtime/executor.d.ts +3 -2
- package/dist/runtime/executor.js +26 -25
- package/dist/runtime/http.d.ts +1 -0
- package/dist/runtime/http.js +515 -53
- package/dist/runtime/insights.js +2 -2
- package/dist/runtime/instrumentation.d.ts +2 -2
- package/dist/runtime/instrumentation.js +366 -8
- package/dist/runtime/native-network-errors.d.ts +33 -0
- package/dist/runtime/native-network-errors.js +69 -0
- package/dist/runtime/native-network.d.ts +96 -0
- package/dist/runtime/native-network.js +1232 -0
- package/dist/runtime/ocr.d.ts +29 -0
- package/dist/runtime/ocr.js +440 -0
- package/dist/runtime/otlp.d.ts +71 -2
- package/dist/runtime/otlp.js +397 -16
- package/dist/runtime/proxy-errors.js +6 -2
- package/dist/runtime/proxy-nodemaven.d.ts +56 -0
- package/dist/runtime/proxy-nodemaven.js +146 -0
- package/dist/runtime/proxy-telemetry.d.ts +80 -1
- package/dist/runtime/proxy-telemetry.js +154 -47
- package/dist/runtime/redirects.d.ts +29 -0
- package/dist/runtime/redirects.js +36 -0
- package/dist/runtime/redis.d.ts +1 -1
- package/dist/runtime/redis.js +4 -2
- package/dist/runtime/request-options.d.ts +68 -1
- package/dist/runtime/request-options.js +548 -0
- package/dist/runtime/resolver-config.d.ts +6 -0
- package/dist/runtime/resolver-config.js +6 -0
- package/dist/runtime/resolver-public.d.ts +1 -0
- package/dist/runtime/resolver-public.js +1 -0
- package/dist/runtime/resolver-shared.d.ts +14 -0
- package/dist/runtime/resolver-shared.js +12 -0
- package/dist/runtime/resolver-vendors/bindings.d.ts +48 -0
- package/dist/runtime/resolver-vendors/bindings.js +40 -0
- package/dist/runtime/resolver-vendors/browser.d.ts +22 -0
- package/dist/runtime/resolver-vendors/browser.js +377 -0
- package/dist/runtime/resolver-vendors/capsolver.d.ts +22 -0
- package/dist/runtime/resolver-vendors/capsolver.js +531 -0
- package/dist/runtime/resolver-vendors/hosts.d.ts +2 -0
- package/dist/runtime/resolver-vendors/hosts.js +33 -0
- package/dist/runtime/resolver-vendors/twocaptcha.d.ts +24 -0
- package/dist/runtime/resolver-vendors/twocaptcha.js +408 -0
- package/dist/runtime/resolver-vendors/types.d.ts +94 -0
- package/dist/runtime/resolver-vendors/types.js +96 -0
- package/dist/runtime/resolver.d.ts +72 -0
- package/dist/runtime/resolver.js +771 -0
- package/dist/runtime/secrets.d.ts +27 -0
- package/dist/runtime/secrets.js +51 -0
- package/dist/runtime/state.d.ts +3 -0
- package/dist/runtime/state.js +277 -71
- package/dist/runtime/stealth-cookies.d.ts +20 -0
- package/dist/runtime/stealth-cookies.js +111 -0
- package/dist/runtime/stealth.d.ts +41 -5
- package/dist/runtime/stealth.js +997 -291
- package/dist/runtime/stt.js +1 -12
- package/dist/runtime/timeout.d.ts +5 -0
- package/dist/runtime/timeout.js +12 -0
- package/dist/runtime/trace-config.d.ts +12 -0
- package/dist/runtime/trace-config.js +62 -0
- package/dist/runtime/trace.d.ts +5 -0
- package/dist/runtime/trace.js +43 -10
- package/dist/serve.d.ts +1 -1
- package/dist/serve.js +1 -1
- package/dist/server/error-observability.d.ts +1 -0
- package/dist/server/error-observability.js +1 -0
- package/dist/server/index.d.ts +5 -2
- package/dist/server/index.js +2 -2
- package/dist/server/self-test-input-tokens.d.ts +2 -1
- package/dist/server/self-test-input-tokens.js +18 -14
- package/dist/server/self-test.d.ts +14 -3
- package/dist/server/self-test.js +129 -58
- package/dist/server/serve-implementation.d.ts +230 -0
- package/dist/server/serve-implementation.js +2265 -0
- package/dist/server/serve.d.ts +1 -70
- package/dist/server/serve.js +1 -1131
- package/dist/server/trace-output.d.ts +6 -0
- package/dist/server/trace-output.js +79 -0
- package/dist/server/types.d.ts +30 -5
- package/dist/server/types.js +13 -1
- package/dist/stateful/errors.d.ts +19 -0
- package/dist/stateful/errors.js +24 -0
- package/dist/stateful/http-provider-event-emitter.d.ts +40 -0
- package/dist/stateful/http-provider-event-emitter.js +237 -0
- package/dist/stateful/http-session-owner-registry.d.ts +44 -0
- package/dist/stateful/http-session-owner-registry.js +210 -0
- package/dist/stateful/index.d.ts +18 -0
- package/dist/stateful/index.js +18 -0
- package/dist/stateful/provider-event-delivery-failures.d.ts +32 -0
- package/dist/stateful/provider-event-delivery-failures.js +43 -0
- package/dist/stateful/provider-event-pipeline-metrics.d.ts +46 -0
- package/dist/stateful/provider-event-pipeline-metrics.js +48 -0
- package/dist/stateful/provider-event-pipeline.d.ts +50 -0
- package/dist/stateful/provider-event-pipeline.js +1 -0
- package/dist/stateful/provider-events.d.ts +101 -0
- package/dist/stateful/provider-events.js +289 -0
- package/dist/stateful/session-key.d.ts +15 -0
- package/dist/stateful/session-key.js +86 -0
- package/dist/stateful/stateful-provider-adapter-context.d.ts +5 -0
- package/dist/stateful/stateful-provider-adapter-context.js +42 -0
- package/dist/stateful/stateful-provider-adapter-metrics.d.ts +15 -0
- package/dist/stateful/stateful-provider-adapter-metrics.js +21 -0
- package/dist/stateful/stateful-provider-adapter.d.ts +98 -0
- package/dist/stateful/stateful-provider-adapter.js +287 -0
- package/dist/stateful/stateful-provider-observability.d.ts +62 -0
- package/dist/stateful/stateful-provider-observability.js +161 -0
- package/dist/stateful/stateful-provider-owner-forwarder.d.ts +41 -0
- package/dist/stateful/stateful-provider-owner-forwarder.js +215 -0
- package/dist/stateful/stateful-provider-runtime-context.d.ts +32 -0
- package/dist/stateful/stateful-provider-runtime-context.js +60 -0
- package/dist/stateful/stateful-provider-runtime-executor.d.ts +34 -0
- package/dist/stateful/stateful-provider-runtime-executor.js +52 -0
- package/dist/stateful/stateful-provider-session-routing.d.ts +67 -0
- package/dist/stateful/stateful-provider-session-routing.js +345 -0
- package/dist/stateful/stateful-provider-session-runtime.d.ts +98 -0
- package/dist/stateful/stateful-provider-session-runtime.js +245 -0
- package/dist/stateful-signing.d.ts +18 -0
- package/dist/stateful-signing.js +27 -0
- package/dist/stealth/profiles.d.ts +9 -4
- package/dist/stealth/profiles.js +160 -211
- package/dist/stream-evidence.d.ts +74 -0
- package/dist/stream-evidence.js +785 -0
- package/dist/stream.js +7 -1
- package/dist/testing/index.d.ts +2 -1
- package/dist/testing/index.js +2 -1
- package/dist/testing/run.d.ts +32 -2
- package/dist/testing/run.js +489 -21
- package/dist/trace-sanitization.d.ts +5 -0
- package/dist/trace-sanitization.js +45 -0
- package/dist/types.d.ts +673 -131
- package/dist/types.js +1 -0
- package/package.json +45 -5
- package/src/auth-turn/index.ts +1 -1
- package/src/auth.ts +118 -0
- package/src/ceremonies/index.ts +189 -46
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/approval-override.ts.txt +6 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/codemod-syntax.ts.txt +3 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/connection-precedence.ts.txt +10 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/docs-conflict.ts.txt +8 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-map.ts.txt +5 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-operation.ts.txt +16 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-map.ts.txt +3 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/hoist-all.ts.txt +31 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/hoisted-const.ts.txt +11 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/imported-spread.ts.txt +11 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-map.ts.txt +11 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-cast-tail.ts.txt +21 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-ekitan.ts.txt +11 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-override.ts.txt +14 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/missing-english-locale.ts.txt +7 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/no-safety.ts.txt +6 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/non-literal.ts.txt +7 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/redundant-approval.ts.txt +6 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/safety-conflict.ts.txt +7 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/stream.ts.txt +7 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/tool-router-spread.ts.txt +15 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/unparseable.ts.txt +4 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/verbatim-template.ts.txt +12 -0
- package/src/cli/commands.ts +33 -0
- package/src/cli/create.ts +50 -37
- package/src/cli/migrate-operation-declaration.ts +1654 -0
- package/src/cli/migrate-operation-shape.ts +184 -0
- package/src/cli/migrate-provider-shape.ts +772 -0
- package/src/cli/prompt-assets.ts +865 -0
- package/src/cli/templates/provider/AGENTS.md.tpl +17 -8
- package/src/cli/templates/provider/Dockerfile.tpl +1 -1
- package/src/cli/templates/provider/README.md.tpl +5 -5
- package/src/cli/templates/provider/index.ts.tpl +6 -3
- package/src/cli/templates/provider/operations/ping.ts.tpl +4 -1
- package/src/cli/templates/provider/provider.json.tpl +6 -0
- package/src/config/loader.ts +690 -163
- package/src/contract-serialization.ts +5 -7
- package/src/contract-types.ts +12 -5
- package/src/contract.ts +24 -10
- package/src/declaration-validation.ts +330 -0
- package/src/define.ts +1048 -131
- package/src/dev.ts +4 -1
- package/src/engine.ts +279 -0
- package/src/error-observability.ts +64 -0
- package/src/error-resolution.ts +127 -0
- package/src/errors.ts +68 -0
- package/src/fixture-sanitization.ts +264 -0
- package/src/health-scenario.ts +875 -0
- package/src/index.ts +220 -13
- package/src/lint.ts +698 -90
- package/src/native-address.ts +340 -0
- package/src/native-egress-policy.ts +358 -0
- package/src/observability.ts +51 -1
- package/src/provider.ts +161 -3
- package/src/runtime/auth-flow.ts +12 -0
- package/src/runtime/browser.ts +661 -63
- package/src/runtime/cache.ts +189 -14
- package/src/runtime/choice-wordlist.ts +145 -0
- package/src/runtime/choice.ts +631 -120
- package/src/runtime/chrome149-header-order.ts +330 -0
- package/src/runtime/env.ts +13 -0
- package/src/runtime/executor.ts +43 -31
- package/src/runtime/http.ts +641 -61
- package/src/runtime/insights.ts +2 -2
- package/src/runtime/instrumentation.ts +520 -15
- package/src/runtime/native-network-errors.ts +99 -0
- package/src/runtime/native-network.ts +1605 -0
- package/src/runtime/ocr.ts +523 -0
- package/src/runtime/otlp.ts +467 -21
- package/src/runtime/proxy-errors.ts +12 -4
- package/src/runtime/proxy-nodemaven.ts +221 -0
- package/src/runtime/proxy-telemetry.ts +244 -75
- package/src/runtime/redirects.ts +66 -0
- package/src/runtime/redis.ts +7 -2
- package/src/runtime/request-options.ts +680 -1
- package/src/runtime/resolver-config.ts +6 -0
- package/src/runtime/resolver-public.ts +23 -0
- package/src/runtime/resolver-shared.ts +33 -0
- package/src/runtime/resolver-vendors/bindings.ts +56 -0
- package/src/runtime/resolver-vendors/browser.ts +533 -0
- package/src/runtime/resolver-vendors/capsolver.ts +707 -0
- package/src/runtime/resolver-vendors/hosts.ts +38 -0
- package/src/runtime/resolver-vendors/twocaptcha.ts +540 -0
- package/src/runtime/resolver-vendors/types.ts +212 -0
- package/src/runtime/resolver.ts +1157 -0
- package/src/runtime/secrets.ts +64 -0
- package/src/runtime/state.ts +394 -77
- package/src/runtime/stealth-cookies.ts +132 -0
- package/src/runtime/stealth.ts +1280 -336
- package/src/runtime/stt.ts +1 -19
- package/src/runtime/timeout.ts +18 -0
- package/src/runtime/trace-config.ts +78 -0
- package/src/runtime/trace.ts +57 -17
- package/src/serve.ts +6 -1
- package/src/server/error-observability.ts +1 -0
- package/src/server/index.ts +34 -2
- package/src/server/self-test-input-tokens.ts +29 -14
- package/src/server/self-test.ts +191 -68
- package/src/server/serve-implementation.ts +3378 -0
- package/src/server/serve.ts +1 -1632
- package/src/server/trace-output.ts +129 -0
- package/src/server/types.ts +13 -1
- package/src/stateful/README.md +146 -0
- package/src/stateful/errors.ts +35 -0
- package/src/stateful/http-provider-event-emitter.ts +314 -0
- package/src/stateful/http-session-owner-registry.ts +306 -0
- package/src/stateful/index.ts +18 -0
- package/src/stateful/provider-event-delivery-failures.ts +80 -0
- package/src/stateful/provider-event-pipeline-metrics.ts +95 -0
- package/src/stateful/provider-event-pipeline.ts +61 -0
- package/src/stateful/provider-events.ts +462 -0
- package/src/stateful/session-key.ts +111 -0
- package/src/stateful/stateful-provider-adapter-context.ts +59 -0
- package/src/stateful/stateful-provider-adapter-metrics.ts +48 -0
- package/src/stateful/stateful-provider-adapter.ts +562 -0
- package/src/stateful/stateful-provider-observability.ts +261 -0
- package/src/stateful/stateful-provider-owner-forwarder.ts +287 -0
- package/src/stateful/stateful-provider-runtime-context.ts +92 -0
- package/src/stateful/stateful-provider-runtime-executor.ts +96 -0
- package/src/stateful/stateful-provider-session-routing.ts +546 -0
- package/src/stateful/stateful-provider-session-runtime.ts +403 -0
- package/src/stateful-signing.ts +46 -0
- package/src/stealth/profiles.ts +202 -231
- package/src/stream-evidence.ts +988 -0
- package/src/stream.ts +8 -1
- package/src/testing/index.ts +10 -1
- package/src/testing/run.ts +658 -15
- package/src/trace-sanitization.ts +63 -0
- package/src/types.ts +788 -174
- package/dist/cli/templates/provider/CLAUDE.md.tpl +0 -1
- package/src/cli/templates/provider/CLAUDE.md.tpl +0 -1
- /package/dist/cli/templates/provider/{skills → .agents/skills}/fixtures-and-recording/SKILL.md.tpl +0 -0
- /package/dist/cli/templates/provider/{skills → .agents/skills}/health-checks-and-fail-closed/SKILL.md.tpl +0 -0
- /package/dist/cli/templates/provider/{skills → .agents/skills}/normalization-standards/SKILL.md.tpl +0 -0
- /package/dist/cli/templates/provider/{skills → .agents/skills}/pagination-and-counts/SKILL.md.tpl +0 -0
- /package/dist/cli/templates/provider/{skills → .agents/skills}/upstream-contract-verification/SKILL.md.tpl +0 -0
- /package/dist/cli/templates/provider/{skills → .agents/skills}/upstream-notes/README.md.tpl +0 -0
- /package/src/cli/templates/provider/{skills → .agents/skills}/fixtures-and-recording/SKILL.md.tpl +0 -0
- /package/src/cli/templates/provider/{skills → .agents/skills}/health-checks-and-fail-closed/SKILL.md.tpl +0 -0
- /package/src/cli/templates/provider/{skills → .agents/skills}/normalization-standards/SKILL.md.tpl +0 -0
- /package/src/cli/templates/provider/{skills → .agents/skills}/pagination-and-counts/SKILL.md.tpl +0 -0
- /package/src/cli/templates/provider/{skills → .agents/skills}/upstream-contract-verification/SKILL.md.tpl +0 -0
- /package/src/cli/templates/provider/{skills → .agents/skills}/upstream-notes/README.md.tpl +0 -0
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
// 3. A Node (not bun) ESM runtime import — node does not tolerate
|
|
19
19
|
// extensionless relative specifiers, bun does.
|
|
20
20
|
//
|
|
21
|
-
//
|
|
21
|
+
// Deliberate negative controls prove the fixture compiler actually fails on
|
|
22
22
|
// type errors, so this check cannot rot into a false-positive green.
|
|
23
23
|
|
|
24
24
|
import { execFileSync, spawnSync } from "node:child_process";
|
|
@@ -36,6 +36,264 @@ const PACK_RESULT_SCHEMA = z.array(
|
|
|
36
36
|
const KEEP_TEMP = process.env.APIFUSE__PACK_TYPES__KEEP_TEMP === "1";
|
|
37
37
|
const sdkRoot = process.cwd();
|
|
38
38
|
|
|
39
|
+
const NEGATIVE_CONTROLS = [
|
|
40
|
+
{
|
|
41
|
+
filename: "negative-control-provider-error-name.ts",
|
|
42
|
+
expectedCode: "TS2322",
|
|
43
|
+
description: "ProviderError.name remains a string",
|
|
44
|
+
source: [
|
|
45
|
+
'import { ProviderError } from "@apifuse/provider-sdk";',
|
|
46
|
+
"",
|
|
47
|
+
"// Intentionally wrong: name is a string. If this file compiles, the",
|
|
48
|
+
"// fixture consumer is not actually type-checking and the guard is void.",
|
|
49
|
+
'export const mustNotCompile: number = new ProviderError("boom").name;',
|
|
50
|
+
"",
|
|
51
|
+
].join("\n"),
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
filename: "negative-control-unknown-resolver-vendor.ts",
|
|
55
|
+
expectedCode: "TS2322",
|
|
56
|
+
description: "ProviderResolverConfig rejects an unknown vendor",
|
|
57
|
+
source: [
|
|
58
|
+
'import type { ProviderResolverConfig } from "@apifuse/provider-sdk";',
|
|
59
|
+
"",
|
|
60
|
+
"export const mustNotCompile: ProviderResolverConfig = {",
|
|
61
|
+
'\tvendors: ["unknown-vendor"],',
|
|
62
|
+
'\tkinds: ["turnstile"],',
|
|
63
|
+
"};",
|
|
64
|
+
"",
|
|
65
|
+
].join("\n"),
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
filename: "negative-control-define-provider-resolver-vendor.ts",
|
|
69
|
+
expectedCode: "TS2322",
|
|
70
|
+
description: "defineProvider rejects an unknown resolver vendor",
|
|
71
|
+
source: [
|
|
72
|
+
'import { defineProvider, z } from "@apifuse/provider-sdk";',
|
|
73
|
+
"",
|
|
74
|
+
"export const mustNotCompile = defineProvider({",
|
|
75
|
+
'\tid: "invalid-resolver-vendor",',
|
|
76
|
+
'\tversion: "1.0.0",',
|
|
77
|
+
'\truntime: "standard",',
|
|
78
|
+
'\tresolver: { vendors: ["unknown-vendor"], kinds: ["turnstile"] },',
|
|
79
|
+
'\tmeta: { displayName: "Invalid Resolver Vendor", descriptionKey: "meta.description", category: "test" },',
|
|
80
|
+
"})({",
|
|
81
|
+
"\toperations: {",
|
|
82
|
+
"\t\tprobe: {",
|
|
83
|
+
'\t\t\triskClass: "read",',
|
|
84
|
+
"\t\t\tinput: z.object({}),",
|
|
85
|
+
"\t\t\toutput: z.object({ ok: z.boolean() }),",
|
|
86
|
+
"\t\t\thandler: async () => ({ ok: true }),",
|
|
87
|
+
'\t\t\thealthCheckUnsupported: { reason: "type fixture" },',
|
|
88
|
+
"\t\t},",
|
|
89
|
+
"\t},",
|
|
90
|
+
"});",
|
|
91
|
+
"",
|
|
92
|
+
].join("\n"),
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
filename: "negative-control-unknown-challenge-kind.ts",
|
|
96
|
+
expectedCode: "TS2820",
|
|
97
|
+
description: "ProviderChallenge rejects an unknown challenge kind",
|
|
98
|
+
source: [
|
|
99
|
+
'import type { ProviderChallenge } from "@apifuse/provider-sdk";',
|
|
100
|
+
"",
|
|
101
|
+
"export const mustNotCompile: ProviderChallenge = {",
|
|
102
|
+
'\tkind: "funcaptcha",',
|
|
103
|
+
'\tsiteKey: "key",',
|
|
104
|
+
'\tpageUrl: "https://example.com",',
|
|
105
|
+
"};",
|
|
106
|
+
"",
|
|
107
|
+
].join("\n"),
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
filename: "negative-control-provider-challenge-kind.ts",
|
|
111
|
+
expectedCode: "TS2820",
|
|
112
|
+
description: "ProviderChallengeKind rejects an unknown challenge kind",
|
|
113
|
+
source: [
|
|
114
|
+
'import type { ProviderChallengeKind } from "@apifuse/provider-sdk";',
|
|
115
|
+
"",
|
|
116
|
+
'export const mustNotCompile: ProviderChallengeKind = "funcaptcha";',
|
|
117
|
+
"",
|
|
118
|
+
].join("\n"),
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
filename: "negative-control-cookie-solution-token-read.ts",
|
|
122
|
+
expectedCode: "TS2339",
|
|
123
|
+
description: "ChallengeSolution requires narrowing before reading token",
|
|
124
|
+
source: [
|
|
125
|
+
'import type { ChallengeSolution } from "@apifuse/provider-sdk";',
|
|
126
|
+
"",
|
|
127
|
+
"export function mustNotCompile(solution: ChallengeSolution): string {",
|
|
128
|
+
"\treturn solution.token;",
|
|
129
|
+
"}",
|
|
130
|
+
"",
|
|
131
|
+
].join("\n"),
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
filename: "negative-control-cookie-challenge-site-key.ts",
|
|
135
|
+
expectedCode: "TS2353",
|
|
136
|
+
description: "cookie-family challenges reject token-family fields",
|
|
137
|
+
source: [
|
|
138
|
+
'import type { ProviderChallenge } from "@apifuse/provider-sdk";',
|
|
139
|
+
"",
|
|
140
|
+
"export const mustNotCompile: ProviderChallenge = {",
|
|
141
|
+
'\tkind: "cloudflare_interstitial",',
|
|
142
|
+
'\tpageUrl: "https://example.com",',
|
|
143
|
+
'\tsiteKey: "not-allowed",',
|
|
144
|
+
"};",
|
|
145
|
+
"",
|
|
146
|
+
].join("\n"),
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
filename: "negative-control-aws-waf-site-key-type.ts",
|
|
150
|
+
expectedCode: "TS2322",
|
|
151
|
+
description: "aws_waf siteKey must be a string",
|
|
152
|
+
source: [
|
|
153
|
+
'import type { ProviderChallenge } from "@apifuse/provider-sdk";',
|
|
154
|
+
"",
|
|
155
|
+
"export const mustNotCompile: ProviderChallenge = {",
|
|
156
|
+
'\tkind: "aws_waf",',
|
|
157
|
+
'\tpageUrl: "https://example.com",',
|
|
158
|
+
"\tsiteKey: 123,",
|
|
159
|
+
"};",
|
|
160
|
+
"",
|
|
161
|
+
].join("\n"),
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
filename: "negative-control-aws-waf-context-type.ts",
|
|
165
|
+
expectedCode: "TS2322",
|
|
166
|
+
description: "aws_waf context must be a string",
|
|
167
|
+
source: [
|
|
168
|
+
'import type { ProviderChallenge } from "@apifuse/provider-sdk";',
|
|
169
|
+
"",
|
|
170
|
+
"export const mustNotCompile: ProviderChallenge = {",
|
|
171
|
+
'\tkind: "aws_waf",',
|
|
172
|
+
'\tpageUrl: "https://example.com",',
|
|
173
|
+
"\tcontext: 123,",
|
|
174
|
+
"};",
|
|
175
|
+
"",
|
|
176
|
+
].join("\n"),
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
filename: "negative-control-aws-waf-unknown-field.ts",
|
|
180
|
+
expectedCode: "TS2353",
|
|
181
|
+
description: "aws_waf rejects fields it does not declare",
|
|
182
|
+
source: [
|
|
183
|
+
'import type { ProviderChallenge } from "@apifuse/provider-sdk";',
|
|
184
|
+
"",
|
|
185
|
+
"export const mustNotCompile: ProviderChallenge = {",
|
|
186
|
+
'\tkind: "aws_waf",',
|
|
187
|
+
'\tpageUrl: "https://example.com",',
|
|
188
|
+
"\tunknownField: 1,",
|
|
189
|
+
"};",
|
|
190
|
+
"",
|
|
191
|
+
].join("\n"),
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
filename: "negative-control-recaptcha-v3-action.ts",
|
|
195
|
+
expectedCode: "TS2322",
|
|
196
|
+
description: "recaptcha_v3 challenges require action",
|
|
197
|
+
source: [
|
|
198
|
+
'import type { ProviderChallenge } from "@apifuse/provider-sdk";',
|
|
199
|
+
"",
|
|
200
|
+
"export const mustNotCompile: ProviderChallenge = {",
|
|
201
|
+
'\tkind: "recaptcha_v3",',
|
|
202
|
+
'\tsiteKey: "key",',
|
|
203
|
+
'\tpageUrl: "https://example.com",',
|
|
204
|
+
"};",
|
|
205
|
+
"",
|
|
206
|
+
].join("\n"),
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
filename: "negative-control-browser-cookie-expires.ts",
|
|
210
|
+
expectedCode: "TS2322",
|
|
211
|
+
description: "BrowserCookie.expires remains optional for session cookies",
|
|
212
|
+
source: [
|
|
213
|
+
'import type { BrowserCookie } from "@apifuse/provider-sdk";',
|
|
214
|
+
"",
|
|
215
|
+
"export function mustNotCompile(cookie: BrowserCookie): number {",
|
|
216
|
+
"\treturn cookie.expires;",
|
|
217
|
+
"}",
|
|
218
|
+
"",
|
|
219
|
+
].join("\n"),
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
filename: "negative-control-resolver-runtime-identity.ts",
|
|
223
|
+
expectedCode: "TS2353",
|
|
224
|
+
description: "ResolverRuntimeOptions does not accept caller-synthesized identity",
|
|
225
|
+
source: [
|
|
226
|
+
'import type { ResolverRuntimeOptions } from "@apifuse/provider-sdk";',
|
|
227
|
+
"",
|
|
228
|
+
"export const mustNotCompile: ResolverRuntimeOptions = {",
|
|
229
|
+
'\tidentity: "caller-controlled",',
|
|
230
|
+
"};",
|
|
231
|
+
"",
|
|
232
|
+
].join("\n"),
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
filename: "negative-control-resolver-runtime-adapter-factories.ts",
|
|
236
|
+
expectedCode: "TS2353",
|
|
237
|
+
description: "ResolverRuntimeOptions does not accept caller-supplied adapter factories",
|
|
238
|
+
source: [
|
|
239
|
+
'import type { ResolverRuntimeOptions } from "@apifuse/provider-sdk";',
|
|
240
|
+
"",
|
|
241
|
+
"export const mustNotCompile: ResolverRuntimeOptions = {",
|
|
242
|
+
"\tadapterFactories: {},",
|
|
243
|
+
"};",
|
|
244
|
+
"",
|
|
245
|
+
].join("\n"),
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
filename: "negative-control-resolver-default-user-agent-test-seam.ts",
|
|
249
|
+
expectedCode: "TS2305",
|
|
250
|
+
description: "the resolver subpath does not expose its default user-agent test seam",
|
|
251
|
+
source: [
|
|
252
|
+
'import { swapResolverDefaultUserAgentForTests } from "@apifuse/provider-sdk/runtime/resolver";',
|
|
253
|
+
"",
|
|
254
|
+
"export const mustNotCompile = swapResolverDefaultUserAgentForTests;",
|
|
255
|
+
"",
|
|
256
|
+
].join("\n"),
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
filename: "negative-control-cache-reset-test-seam.ts",
|
|
260
|
+
expectedCode: "TS2305",
|
|
261
|
+
description: "the package root does not expose its cache-reset test seam",
|
|
262
|
+
source: [
|
|
263
|
+
'import { resetProviderCacheForTests } from "@apifuse/provider-sdk";',
|
|
264
|
+
"",
|
|
265
|
+
"export const mustNotCompile = resetProviderCacheForTests;",
|
|
266
|
+
"",
|
|
267
|
+
].join("\n"),
|
|
268
|
+
},
|
|
269
|
+
{
|
|
270
|
+
filename: "negative-control-resolver-runtime-allowed-hosts.ts",
|
|
271
|
+
expectedCode: "TS2322",
|
|
272
|
+
description: "ResolverRuntimeOptions.allowedHosts accepts only host strings",
|
|
273
|
+
source: [
|
|
274
|
+
'import type { ResolverRuntimeOptions } from "@apifuse/provider-sdk";',
|
|
275
|
+
"",
|
|
276
|
+
"export const mustNotCompile: ResolverRuntimeOptions = {",
|
|
277
|
+
'\tallowedHosts: ["example.com", 42],',
|
|
278
|
+
"};",
|
|
279
|
+
"",
|
|
280
|
+
].join("\n"),
|
|
281
|
+
},
|
|
282
|
+
{
|
|
283
|
+
filename: "negative-control-resolver-signal.ts",
|
|
284
|
+
expectedCode: "TS2345",
|
|
285
|
+
description: "ResolverContext.solve accepts only AbortSignal as its optional signal",
|
|
286
|
+
source: [
|
|
287
|
+
'import type { ProviderChallenge, ResolverContext } from "@apifuse/provider-sdk";',
|
|
288
|
+
"",
|
|
289
|
+
"declare const resolver: ResolverContext;",
|
|
290
|
+
"declare const challenge: ProviderChallenge;",
|
|
291
|
+
"resolver.solve(challenge, { aborted: false });",
|
|
292
|
+
"",
|
|
293
|
+
].join("\n"),
|
|
294
|
+
},
|
|
295
|
+
] as const;
|
|
296
|
+
|
|
39
297
|
const tempRoot = mkdtempSync(join(tmpdir(), "apifuse-provider-sdk-pack-types-"));
|
|
40
298
|
const packDir = join(tempRoot, "pack");
|
|
41
299
|
const consumerDir = join(tempRoot, "consumer");
|
|
@@ -123,12 +381,16 @@ function setUpFixtureConsumer(consumerDir: string, tarballPath: string): void {
|
|
|
123
381
|
writeFileSync(
|
|
124
382
|
join(consumerDir, "consumer.ts"),
|
|
125
383
|
[
|
|
126
|
-
'import { ProviderError, SessionExpiredError, z } from "@apifuse/provider-sdk";',
|
|
384
|
+
'import { defineProvider, ProviderError, resolveProxy, SessionExpiredError, z } from "@apifuse/provider-sdk";',
|
|
385
|
+
'import { invalidateResolverSolution } from "@apifuse/provider-sdk/runtime/resolver";',
|
|
386
|
+
'import type { BrowserCookie, ChallengeSolution, NativeContext, NativeNetworkClient, NativeNetworkConnection, NativeProviderConfig, NativeTcpEgressGrant, ProviderChallenge, ProviderContext, ProviderFileRef, ProviderFilesContext, ProviderResolvedFile, ProviderResolverConfig, ResolverContext, ResolverRuntimeOptions } from "@apifuse/provider-sdk";',
|
|
387
|
+
'import type { ProxyProtocol, ProxyResolutionOptions, ProxyResolutionSource, ProxyVendorName, RequestOptions, ResolvedProxyConfig } from "@apifuse/provider-sdk";',
|
|
127
388
|
'import { defineCredentialsAuth } from "@apifuse/provider-sdk/provider";',
|
|
389
|
+
'import type { NativeNetworkClient as ProviderEntryNativeNetworkClient, ProviderFilesContext as ProviderEntryFilesContext } from "@apifuse/provider-sdk/provider";',
|
|
128
390
|
'import { extractProviderContract } from "@apifuse/provider-sdk/contract";',
|
|
129
391
|
'import { AUTH_TURN_SCHEMA } from "@apifuse/provider-sdk/auth-turn";',
|
|
130
392
|
'import { serve } from "@apifuse/provider-sdk/server";',
|
|
131
|
-
'import { runStandardTests } from "@apifuse/provider-sdk/testing";',
|
|
393
|
+
'import { resetProviderCacheForTests, runStandardTests } from "@apifuse/provider-sdk/testing";',
|
|
132
394
|
"",
|
|
133
395
|
"// ProviderError must keep its inherited Error members under nodenext.",
|
|
134
396
|
"// When dist d.ts imports fail to resolve, the class type degrades and",
|
|
@@ -143,6 +405,44 @@ function setUpFixtureConsumer(consumerDir: string, tarballPath: string): void {
|
|
|
143
405
|
"// Re-exported zod must keep .refine() callback parameter inference.",
|
|
144
406
|
"const refined = z.object({ shopId: z.string() }).refine((value) => value.shopId.length > 0);",
|
|
145
407
|
'const refinedString = z.string().refine((value) => value.startsWith("tabelog:"));',
|
|
408
|
+
'const proxyOptions: ProxyResolutionOptions = { proxyPolicy: { mode: "disabled" } };',
|
|
409
|
+
'const proxyProtocol: ProxyProtocol = "http";',
|
|
410
|
+
"const proxyResult: Promise<ResolvedProxyConfig> = resolveProxy(proxyOptions);",
|
|
411
|
+
'const proxySource: ProxyResolutionSource = "smartproxy-allocator";',
|
|
412
|
+
'const proxyVendor: ProxyVendorName = "smartproxy";',
|
|
413
|
+
'const requestFile: ProviderFileRef = { type: "request_file", id: "photo", filename: "photo.jpg", mime_type: "image/jpeg", size: 4 };',
|
|
414
|
+
'const resolvedFile: ProviderResolvedFile = { type: "request_file", id: requestFile.id, filename: requestFile.filename, size: requestFile.size, sha256: requestFile.sha256, mimeType: requestFile.mime_type, arrayBuffer: async () => new ArrayBuffer(0), bytes: async () => new Uint8Array(), stream: () => new ReadableStream<Uint8Array>() };',
|
|
415
|
+
"const files: ProviderFilesContext = { has: () => true, resolve: async () => resolvedFile };",
|
|
416
|
+
"const providerEntryFiles: ProviderEntryFilesContext = files;",
|
|
417
|
+
"const connection: NativeNetworkConnection = { read: async () => null, write: async () => {}, close: async () => {} };",
|
|
418
|
+
"const network: NativeNetworkClient = { connectTcp: async () => connection, connectTls: async () => connection, grantTcpEgress: () => ({ revoke() {} }) };",
|
|
419
|
+
"const providerEntryNetwork: ProviderEntryNativeNetworkClient = network;",
|
|
420
|
+
"const nativeContext: NativeContext = { network };",
|
|
421
|
+
'const grant: NativeTcpEgressGrant = network.grantTcpEgress({ sourceHost: "booking-loco.kakao.com", sourcePort: 443, host: "loco.kakao.com", port: 5228, tls: "disabled" });',
|
|
422
|
+
'const nativeConfig: NativeProviderConfig = { network: { tcp: [{ host: "booking-loco.kakao.com", ports: [443], tls: "required" }] } };',
|
|
423
|
+
"const providerContext = undefined as unknown as ProviderContext;",
|
|
424
|
+
"const optionalFiles: ProviderFilesContext | undefined = providerContext.files;",
|
|
425
|
+
"const native: NativeContext = providerContext.native;",
|
|
426
|
+
"export const providerResolver: ResolverContext = providerContext.resolver;",
|
|
427
|
+
'export const resolverRuntimeOptions: ResolverRuntimeOptions = { allowedHosts: ["example.com"], cache: providerContext.cache };',
|
|
428
|
+
"",
|
|
429
|
+
'export const turnstileChallenge: ProviderChallenge = { kind: "turnstile", siteKey: "key", pageUrl: "https://example.com" };',
|
|
430
|
+
"export const abortableResolverSolve = providerResolver.solve(turnstileChallenge, new AbortController().signal);",
|
|
431
|
+
'export const recaptchaV2Challenge: ProviderChallenge = { kind: "recaptcha_v2", siteKey: "key", pageUrl: "https://example.com" };',
|
|
432
|
+
'export const recaptchaV3Challenge: ProviderChallenge = { kind: "recaptcha_v3", siteKey: "key", pageUrl: "https://example.com", action: "login" };',
|
|
433
|
+
'export const hcaptchaChallenge: ProviderChallenge = { kind: "hcaptcha", siteKey: "key", pageUrl: "https://example.com" };',
|
|
434
|
+
'export const cloudflareInterstitialChallenge: ProviderChallenge = { kind: "cloudflare_interstitial", pageUrl: "https://example.com", blockedHtml: "<html></html>" };',
|
|
435
|
+
'export const awsWafChallenge: ProviderChallenge = { kind: "aws_waf", pageUrl: "https://example.com", captchaScript: "script" };',
|
|
436
|
+
'export const tokenSolution: ChallengeSolution = { form: "token", token: "solved-token" };',
|
|
437
|
+
'export const cookieSolution: ChallengeSolution = { form: "cookies", cookies: { cf_clearance: "clearance" }, userAgent: "fixture-agent" };',
|
|
438
|
+
"export const invalidation = invalidateResolverSolution(providerContext.resolver, awsWafChallenge, cookieSolution);",
|
|
439
|
+
'export const resolverConfig: ProviderResolverConfig = { vendors: ["browser", "capsolver"], kinds: ["cloudflare_interstitial", "turnstile"] };',
|
|
440
|
+
'export const resolverProvider = defineProvider({ id: "pack-types-resolver", version: "1.0.0", runtime: "standard", resolver: resolverConfig, meta: { displayName: "Pack Types Resolver", descriptionKey: "meta.description", category: "test" } })({ operations: { probe: { riskClass: "read", input: z.object({}), output: z.object({ ok: z.boolean() }), handler: async () => ({ ok: true }), healthCheckUnsupported: { reason: "type fixture" } } } });',
|
|
441
|
+
"export const resolverContext: ResolverContext = { solve: async () => tokenSolution };",
|
|
442
|
+
'export const browserCookie: BrowserCookie = { name: "persistent-id", value: "persistent-token", domain: "example.com", path: "/", expires: 1786698176, httpOnly: true, secure: true };',
|
|
443
|
+
'const browserPage = undefined as unknown as Awaited<ReturnType<ProviderContext["browser"]["newPage"]>>;',
|
|
444
|
+
"export const browserCookies: Promise<readonly BrowserCookie[]> = browserPage.cookies();",
|
|
445
|
+
'const queryCredentialOptions: RequestOptions = { sensitiveParams: { serviceKey: "type-test-key" } };',
|
|
146
446
|
"",
|
|
147
447
|
"export const witnesses = {",
|
|
148
448
|
" inheritedName,",
|
|
@@ -152,27 +452,39 @@ function setUpFixtureConsumer(consumerDir: string, tarballPath: string): void {
|
|
|
152
452
|
" sessionExpired,",
|
|
153
453
|
" refined,",
|
|
154
454
|
" refinedString,",
|
|
455
|
+
" proxyResult,",
|
|
456
|
+
" proxyProtocol,",
|
|
457
|
+
" proxySource,",
|
|
458
|
+
" proxyVendor,",
|
|
459
|
+
" requestFile,",
|
|
460
|
+
" resolvedFile,",
|
|
461
|
+
" files,",
|
|
462
|
+
" providerEntryFiles,",
|
|
463
|
+
" connection,",
|
|
464
|
+
" network,",
|
|
465
|
+
" providerEntryNetwork,",
|
|
466
|
+
" nativeContext,",
|
|
467
|
+
" grant,",
|
|
468
|
+
" nativeConfig,",
|
|
469
|
+
" optionalFiles,",
|
|
470
|
+
" native,",
|
|
471
|
+
" browserCookie,",
|
|
472
|
+
" browserCookies,",
|
|
473
|
+
" queryCredentialOptions,",
|
|
155
474
|
" defineCredentialsAuth,",
|
|
156
475
|
" extractProviderContract,",
|
|
157
476
|
" AUTH_TURN_SCHEMA,",
|
|
158
477
|
" serve,",
|
|
478
|
+
" resetProviderCacheForTests,",
|
|
159
479
|
" runStandardTests,",
|
|
160
480
|
"};",
|
|
161
481
|
"",
|
|
162
482
|
].join("\n"),
|
|
163
483
|
);
|
|
164
484
|
|
|
165
|
-
|
|
166
|
-
join(consumerDir,
|
|
167
|
-
|
|
168
|
-
'import { ProviderError } from "@apifuse/provider-sdk";',
|
|
169
|
-
"",
|
|
170
|
-
"// Intentionally wrong: name is a string. If this file compiles, the",
|
|
171
|
-
"// fixture consumer is not actually type-checking and the guard is void.",
|
|
172
|
-
'export const mustNotCompile: number = new ProviderError("boom").name;',
|
|
173
|
-
"",
|
|
174
|
-
].join("\n"),
|
|
175
|
-
);
|
|
485
|
+
for (const negativeControl of NEGATIVE_CONTROLS) {
|
|
486
|
+
writeFileSync(join(consumerDir, negativeControl.filename), negativeControl.source);
|
|
487
|
+
}
|
|
176
488
|
}
|
|
177
489
|
|
|
178
490
|
function compileFixtureConsumer(consumerDir: string): void {
|
|
@@ -184,31 +496,38 @@ function compileFixtureConsumer(consumerDir: string): void {
|
|
|
184
496
|
}
|
|
185
497
|
|
|
186
498
|
function assertNegativeControlFails(consumerDir: string): void {
|
|
187
|
-
const
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
if (result.status === 0) {
|
|
204
|
-
throw new Error(
|
|
205
|
-
"Negative control compiled cleanly: the fixture consumer is not detecting type errors, so the nodenext guard proves nothing.",
|
|
206
|
-
);
|
|
207
|
-
}
|
|
208
|
-
if (!`${result.stdout}\n${result.stderr}`.includes("TS2322")) {
|
|
209
|
-
throw new Error(
|
|
210
|
-
`Negative control failed for an unexpected reason (wanted TS2322):\n${result.stdout}\n${result.stderr}`,
|
|
499
|
+
for (const negativeControl of NEGATIVE_CONTROLS) {
|
|
500
|
+
const result = spawnSync(
|
|
501
|
+
"bun",
|
|
502
|
+
[
|
|
503
|
+
join(consumerDir, "node_modules", ".bin", "tsc"),
|
|
504
|
+
"--target",
|
|
505
|
+
"ES2022",
|
|
506
|
+
"--module",
|
|
507
|
+
"nodenext",
|
|
508
|
+
"--moduleResolution",
|
|
509
|
+
"nodenext",
|
|
510
|
+
"--strict",
|
|
511
|
+
"--noEmit",
|
|
512
|
+
negativeControl.filename,
|
|
513
|
+
],
|
|
514
|
+
{ cwd: consumerDir, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] },
|
|
211
515
|
);
|
|
516
|
+
if (result.status === 0) {
|
|
517
|
+
throw new Error(
|
|
518
|
+
'Negative control "' +
|
|
519
|
+
negativeControl.description +
|
|
520
|
+
'" (' +
|
|
521
|
+
negativeControl.filename +
|
|
522
|
+
") compiled cleanly: the fixture consumer is not detecting its error, so the guard proves nothing.",
|
|
523
|
+
);
|
|
524
|
+
}
|
|
525
|
+
const output = `${result.stdout}\n${result.stderr}`;
|
|
526
|
+
if (!output.includes(negativeControl.expectedCode)) {
|
|
527
|
+
throw new Error(
|
|
528
|
+
`Negative control "${negativeControl.description}" (${negativeControl.filename}) failed for an unexpected reason (wanted ${negativeControl.expectedCode}):\n${output}`,
|
|
529
|
+
);
|
|
530
|
+
}
|
|
212
531
|
}
|
|
213
532
|
}
|
|
214
533
|
|
package/bin/apifuse-perf.ts
CHANGED
|
@@ -11,7 +11,6 @@ import {
|
|
|
11
11
|
createBypassProviderCache,
|
|
12
12
|
createHttpClient,
|
|
13
13
|
createProviderChoiceContext,
|
|
14
|
-
createStealthClient,
|
|
15
14
|
createSttClientFromEnv,
|
|
16
15
|
executeOperation,
|
|
17
16
|
getProviderBaseUrl,
|
|
@@ -20,6 +19,7 @@ import {
|
|
|
20
19
|
type ProviderContext,
|
|
21
20
|
type ProviderDefinition,
|
|
22
21
|
ProviderError,
|
|
22
|
+
resolveProxy,
|
|
23
23
|
type Span,
|
|
24
24
|
type StealthClient,
|
|
25
25
|
type StealthResponse,
|
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
} from "../src/index.js";
|
|
28
28
|
import { computeStats, groupSpansByName, type PerfStats } from "../src/runtime/perf.js";
|
|
29
29
|
import { createMemoryProviderRuntimeState } from "../src/runtime/state.js";
|
|
30
|
+
import { createStealthClient } from "../src/runtime/stealth.js";
|
|
30
31
|
import { createTraceContext, resolveTraceContextOptions } from "../src/runtime/trace.js";
|
|
31
32
|
import { renderWaterfall } from "../src/runtime/waterfall.js";
|
|
32
33
|
import type { BrowserClient } from "../src/types.js";
|
|
@@ -122,7 +123,7 @@ export async function main() {
|
|
|
122
123
|
|
|
123
124
|
let proxySuite: ProfileSuite | undefined;
|
|
124
125
|
if (args.compareProxy) {
|
|
125
|
-
assertProxyConfigured(
|
|
126
|
+
await assertProxyConfigured(provider);
|
|
126
127
|
proxySuite = await runProfileSuite({
|
|
127
128
|
args,
|
|
128
129
|
config,
|
|
@@ -454,14 +455,18 @@ async function loadFixtureReplay(providerDirectory: string): Promise<FixtureRepl
|
|
|
454
455
|
};
|
|
455
456
|
}
|
|
456
457
|
|
|
457
|
-
function assertProxyConfigured(
|
|
458
|
-
|
|
459
|
-
|
|
458
|
+
async function assertProxyConfigured(provider: ProviderDefinition): Promise<void> {
|
|
459
|
+
const policy = provider.proxy;
|
|
460
|
+
if (!policy || typeof policy !== "object" || policy.mode === "disabled") {
|
|
461
|
+
throw new Error("--compare-proxy requires an enabled ProviderProxyPolicy on the provider.");
|
|
460
462
|
}
|
|
461
463
|
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
464
|
+
const resolved = await resolveProxy({ proxyPolicy: policy });
|
|
465
|
+
if (!resolved.url) {
|
|
466
|
+
throw new Error(
|
|
467
|
+
"--compare-proxy could not resolve the provider proxy policy; configure its allocator credentials (for smartproxy, APIFUSE__PROXY__SMARTPROXY_APP_KEY).",
|
|
468
|
+
);
|
|
469
|
+
}
|
|
465
470
|
}
|
|
466
471
|
|
|
467
472
|
async function runProfileSuite(options: {
|
|
@@ -629,22 +634,18 @@ function createBaseContext(options: {
|
|
|
629
634
|
traceContext: ReturnType<typeof createTraceContext>;
|
|
630
635
|
}): ProviderContext {
|
|
631
636
|
const upstream = {
|
|
632
|
-
|
|
633
|
-
proxy: options.proxyEnabled,
|
|
637
|
+
proxy: options.proxyEnabled ? options.provider.proxy : false,
|
|
634
638
|
};
|
|
635
|
-
const apifuseConfig = options.proxyEnabled ? options.config : {};
|
|
636
639
|
const http =
|
|
637
640
|
options.forceFixtureReplay && options.fixtureReplay
|
|
638
641
|
? createFixtureHttpClient(options.fixtureReplay.raw)
|
|
639
642
|
: createHttpClient(getProviderBaseUrl(options.provider), {
|
|
640
|
-
apifuseConfig,
|
|
641
643
|
upstream,
|
|
642
644
|
});
|
|
643
645
|
const stealth =
|
|
644
646
|
options.forceFixtureReplay && options.fixtureReplay
|
|
645
647
|
? createFixtureStealthClient(options.fixtureReplay.rawText)
|
|
646
648
|
: createStealthClient(getProviderBaseUrl(options.provider), {
|
|
647
|
-
apifuseConfig,
|
|
648
649
|
upstream,
|
|
649
650
|
});
|
|
650
651
|
|