@apifuse/provider-sdk 2.2.0-beta.3 → 2.2.0-beta.31
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 +131 -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 +123 -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 +14 -1
- package/dist/runtime/choice.js +566 -101
- 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 +2078 -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 +128 -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 +158 -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 +66 -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 +758 -197
- 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 +3062 -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-dev.ts
CHANGED
|
@@ -2,22 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
import { existsSync } from "node:fs";
|
|
4
4
|
import { dirname, relative, resolve } from "node:path";
|
|
5
|
-
import type { ProviderDefinition } from "../src";
|
|
6
5
|
import {
|
|
7
|
-
createBrowserClient,
|
|
8
6
|
createCredentialContext,
|
|
9
7
|
createEnvContext,
|
|
10
8
|
createHttpClient,
|
|
9
|
+
createOcrClientFromEnv,
|
|
11
10
|
createProviderCache,
|
|
12
11
|
createProviderChoiceContext,
|
|
13
|
-
|
|
12
|
+
createUnsupportedResolverClient,
|
|
14
13
|
createSttClientFromEnv,
|
|
15
14
|
PROVIDER_RUNTIME_CHOICE_TOKEN_MASTER_SECRET_ENV,
|
|
15
|
+
type ProviderDefinition,
|
|
16
16
|
ProviderError,
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
import {
|
|
20
|
-
import
|
|
17
|
+
type ProviderProxyPolicy,
|
|
18
|
+
} from "../src/index.js";
|
|
19
|
+
import { createBrowserClient } from "../src/runtime/browser.js";
|
|
20
|
+
import { createResolverClientFromEnv } from "../src/runtime/resolver.js";
|
|
21
|
+
import { createMemoryProviderRuntimeState } from "../src/runtime/state.js";
|
|
22
|
+
import { createStealthClient } from "../src/runtime/stealth.js";
|
|
23
|
+
import { createTraceContext } from "../src/runtime/trace.js";
|
|
24
|
+
import { getStealthProfile } from "../src/stealth/profiles.js";
|
|
25
|
+
import type { BrowserClient, ProviderContext } from "../src/types.js";
|
|
21
26
|
|
|
22
27
|
const HELP_TEXT = `Usage: apifuse dev [path]
|
|
23
28
|
Example: apifuse dev providers/korea-air-quality
|
|
@@ -33,12 +38,9 @@ export async function main() {
|
|
|
33
38
|
|
|
34
39
|
const providerPath = resolveProviderPath(args[0] ?? ".");
|
|
35
40
|
const providerModule = await import(resolve(providerPath, "index.ts"));
|
|
36
|
-
const provider = assertProviderDefinition(
|
|
37
|
-
providerModule.default,
|
|
38
|
-
providerPath,
|
|
39
|
-
);
|
|
41
|
+
const provider = assertProviderDefinition(providerModule.default, providerPath);
|
|
40
42
|
|
|
41
|
-
const { startDevServer } = await import("../src/dev");
|
|
43
|
+
const { startDevServer } = await import("../src/dev.js");
|
|
42
44
|
const port = Number(process.env.APIFUSE__RUNTIME__PORT) || 3900;
|
|
43
45
|
|
|
44
46
|
startDevServer(provider, { port });
|
|
@@ -57,8 +59,7 @@ export async function main() {
|
|
|
57
59
|
|
|
58
60
|
const firstOperation = Object.keys(provider.operations)[0];
|
|
59
61
|
if (firstOperation) {
|
|
60
|
-
const sampleInput =
|
|
61
|
-
provider.operations[firstOperation]?.fixtures?.request ?? {};
|
|
62
|
+
const sampleInput = provider.operations[firstOperation]?.fixtures?.request ?? {};
|
|
62
63
|
const sampleBody = JSON.stringify({
|
|
63
64
|
requestId: `req_local_${firstOperation}`,
|
|
64
65
|
input: sampleInput,
|
|
@@ -84,6 +85,11 @@ export function createProviderContext(provider: ProviderDefinition): {
|
|
|
84
85
|
]);
|
|
85
86
|
const credential = createCredentialContext();
|
|
86
87
|
const state = createMemoryProviderRuntimeState();
|
|
88
|
+
const cache = createProviderCache({ providerId: provider.id });
|
|
89
|
+
const proxyPolicy = resolveNativeProxyPolicy(provider);
|
|
90
|
+
const stealthProfile = provider.stealth?.profile
|
|
91
|
+
? getStealthProfile(provider.stealth.profile)
|
|
92
|
+
: undefined;
|
|
87
93
|
const ctx: ProviderContext = {
|
|
88
94
|
env,
|
|
89
95
|
credential,
|
|
@@ -96,11 +102,27 @@ export function createProviderContext(provider: ProviderDefinition): {
|
|
|
96
102
|
})
|
|
97
103
|
: createUnsupportedBrowserStub(),
|
|
98
104
|
http: createHttpClient(),
|
|
99
|
-
cache
|
|
105
|
+
cache,
|
|
100
106
|
state,
|
|
101
107
|
trace: createTraceContext(),
|
|
102
108
|
stealth: createStealthClient("http://localhost"),
|
|
109
|
+
ocr: createOcrClientFromEnv(provider.ocr),
|
|
103
110
|
stt: createSttClientFromEnv(provider.stt),
|
|
111
|
+
resolver: provider.resolver
|
|
112
|
+
? createResolverClientFromEnv(provider.resolver, undefined, {
|
|
113
|
+
allowedHosts: provider.allowedHosts,
|
|
114
|
+
cache,
|
|
115
|
+
...(proxyPolicy
|
|
116
|
+
? {
|
|
117
|
+
proxyIntent: {
|
|
118
|
+
mode: proxyPolicy.mode,
|
|
119
|
+
upstream: { proxy: provider.proxy },
|
|
120
|
+
...(stealthProfile ? { userAgent: stealthProfile.userAgent } : {}),
|
|
121
|
+
},
|
|
122
|
+
}
|
|
123
|
+
: {}),
|
|
124
|
+
})
|
|
125
|
+
: createUnsupportedResolverClient("Provider does not declare resolver capability"),
|
|
104
126
|
choice: createProviderChoiceContext({
|
|
105
127
|
providerId: provider.id,
|
|
106
128
|
env,
|
|
@@ -112,6 +134,13 @@ export function createProviderContext(provider: ProviderDefinition): {
|
|
|
112
134
|
return { ctx };
|
|
113
135
|
}
|
|
114
136
|
|
|
137
|
+
function resolveNativeProxyPolicy(provider: ProviderDefinition): ProviderProxyPolicy | undefined {
|
|
138
|
+
if (typeof provider.proxy === "object") return provider.proxy;
|
|
139
|
+
if (provider.proxy === true) return { mode: "optional" };
|
|
140
|
+
if (provider.proxy === false) return { mode: "disabled" };
|
|
141
|
+
return undefined;
|
|
142
|
+
}
|
|
143
|
+
|
|
115
144
|
function normalizeArgs(argv: string[]): string[] {
|
|
116
145
|
return argv[0] === "dev" ? argv.slice(1) : argv;
|
|
117
146
|
}
|
|
@@ -149,9 +178,7 @@ function renderHotReloadCommand(providerPath: string, port: number): string {
|
|
|
149
178
|
const devEntry = resolve(providerPath, "dev.ts");
|
|
150
179
|
if (existsSync(devEntry)) {
|
|
151
180
|
const relativeDevEntry = relative(process.cwd(), devEntry) || "dev.ts";
|
|
152
|
-
const portPrefix = process.env.APIFUSE__RUNTIME__PORT
|
|
153
|
-
? `APIFUSE__RUNTIME__PORT=${port} `
|
|
154
|
-
: "";
|
|
181
|
+
const portPrefix = process.env.APIFUSE__RUNTIME__PORT ? `APIFUSE__RUNTIME__PORT=${port} ` : "";
|
|
155
182
|
return `${portPrefix}bun --hot ${relativeDevEntry}`;
|
|
156
183
|
}
|
|
157
184
|
return "rerun `apifuse dev` after edits (no dev.ts entrypoint found)";
|
|
@@ -166,40 +193,28 @@ function createUnsupportedBrowserStub(): BrowserClient {
|
|
|
166
193
|
engine: "playwright-stealth",
|
|
167
194
|
async close() {},
|
|
168
195
|
async newPage() {
|
|
169
|
-
throw new ProviderError(
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
fix: 'Set provider runtime to "browser" to use ctx.browser',
|
|
174
|
-
},
|
|
175
|
-
);
|
|
196
|
+
throw new ProviderError("Browser runtime is not enabled for this provider", {
|
|
197
|
+
code: "BROWSER_RUNTIME_UNSUPPORTED",
|
|
198
|
+
fix: 'Set provider runtime to "browser" to use ctx.browser',
|
|
199
|
+
});
|
|
176
200
|
},
|
|
177
201
|
async rawPage() {
|
|
178
|
-
throw new ProviderError(
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
fix: 'Set provider runtime to "browser" and APIFUSE__CDP_POOL__URL to use ctx.browser.rawPage',
|
|
183
|
-
},
|
|
184
|
-
);
|
|
202
|
+
throw new ProviderError("Browser runtime is not enabled for this provider", {
|
|
203
|
+
code: "BROWSER_RUNTIME_UNSUPPORTED",
|
|
204
|
+
fix: 'Set provider runtime to "browser" and APIFUSE__CDP_POOL__URL to use ctx.browser.rawPage',
|
|
205
|
+
});
|
|
185
206
|
},
|
|
186
207
|
async withIsolatedContext() {
|
|
187
|
-
throw new ProviderError(
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
fix: 'Set provider runtime to "browser" to use ctx.browser.withIsolatedContext',
|
|
192
|
-
},
|
|
193
|
-
);
|
|
208
|
+
throw new ProviderError("Browser runtime is not enabled for this provider", {
|
|
209
|
+
code: "BROWSER_RUNTIME_UNSUPPORTED",
|
|
210
|
+
fix: 'Set provider runtime to "browser" to use ctx.browser.withIsolatedContext',
|
|
211
|
+
});
|
|
194
212
|
},
|
|
195
213
|
async solveChallenge() {
|
|
196
|
-
throw new ProviderError(
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
fix: 'Set provider runtime to "browser" to use ctx.browser.solveChallenge',
|
|
201
|
-
},
|
|
202
|
-
);
|
|
214
|
+
throw new ProviderError("Browser runtime is not enabled for this provider", {
|
|
215
|
+
code: "BROWSER_RUNTIME_UNSUPPORTED",
|
|
216
|
+
fix: 'Set provider runtime to "browser" to use ctx.browser.solveChallenge',
|
|
217
|
+
});
|
|
203
218
|
},
|
|
204
219
|
};
|
|
205
220
|
}
|
|
@@ -216,10 +231,7 @@ function createUnsupportedAuthStub() {
|
|
|
216
231
|
};
|
|
217
232
|
}
|
|
218
233
|
|
|
219
|
-
function assertProviderDefinition(
|
|
220
|
-
value: unknown,
|
|
221
|
-
providerPath: string,
|
|
222
|
-
): ProviderDefinition {
|
|
234
|
+
function assertProviderDefinition(value: unknown, providerPath: string): ProviderDefinition {
|
|
223
235
|
if (!isProviderDefinition(value)) {
|
|
224
236
|
throw new Error(
|
|
225
237
|
`Expected ${resolve(providerPath, "index.ts")} to export default defineProvider(...)`,
|
|
@@ -230,11 +242,7 @@ function assertProviderDefinition(
|
|
|
230
242
|
}
|
|
231
243
|
|
|
232
244
|
function isProviderDefinition(value: unknown): value is ProviderDefinition {
|
|
233
|
-
if (
|
|
234
|
-
!isRecord(value) ||
|
|
235
|
-
!isRecord(value.meta) ||
|
|
236
|
-
!isRecord(value.operations)
|
|
237
|
-
) {
|
|
245
|
+
if (!isRecord(value) || !isRecord(value.meta) || !isRecord(value.operations)) {
|
|
238
246
|
return false;
|
|
239
247
|
}
|
|
240
248
|
|
|
@@ -48,6 +48,13 @@ const requiredPaths = [
|
|
|
48
48
|
"src/cli/templates/provider/operations/ping.ts.tpl",
|
|
49
49
|
"src/cli/templates/provider/schemas/ping.ts.tpl",
|
|
50
50
|
"src/cli/templates/provider/upstream/README.md.tpl",
|
|
51
|
+
"src/cli/templates/provider/AGENTS.md.tpl",
|
|
52
|
+
"src/cli/templates/provider/.agents/skills/normalization-standards/SKILL.md.tpl",
|
|
53
|
+
"src/cli/templates/provider/.agents/skills/upstream-contract-verification/SKILL.md.tpl",
|
|
54
|
+
"src/cli/templates/provider/.agents/skills/fixtures-and-recording/SKILL.md.tpl",
|
|
55
|
+
"src/cli/templates/provider/.agents/skills/pagination-and-counts/SKILL.md.tpl",
|
|
56
|
+
"src/cli/templates/provider/.agents/skills/health-checks-and-fail-closed/SKILL.md.tpl",
|
|
57
|
+
"src/cli/templates/provider/.agents/skills/upstream-notes/README.md.tpl",
|
|
51
58
|
"dist/cli/templates/provider/.dockerignore.tpl",
|
|
52
59
|
"dist/cli/templates/provider/.gitignore.tpl",
|
|
53
60
|
"dist/cli/templates/provider/Dockerfile.tpl",
|
|
@@ -60,6 +67,13 @@ const requiredPaths = [
|
|
|
60
67
|
"dist/cli/templates/provider/operations/ping.ts.tpl",
|
|
61
68
|
"dist/cli/templates/provider/schemas/ping.ts.tpl",
|
|
62
69
|
"dist/cli/templates/provider/upstream/README.md.tpl",
|
|
70
|
+
"dist/cli/templates/provider/AGENTS.md.tpl",
|
|
71
|
+
"dist/cli/templates/provider/.agents/skills/normalization-standards/SKILL.md.tpl",
|
|
72
|
+
"dist/cli/templates/provider/.agents/skills/upstream-contract-verification/SKILL.md.tpl",
|
|
73
|
+
"dist/cli/templates/provider/.agents/skills/fixtures-and-recording/SKILL.md.tpl",
|
|
74
|
+
"dist/cli/templates/provider/.agents/skills/pagination-and-counts/SKILL.md.tpl",
|
|
75
|
+
"dist/cli/templates/provider/.agents/skills/health-checks-and-fail-closed/SKILL.md.tpl",
|
|
76
|
+
"dist/cli/templates/provider/.agents/skills/upstream-notes/README.md.tpl",
|
|
63
77
|
"dist/auth-turn/index.js",
|
|
64
78
|
"dist/auth-turn/index.d.ts",
|
|
65
79
|
"dist/auth-turn/auth-turn.v1.schema.json",
|
|
@@ -142,9 +156,9 @@ function assertPublicSmokeDocs(label: string, content: string): void {
|
|
|
142
156
|
);
|
|
143
157
|
}
|
|
144
158
|
|
|
145
|
-
if (!content.includes("
|
|
159
|
+
if (!content.includes("wreq-js")) {
|
|
146
160
|
throw new Error(
|
|
147
|
-
`${label} must include
|
|
161
|
+
`${label} must include wreq-js stealth runtime guidance for TLS/browser bounties.`,
|
|
148
162
|
);
|
|
149
163
|
}
|
|
150
164
|
|
|
@@ -154,6 +168,12 @@ function assertPublicSmokeDocs(label: string, content: string): void {
|
|
|
154
168
|
);
|
|
155
169
|
}
|
|
156
170
|
|
|
171
|
+
if (!content.includes("Chrome, Firefox, and Safari")) {
|
|
172
|
+
throw new Error(
|
|
173
|
+
`${label} must document the browser families supported by the TypeScript stealth runtime.`,
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
|
|
157
177
|
if (
|
|
158
178
|
!content.includes('browser.engine: "playwright-stealth"') ||
|
|
159
179
|
!content.includes("nodriver")
|
|
@@ -1,19 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
execFileSync,
|
|
6
|
-
spawn,
|
|
7
|
-
spawnSync,
|
|
8
|
-
} from "node:child_process";
|
|
9
|
-
import {
|
|
10
|
-
existsSync,
|
|
11
|
-
mkdirSync,
|
|
12
|
-
mkdtempSync,
|
|
13
|
-
readFileSync,
|
|
14
|
-
rmSync,
|
|
15
|
-
writeFileSync,
|
|
16
|
-
} from "node:fs";
|
|
3
|
+
import { type ChildProcess, execFileSync, spawn, spawnSync } from "node:child_process";
|
|
4
|
+
import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
17
5
|
import { createServer } from "node:net";
|
|
18
6
|
import { tmpdir } from "node:os";
|
|
19
7
|
import { join, resolve } from "node:path";
|
|
@@ -41,9 +29,7 @@ const PING_RESPONSE_SCHEMA = z.object({
|
|
|
41
29
|
|
|
42
30
|
const KEEP_TEMP = process.env.APIFUSE__PACK_SMOKE__KEEP_TEMP === "1";
|
|
43
31
|
|
|
44
|
-
const tempRoot = mkdtempSync(
|
|
45
|
-
join(tmpdir(), "apifuse-provider-sdk-pack-smoke-"),
|
|
46
|
-
);
|
|
32
|
+
const tempRoot = mkdtempSync(join(tmpdir(), "apifuse-provider-sdk-pack-smoke-"));
|
|
47
33
|
const packDir = join(tempRoot, "pack");
|
|
48
34
|
const consumerDir = join(tempRoot, "consumer");
|
|
49
35
|
const externalWorkspaceDir = join(tempRoot, "external-workspace");
|
|
@@ -73,6 +59,21 @@ try {
|
|
|
73
59
|
);
|
|
74
60
|
|
|
75
61
|
run("bun", ["install"], consumerDir);
|
|
62
|
+
run(
|
|
63
|
+
"bun",
|
|
64
|
+
[
|
|
65
|
+
"--eval",
|
|
66
|
+
[
|
|
67
|
+
'import { resolveProxy } from "@apifuse/provider-sdk";',
|
|
68
|
+
'if (typeof resolveProxy !== "function") throw new Error("resolveProxy is not exported");',
|
|
69
|
+
'const resolved = await resolveProxy({ proxy: "http://127.0.0.1:8080" });',
|
|
70
|
+
'if (resolved.url !== "http://127.0.0.1:8080") throw new Error("resolveProxy returned the wrong URL");',
|
|
71
|
+
'console.log("packed root resolveProxy export OK");',
|
|
72
|
+
].join("\n"),
|
|
73
|
+
],
|
|
74
|
+
consumerDir,
|
|
75
|
+
);
|
|
76
|
+
smokePackedStealthNative(consumerDir);
|
|
76
77
|
|
|
77
78
|
const cliBin = join(consumerDir, "node_modules", ".bin", "apifuse");
|
|
78
79
|
if (!existsSync(cliBin)) {
|
|
@@ -81,15 +82,7 @@ try {
|
|
|
81
82
|
|
|
82
83
|
run(
|
|
83
84
|
"bun",
|
|
84
|
-
[
|
|
85
|
-
cliBin,
|
|
86
|
-
"create",
|
|
87
|
-
"dx-smoke",
|
|
88
|
-
"--yes",
|
|
89
|
-
"--json",
|
|
90
|
-
"--sdk-specifier",
|
|
91
|
-
tarballSpecifier,
|
|
92
|
-
],
|
|
85
|
+
[cliBin, "create", "dx-smoke", "--yes", "--json", "--sdk-specifier", tarballSpecifier],
|
|
93
86
|
consumerDir,
|
|
94
87
|
);
|
|
95
88
|
|
|
@@ -99,11 +92,7 @@ try {
|
|
|
99
92
|
run("bun", ["run", "test"], generatedProviderDir);
|
|
100
93
|
assertGeneratedReadme(generatedProviderDir);
|
|
101
94
|
await smokeGeneratedDevServer(generatedProviderDir);
|
|
102
|
-
assertExternalWorkspaceTopology(
|
|
103
|
-
cliBin,
|
|
104
|
-
externalWorkspaceDir,
|
|
105
|
-
tarballSpecifier,
|
|
106
|
-
);
|
|
95
|
+
assertExternalWorkspaceTopology(cliBin, externalWorkspaceDir, tarballSpecifier);
|
|
107
96
|
|
|
108
97
|
console.log(
|
|
109
98
|
`Provider SDK packed-artifact smoke passed: ${tarballPath} -> ${generatedProviderDir}`,
|
|
@@ -148,15 +137,8 @@ function assertExternalWorkspaceTopology(
|
|
|
148
137
|
externalWorkspaceDir,
|
|
149
138
|
);
|
|
150
139
|
|
|
151
|
-
const generatedProviderDir = join(
|
|
152
|
-
|
|
153
|
-
"external-workspace-smoke",
|
|
154
|
-
);
|
|
155
|
-
const forbiddenProviderDir = join(
|
|
156
|
-
externalWorkspaceDir,
|
|
157
|
-
"providers",
|
|
158
|
-
"external-workspace-smoke",
|
|
159
|
-
);
|
|
140
|
+
const generatedProviderDir = join(externalWorkspaceDir, "external-workspace-smoke");
|
|
141
|
+
const forbiddenProviderDir = join(externalWorkspaceDir, "providers", "external-workspace-smoke");
|
|
160
142
|
if (!existsSync(generatedProviderDir)) {
|
|
161
143
|
throw new Error(
|
|
162
144
|
"Public create must generate a one-provider repository at <name>/ even when providers/ exists.",
|
|
@@ -168,9 +150,7 @@ function assertExternalWorkspaceTopology(
|
|
|
168
150
|
);
|
|
169
151
|
}
|
|
170
152
|
|
|
171
|
-
const packageJson = JSON.parse(
|
|
172
|
-
readFileSync(join(generatedProviderDir, "package.json"), "utf8"),
|
|
173
|
-
);
|
|
153
|
+
const packageJson = JSON.parse(readFileSync(join(generatedProviderDir, "package.json"), "utf8"));
|
|
174
154
|
const sdkDependency = packageJson?.dependencies?.["@apifuse/provider-sdk"];
|
|
175
155
|
if (sdkDependency !== tarballSpecifier) {
|
|
176
156
|
throw new Error(
|
|
@@ -178,9 +158,7 @@ function assertExternalWorkspaceTopology(
|
|
|
178
158
|
);
|
|
179
159
|
}
|
|
180
160
|
if (JSON.stringify(packageJson).includes("workspace:")) {
|
|
181
|
-
throw new Error(
|
|
182
|
-
"External bounty workspace scaffold must not contain workspace: dependencies.",
|
|
183
|
-
);
|
|
161
|
+
throw new Error("External bounty workspace scaffold must not contain workspace: dependencies.");
|
|
184
162
|
}
|
|
185
163
|
|
|
186
164
|
run("bun", ["install"], generatedProviderDir);
|
|
@@ -199,30 +177,20 @@ function assertExternalWorkspaceTopology(
|
|
|
199
177
|
},
|
|
200
178
|
);
|
|
201
179
|
if (monorepoAttempt.status === 0) {
|
|
202
|
-
throw new Error(
|
|
203
|
-
"--preset monorepo must reject outside the private APIFuse monorepo.",
|
|
204
|
-
);
|
|
180
|
+
throw new Error("--preset monorepo must reject outside the private APIFuse monorepo.");
|
|
205
181
|
}
|
|
206
182
|
const rejectionOutput = `${monorepoAttempt.stdout}\n${monorepoAttempt.stderr}`;
|
|
207
|
-
if (
|
|
208
|
-
!rejectionOutput.includes(
|
|
209
|
-
"Monorepo preset is internal to the APIFuse repository",
|
|
210
|
-
)
|
|
211
|
-
) {
|
|
183
|
+
if (!rejectionOutput.includes("Monorepo preset is internal to the APIFuse repository")) {
|
|
212
184
|
throw new Error(`Unexpected monorepo rejection output: ${rejectionOutput}`);
|
|
213
185
|
}
|
|
214
186
|
}
|
|
215
187
|
|
|
216
188
|
function packSdk(destination: string): { filename: string } {
|
|
217
|
-
const raw = execFileSync(
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
encoding: "utf8",
|
|
223
|
-
stdio: ["ignore", "pipe", "inherit"],
|
|
224
|
-
},
|
|
225
|
-
);
|
|
189
|
+
const raw = execFileSync("npm", ["pack", "--json", "--pack-destination", destination], {
|
|
190
|
+
cwd: process.cwd(),
|
|
191
|
+
encoding: "utf8",
|
|
192
|
+
stdio: ["ignore", "pipe", "inherit"],
|
|
193
|
+
});
|
|
226
194
|
const parsed = PACK_RESULT_SCHEMA.parse(JSON.parse(raw));
|
|
227
195
|
const first = parsed[0];
|
|
228
196
|
if (!first) {
|
|
@@ -249,32 +217,62 @@ function run(command: string, args: string[], cwd: string): void {
|
|
|
249
217
|
}
|
|
250
218
|
}
|
|
251
219
|
|
|
220
|
+
function smokePackedStealthNative(consumerDir: string): void {
|
|
221
|
+
run(
|
|
222
|
+
"bun",
|
|
223
|
+
[
|
|
224
|
+
"--eval",
|
|
225
|
+
[
|
|
226
|
+
'import { createServer } from "node:http";',
|
|
227
|
+
'import { createStealthClient } from "@apifuse/provider-sdk/runtime/stealth";',
|
|
228
|
+
"const server = createServer((_request, response) => {",
|
|
229
|
+
' response.setHeader("set-cookie", "pack_native_cookie=landed; Path=/");',
|
|
230
|
+
' response.end("packed native stealth ok");',
|
|
231
|
+
"});",
|
|
232
|
+
"await new Promise((resolve, reject) => {",
|
|
233
|
+
' server.once("error", reject);',
|
|
234
|
+
' server.listen(0, "127.0.0.1", resolve);',
|
|
235
|
+
"});",
|
|
236
|
+
"const address = server.address();",
|
|
237
|
+
'if (!address || typeof address === "string") throw new Error("Local server has no TCP address");',
|
|
238
|
+
'const baseUrl = "http://127.0.0.1:" + address.port;',
|
|
239
|
+
'const session = createStealthClient(baseUrl).createSession({ profile: "safari-17" });',
|
|
240
|
+
"try {",
|
|
241
|
+
' const response = await session.fetch("/native");',
|
|
242
|
+
' if (response.body !== "packed native stealth ok") throw new Error("Unexpected stealth body: " + response.body);',
|
|
243
|
+
' if (session.cookies.get("pack_native_cookie", baseUrl + "/native") !== "landed") {',
|
|
244
|
+
' throw new Error("Packed stealth Set-Cookie did not land in the SDK jar");',
|
|
245
|
+
" }",
|
|
246
|
+
' console.log("packed native Safari stealth request OK");',
|
|
247
|
+
"} finally {",
|
|
248
|
+
" session.close();",
|
|
249
|
+
" await new Promise((resolve, reject) => server.close((error) => error ? reject(error) : resolve()));",
|
|
250
|
+
"}",
|
|
251
|
+
].join("\n"),
|
|
252
|
+
],
|
|
253
|
+
consumerDir,
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
|
|
252
257
|
function assertGeneratedReadme(providerDir: string): void {
|
|
253
258
|
const readme = readFileSync(join(providerDir, "README.md"), "utf8");
|
|
254
259
|
if (!readme.includes('"requestId":"req_local_ping"')) {
|
|
255
|
-
throw new Error(
|
|
256
|
-
"Generated README is missing requestId in local smoke docs.",
|
|
257
|
-
);
|
|
260
|
+
throw new Error("Generated README is missing requestId in local smoke docs.");
|
|
258
261
|
}
|
|
259
262
|
if (readme.includes('"connection":null')) {
|
|
260
|
-
throw new Error(
|
|
261
|
-
"Generated README must not document connection:null for no-auth local smoke.",
|
|
262
|
-
);
|
|
263
|
+
throw new Error("Generated README must not document connection:null for no-auth local smoke.");
|
|
263
264
|
}
|
|
264
265
|
if (!readme.includes("bunx playwright install chromium")) {
|
|
265
|
-
throw new Error(
|
|
266
|
-
"Generated README is missing browser runtime troubleshooting guidance.",
|
|
267
|
-
);
|
|
266
|
+
throw new Error("Generated README is missing browser runtime troubleshooting guidance.");
|
|
268
267
|
}
|
|
269
|
-
if (!readme.includes("
|
|
270
|
-
throw new Error(
|
|
271
|
-
|
|
272
|
-
|
|
268
|
+
if (!readme.includes("wreq-js")) {
|
|
269
|
+
throw new Error("Generated README is missing wreq-js stealth runtime guidance.");
|
|
270
|
+
}
|
|
271
|
+
if (!readme.includes("Chrome, Firefox, and Safari")) {
|
|
272
|
+
throw new Error("Generated README is missing supported stealth browser families.");
|
|
273
273
|
}
|
|
274
274
|
if (!readme.includes("bun run submit-check")) {
|
|
275
|
-
throw new Error(
|
|
276
|
-
"Generated README must document the submit-check pre-submission workflow.",
|
|
277
|
-
);
|
|
275
|
+
throw new Error("Generated README must document the submit-check pre-submission workflow.");
|
|
278
276
|
}
|
|
279
277
|
if (!readme.includes("bun run record -- --operation <operation>")) {
|
|
280
278
|
throw new Error(
|
|
@@ -368,9 +366,7 @@ async function waitForHttp(
|
|
|
368
366
|
|
|
369
367
|
while (Date.now() < deadline) {
|
|
370
368
|
if (server.exitCode !== null) {
|
|
371
|
-
throw new Error(
|
|
372
|
-
`Dev server exited early with code ${server.exitCode}\n${getOutput()}`,
|
|
373
|
-
);
|
|
369
|
+
throw new Error(`Dev server exited early with code ${server.exitCode}\n${getOutput()}`);
|
|
374
370
|
}
|
|
375
371
|
|
|
376
372
|
try {
|