@apifuse/provider-sdk 2.2.0-beta.3 → 2.2.0-beta.30
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 +493 -5
- package/CHANGELOG.md +127 -1
- package/README.md +52 -6
- package/SUBMISSION.md +1 -1
- package/bin/apifuse-check.ts +106 -62
- package/bin/apifuse-create.ts +1 -1
- package/bin/apifuse-dev.ts +63 -55
- package/bin/apifuse-pack-check.ts +22 -2
- package/bin/apifuse-pack-smoke.ts +78 -82
- package/bin/apifuse-pack-types.ts +583 -0
- package/bin/apifuse-perf.ts +59 -140
- package/bin/apifuse-record.ts +698 -113
- package/bin/apifuse-submit-check.ts +517 -44
- package/bin/apifuse-sync-assets.ts +117 -0
- package/bin/apifuse.ts +1 -1
- package/bin/submit-check-delimited-text.ts +50 -0
- package/bin/submit-check-xml.ts +1 -1
- package/dist/auth-turn/index.d.ts +4 -4
- package/dist/auth-turn/index.js +1 -1
- package/dist/auth.d.ts +16 -2
- package/dist/auth.js +76 -18
- package/dist/ceremonies/index.d.ts +9 -1
- package/dist/ceremonies/index.js +117 -29
- package/dist/cli/commands.d.ts +1 -1
- package/dist/cli/commands.js +8 -0
- package/dist/cli/create.d.ts +3 -0
- package/dist/cli/create.js +34 -35
- 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/README.md.tpl +4 -4
- package/dist/config/loader.d.ts +176 -17
- package/dist/config/loader.js +434 -161
- package/dist/contract-serialization.d.ts +2 -2
- package/dist/contract-serialization.js +7 -14
- package/dist/contract-types.d.ts +3 -2
- package/dist/contract.d.ts +3 -3
- package/dist/contract.js +6 -6
- package/dist/declaration-validation.d.ts +23 -0
- package/dist/declaration-validation.js +159 -0
- package/dist/define.d.ts +13 -1
- package/dist/define.js +391 -122
- package/dist/dev.d.ts +1 -1
- package/dist/dev.js +1 -1
- package/dist/error-resolution.d.ts +4 -0
- package/dist/error-resolution.js +122 -0
- package/dist/errors.d.ts +19 -1
- package/dist/errors.js +41 -3
- package/dist/fixture-sanitization.d.ts +26 -0
- package/dist/fixture-sanitization.js +216 -0
- package/dist/i18n/catalog.d.ts +2 -2
- package/dist/i18n/catalog.js +4 -10
- package/dist/i18n/index.d.ts +2 -2
- package/dist/i18n/index.js +2 -2
- package/dist/i18n/keys.d.ts +2 -2
- package/dist/index.d.ts +50 -42
- package/dist/index.js +41 -37
- package/dist/lint.d.ts +6 -1
- package/dist/lint.js +370 -18
- 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 +13 -11
- package/dist/provider.js +10 -9
- package/dist/public-schema-field-lint.d.ts +1 -1
- package/dist/recipes/gov-api.js +1 -1
- package/dist/runtime/auth-flow.d.ts +3 -1
- package/dist/runtime/auth-flow.js +8 -3
- package/dist/runtime/browser.d.ts +1 -1
- package/dist/runtime/browser.js +138 -40
- package/dist/runtime/cache.d.ts +2 -1
- package/dist/runtime/cache.js +173 -23
- 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 +514 -124
- package/dist/runtime/credential.d.ts +1 -1
- package/dist/runtime/credential.js +1 -1
- package/dist/runtime/env.d.ts +1 -1
- package/dist/runtime/executor.d.ts +1 -1
- package/dist/runtime/executor.js +25 -3
- package/dist/runtime/http.d.ts +3 -2
- package/dist/runtime/http.js +517 -55
- package/dist/runtime/insights.d.ts +1 -1
- package/dist/runtime/insights.js +6 -13
- package/dist/runtime/instrumentation.d.ts +2 -2
- package/dist/runtime/instrumentation.js +371 -23
- package/dist/runtime/keyring.js +1 -1
- package/dist/runtime/namespace.js +1 -1
- 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 +1 -1
- package/dist/runtime/perf.d.ts +1 -1
- package/dist/runtime/provider.d.ts +1 -1
- package/dist/runtime/provider.js +1 -2
- package/dist/runtime/proxy-errors.d.ts +1 -1
- package/dist/runtime/proxy-errors.js +9 -7
- package/dist/runtime/proxy-nodemaven.d.ts +56 -0
- package/dist/runtime/proxy-nodemaven.js +146 -0
- package/dist/runtime/proxy-retry-policy.d.ts +2 -2
- package/dist/runtime/proxy-retry-policy.js +2 -2
- package/dist/runtime/proxy-telemetry.d.ts +2 -1
- package/dist/runtime/proxy-telemetry.js +58 -52
- 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 +5 -5
- 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 +3 -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 +20 -0
- package/dist/runtime/resolver-vendors/browser.js +282 -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 +368 -0
- package/dist/runtime/resolver-vendors/types.d.ts +83 -0
- package/dist/runtime/resolver-vendors/types.js +69 -0
- package/dist/runtime/resolver.d.ts +59 -0
- package/dist/runtime/resolver.js +705 -0
- package/dist/runtime/secrets.d.ts +27 -0
- package/dist/runtime/secrets.js +51 -0
- package/dist/runtime/state.d.ts +5 -2
- package/dist/runtime/state.js +280 -74
- package/dist/runtime/stealth-cookies.d.ts +20 -0
- package/dist/runtime/stealth-cookies.js +111 -0
- package/dist/runtime/stealth.d.ts +30 -5
- package/dist/runtime/stealth.js +523 -259
- package/dist/runtime/stt.d.ts +1 -1
- package/dist/runtime/stt.js +12 -27
- package/dist/runtime/timeout.d.ts +5 -0
- package/dist/runtime/timeout.js +12 -0
- package/dist/runtime/trace.d.ts +2 -2
- package/dist/runtime/trace.js +2 -4
- package/dist/runtime/waterfall.d.ts +1 -1
- package/dist/schema.d.ts +1 -1
- package/dist/schema.js +7 -15
- package/dist/serve.d.ts +1 -1
- package/dist/serve.js +1 -1
- package/dist/server/index.d.ts +7 -7
- package/dist/server/index.js +6 -6
- 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-redaction.d.ts +1 -1
- package/dist/server/self-test-redaction.js +1 -1
- package/dist/server/self-test.d.ts +117 -3
- package/dist/server/self-test.js +787 -151
- package/dist/server/serve-implementation.d.ts +210 -0
- package/dist/server/serve-implementation.js +2077 -0
- package/dist/server/serve.d.ts +1 -70
- package/dist/server/serve.js +1 -1143
- package/dist/server/types.d.ts +34 -9
- package/dist/server/types.js +8 -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 +1 -1
- package/dist/stealth/profiles.js +21 -21
- package/dist/stream-evidence.d.ts +74 -0
- package/dist/stream-evidence.js +785 -0
- package/dist/stream.d.ts +1 -1
- package/dist/stream.js +7 -1
- package/dist/testing/index.d.ts +3 -2
- package/dist/testing/index.js +3 -2
- package/dist/testing/run.d.ts +32 -2
- package/dist/testing/run.js +488 -28
- package/dist/types.d.ts +566 -19
- package/dist/types.js +1 -0
- package/dist/user-input.d.ts +30 -0
- package/dist/user-input.js +66 -0
- package/package.json +42 -7
- package/src/auth-turn/index.ts +2 -2
- package/src/auth.ts +146 -86
- package/src/ceremonies/index.ts +167 -92
- package/src/cli/commands.ts +10 -0
- package/src/cli/create.ts +42 -35
- package/src/cli/prompt-assets.ts +865 -0
- package/src/cli/templates/provider/AGENTS.md.tpl +17 -8
- package/src/cli/templates/provider/README.md.tpl +4 -4
- package/src/config/loader.ts +667 -289
- package/src/contract-serialization.ts +10 -18
- package/src/contract-types.ts +3 -2
- package/src/contract.ts +14 -28
- package/src/declaration-validation.ts +202 -0
- package/src/define.ts +631 -495
- package/src/dev.ts +4 -9
- package/src/error-resolution.ts +127 -0
- package/src/errors.ts +56 -11
- package/src/fixture-sanitization.ts +247 -0
- package/src/i18n/catalog.ts +10 -32
- package/src/i18n/index.ts +2 -2
- package/src/i18n/keys.ts +5 -11
- package/src/index.ts +157 -44
- package/src/lint.ts +488 -154
- 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 +65 -11
- package/src/public-schema-field-lint.ts +7 -33
- package/src/recipes/gov-api.ts +2 -5
- package/src/runtime/auth-flow.ts +13 -7
- package/src/runtime/browser.ts +252 -207
- package/src/runtime/cache.ts +209 -81
- package/src/runtime/choice-wordlist.ts +145 -0
- package/src/runtime/choice.ts +685 -216
- package/src/runtime/credential.ts +2 -2
- package/src/runtime/env.ts +1 -1
- package/src/runtime/executor.ts +37 -19
- package/src/runtime/http.ts +645 -65
- package/src/runtime/insights.ts +15 -53
- package/src/runtime/instrumentation.ts +530 -67
- package/src/runtime/keyring.ts +7 -19
- package/src/runtime/namespace.ts +2 -7
- 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 +12 -23
- package/src/runtime/perf.ts +1 -1
- package/src/runtime/provider.ts +4 -9
- package/src/runtime/proxy-errors.ts +29 -42
- package/src/runtime/proxy-nodemaven.ts +221 -0
- package/src/runtime/proxy-retry-policy.ts +3 -3
- package/src/runtime/proxy-telemetry.ts +84 -77
- package/src/runtime/redirects.ts +66 -0
- package/src/runtime/redis.ts +10 -13
- package/src/runtime/request-options.ts +679 -9
- package/src/runtime/resolver-config.ts +6 -0
- package/src/runtime/resolver-public.ts +18 -0
- package/src/runtime/resolver-shared.ts +17 -0
- package/src/runtime/resolver-vendors/bindings.ts +56 -0
- package/src/runtime/resolver-vendors/browser.ts +408 -0
- package/src/runtime/resolver-vendors/hosts.ts +38 -0
- package/src/runtime/resolver-vendors/twocaptcha.ts +500 -0
- package/src/runtime/resolver-vendors/types.ts +173 -0
- package/src/runtime/resolver.ts +1060 -0
- package/src/runtime/secrets.ts +64 -0
- package/src/runtime/state.ts +399 -161
- package/src/runtime/stealth-cookies.ts +132 -0
- package/src/runtime/stealth.ts +681 -295
- package/src/runtime/stt.ts +39 -113
- package/src/runtime/timeout.ts +18 -0
- package/src/runtime/trace.ts +14 -44
- package/src/runtime/waterfall.ts +5 -18
- package/src/schema.ts +23 -84
- package/src/serve.ts +6 -1
- package/src/server/index.ts +30 -7
- package/src/server/self-test-input-tokens.ts +29 -14
- package/src/server/self-test-redaction.ts +2 -2
- package/src/server/self-test.ts +1030 -180
- package/src/server/serve-implementation.ts +3060 -0
- package/src/server/serve.ts +1 -1781
- package/src/server/types.ts +12 -13
- 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 +27 -33
- package/src/stream-evidence.ts +988 -0
- package/src/stream.ts +16 -20
- package/src/testing/index.ts +11 -2
- package/src/testing/run.ts +668 -74
- package/src/types.ts +665 -35
- package/src/user-input.ts +118 -0
- 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
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,23 +19,18 @@ 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,
|
|
26
26
|
wrapWithInstrumentation,
|
|
27
|
-
} from "../src";
|
|
28
|
-
import {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
} from "../src/runtime/
|
|
33
|
-
import {
|
|
34
|
-
import {
|
|
35
|
-
createTraceContext,
|
|
36
|
-
resolveTraceContextOptions,
|
|
37
|
-
} from "../src/runtime/trace";
|
|
38
|
-
import { renderWaterfall } from "../src/runtime/waterfall";
|
|
39
|
-
import type { BrowserClient } from "../src/types";
|
|
27
|
+
} from "../src/index.js";
|
|
28
|
+
import { computeStats, groupSpansByName, type PerfStats } from "../src/runtime/perf.js";
|
|
29
|
+
import { createMemoryProviderRuntimeState } from "../src/runtime/state.js";
|
|
30
|
+
import { createStealthClient } from "../src/runtime/stealth.js";
|
|
31
|
+
import { createTraceContext, resolveTraceContextOptions } from "../src/runtime/trace.js";
|
|
32
|
+
import { renderWaterfall } from "../src/runtime/waterfall.js";
|
|
33
|
+
import type { BrowserClient } from "../src/types.js";
|
|
40
34
|
|
|
41
35
|
type CliArgs = {
|
|
42
36
|
compareProxy: boolean;
|
|
@@ -112,11 +106,7 @@ export async function main() {
|
|
|
112
106
|
const inputSchema = getOperationSchema(provider, operation, "input");
|
|
113
107
|
const outputSchema = getOperationSchema(provider, operation, "output");
|
|
114
108
|
const fixtureReplay = await loadFixtureReplay(providerDirectory);
|
|
115
|
-
const inputTemplate = resolveInputTemplate(
|
|
116
|
-
provider,
|
|
117
|
-
inputSchema,
|
|
118
|
-
args.params,
|
|
119
|
-
);
|
|
109
|
+
const inputTemplate = resolveInputTemplate(provider, inputSchema, args.params);
|
|
120
110
|
|
|
121
111
|
const directSuite = await runProfileSuite({
|
|
122
112
|
args,
|
|
@@ -133,7 +123,7 @@ export async function main() {
|
|
|
133
123
|
|
|
134
124
|
let proxySuite: ProfileSuite | undefined;
|
|
135
125
|
if (args.compareProxy) {
|
|
136
|
-
assertProxyConfigured(
|
|
126
|
+
await assertProxyConfigured(provider);
|
|
137
127
|
proxySuite = await runProfileSuite({
|
|
138
128
|
args,
|
|
139
129
|
config,
|
|
@@ -168,9 +158,7 @@ export async function main() {
|
|
|
168
158
|
label: `${providerId}/${args.operation}`,
|
|
169
159
|
proxyEnabled: false,
|
|
170
160
|
stats: directSuite.stats,
|
|
171
|
-
mode: directSuite.runs.some((run) => run.mode === "fixture")
|
|
172
|
-
? "fixture"
|
|
173
|
-
: "live",
|
|
161
|
+
mode: directSuite.runs.some((run) => run.mode === "fixture") ? "fixture" : "live",
|
|
174
162
|
});
|
|
175
163
|
console.log(`Flamegraph: ${flamePath}`);
|
|
176
164
|
}
|
|
@@ -294,27 +282,18 @@ function parseArgs(argv: string[]): CliArgs {
|
|
|
294
282
|
}
|
|
295
283
|
|
|
296
284
|
if (arg.startsWith("--warmup=")) {
|
|
297
|
-
warmup = parseNonNegativeInteger(
|
|
298
|
-
arg.slice("--warmup=".length),
|
|
299
|
-
"--warmup",
|
|
300
|
-
);
|
|
285
|
+
warmup = parseNonNegativeInteger(arg.slice("--warmup=".length), "--warmup");
|
|
301
286
|
continue;
|
|
302
287
|
}
|
|
303
288
|
|
|
304
289
|
if (arg === "--concurrency" || arg === "-c") {
|
|
305
|
-
concurrency = parsePositiveInteger(
|
|
306
|
-
requireArgValue(argv, index, arg),
|
|
307
|
-
arg,
|
|
308
|
-
);
|
|
290
|
+
concurrency = parsePositiveInteger(requireArgValue(argv, index, arg), arg);
|
|
309
291
|
index += 1;
|
|
310
292
|
continue;
|
|
311
293
|
}
|
|
312
294
|
|
|
313
295
|
if (arg.startsWith("--concurrency=")) {
|
|
314
|
-
concurrency = parsePositiveInteger(
|
|
315
|
-
arg.slice("--concurrency=".length),
|
|
316
|
-
"--concurrency",
|
|
317
|
-
);
|
|
296
|
+
concurrency = parsePositiveInteger(arg.slice("--concurrency=".length), "--concurrency");
|
|
318
297
|
continue;
|
|
319
298
|
}
|
|
320
299
|
|
|
@@ -354,11 +333,7 @@ function parseArgs(argv: string[]): CliArgs {
|
|
|
354
333
|
};
|
|
355
334
|
}
|
|
356
335
|
|
|
357
|
-
function requireArgValue(
|
|
358
|
-
argv: string[],
|
|
359
|
-
index: number,
|
|
360
|
-
option: string,
|
|
361
|
-
): string {
|
|
336
|
+
function requireArgValue(argv: string[], index: number, option: string): string {
|
|
362
337
|
const value = argv[index + 1];
|
|
363
338
|
if (!value) {
|
|
364
339
|
throw new Error(`Missing value for ${option}`);
|
|
@@ -396,9 +371,7 @@ function resolveProviderEntry(providerDirectory: string): string {
|
|
|
396
371
|
throw new Error(`Provider entry not found in ${providerDirectory}`);
|
|
397
372
|
}
|
|
398
373
|
|
|
399
|
-
async function loadProvider(
|
|
400
|
-
providerEntry: string,
|
|
401
|
-
): Promise<ProviderDefinition> {
|
|
374
|
+
async function loadProvider(providerEntry: string): Promise<ProviderDefinition> {
|
|
402
375
|
const mod = (await import(pathToFileURL(providerEntry).href)) as {
|
|
403
376
|
default?: ProviderDefinition;
|
|
404
377
|
};
|
|
@@ -469,9 +442,7 @@ function resolveInputTemplate(
|
|
|
469
442
|
}
|
|
470
443
|
}
|
|
471
444
|
|
|
472
|
-
async function loadFixtureReplay(
|
|
473
|
-
providerDirectory: string,
|
|
474
|
-
): Promise<FixtureReplay | null> {
|
|
445
|
+
async function loadFixtureReplay(providerDirectory: string): Promise<FixtureReplay | null> {
|
|
475
446
|
const fixturePath = resolve(providerDirectory, "__fixtures__", "raw.json");
|
|
476
447
|
if (!existsSync(fixturePath)) {
|
|
477
448
|
return null;
|
|
@@ -484,14 +455,18 @@ async function loadFixtureReplay(
|
|
|
484
455
|
};
|
|
485
456
|
}
|
|
486
457
|
|
|
487
|
-
function assertProxyConfigured(
|
|
488
|
-
|
|
489
|
-
|
|
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.");
|
|
490
462
|
}
|
|
491
463
|
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
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
|
+
}
|
|
495
470
|
}
|
|
496
471
|
|
|
497
472
|
async function runProfileSuite(options: {
|
|
@@ -521,15 +496,8 @@ async function runProfileSuite(options: {
|
|
|
521
496
|
}
|
|
522
497
|
|
|
523
498
|
const runs: RunResult[] = [];
|
|
524
|
-
for (
|
|
525
|
-
|
|
526
|
-
index < options.args.runs;
|
|
527
|
-
index += options.args.concurrency
|
|
528
|
-
) {
|
|
529
|
-
const batchSize = Math.min(
|
|
530
|
-
options.args.concurrency,
|
|
531
|
-
options.args.runs - index,
|
|
532
|
-
);
|
|
499
|
+
for (let index = 0; index < options.args.runs; index += options.args.concurrency) {
|
|
500
|
+
const batchSize = Math.min(options.args.concurrency, options.args.runs - index);
|
|
533
501
|
const batch = Array.from({ length: batchSize }, () =>
|
|
534
502
|
profileRun({
|
|
535
503
|
config: options.config,
|
|
@@ -552,8 +520,7 @@ async function runProfileSuite(options: {
|
|
|
552
520
|
const breakdown = [...groupedSpans.entries()]
|
|
553
521
|
.filter(([name]) => name !== rootSpanName)
|
|
554
522
|
.map(([name, durations]) => {
|
|
555
|
-
const avgMs =
|
|
556
|
-
durations.reduce((sum, value) => sum + value, 0) / durations.length;
|
|
523
|
+
const avgMs = durations.reduce((sum, value) => sum + value, 0) / durations.length;
|
|
557
524
|
const percent = stats.avg > 0 ? (avgMs / stats.avg) * 100 : 0;
|
|
558
525
|
return { avgMs, name, percent };
|
|
559
526
|
})
|
|
@@ -611,9 +578,7 @@ async function executeProfileRun(options: {
|
|
|
611
578
|
proxyEnabled: boolean;
|
|
612
579
|
}): Promise<RunResult> {
|
|
613
580
|
const _operation = getOperation(options.provider, options.operationName);
|
|
614
|
-
const traceContext = createTraceContext(
|
|
615
|
-
resolveTraceContextOptions(options.config.trace),
|
|
616
|
-
);
|
|
581
|
+
const traceContext = createTraceContext(resolveTraceContextOptions(options.config.trace));
|
|
617
582
|
const baseContext = createBaseContext({
|
|
618
583
|
config: options.config,
|
|
619
584
|
provider: options.provider,
|
|
@@ -638,9 +603,7 @@ async function executeProfileRun(options: {
|
|
|
638
603
|
normalizedInput,
|
|
639
604
|
);
|
|
640
605
|
|
|
641
|
-
return ctx.trace.span("transformResponse", async () =>
|
|
642
|
-
options.outputSchema.parse(result),
|
|
643
|
-
);
|
|
606
|
+
return ctx.trace.span("transformResponse", async () => options.outputSchema.parse(result));
|
|
644
607
|
});
|
|
645
608
|
const durationMs = performance.now() - startedAt;
|
|
646
609
|
const spans = ctx.trace.getSpans();
|
|
@@ -671,22 +634,18 @@ function createBaseContext(options: {
|
|
|
671
634
|
traceContext: ReturnType<typeof createTraceContext>;
|
|
672
635
|
}): ProviderContext {
|
|
673
636
|
const upstream = {
|
|
674
|
-
|
|
675
|
-
proxy: options.proxyEnabled,
|
|
637
|
+
proxy: options.proxyEnabled ? options.provider.proxy : false,
|
|
676
638
|
};
|
|
677
|
-
const apifuseConfig = options.proxyEnabled ? options.config : {};
|
|
678
639
|
const http =
|
|
679
640
|
options.forceFixtureReplay && options.fixtureReplay
|
|
680
641
|
? createFixtureHttpClient(options.fixtureReplay.raw)
|
|
681
642
|
: createHttpClient(getProviderBaseUrl(options.provider), {
|
|
682
|
-
apifuseConfig,
|
|
683
643
|
upstream,
|
|
684
644
|
});
|
|
685
645
|
const stealth =
|
|
686
646
|
options.forceFixtureReplay && options.fixtureReplay
|
|
687
647
|
? createFixtureStealthClient(options.fixtureReplay.rawText)
|
|
688
648
|
: createStealthClient(getProviderBaseUrl(options.provider), {
|
|
689
|
-
apifuseConfig,
|
|
690
649
|
upstream,
|
|
691
650
|
});
|
|
692
651
|
|
|
@@ -790,36 +749,24 @@ function createBrowserStub(): BrowserClient {
|
|
|
790
749
|
engine: "playwright-stealth",
|
|
791
750
|
async close() {},
|
|
792
751
|
async newPage() {
|
|
793
|
-
throw new ProviderError(
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
code: "BROWSER_RUNTIME_UNSUPPORTED",
|
|
797
|
-
},
|
|
798
|
-
);
|
|
752
|
+
throw new ProviderError("Browser runtime is not supported by apifuse perf yet.", {
|
|
753
|
+
code: "BROWSER_RUNTIME_UNSUPPORTED",
|
|
754
|
+
});
|
|
799
755
|
},
|
|
800
756
|
async rawPage() {
|
|
801
|
-
throw new ProviderError(
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
code: "BROWSER_RUNTIME_UNSUPPORTED",
|
|
805
|
-
},
|
|
806
|
-
);
|
|
757
|
+
throw new ProviderError("Browser runtime is not supported by apifuse perf yet.", {
|
|
758
|
+
code: "BROWSER_RUNTIME_UNSUPPORTED",
|
|
759
|
+
});
|
|
807
760
|
},
|
|
808
761
|
async withIsolatedContext() {
|
|
809
|
-
throw new ProviderError(
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
code: "BROWSER_RUNTIME_UNSUPPORTED",
|
|
813
|
-
},
|
|
814
|
-
);
|
|
762
|
+
throw new ProviderError("Browser runtime is not supported by apifuse perf yet.", {
|
|
763
|
+
code: "BROWSER_RUNTIME_UNSUPPORTED",
|
|
764
|
+
});
|
|
815
765
|
},
|
|
816
766
|
async solveChallenge() {
|
|
817
|
-
throw new ProviderError(
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
code: "BROWSER_RUNTIME_UNSUPPORTED",
|
|
821
|
-
},
|
|
822
|
-
);
|
|
767
|
+
throw new ProviderError("Browser runtime is not supported by apifuse perf yet.", {
|
|
768
|
+
code: "BROWSER_RUNTIME_UNSUPPORTED",
|
|
769
|
+
});
|
|
823
770
|
},
|
|
824
771
|
};
|
|
825
772
|
}
|
|
@@ -833,9 +780,7 @@ function buildInsights(
|
|
|
833
780
|
const allSpans = runs.flatMap((run) => run.spans);
|
|
834
781
|
const stealthSpans = allSpans.filter((span) => span.name === "stealth.fetch");
|
|
835
782
|
const dnsSpans = allSpans.filter((span) => span.name === "dns");
|
|
836
|
-
const transform = breakdown.find(
|
|
837
|
-
(entry) => entry.name === "transformResponse",
|
|
838
|
-
);
|
|
783
|
+
const transform = breakdown.find((entry) => entry.name === "transformResponse");
|
|
839
784
|
const responseSizes = allSpans
|
|
840
785
|
.map((span) => span.attributes.response_size)
|
|
841
786
|
.filter((value): value is number => typeof value === "number");
|
|
@@ -844,9 +789,7 @@ function buildInsights(
|
|
|
844
789
|
.filter((value): value is boolean => typeof value === "boolean");
|
|
845
790
|
|
|
846
791
|
if (reuseFlags.length > 0) {
|
|
847
|
-
const reusePercent = Math.round(
|
|
848
|
-
(reuseFlags.filter(Boolean).length / reuseFlags.length) * 100,
|
|
849
|
-
);
|
|
792
|
+
const reusePercent = Math.round((reuseFlags.filter(Boolean).length / reuseFlags.length) * 100);
|
|
850
793
|
insights.push(
|
|
851
794
|
reusePercent >= 80
|
|
852
795
|
? `✓ Stealth connection reuse: ${reusePercent}% (good)`
|
|
@@ -863,24 +806,16 @@ function buildInsights(
|
|
|
863
806
|
}
|
|
864
807
|
|
|
865
808
|
if (dnsSpans.length > 0) {
|
|
866
|
-
const dnsAvg =
|
|
867
|
-
dnsSpans.reduce((sum, span) => sum + span.duration_ms, 0) /
|
|
868
|
-
dnsSpans.length;
|
|
809
|
+
const dnsAvg = dnsSpans.reduce((sum, span) => sum + span.duration_ms, 0) / dnsSpans.length;
|
|
869
810
|
if (dnsAvg >= 5) {
|
|
870
|
-
insights.push(
|
|
871
|
-
`⚠ DNS resolution: ${formatDuration(dnsAvg)} avg — consider DNS caching`,
|
|
872
|
-
);
|
|
811
|
+
insights.push(`⚠ DNS resolution: ${formatDuration(dnsAvg)} avg — consider DNS caching`);
|
|
873
812
|
}
|
|
874
813
|
}
|
|
875
814
|
|
|
876
815
|
if (responseSizes.length > 0) {
|
|
877
|
-
const avgSize =
|
|
878
|
-
responseSizes.reduce((sum, value) => sum + value, 0) /
|
|
879
|
-
responseSizes.length;
|
|
816
|
+
const avgSize = responseSizes.reduce((sum, value) => sum + value, 0) / responseSizes.length;
|
|
880
817
|
if (avgSize >= 4096) {
|
|
881
|
-
insights.push(
|
|
882
|
-
`⚠ Response size: ${formatBytes(avgSize)} avg — check gzip (Accept-Encoding)`,
|
|
883
|
-
);
|
|
818
|
+
insights.push(`⚠ Response size: ${formatBytes(avgSize)} avg — check gzip (Accept-Encoding)`);
|
|
884
819
|
}
|
|
885
820
|
}
|
|
886
821
|
|
|
@@ -925,13 +860,10 @@ function renderReport(options: {
|
|
|
925
860
|
|
|
926
861
|
if (options.proxySuite) {
|
|
927
862
|
const delta = options.proxySuite.stats.p50 - options.suite.stats.p50;
|
|
928
|
-
const deltaPercent =
|
|
929
|
-
options.suite.stats.p50 > 0 ? (delta / options.suite.stats.p50) * 100 : 0;
|
|
863
|
+
const deltaPercent = options.suite.stats.p50 > 0 ? (delta / options.suite.stats.p50) * 100 : 0;
|
|
930
864
|
lines.push("│");
|
|
931
865
|
lines.push("│ Proxy Comparison (--compare-proxy):");
|
|
932
|
-
lines.push(
|
|
933
|
-
`│ proxy: off → p50: ${formatDuration(options.suite.stats.p50)}`,
|
|
934
|
-
);
|
|
866
|
+
lines.push(`│ proxy: off → p50: ${formatDuration(options.suite.stats.p50)}`);
|
|
935
867
|
lines.push(
|
|
936
868
|
`│ proxy: on → p50: ${formatDuration(options.proxySuite.stats.p50)} (${delta >= 0 ? "+" : ""}${Math.round(deltaPercent)}%)`,
|
|
937
869
|
);
|
|
@@ -979,9 +911,7 @@ function formatBytes(value: number): string {
|
|
|
979
911
|
}
|
|
980
912
|
|
|
981
913
|
function selectRepresentativeRun(runs: RunResult[]): RunResult {
|
|
982
|
-
const sorted = [...runs].sort(
|
|
983
|
-
(left, right) => left.durationMs - right.durationMs,
|
|
984
|
-
);
|
|
914
|
+
const sorted = [...runs].sort((left, right) => left.durationMs - right.durationMs);
|
|
985
915
|
const middle = sorted[Math.floor(sorted.length / 2)];
|
|
986
916
|
if (middle) {
|
|
987
917
|
return middle;
|
|
@@ -1065,17 +995,10 @@ function buildFlamegraphSvg(
|
|
|
1065
995
|
|
|
1066
996
|
const rects = flattened
|
|
1067
997
|
.map((node) => {
|
|
1068
|
-
const x =
|
|
1069
|
-
|
|
1070
|
-
((node.span.startedAt - root.startedAt) / totalDuration) * (width - 24);
|
|
1071
|
-
const rectWidth = Math.max(
|
|
1072
|
-
1,
|
|
1073
|
-
(node.span.duration_ms / totalDuration) * (width - 24),
|
|
1074
|
-
);
|
|
998
|
+
const x = 12 + ((node.span.startedAt - root.startedAt) / totalDuration) * (width - 24);
|
|
999
|
+
const rectWidth = Math.max(1, (node.span.duration_ms / totalDuration) * (width - 24));
|
|
1075
1000
|
const y = chartTop + node.depth * rowHeight;
|
|
1076
|
-
const label = escapeXml(
|
|
1077
|
-
`${node.span.name} (${formatDuration(node.span.duration_ms)})`,
|
|
1078
|
-
);
|
|
1001
|
+
const label = escapeXml(`${node.span.name} (${formatDuration(node.span.duration_ms)})`);
|
|
1079
1002
|
const title = escapeXml(
|
|
1080
1003
|
`${node.span.name}\n${formatDuration(node.span.duration_ms)}\nstatus: ${node.span.status}`,
|
|
1081
1004
|
);
|
|
@@ -1094,9 +1017,7 @@ function buildFlamegraphSvg(
|
|
|
1094
1017
|
}
|
|
1095
1018
|
|
|
1096
1019
|
function buildFlameTree(spans: Span[]): FlameNode[] {
|
|
1097
|
-
const sorted = [...spans].sort(
|
|
1098
|
-
(left, right) => left.startedAt - right.startedAt,
|
|
1099
|
-
);
|
|
1020
|
+
const sorted = [...spans].sort((left, right) => left.startedAt - right.startedAt);
|
|
1100
1021
|
const nodeMap = new Map<string, FlameNode>();
|
|
1101
1022
|
|
|
1102
1023
|
for (const span of sorted) {
|
|
@@ -1139,9 +1060,7 @@ function findRootSpan(spans: Span[]): Span {
|
|
|
1139
1060
|
return root;
|
|
1140
1061
|
}
|
|
1141
1062
|
|
|
1142
|
-
const sorted = [...spans].sort(
|
|
1143
|
-
(left, right) => left.startedAt - right.startedAt,
|
|
1144
|
-
);
|
|
1063
|
+
const sorted = [...spans].sort((left, right) => left.startedAt - right.startedAt);
|
|
1145
1064
|
const first = sorted[0];
|
|
1146
1065
|
if (!first) {
|
|
1147
1066
|
throw new Error("Expected at least one span");
|