@apifuse/provider-sdk 2.2.0-beta.2 → 2.2.0-beta.21
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 +487 -0
- package/CHANGELOG.md +90 -0
- package/README.md +49 -3
- package/SUBMISSION.md +1 -1
- package/bin/apifuse-check.ts +44 -59
- package/bin/apifuse-create.ts +1 -1
- package/bin/apifuse-dev.ts +27 -52
- package/bin/apifuse-pack-check.ts +14 -0
- package/bin/apifuse-pack-smoke.ts +36 -81
- package/bin/apifuse-pack-types.ts +305 -0
- package/bin/apifuse-perf.ts +45 -127
- package/bin/apifuse-record.ts +659 -111
- package/bin/apifuse-submit-check.ts +546 -48
- 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-semantics.ts +204 -0
- package/bin/submit-check-xml.ts +134 -0
- package/dist/auth-turn/index.d.ts +3 -3
- package/dist/auth.d.ts +2 -2
- package/dist/auth.js +9 -18
- package/dist/ceremonies/index.d.ts +9 -1
- package/dist/ceremonies/index.js +65 -18
- 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/config/loader.d.ts +176 -8
- package/dist/config/loader.js +424 -95
- package/dist/contract-serialization.d.ts +2 -2
- package/dist/contract-serialization.js +3 -6
- package/dist/contract-types.d.ts +2 -2
- package/dist/contract.d.ts +3 -3
- package/dist/contract.js +4 -6
- package/dist/define.d.ts +9 -1
- package/dist/define.js +304 -119
- package/dist/dev.d.ts +1 -1
- package/dist/dev.js +1 -1
- package/dist/error-resolution.d.ts +2 -0
- package/dist/error-resolution.js +90 -0
- package/dist/errors.d.ts +22 -1
- package/dist/errors.js +88 -0
- 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 +46 -42
- package/dist/index.js +41 -37
- package/dist/lint.d.ts +1 -1
- package/dist/lint.js +8 -15
- 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 +12 -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 +2 -1
- package/dist/runtime/auth-flow.js +4 -3
- package/dist/runtime/browser.d.ts +1 -1
- package/dist/runtime/browser.js +15 -29
- package/dist/runtime/cache.d.ts +1 -1
- package/dist/runtime/cache.js +4 -8
- package/dist/runtime/choice.d.ts +1 -1
- package/dist/runtime/choice.js +31 -35
- 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 +31 -4
- package/dist/runtime/http.d.ts +2 -2
- package/dist/runtime/http.js +387 -47
- 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 +345 -22
- package/dist/runtime/keyring.js +1 -1
- package/dist/runtime/namespace.js +1 -1
- package/dist/runtime/native-network.d.ts +127 -0
- package/dist/runtime/native-network.js +1298 -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 +55 -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 +2 -4
- package/dist/runtime/request-options.d.ts +68 -1
- package/dist/runtime/request-options.js +548 -0
- package/dist/runtime/secrets.d.ts +27 -0
- package/dist/runtime/secrets.js +51 -0
- package/dist/runtime/state.d.ts +2 -2
- package/dist/runtime/state.js +238 -26
- package/dist/runtime/stealth.d.ts +5 -3
- package/dist/runtime/stealth.js +423 -143
- package/dist/runtime/stt.d.ts +1 -1
- package/dist/runtime/stt.js +11 -15
- 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 +104 -3
- package/dist/server/self-test.js +673 -115
- package/dist/server/serve.d.ts +116 -4
- package/dist/server/serve.js +799 -128
- package/dist/server/types.d.ts +34 -9
- package/dist/server/types.js +8 -1
- package/dist/stateful/errors.d.ts +14 -0
- package/dist/stateful/errors.js +14 -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 +71 -0
- package/dist/stateful/stateful-provider-session-routing.js +353 -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 +5 -14
- package/dist/stream-evidence.d.ts +74 -0
- package/dist/stream-evidence.js +785 -0
- package/dist/stream.d.ts +1 -1
- package/dist/testing/index.d.ts +2 -2
- package/dist/testing/index.js +2 -2
- package/dist/testing/run.d.ts +32 -2
- package/dist/testing/run.js +478 -28
- package/dist/types.d.ts +342 -14
- package/dist/types.js +1 -0
- package/dist/user-input.d.ts +30 -0
- package/dist/user-input.js +66 -0
- package/package.json +16 -5
- package/src/auth-turn/index.ts +1 -1
- package/src/auth.ts +28 -86
- package/src/ceremonies/index.ts +103 -78
- 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/config/loader.ts +652 -204
- package/src/contract-serialization.ts +5 -11
- package/src/contract-types.ts +2 -2
- package/src/contract.ts +12 -28
- package/src/define.ts +499 -498
- package/src/dev.ts +4 -9
- package/src/error-resolution.ts +91 -0
- package/src/errors.ts +110 -5
- 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 +112 -42
- package/src/lint.ts +88 -152
- 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 +7 -7
- package/src/runtime/browser.ts +64 -187
- package/src/runtime/cache.ts +20 -67
- package/src/runtime/choice.ts +79 -132
- package/src/runtime/credential.ts +2 -2
- package/src/runtime/env.ts +1 -1
- package/src/runtime/executor.ts +43 -20
- package/src/runtime/http.ts +494 -57
- package/src/runtime/insights.ts +15 -53
- package/src/runtime/instrumentation.ts +495 -66
- package/src/runtime/keyring.ts +7 -19
- package/src/runtime/namespace.ts +2 -7
- package/src/runtime/native-network.ts +1686 -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 +79 -77
- package/src/runtime/redirects.ts +66 -0
- package/src/runtime/redis.ts +4 -12
- package/src/runtime/request-options.ts +679 -9
- package/src/runtime/secrets.ts +64 -0
- package/src/runtime/state.ts +353 -133
- package/src/runtime/stealth.ts +505 -154
- package/src/runtime/stt.ts +38 -94
- package/src/runtime/trace.ts +14 -44
- package/src/runtime/waterfall.ts +5 -18
- package/src/schema.ts +23 -84
- package/src/serve.ts +1 -1
- package/src/server/index.ts +29 -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 +857 -132
- package/src/server/serve.ts +1151 -328
- package/src/server/types.ts +12 -13
- package/src/stateful/README.md +146 -0
- package/src/stateful/errors.ts +23 -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 +555 -0
- package/src/stateful/stateful-provider-session-runtime.ts +403 -0
- package/src/stateful-signing.ts +46 -0
- package/src/stealth/profiles.ts +10 -26
- package/src/stream-evidence.ts +988 -0
- package/src/stream.ts +8 -19
- package/src/testing/index.ts +10 -2
- package/src/testing/run.ts +653 -74
- package/src/types.ts +408 -28
- 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/dist/index.d.ts
CHANGED
|
@@ -1,42 +1,46 @@
|
|
|
1
|
-
export * from "./auth";
|
|
2
|
-
export * from "./ceremonies";
|
|
3
|
-
export * from "./choice-token";
|
|
4
|
-
export type { ApiFuseConfig, BrowserConfig, ProxyConfig, SessionConfig, } from "./config/loader";
|
|
5
|
-
export { defineConfig, loadApiFuseConfig } from "./config/loader";
|
|
6
|
-
export { canonicalJson, digestProviderContract, extractProviderContract, type JsonPrimitive, type JsonValue, PROVIDER_CONTRACT_SCHEMA_VERSION, type ProviderContractOperation, type ProviderContractSnapshot, } from "./contract";
|
|
7
|
-
export { centered, delayed, defineHealthJourney, defineOperation, defineProvider, defineSmsOtpMatcher, defineStreamOperation, every, type ProviderConfig, } from "./define";
|
|
8
|
-
export type { DevServerOptions } from "./dev";
|
|
9
|
-
export { createDevServer, startDevServer } from "./dev";
|
|
10
|
-
export * from "./errors";
|
|
11
|
-
export * from "./
|
|
12
|
-
export
|
|
13
|
-
export * from "./
|
|
14
|
-
export
|
|
15
|
-
export
|
|
16
|
-
export
|
|
17
|
-
export {
|
|
18
|
-
export
|
|
19
|
-
export {
|
|
20
|
-
export { type
|
|
21
|
-
export {
|
|
22
|
-
export {
|
|
23
|
-
export {
|
|
24
|
-
export
|
|
25
|
-
export {
|
|
26
|
-
export { type
|
|
27
|
-
export {
|
|
28
|
-
export {
|
|
29
|
-
export {
|
|
30
|
-
export {
|
|
31
|
-
export {
|
|
32
|
-
export {
|
|
33
|
-
export {
|
|
34
|
-
export {
|
|
35
|
-
export {
|
|
36
|
-
export
|
|
37
|
-
export
|
|
38
|
-
export {
|
|
39
|
-
export
|
|
40
|
-
export * from "./
|
|
41
|
-
export
|
|
42
|
-
export
|
|
1
|
+
export * from "./auth.js";
|
|
2
|
+
export * from "./ceremonies/index.js";
|
|
3
|
+
export * from "./choice-token.js";
|
|
4
|
+
export type { ApiFuseConfig, BrowserConfig, ProxyConfig, ProxyProtocol, ProxyResolutionOptions, ProxyResolutionSource, ProxyVendorName, ResolvedProxyConfig, SessionConfig, } from "./config/loader.js";
|
|
5
|
+
export { defineConfig, loadApiFuseConfig, resolveProxy } from "./config/loader.js";
|
|
6
|
+
export { canonicalJson, digestProviderContract, extractProviderContract, type JsonPrimitive, type JsonValue, PROVIDER_CONTRACT_SCHEMA_VERSION, type ProviderContractOperation, type ProviderContractSnapshot, } from "./contract.js";
|
|
7
|
+
export { centered, delayed, defineHealthJourney, defineOperation, defineProvider, defineSmsOtpMatcher, defineStreamOperation, every, type ProviderConfig, } from "./define.js";
|
|
8
|
+
export type { DevServerOptions } from "./dev.js";
|
|
9
|
+
export { createDevServer, startDevServer } from "./dev.js";
|
|
10
|
+
export * from "./errors.js";
|
|
11
|
+
export * from "./observability.js";
|
|
12
|
+
export * from "./user-input.js";
|
|
13
|
+
export * from "./i18n/index.js";
|
|
14
|
+
export { type LintDiagnostic, lintOperation, lintProvider, } from "./lint.js";
|
|
15
|
+
export * from "./recipes/gov-api.js";
|
|
16
|
+
export * from "./recipes/rest-api.js";
|
|
17
|
+
export { createFlowContext, createScratchpad } from "./runtime/auth-flow.js";
|
|
18
|
+
export type { BrowserClientOptions } from "./runtime/browser.js";
|
|
19
|
+
export { BrowserClient, createBrowserClient } from "./runtime/browser.js";
|
|
20
|
+
export { createBypassProviderCache, createProviderCache, type ProviderCacheOptions, resetProviderCacheForTests, } from "./runtime/cache.js";
|
|
21
|
+
export { type CreateProviderChoiceContextOptions, createProviderChoiceContext, createTestProviderChoiceContext, PROVIDER_RUNTIME_CHOICE_TOKEN_MASTER_SECRET_ENV, } from "./runtime/choice.js";
|
|
22
|
+
export { type CreateCredentialContextOptions, createCredentialContext, } from "./runtime/credential.js";
|
|
23
|
+
export { createEnvContext } from "./runtime/env.js";
|
|
24
|
+
export { executeOperation } from "./runtime/executor.js";
|
|
25
|
+
export { createHttpClient } from "./runtime/http.js";
|
|
26
|
+
export { createNativeNetworkClient, createEnvVendorCredentialResolver, deriveNativeCredentialAffinityKey, NativeEgressGrantExpiredError, NativeEgressNotDeclaredError, NativeIdleTimeoutError, NativeNetworkError, NativeProxyExpiredError, resolveNativeGatewayProxy, type NativeGatewayProxy, type NativeGatewayProxyResolutionInput, type NativeGatewayProxySkipReason, type NativeGatewayProxySynthesizer, type NativeGatewayProxySynthesisResult, type NativeGatewayProxySynthesisInput, type NativeNetworkClientOptions, type NativeNetworkErrorCode, type VendorCredentialLookup, type VendorCredentialResolver, } from "./runtime/native-network.js";
|
|
27
|
+
export type { Insight, InsightSeverity } from "./runtime/insights.js";
|
|
28
|
+
export { generateInsights } from "./runtime/insights.js";
|
|
29
|
+
export { type InstrumentationOptions, type InstrumentedProviderContext, wrapWithInstrumentation, } from "./runtime/instrumentation.js";
|
|
30
|
+
export { type PrevalidateResult, prevalidate } from "./runtime/prevalidate.js";
|
|
31
|
+
export { getProviderBaseUrl } from "./runtime/provider.js";
|
|
32
|
+
export { assertRequiredSecretsPresent, listMissingRequiredSecrets, MISSING_SECRET_CODE, } from "./runtime/secrets.js";
|
|
33
|
+
export { createUnsupportedProviderRuntimeState, UnsupportedProviderStateError, } from "./runtime/state.js";
|
|
34
|
+
export { createStealthClient } from "./runtime/stealth.js";
|
|
35
|
+
export { APIFUSE__STT__BACKEND_ENV, APIFUSE__STT__CLOUDFLARE_API_TOKEN_ENV, APIFUSE__STT__MODEL_ENV, createSttClientFromEnv, createUnsupportedSttClient, extractVerificationCode, resolveSttPrompt, } from "./runtime/stt.js";
|
|
36
|
+
export { type CreateTraceContextOptions, createTraceContext, type Span, type TraceContext, } from "./runtime/trace.js";
|
|
37
|
+
export { APIFUSE_DESCRIPTION_KEY_META_KEY, APIFUSE_REDACTION_MARKER, APIFUSE_SENSITIVE_KIND_META_KEY, APIFUSE_SENSITIVE_META_KEY, collectSensitivePaths, describeKey, field, fields, isSensitiveSchema, redactPayload, type SensitiveFieldKind, type SensitiveFieldOptions, type SensitivePath, sensitive, z, } from "./schema.js";
|
|
38
|
+
export { createServerApp, ERROR_OBSERVABILITY_HEADER, type ServeOptions, serve, } from "./server/index.js";
|
|
39
|
+
export { getStealthProfile, listStealthProfiles } from "./stealth/profiles.js";
|
|
40
|
+
export * from "./stream.js";
|
|
41
|
+
export type { ApiFuseResponse, AuthConfig, AuthContext, AuthFlowDefinition, AuthFlowInputHandler, AuthFlowStartHandler, AuthMode, AuthTurn, Bcp47Locale, BrowserEngine, BrowserOptions, BrowserResourceBody, BrowserResourceDecision, BrowserResourceMethod, BrowserResourcePolicy, BrowserResourceRequest, BrowserResourceRoute, ConnectionMode, ContextDeclaration, CookieJar, ContextScratchpad, CredentialContext, CredentialDeclaration, E164PhoneNumber, EnvContext, FlowContext, FlowContextStore, HealthCheckAssertionContext, HealthCheckCase, HealthCheckCaseResult, HealthCheckSuite, HealthCheckUnsupported, HealthJourneyDefinition, HealthJourneyEventContext, HealthJourneyGatewayContext, HealthJourneyJournalContext, HealthJourneyManualTriggerPolicy, HealthJourneyRunContext, HealthJourneyRunResult, HealthJourneySchedule, HealthScheduleRandomization, HealthJourneySmsContext, HealthJourneyStep, HttpClient, HttpMethod, HttpRedirectFailureReason, HttpRedirectPolicy, HttpRedirectPolicyMode, HttpResponse, HttpRetryOptions, HttpRetrySummary, HttpStreamResponse, IanaTimeZone, InferSchemaOutput, Iso3166Alpha2CountryCode, Iso4217CurrencyCode, Iso8601Duration, NativeContext, NativeNetworkClient, NativeNetworkCloseReason, NativeNetworkConnection, NativeNetworkConnectInput, NativeNetworkConnectOptions, NativeNetworkDynamicGrantOptions, NativeNetworkEgressGrant, NativeProviderConfig, NativeProviderContext, NativeProxyDrainHandler, NativeProxyEgressInfo, NativeProxyExpiringEvent, NativeProxyExpiringReason, NativeTcpDynamicEgressRule, NativeTcpEgressGrant, NativeTcpEgressRule, NativeTcpPortRange, NativeTcpTlsMode, NativeTlsConnectOptions, OperationAnnotations, OperationApprovalPolicy, OperationContractMetadata, OperationDefinition, OperationDeprecationMetadata, OperationDocMeta, OperationErrorCode, ProviderErrorStatus, OperationHandlerResult, OperationInputExample, OperationLifecycle, OperationObservabilityConfig, OperationObservabilitySensitiveConfig, OperationRelationships, OperationRiskClass, OperationSensitivePath, OperationToolRouterMetadata, OperationTransport, OperationTransportKind, ProbeInterval, ProviderAccessConfig, ProviderAccessVisibility, ProviderCache, ProviderCacheGetOrSetOptions, ProviderCacheKeyOptions, ProviderCacheLookupMeta, ProviderCacheResponseMeta, ProviderCacheResult, ProviderChoiceBindingOptions, ProviderChoiceContext, ProviderChoiceIssueOptions, ProviderChoiceParseOptions, ProviderContext, ProviderDefinition, ProviderDeploymentOverrides, ProviderFileRef, ProviderFilesContext, ProviderHealthMonitorConfig, ProviderHealthProbeConfig, ProviderLocale, ProviderLocaleKey, ProviderLocaleKeyInput, ProviderLogoProfile, ProviderLogoSource, ProviderMeta, ProviderProxyConfig, ProviderProxyMode, ProviderProxyPolicy, ProxiedOAuthConfig, ProviderProxyProvider, ProviderProxySessionAffinity, ProviderPublicConnectionMode, ProviderPublicProfile, ProviderReviewed, ProviderResolvedFile, ProviderRuntimeState, ProviderSecretDeclaration, ProviderStateDurationString, ProviderStateNamespace, ProviderStreamEvent, ProviderSttConfig, ProviderSttMode, ProviderSupportLevel, RequestOptions, RedirectRunReason, Rfc3339Instant, SchemaLike, SmsOrigin, SmsOtpExtractionPattern, SmsOtpMatcherDefinition, SseMessage, StandardSchemaV1, StateCasResult, StateNamespaceOptions, StateValue, StateWriteOptions, StealthClient, StealthCookieStore, StealthCookieStoreV1, StealthFetchOptions, StealthPlatform, StealthProfile, StealthRedirectHop, StealthRedirectRunOptions, StealthRedirectRunResult, StealthResponse, StealthSession, StealthSessionCookies, SttAudioInput, SttContext, SttPromptPolicy, SttSegment, SttTranscribeMode, SttTranscribeRequest, SttTranscript, SttUnsupportedOptionPolicy, SttUsage, SttVerificationCodeOptions, SttWarning, TraceConfig, TraceSpan, VerificationCodeCandidate, VerificationCodeCandidateSource, VerificationCodeExtractionResult, } from "./types.js";
|
|
42
|
+
export { DEFAULT_OPERATION_TRANSPORT, HttpRetryAfterPolicy, HttpRetryDelayStrategy, HttpRetryJitter, HttpRetryPreset, HttpRetryUnsafeMethodPolicy, PROBE_INTERVALS, STREAM_CHUNK_BYTES_MAX, STREAM_CHUNK_BYTES_MIN, STREAM_HEARTBEAT_MS_MAX, STREAM_HEARTBEAT_MS_MIN, STREAM_IDLE_TIMEOUT_MS_MAX, STREAM_IDLE_TIMEOUT_MS_MIN, STREAM_MAX_DURATION_MS_MAX, STREAM_MAX_DURATION_MS_MIN, } from "./types.js";
|
|
43
|
+
export * from "./utils/date.js";
|
|
44
|
+
export * from "./utils/parse.js";
|
|
45
|
+
export * from "./utils/text.js";
|
|
46
|
+
export * from "./utils/transform.js";
|
package/dist/index.js
CHANGED
|
@@ -1,38 +1,42 @@
|
|
|
1
1
|
// @apifuse/provider-sdk
|
|
2
|
-
export * from "./auth";
|
|
3
|
-
export * from "./ceremonies";
|
|
4
|
-
export * from "./choice-token";
|
|
5
|
-
export { defineConfig, loadApiFuseConfig } from "./config/loader";
|
|
6
|
-
export { canonicalJson, digestProviderContract, extractProviderContract, PROVIDER_CONTRACT_SCHEMA_VERSION, } from "./contract";
|
|
7
|
-
export { centered, delayed, defineHealthJourney, defineOperation, defineProvider, defineSmsOtpMatcher, defineStreamOperation, every, } from "./define";
|
|
8
|
-
export { createDevServer, startDevServer } from "./dev";
|
|
9
|
-
export * from "./errors";
|
|
10
|
-
export * from "./
|
|
11
|
-
export
|
|
12
|
-
export * from "./
|
|
13
|
-
export
|
|
14
|
-
export
|
|
15
|
-
export
|
|
16
|
-
export {
|
|
17
|
-
export {
|
|
18
|
-
export {
|
|
19
|
-
export {
|
|
20
|
-
export {
|
|
21
|
-
export {
|
|
22
|
-
export {
|
|
23
|
-
export {
|
|
24
|
-
export {
|
|
25
|
-
export {
|
|
26
|
-
export {
|
|
27
|
-
export {
|
|
28
|
-
export {
|
|
29
|
-
export {
|
|
30
|
-
export {
|
|
31
|
-
export {
|
|
32
|
-
export {
|
|
33
|
-
export
|
|
34
|
-
export {
|
|
35
|
-
export
|
|
36
|
-
export
|
|
37
|
-
export * from "./
|
|
38
|
-
export
|
|
2
|
+
export * from "./auth.js";
|
|
3
|
+
export * from "./ceremonies/index.js";
|
|
4
|
+
export * from "./choice-token.js";
|
|
5
|
+
export { defineConfig, loadApiFuseConfig, resolveProxy } from "./config/loader.js";
|
|
6
|
+
export { canonicalJson, digestProviderContract, extractProviderContract, PROVIDER_CONTRACT_SCHEMA_VERSION, } from "./contract.js";
|
|
7
|
+
export { centered, delayed, defineHealthJourney, defineOperation, defineProvider, defineSmsOtpMatcher, defineStreamOperation, every, } from "./define.js";
|
|
8
|
+
export { createDevServer, startDevServer } from "./dev.js";
|
|
9
|
+
export * from "./errors.js";
|
|
10
|
+
export * from "./observability.js";
|
|
11
|
+
export * from "./user-input.js";
|
|
12
|
+
export * from "./i18n/index.js";
|
|
13
|
+
export { lintOperation, lintProvider, } from "./lint.js";
|
|
14
|
+
export * from "./recipes/gov-api.js";
|
|
15
|
+
export * from "./recipes/rest-api.js";
|
|
16
|
+
export { createFlowContext, createScratchpad } from "./runtime/auth-flow.js";
|
|
17
|
+
export { BrowserClient, createBrowserClient } from "./runtime/browser.js";
|
|
18
|
+
export { createBypassProviderCache, createProviderCache, resetProviderCacheForTests, } from "./runtime/cache.js";
|
|
19
|
+
export { createProviderChoiceContext, createTestProviderChoiceContext, PROVIDER_RUNTIME_CHOICE_TOKEN_MASTER_SECRET_ENV, } from "./runtime/choice.js";
|
|
20
|
+
export { createCredentialContext, } from "./runtime/credential.js";
|
|
21
|
+
export { createEnvContext } from "./runtime/env.js";
|
|
22
|
+
export { executeOperation } from "./runtime/executor.js";
|
|
23
|
+
export { createHttpClient } from "./runtime/http.js";
|
|
24
|
+
export { createNativeNetworkClient, createEnvVendorCredentialResolver, deriveNativeCredentialAffinityKey, NativeEgressGrantExpiredError, NativeEgressNotDeclaredError, NativeIdleTimeoutError, NativeNetworkError, NativeProxyExpiredError, resolveNativeGatewayProxy, } from "./runtime/native-network.js";
|
|
25
|
+
export { generateInsights } from "./runtime/insights.js";
|
|
26
|
+
export { wrapWithInstrumentation, } from "./runtime/instrumentation.js";
|
|
27
|
+
export { prevalidate } from "./runtime/prevalidate.js";
|
|
28
|
+
export { getProviderBaseUrl } from "./runtime/provider.js";
|
|
29
|
+
export { assertRequiredSecretsPresent, listMissingRequiredSecrets, MISSING_SECRET_CODE, } from "./runtime/secrets.js";
|
|
30
|
+
export { createUnsupportedProviderRuntimeState, UnsupportedProviderStateError, } from "./runtime/state.js";
|
|
31
|
+
export { createStealthClient } from "./runtime/stealth.js";
|
|
32
|
+
export { APIFUSE__STT__BACKEND_ENV, APIFUSE__STT__CLOUDFLARE_API_TOKEN_ENV, APIFUSE__STT__MODEL_ENV, createSttClientFromEnv, createUnsupportedSttClient, extractVerificationCode, resolveSttPrompt, } from "./runtime/stt.js";
|
|
33
|
+
export { createTraceContext, } from "./runtime/trace.js";
|
|
34
|
+
export { APIFUSE_DESCRIPTION_KEY_META_KEY, APIFUSE_REDACTION_MARKER, APIFUSE_SENSITIVE_KIND_META_KEY, APIFUSE_SENSITIVE_META_KEY, collectSensitivePaths, describeKey, field, fields, isSensitiveSchema, redactPayload, sensitive, z, } from "./schema.js";
|
|
35
|
+
export { createServerApp, ERROR_OBSERVABILITY_HEADER, serve, } from "./server/index.js";
|
|
36
|
+
export { getStealthProfile, listStealthProfiles } from "./stealth/profiles.js";
|
|
37
|
+
export * from "./stream.js";
|
|
38
|
+
export { DEFAULT_OPERATION_TRANSPORT, HttpRetryAfterPolicy, HttpRetryDelayStrategy, HttpRetryJitter, HttpRetryPreset, HttpRetryUnsafeMethodPolicy, PROBE_INTERVALS, STREAM_CHUNK_BYTES_MAX, STREAM_CHUNK_BYTES_MIN, STREAM_HEARTBEAT_MS_MAX, STREAM_HEARTBEAT_MS_MIN, STREAM_IDLE_TIMEOUT_MS_MAX, STREAM_IDLE_TIMEOUT_MS_MIN, STREAM_MAX_DURATION_MS_MAX, STREAM_MAX_DURATION_MS_MIN, } from "./types.js";
|
|
39
|
+
export * from "./utils/date.js";
|
|
40
|
+
export * from "./utils/parse.js";
|
|
41
|
+
export * from "./utils/text.js";
|
|
42
|
+
export * from "./utils/transform.js";
|
package/dist/lint.d.ts
CHANGED
package/dist/lint.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { lintPublicSchemaFieldNames } from "./public-schema-field-lint";
|
|
2
|
-
import { APIFUSE_DESCRIPTION_KEY_META_KEY, APIFUSE_SENSITIVE_META_KEY
|
|
1
|
+
import { lintPublicSchemaFieldNames } from "./public-schema-field-lint.js";
|
|
2
|
+
import { APIFUSE_DESCRIPTION_KEY_META_KEY, APIFUSE_SENSITIVE_META_KEY } from "./schema.js";
|
|
3
3
|
const AUTH_OPERATION_ID_PATTERN = /^(?:auth[-_])?(?:login|exchange|continue|refresh|callback)(?:[-_]|$)/i;
|
|
4
4
|
function lintAllowedHosts(providerId, allowedHosts) {
|
|
5
5
|
const prefix = providerId ? `Provider "${providerId}"` : "Provider";
|
|
@@ -120,8 +120,7 @@ function lintAuthModel(provider) {
|
|
|
120
120
|
});
|
|
121
121
|
}
|
|
122
122
|
if (hasReusableSecretKeys(credentialKeys) &&
|
|
123
|
-
(!provider.credential?.storesReusableSecret ||
|
|
124
|
-
!provider.credential.justification)) {
|
|
123
|
+
(!provider.credential?.storesReusableSecret || !provider.credential.justification)) {
|
|
125
124
|
diagnostics.push({
|
|
126
125
|
rule: "credential-reusable-secret",
|
|
127
126
|
level: "error",
|
|
@@ -131,8 +130,7 @@ function lintAuthModel(provider) {
|
|
|
131
130
|
}
|
|
132
131
|
if (typeof provider.auth?.flow?.refresh === "function" &&
|
|
133
132
|
hasReusableReloginSecretKeys(credentialKeys) &&
|
|
134
|
-
(!provider.credential?.storesReusableSecret ||
|
|
135
|
-
!provider.credential.justification)) {
|
|
133
|
+
(!provider.credential?.storesReusableSecret || !provider.credential.justification)) {
|
|
136
134
|
diagnostics.push({
|
|
137
135
|
rule: "auth-refresh-reusable-secret",
|
|
138
136
|
level: "error",
|
|
@@ -149,8 +147,7 @@ function lintAuthModel(provider) {
|
|
|
149
147
|
});
|
|
150
148
|
}
|
|
151
149
|
const authFlowSource = getAuthFlowSource(provider);
|
|
152
|
-
if (authFlowSource.includes("ctx.context") &&
|
|
153
|
-
(provider.context?.keys?.length ?? 0) === 0) {
|
|
150
|
+
if (authFlowSource.includes("ctx.context") && (provider.context?.keys?.length ?? 0) === 0) {
|
|
154
151
|
diagnostics.push({
|
|
155
152
|
rule: "context-keys-required",
|
|
156
153
|
level: "warn",
|
|
@@ -435,8 +432,7 @@ function isComplexSchema(schema, seen = new Set()) {
|
|
|
435
432
|
const childChildren = getChildSchemas(child);
|
|
436
433
|
return childChildren.length > 0;
|
|
437
434
|
});
|
|
438
|
-
return
|
|
439
|
-
children.some(({ schema: child }) => isComplexSchema(child, seen)));
|
|
435
|
+
return hasNestedComposite || children.some(({ schema: child }) => isComplexSchema(child, seen));
|
|
440
436
|
}
|
|
441
437
|
function hasBidirectionalFixtures(fixtures) {
|
|
442
438
|
if (!fixtures || typeof fixtures !== "object") {
|
|
@@ -448,9 +444,7 @@ function getOperationSource(operation) {
|
|
|
448
444
|
if (operation.source) {
|
|
449
445
|
return operation.source;
|
|
450
446
|
}
|
|
451
|
-
return typeof operation.handler === "function"
|
|
452
|
-
? operation.handler.toString()
|
|
453
|
-
: "";
|
|
447
|
+
return typeof operation.handler === "function" ? operation.handler.toString() : "";
|
|
454
448
|
}
|
|
455
449
|
function lintStealthTransportUsage(provider) {
|
|
456
450
|
if (provider.stealth || !provider.operations) {
|
|
@@ -621,8 +615,7 @@ export function lintOperation(op) {
|
|
|
621
615
|
message: "Operation whenToUse must use whenToUseKeys instead of raw static prose.",
|
|
622
616
|
});
|
|
623
617
|
}
|
|
624
|
-
if ((op.whenNotToUse?.length ?? 0) > 0 &&
|
|
625
|
-
!(op.whenNotToUseKeys?.length ?? 0)) {
|
|
618
|
+
if ((op.whenNotToUse?.length ?? 0) > 0 && !(op.whenNotToUseKeys?.length ?? 0)) {
|
|
626
619
|
diagnostics.push({
|
|
627
620
|
rule: "operation-when-not-to-use-raw-prose",
|
|
628
621
|
level: "error",
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export type EgressHostKind = "ipv4" | "ipv6" | "ipv4-mapped-ipv6" | "numeric-ambiguous" | "dns";
|
|
2
|
+
export type EgressHostCanonicalizationFailure = "not-string" | "reserved-delimiter" | "control-character" | "whitespace" | "canonicalization-empty";
|
|
3
|
+
export type EgressHostCanonicalizationResult = {
|
|
4
|
+
readonly ok: true;
|
|
5
|
+
readonly host: string;
|
|
6
|
+
} | {
|
|
7
|
+
readonly ok: false;
|
|
8
|
+
readonly reason: EgressHostCanonicalizationFailure;
|
|
9
|
+
};
|
|
10
|
+
export type Ipv6CidrOverlap = "ipv4-mapped" | "ipv4-compatible";
|
|
11
|
+
export type Ipv6CidrParseResult = {
|
|
12
|
+
readonly ok: true;
|
|
13
|
+
readonly network: Uint8Array;
|
|
14
|
+
readonly prefix: number;
|
|
15
|
+
} | {
|
|
16
|
+
readonly ok: false;
|
|
17
|
+
readonly reason: "malformed";
|
|
18
|
+
readonly overlap?: Ipv6CidrOverlap;
|
|
19
|
+
} | {
|
|
20
|
+
readonly ok: false;
|
|
21
|
+
readonly reason: "non-canonical-network";
|
|
22
|
+
};
|
|
23
|
+
export declare function parseStrictIpv4(value: string): number | undefined;
|
|
24
|
+
/** Parse the RFC 4291 IPv6 text forms accepted at both policy and runtime boundaries. */
|
|
25
|
+
export declare function parseIpv6(value: string): Uint8Array | undefined;
|
|
26
|
+
export declare function parseIpv4Cidr(value: string): {
|
|
27
|
+
readonly ok: true;
|
|
28
|
+
readonly network: number;
|
|
29
|
+
readonly prefix: number;
|
|
30
|
+
} | {
|
|
31
|
+
readonly ok: false;
|
|
32
|
+
readonly reason: "malformed" | "non-canonical-network";
|
|
33
|
+
};
|
|
34
|
+
export declare function parseIpv6Cidr(value: string): Ipv6CidrParseResult;
|
|
35
|
+
export declare function ipv4InCidr(address: number, cidr: string): boolean;
|
|
36
|
+
export declare function ipv6InCidr(address: Uint8Array, cidr: string): boolean;
|
|
37
|
+
export declare function embeddedIpv4FromIpv6(address: Uint8Array): number | undefined;
|
|
38
|
+
export declare function formatIpv6(address: Uint8Array): string;
|
|
39
|
+
/** The single family and ambiguity classifier used by policy and runtime matching. */
|
|
40
|
+
export declare function classifyEgressHost(host: string): EgressHostKind;
|
|
41
|
+
export declare function hasReservedEgressHostDelimiter(value: string): boolean;
|
|
42
|
+
export declare function hasEgressHostControlCharacter(value: string): boolean;
|
|
43
|
+
export declare function canonicalizeEgressHost(value: unknown): EgressHostCanonicalizationResult;
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import { domainToASCII } from "node:url";
|
|
2
|
+
const STRICT_IPV4_PATTERN = /^(0|[1-9]\d{0,2})\.(0|[1-9]\d{0,2})\.(0|[1-9]\d{0,2})\.(0|[1-9]\d{0,2})$/;
|
|
3
|
+
const DECIMAL_COMPONENT_PATTERN = /^\d+$/;
|
|
4
|
+
const HEX_COMPONENT_PATTERN = /^0[xX][\da-fA-F]+$/;
|
|
5
|
+
const IPV6_GROUP_PATTERN = /^[\da-fA-F]{1,4}$/;
|
|
6
|
+
const FORMAT_CONTROL_PATTERN = /\p{Cf}/u;
|
|
7
|
+
const RESERVED_EGRESS_HOST_DELIMITERS = ["/", "\\", "?", "#", "@", "[", "]", " ", "%"];
|
|
8
|
+
const IPV4_MAPPED_PREFIX = Uint8Array.of(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff);
|
|
9
|
+
const IPV4_COMPATIBLE_MIN = Uint8Array.of(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2);
|
|
10
|
+
const IPV4_COMPATIBLE_MAX = Uint8Array.of(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff);
|
|
11
|
+
export function parseStrictIpv4(value) {
|
|
12
|
+
const match = STRICT_IPV4_PATTERN.exec(value);
|
|
13
|
+
if (!match || match[0] !== value)
|
|
14
|
+
return undefined;
|
|
15
|
+
const [, first, second, third, fourth] = match;
|
|
16
|
+
if (first === undefined || second === undefined || third === undefined || fourth === undefined)
|
|
17
|
+
return undefined;
|
|
18
|
+
const octets = [Number(first), Number(second), Number(third), Number(fourth)];
|
|
19
|
+
if (octets.some((octet) => octet > 255))
|
|
20
|
+
return undefined;
|
|
21
|
+
const [a, b, c, d] = octets;
|
|
22
|
+
if (a === undefined || b === undefined || c === undefined || d === undefined)
|
|
23
|
+
return undefined;
|
|
24
|
+
return (a * 0x1000000 + b * 0x10000 + c * 0x100 + d) >>> 0;
|
|
25
|
+
}
|
|
26
|
+
function ipv4HexGroups(value) {
|
|
27
|
+
const address = parseStrictIpv4(value);
|
|
28
|
+
if (address === undefined)
|
|
29
|
+
return undefined;
|
|
30
|
+
return [((address >>> 16) & 0xffff).toString(16), (address & 0xffff).toString(16)];
|
|
31
|
+
}
|
|
32
|
+
/** Parse the RFC 4291 IPv6 text forms accepted at both policy and runtime boundaries. */
|
|
33
|
+
export function parseIpv6(value) {
|
|
34
|
+
if (!value || value.includes("%") || value.includes("[") || value.includes("]"))
|
|
35
|
+
return undefined;
|
|
36
|
+
if (value.indexOf("::") !== value.lastIndexOf("::"))
|
|
37
|
+
return undefined;
|
|
38
|
+
let text = value;
|
|
39
|
+
if (text.includes(".")) {
|
|
40
|
+
const finalColon = text.lastIndexOf(":");
|
|
41
|
+
if (finalColon < 0)
|
|
42
|
+
return undefined;
|
|
43
|
+
const groups = ipv4HexGroups(text.slice(finalColon + 1));
|
|
44
|
+
if (!groups)
|
|
45
|
+
return undefined;
|
|
46
|
+
text = `${text.slice(0, finalColon + 1)}${groups[0]}:${groups[1]}`;
|
|
47
|
+
}
|
|
48
|
+
const compression = text.indexOf("::");
|
|
49
|
+
let groups;
|
|
50
|
+
if (compression >= 0) {
|
|
51
|
+
const leftText = text.slice(0, compression);
|
|
52
|
+
const rightText = text.slice(compression + 2);
|
|
53
|
+
const left = leftText ? leftText.split(":") : [];
|
|
54
|
+
const right = rightText ? rightText.split(":") : [];
|
|
55
|
+
if (left.some((group) => !IPV6_GROUP_PATTERN.test(group)) ||
|
|
56
|
+
right.some((group) => !IPV6_GROUP_PATTERN.test(group)) ||
|
|
57
|
+
left.length + right.length >= 8)
|
|
58
|
+
return undefined;
|
|
59
|
+
groups = [...left, ...Array(8 - left.length - right.length).fill("0"), ...right];
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
groups = text.split(":");
|
|
63
|
+
if (groups.length !== 8 || groups.some((group) => !IPV6_GROUP_PATTERN.test(group)))
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
const bytes = new Uint8Array(16);
|
|
67
|
+
for (let index = 0; index < groups.length; index += 1) {
|
|
68
|
+
const group = groups[index];
|
|
69
|
+
if (group === undefined)
|
|
70
|
+
return undefined;
|
|
71
|
+
const parsed = Number.parseInt(group, 16);
|
|
72
|
+
bytes[index * 2] = parsed >>> 8;
|
|
73
|
+
bytes[index * 2 + 1] = parsed & 0xff;
|
|
74
|
+
}
|
|
75
|
+
return bytes;
|
|
76
|
+
}
|
|
77
|
+
function prefixMatches(address, network, prefix) {
|
|
78
|
+
const wholeBytes = Math.floor(prefix / 8);
|
|
79
|
+
for (let index = 0; index < wholeBytes; index += 1) {
|
|
80
|
+
if (address[index] !== network[index])
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
const remainingBits = prefix % 8;
|
|
84
|
+
if (remainingBits === 0)
|
|
85
|
+
return true;
|
|
86
|
+
const mask = (0xff << (8 - remainingBits)) & 0xff;
|
|
87
|
+
return ((address[wholeBytes] ?? 0) & mask) === ((network[wholeBytes] ?? 0) & mask);
|
|
88
|
+
}
|
|
89
|
+
function compareIpv6(left, right) {
|
|
90
|
+
for (let index = 0; index < 16; index += 1) {
|
|
91
|
+
const difference = (left[index] ?? 0) - (right[index] ?? 0);
|
|
92
|
+
if (difference !== 0)
|
|
93
|
+
return difference;
|
|
94
|
+
}
|
|
95
|
+
return 0;
|
|
96
|
+
}
|
|
97
|
+
function cidrMaximum(network, prefix) {
|
|
98
|
+
const maximum = network.slice();
|
|
99
|
+
for (let bit = prefix; bit < 128; bit += 1) {
|
|
100
|
+
const byteIndex = Math.floor(bit / 8);
|
|
101
|
+
maximum[byteIndex] = (maximum[byteIndex] ?? 0) | (1 << (7 - (bit % 8)));
|
|
102
|
+
}
|
|
103
|
+
return maximum;
|
|
104
|
+
}
|
|
105
|
+
function rangesOverlap(leftMin, leftMax, rightMin, rightMax) {
|
|
106
|
+
return compareIpv6(leftMin, rightMax) <= 0 && compareIpv6(rightMin, leftMax) <= 0;
|
|
107
|
+
}
|
|
108
|
+
function ipv6CidrOverlap(network, prefix) {
|
|
109
|
+
const maximum = cidrMaximum(network, prefix);
|
|
110
|
+
const mappedMin = new Uint8Array(16);
|
|
111
|
+
mappedMin.set(IPV4_MAPPED_PREFIX);
|
|
112
|
+
const mappedMax = mappedMin.slice();
|
|
113
|
+
mappedMax.fill(0xff, 12);
|
|
114
|
+
if (rangesOverlap(network, maximum, mappedMin, mappedMax))
|
|
115
|
+
return "ipv4-mapped";
|
|
116
|
+
if (rangesOverlap(network, maximum, IPV4_COMPATIBLE_MIN, IPV4_COMPATIBLE_MAX))
|
|
117
|
+
return "ipv4-compatible";
|
|
118
|
+
return undefined;
|
|
119
|
+
}
|
|
120
|
+
export function parseIpv4Cidr(value) {
|
|
121
|
+
const separator = value.indexOf("/");
|
|
122
|
+
if (separator <= 0 || separator !== value.lastIndexOf("/"))
|
|
123
|
+
return { ok: false, reason: "malformed" };
|
|
124
|
+
const address = parseStrictIpv4(value.slice(0, separator));
|
|
125
|
+
const prefixText = value.slice(separator + 1);
|
|
126
|
+
const prefix = Number(prefixText);
|
|
127
|
+
if (address === undefined ||
|
|
128
|
+
!Number.isInteger(prefix) ||
|
|
129
|
+
prefix < 0 ||
|
|
130
|
+
prefix > 32 ||
|
|
131
|
+
String(prefix) !== prefixText)
|
|
132
|
+
return { ok: false, reason: "malformed" };
|
|
133
|
+
const mask = prefix === 0 ? 0 : (0xffffffff << (32 - prefix)) >>> 0;
|
|
134
|
+
const network = (address & mask) >>> 0;
|
|
135
|
+
if (address !== network)
|
|
136
|
+
return { ok: false, reason: "non-canonical-network" };
|
|
137
|
+
return { ok: true, network, prefix };
|
|
138
|
+
}
|
|
139
|
+
export function parseIpv6Cidr(value) {
|
|
140
|
+
const separator = value.indexOf("/");
|
|
141
|
+
if (separator <= 0 || separator !== value.lastIndexOf("/"))
|
|
142
|
+
return { ok: false, reason: "malformed" };
|
|
143
|
+
const address = parseIpv6(value.slice(0, separator));
|
|
144
|
+
const prefixText = value.slice(separator + 1);
|
|
145
|
+
const prefix = Number(prefixText);
|
|
146
|
+
if (address === undefined ||
|
|
147
|
+
!Number.isInteger(prefix) ||
|
|
148
|
+
prefix < 0 ||
|
|
149
|
+
prefix > 128 ||
|
|
150
|
+
String(prefix) !== prefixText)
|
|
151
|
+
return { ok: false, reason: "malformed" };
|
|
152
|
+
const network = address.slice();
|
|
153
|
+
const wholeBytes = Math.floor(prefix / 8);
|
|
154
|
+
const remainingBits = prefix % 8;
|
|
155
|
+
if (remainingBits > 0) {
|
|
156
|
+
const mask = (0xff << (8 - remainingBits)) & 0xff;
|
|
157
|
+
network[wholeBytes] = (network[wholeBytes] ?? 0) & mask;
|
|
158
|
+
}
|
|
159
|
+
network.fill(0, wholeBytes + (remainingBits > 0 ? 1 : 0));
|
|
160
|
+
if (compareIpv6(address, network) !== 0)
|
|
161
|
+
return { ok: false, reason: "non-canonical-network" };
|
|
162
|
+
const overlap = ipv6CidrOverlap(network, prefix);
|
|
163
|
+
if (overlap)
|
|
164
|
+
return { ok: false, reason: "malformed", overlap };
|
|
165
|
+
return { ok: true, network, prefix };
|
|
166
|
+
}
|
|
167
|
+
export function ipv4InCidr(address, cidr) {
|
|
168
|
+
const parsed = parseIpv4Cidr(cidr);
|
|
169
|
+
if (!parsed.ok)
|
|
170
|
+
return false;
|
|
171
|
+
return (parsed.prefix === 0 ||
|
|
172
|
+
address >>> (32 - parsed.prefix) === parsed.network >>> (32 - parsed.prefix));
|
|
173
|
+
}
|
|
174
|
+
export function ipv6InCidr(address, cidr) {
|
|
175
|
+
if (address.length !== 16)
|
|
176
|
+
return false;
|
|
177
|
+
const parsed = parseIpv6Cidr(cidr);
|
|
178
|
+
return parsed.ok && prefixMatches(address, parsed.network, parsed.prefix);
|
|
179
|
+
}
|
|
180
|
+
export function embeddedIpv4FromIpv6(address) {
|
|
181
|
+
if (address.length !== 16)
|
|
182
|
+
return undefined;
|
|
183
|
+
const mapped = IPV4_MAPPED_PREFIX.every((byte, index) => address[index] === byte);
|
|
184
|
+
const compatible = address.slice(0, 12).every((byte) => byte === 0);
|
|
185
|
+
const embedded = ((address[12] ?? 0) * 0x1000000 +
|
|
186
|
+
(address[13] ?? 0) * 0x10000 +
|
|
187
|
+
(address[14] ?? 0) * 0x100 +
|
|
188
|
+
(address[15] ?? 0)) >>>
|
|
189
|
+
0;
|
|
190
|
+
if (mapped || (compatible && embedded !== 0 && embedded !== 1))
|
|
191
|
+
return embedded;
|
|
192
|
+
return undefined;
|
|
193
|
+
}
|
|
194
|
+
export function formatIpv6(address) {
|
|
195
|
+
if (address.length !== 16)
|
|
196
|
+
throw new TypeError("IPv6 addresses must contain exactly 16 bytes");
|
|
197
|
+
const groups = Array.from({ length: 8 }, (_, index) => (((address[index * 2] ?? 0) << 8) | (address[index * 2 + 1] ?? 0)).toString(16));
|
|
198
|
+
let bestStart = -1;
|
|
199
|
+
let bestLength = 0;
|
|
200
|
+
for (let index = 0; index < groups.length;) {
|
|
201
|
+
if (groups[index] !== "0") {
|
|
202
|
+
index += 1;
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
let end = index + 1;
|
|
206
|
+
while (end < groups.length && groups[end] === "0")
|
|
207
|
+
end += 1;
|
|
208
|
+
if (end - index > bestLength && end - index >= 2) {
|
|
209
|
+
bestStart = index;
|
|
210
|
+
bestLength = end - index;
|
|
211
|
+
}
|
|
212
|
+
index = end;
|
|
213
|
+
}
|
|
214
|
+
if (bestStart < 0)
|
|
215
|
+
return groups.join(":");
|
|
216
|
+
const left = groups.slice(0, bestStart).join(":");
|
|
217
|
+
const right = groups.slice(bestStart + bestLength).join(":");
|
|
218
|
+
return `${left}::${right}`;
|
|
219
|
+
}
|
|
220
|
+
/** The single family and ambiguity classifier used by policy and runtime matching. */
|
|
221
|
+
export function classifyEgressHost(host) {
|
|
222
|
+
if (hasReservedEgressHostDelimiter(host) ||
|
|
223
|
+
hasEgressHostControlCharacter(host) ||
|
|
224
|
+
/\s/u.test(host))
|
|
225
|
+
return "numeric-ambiguous";
|
|
226
|
+
if (parseStrictIpv4(host) !== undefined)
|
|
227
|
+
return "ipv4";
|
|
228
|
+
const ipv6 = parseIpv6(host);
|
|
229
|
+
if (ipv6)
|
|
230
|
+
return embeddedIpv4FromIpv6(ipv6) === undefined ? "ipv6" : "ipv4-mapped-ipv6";
|
|
231
|
+
if (host.includes(":"))
|
|
232
|
+
return "numeric-ambiguous";
|
|
233
|
+
const labels = host.split(".");
|
|
234
|
+
if (labels.every((label) => DECIMAL_COMPONENT_PATTERN.exec(label)?.[0] === label ||
|
|
235
|
+
HEX_COMPONENT_PATTERN.exec(label)?.[0] === label))
|
|
236
|
+
return "numeric-ambiguous";
|
|
237
|
+
return "dns";
|
|
238
|
+
}
|
|
239
|
+
export function hasReservedEgressHostDelimiter(value) {
|
|
240
|
+
return RESERVED_EGRESS_HOST_DELIMITERS.some((delimiter) => value.includes(delimiter));
|
|
241
|
+
}
|
|
242
|
+
export function hasEgressHostControlCharacter(value) {
|
|
243
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
244
|
+
const code = value.charCodeAt(index);
|
|
245
|
+
if (code <= 31 || code === 127)
|
|
246
|
+
return true;
|
|
247
|
+
}
|
|
248
|
+
return FORMAT_CONTROL_PATTERN.test(value);
|
|
249
|
+
}
|
|
250
|
+
export function canonicalizeEgressHost(value) {
|
|
251
|
+
if (typeof value !== "string")
|
|
252
|
+
return { ok: false, reason: "not-string" };
|
|
253
|
+
if (hasReservedEgressHostDelimiter(value))
|
|
254
|
+
return { ok: false, reason: "reserved-delimiter" };
|
|
255
|
+
if (hasEgressHostControlCharacter(value))
|
|
256
|
+
return { ok: false, reason: "control-character" };
|
|
257
|
+
if (/\s/u.test(value))
|
|
258
|
+
return { ok: false, reason: "whitespace" };
|
|
259
|
+
const raw = value.trim();
|
|
260
|
+
if (!raw)
|
|
261
|
+
return { ok: false, reason: "canonicalization-empty" };
|
|
262
|
+
const ipv6 = parseIpv6(raw);
|
|
263
|
+
if (ipv6)
|
|
264
|
+
return { ok: true, host: formatIpv6(ipv6) };
|
|
265
|
+
// Classify the spelling with one optional root-label dot removed before IDNA.
|
|
266
|
+
// This keeps resolver-numeric ASCII forms from being widened into canonical IPv4.
|
|
267
|
+
const numericCandidate = raw.endsWith(".") ? raw.slice(0, -1) : raw;
|
|
268
|
+
const normalizedNumericCandidate = numericCandidate.toLowerCase();
|
|
269
|
+
if (classifyEgressHost(normalizedNumericCandidate) === "numeric-ambiguous")
|
|
270
|
+
return { ok: true, host: normalizedNumericCandidate };
|
|
271
|
+
let ascii;
|
|
272
|
+
try {
|
|
273
|
+
ascii = domainToASCII(raw).toLowerCase().replace(/\.$/, "");
|
|
274
|
+
}
|
|
275
|
+
catch {
|
|
276
|
+
return { ok: false, reason: "canonicalization-empty" };
|
|
277
|
+
}
|
|
278
|
+
if (!ascii || /^\.+$/.test(ascii))
|
|
279
|
+
return { ok: false, reason: "canonicalization-empty" };
|
|
280
|
+
return { ok: true, host: ascii };
|
|
281
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { NativeTcpPortRange, NativeTcpTlsMode } from "./types.js";
|
|
2
|
+
export type StaticEgressRuleSnapshot = {
|
|
3
|
+
readonly host: string;
|
|
4
|
+
readonly ports: readonly number[];
|
|
5
|
+
readonly tls: NativeTcpTlsMode;
|
|
6
|
+
};
|
|
7
|
+
export type DynamicEgressRuleSnapshot = {
|
|
8
|
+
readonly sourceHost?: string;
|
|
9
|
+
readonly sourceHostSuffixes: readonly string[];
|
|
10
|
+
readonly sourceIpv4Cidrs: readonly string[];
|
|
11
|
+
readonly sourceIpv6Cidrs: readonly string[];
|
|
12
|
+
readonly sourcePorts: readonly number[];
|
|
13
|
+
readonly sourcePortRanges: readonly NativeTcpPortRange[];
|
|
14
|
+
readonly targetHostSuffixes: readonly string[];
|
|
15
|
+
readonly targetIpv4Cidrs: readonly string[];
|
|
16
|
+
readonly targetIpv6Cidrs: readonly string[];
|
|
17
|
+
readonly targetPorts: readonly number[];
|
|
18
|
+
readonly targetPortRanges: readonly NativeTcpPortRange[];
|
|
19
|
+
readonly tls: NativeTcpTlsMode;
|
|
20
|
+
readonly ttlMs?: number;
|
|
21
|
+
readonly maxGrants?: number;
|
|
22
|
+
};
|
|
23
|
+
export type NativeEgressPolicySnapshot = {
|
|
24
|
+
readonly staticRules: readonly StaticEgressRuleSnapshot[];
|
|
25
|
+
readonly dynamicRules: readonly DynamicEgressRuleSnapshot[];
|
|
26
|
+
};
|
|
27
|
+
export declare class NativeEgressPolicyValidationError extends Error {
|
|
28
|
+
constructor(message: string);
|
|
29
|
+
}
|
|
30
|
+
export declare function parseNativeEgressPolicy(value: unknown): NativeEgressPolicySnapshot;
|
|
31
|
+
export declare function validateNativeProviderConfig(value: unknown): void;
|