@apifuse/provider-sdk 2.2.0-beta.58 → 2.2.0-beta.60

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.
Files changed (150) hide show
  1. package/AUTHORING.md +25 -0
  2. package/CHANGELOG.md +8 -0
  3. package/README.md +18 -2
  4. package/bin/apifuse-dev.ts +2 -1
  5. package/bin/apifuse-pack-types.ts +49 -0
  6. package/bin/apifuse-perf.ts +41 -4
  7. package/bin/apifuse-record.ts +9 -2
  8. package/dist/cli/templates/provider/README.md.tpl +15 -3
  9. package/dist/config/loader.d.ts +7 -0
  10. package/dist/config/loader.js +43 -18
  11. package/dist/declaration-validation.d.ts +2 -1
  12. package/dist/declaration-validation.js +39 -0
  13. package/dist/define.d.ts +4 -4
  14. package/dist/define.js +25 -1
  15. package/dist/engine.d.ts +16 -0
  16. package/dist/engine.js +59 -3
  17. package/dist/error-resolution.js +13 -0
  18. package/dist/index.d.ts +7 -4
  19. package/dist/index.js +4 -2
  20. package/dist/lint.js +38 -17
  21. package/dist/provider.d.ts +3 -3
  22. package/dist/provider.js +2 -2
  23. package/dist/runtime/bounded-expiring-map.d.ts +21 -0
  24. package/dist/runtime/bounded-expiring-map.js +64 -0
  25. package/dist/runtime/browser.js +2 -1
  26. package/dist/runtime/cache.d.ts +2 -0
  27. package/dist/runtime/cache.js +11 -3
  28. package/dist/runtime/diagnostic-env-values.d.ts +5 -0
  29. package/dist/runtime/diagnostic-env-values.js +57 -0
  30. package/dist/runtime/diagnostic-env.d.ts +11 -0
  31. package/dist/runtime/diagnostic-env.js +35 -0
  32. package/dist/runtime/diagnostic-redactor.d.ts +49 -0
  33. package/dist/runtime/diagnostic-redactor.js +569 -0
  34. package/dist/runtime/egress-lease.d.ts +65 -0
  35. package/dist/runtime/egress-lease.js +236 -0
  36. package/dist/runtime/env.js +2 -1
  37. package/dist/runtime/http.js +1 -0
  38. package/dist/runtime/instrumentation.js +3 -0
  39. package/dist/runtime/ocr.js +2 -1
  40. package/dist/runtime/otlp.js +5 -4
  41. package/dist/runtime/proxy-nodemaven.js +3 -2
  42. package/dist/runtime/proxy-retry-policy.d.ts +4 -1
  43. package/dist/runtime/proxy-retry-policy.js +11 -2
  44. package/dist/runtime/request-options.d.ts +7 -0
  45. package/dist/runtime/request-options.js +62 -22
  46. package/dist/runtime/request-telemetry.d.ts +7 -9
  47. package/dist/runtime/resolver-config.d.ts +7 -0
  48. package/dist/runtime/resolver-config.js +8 -0
  49. package/dist/runtime/resolver-public.d.ts +3 -1
  50. package/dist/runtime/resolver-public.js +1 -1
  51. package/dist/runtime/resolver-shared.d.ts +9 -0
  52. package/dist/runtime/resolver-shared.js +57 -0
  53. package/dist/runtime/resolver-telemetry.d.ts +134 -0
  54. package/dist/runtime/resolver-telemetry.js +204 -0
  55. package/dist/runtime/resolver-usage.d.ts +24 -0
  56. package/dist/runtime/resolver-usage.js +60 -0
  57. package/dist/runtime/resolver-vendors/bindings.d.ts +5 -0
  58. package/dist/runtime/resolver-vendors/bindings.js +5 -0
  59. package/dist/runtime/resolver-vendors/browser.js +0 -1
  60. package/dist/runtime/resolver-vendors/capsolver.d.ts +2 -2
  61. package/dist/runtime/resolver-vendors/capsolver.js +21 -9
  62. package/dist/runtime/resolver-vendors/hypersolutions.d.ts +27 -0
  63. package/dist/runtime/resolver-vendors/hypersolutions.js +369 -0
  64. package/dist/runtime/resolver-vendors/twocaptcha.d.ts +2 -2
  65. package/dist/runtime/resolver-vendors/twocaptcha.js +26 -10
  66. package/dist/runtime/resolver-vendors/types.d.ts +35 -5
  67. package/dist/runtime/resolver-vendors/types.js +20 -10
  68. package/dist/runtime/resolver.d.ts +5 -1
  69. package/dist/runtime/resolver.js +400 -111
  70. package/dist/runtime/stealth-akamai-sbsd.d.ts +54 -0
  71. package/dist/runtime/stealth-akamai-sbsd.js +142 -0
  72. package/dist/runtime/stealth.js +547 -53
  73. package/dist/runtime/stt.js +3 -2
  74. package/dist/runtime/trace.d.ts +5 -0
  75. package/dist/runtime/trace.js +115 -20
  76. package/dist/schema.d.ts +20 -0
  77. package/dist/schema.js +72 -2
  78. package/dist/server/index.d.ts +2 -0
  79. package/dist/server/index.js +1 -0
  80. package/dist/server/self-test-redaction.js +8 -33
  81. package/dist/server/self-test.d.ts +4 -0
  82. package/dist/server/self-test.js +10 -1
  83. package/dist/server/sensitive-values.d.ts +26 -0
  84. package/dist/server/sensitive-values.js +131 -0
  85. package/dist/server/serve-implementation.d.ts +7 -1
  86. package/dist/server/serve-implementation.js +394 -125
  87. package/dist/server/trace-output.d.ts +2 -1
  88. package/dist/server/trace-output.js +46 -14
  89. package/dist/server/types.d.ts +6 -0
  90. package/dist/server/types.js +14 -0
  91. package/dist/stealth/profiles.d.ts +7 -1
  92. package/dist/stealth/profiles.js +9 -0
  93. package/dist/testing/run.js +6 -0
  94. package/dist/trace-sanitization.d.ts +4 -3
  95. package/dist/trace-sanitization.js +45 -22
  96. package/dist/types.d.ts +106 -10
  97. package/package.json +2 -1
  98. package/src/cli/templates/provider/README.md.tpl +15 -3
  99. package/src/config/loader.ts +47 -18
  100. package/src/declaration-validation.ts +47 -1
  101. package/src/define.ts +45 -3
  102. package/src/engine.ts +78 -3
  103. package/src/error-resolution.ts +13 -0
  104. package/src/index.ts +34 -1
  105. package/src/lint.ts +44 -18
  106. package/src/provider.ts +10 -0
  107. package/src/runtime/bounded-expiring-map.ts +67 -0
  108. package/src/runtime/browser.ts +2 -1
  109. package/src/runtime/cache.ts +13 -3
  110. package/src/runtime/diagnostic-env-values.ts +56 -0
  111. package/src/runtime/diagnostic-env.ts +55 -0
  112. package/src/runtime/diagnostic-redactor.ts +662 -0
  113. package/src/runtime/egress-lease.ts +341 -0
  114. package/src/runtime/env.ts +2 -1
  115. package/src/runtime/http.ts +1 -0
  116. package/src/runtime/instrumentation.ts +3 -0
  117. package/src/runtime/ocr.ts +2 -1
  118. package/src/runtime/otlp.ts +5 -4
  119. package/src/runtime/proxy-nodemaven.ts +3 -2
  120. package/src/runtime/proxy-retry-policy.ts +12 -1
  121. package/src/runtime/request-options.ts +76 -28
  122. package/src/runtime/request-telemetry.ts +5 -7
  123. package/src/runtime/resolver-config.ts +12 -0
  124. package/src/runtime/resolver-public.ts +21 -0
  125. package/src/runtime/resolver-shared.ts +75 -0
  126. package/src/runtime/resolver-telemetry.ts +362 -0
  127. package/src/runtime/resolver-usage.ts +96 -0
  128. package/src/runtime/resolver-vendors/bindings.ts +5 -0
  129. package/src/runtime/resolver-vendors/browser.ts +0 -1
  130. package/src/runtime/resolver-vendors/capsolver.ts +22 -3
  131. package/src/runtime/resolver-vendors/hypersolutions.ts +480 -0
  132. package/src/runtime/resolver-vendors/twocaptcha.ts +26 -12
  133. package/src/runtime/resolver-vendors/types.ts +60 -12
  134. package/src/runtime/resolver.ts +468 -126
  135. package/src/runtime/stealth-akamai-sbsd.ts +207 -0
  136. package/src/runtime/stealth.ts +727 -95
  137. package/src/runtime/stt.ts +3 -2
  138. package/src/runtime/trace.ts +168 -26
  139. package/src/schema.ts +80 -2
  140. package/src/server/index.ts +21 -0
  141. package/src/server/self-test-redaction.ts +10 -40
  142. package/src/server/self-test.ts +13 -0
  143. package/src/server/sensitive-values.ts +200 -0
  144. package/src/server/serve-implementation.ts +561 -136
  145. package/src/server/trace-output.ts +77 -17
  146. package/src/server/types.ts +14 -0
  147. package/src/stealth/profiles.ts +10 -0
  148. package/src/testing/run.ts +6 -0
  149. package/src/trace-sanitization.ts +70 -23
  150. package/src/types.ts +124 -19
package/dist/define.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { AuthConfig, BrowserEngine, ContextDeclaration, CredentialDeclaration, HealthJourneyDefinition, HealthJourneySchedule, HealthScheduleRandomization, InferSchemaOutput, NativeProviderConfig, OperationDefinition, OperationHandlerResult, OperationHttpStreamTransport, OperationSseTransport, OperationWebSocketTransport, ProviderAccessConfig, ProviderContext, ProviderDefinition, ProviderDeploymentOverrides, ProviderHealthMonitorConfig, ProviderOcrConfig, ProviderProxyConfig, ProviderPublicProfile, ProviderResolverConfig, ProviderReviewed, ProviderRuntimeTarget, ProviderSecretDeclaration, ProviderStreamEvent, ProviderSttConfig, SchemaLike, SmsOtpMatcherDefinition, StealthProfileSelection } from "./types.js";
1
+ import type { AuthConfig, BrowserEngine, ContextDeclaration, CredentialDeclaration, HealthJourneyDefinition, HealthJourneySchedule, HealthScheduleRandomization, InferSchemaOutput, NativeProviderConfig, OperationDefinition, OperationHandlerResult, OperationHttpStreamTransport, OperationSseTransport, OperationWebSocketTransport, ProviderAccessConfig, ProviderContext, ProviderDefinition, ProviderDeploymentOverrides, ProviderHealthMonitorConfig, ProviderOcrConfig, ProviderProxyConfig, ProviderPublicProfile, ProviderResolverConfig, ProviderReviewed, ProviderRuntimeTarget, ProviderSecretDeclaration, ProviderStreamEvent, ProviderSttConfig, ProviderStealthConfig, SchemaLike, SmsOtpMatcherDefinition } from "./types.js";
2
2
  type ProviderImplementationSourceAccess = "official_api" | "private_api" | "browser_flow" | "hybrid";
3
3
  type ProviderImplementationCredentialStrategy = "apifuse_managed" | "workspace_secret" | "user_oauth" | "user_session" | "none";
4
4
  interface ProviderImplementationProfile {
@@ -8,8 +8,8 @@ interface ProviderImplementationProfile {
8
8
  operatorNotes?: string;
9
9
  visibility: "internal" | "operator";
10
10
  }
11
- export declare const VALID_PROVIDER_RESOLVER_VENDORS: readonly ["browser", "capsolver", "capmonster", "2captcha", "custom"];
12
- export declare const VALID_PROVIDER_CHALLENGE_KINDS: readonly ["turnstile", "recaptcha_v2", "recaptcha_v3", "hcaptcha", "cloudflare_interstitial", "aws_waf", "akamai_sec_cpt", "akamai_sensor"];
11
+ export declare const VALID_PROVIDER_RESOLVER_VENDORS: readonly ["browser", "capsolver", "capmonster", "2captcha", "hypersolutions", "custom"];
12
+ export declare const VALID_PROVIDER_CHALLENGE_KINDS: readonly ["turnstile", "recaptcha_v2", "recaptcha_v3", "hcaptcha", "cloudflare_interstitial", "aws_waf", "akamai_sec_cpt", "akamai_sensor", "akamai_sbsd"];
13
13
  type ProviderOperation = OperationDefinition<any, any, any>;
14
14
  type OperationConfig<TInput extends SchemaLike, TOutput extends SchemaLike, TContext = ProviderContext> = Omit<OperationDefinition<TInput, TOutput, TContext>, "handler"> & {
15
15
  handler(ctx: TContext, input: InferSchemaOutput<TInput>): OperationHandlerResult<InferSchemaOutput<TOutput>> | Promise<OperationHandlerResult<InferSchemaOutput<TOutput>>>;
@@ -60,7 +60,7 @@ export interface ProviderDeclaration {
60
60
  /** Declares upstream host policy; this does not add a `ctx.allowedHosts` member. */
61
61
  allowedHosts?: string[];
62
62
  native?: NativeProviderConfig;
63
- stealth?: StealthProfileSelection;
63
+ stealth?: ProviderStealthConfig;
64
64
  /** Declares proxy policy; this is provider intent and does not add a `ctx.proxy` member. */
65
65
  proxy?: ProviderProxyConfig;
66
66
  ocr?: ProviderOcrConfig;
package/dist/define.js CHANGED
@@ -2,8 +2,9 @@ import ms from "ms";
2
2
  import { validateFailClosedOperationDeclaration, validateFailClosedProviderDeclaration, } from "./declaration-validation.js";
3
3
  import { SDK_RUNTIME_OWNED_ERROR_CODES } from "./error-resolution.js";
4
4
  import { ProviderError, ValidationError } from "./errors.js";
5
- import { isEngineOwnedProxyCredentialName, isEngineOwnedTelemetryEnvName } from "./engine.js";
5
+ import { engineOwnedResolverCredentialTarget, isEngineOwnedEnvName, isEngineOwnedProxyCredentialName, isEngineOwnedRuntimeEnvName, isEngineOwnedTelemetryEnvName, } from "./engine.js";
6
6
  import { HealthScenarioSchema } from "./health-scenario.js";
7
+ import { kindRequiresClientProfile } from "./runtime/resolver-config.js";
7
8
  import { NativeEgressPolicyValidationError, validateNativeProviderConfig, } from "./native-egress-policy.js";
8
9
  import { safeParseSchemaSync } from "./schema.js";
9
10
  import { resolveHealthCheckInputDateTokens } from "./server/self-test-input-tokens.js";
@@ -61,6 +62,7 @@ export const VALID_PROVIDER_RESOLVER_VENDORS = exhaustiveLiteralArray()([
61
62
  "capsolver",
62
63
  "capmonster",
63
64
  "2captcha",
65
+ "hypersolutions",
64
66
  "custom",
65
67
  ]);
66
68
  export const VALID_PROVIDER_CHALLENGE_KINDS = exhaustiveLiteralArray()([
@@ -72,6 +74,7 @@ export const VALID_PROVIDER_CHALLENGE_KINDS = exhaustiveLiteralArray()([
72
74
  "aws_waf",
73
75
  "akamai_sec_cpt",
74
76
  "akamai_sensor",
77
+ "akamai_sbsd",
75
78
  ]);
76
79
  const RESERVED_OPERATION_IDS = new Set(["auth", "health"]);
77
80
  const VALID_OPERATION_RISK_CLASSES = ["read", "write", "destructive", "external-send"];
@@ -633,11 +636,27 @@ function validateProviderImplementationShape(config) {
633
636
  }
634
637
  function validateProviderProxy(config) {
635
638
  for (const secret of config.secrets ?? []) {
639
+ const engineName = engineOwnedResolverCredentialTarget(secret.name);
640
+ if (engineName !== undefined) {
641
+ throw new ValidationError(`Provider "${config.id}" cannot declare engine-owned resolver credential "${secret.name}"`, {
642
+ fix: `Remove "${secret.name}" from provider secrets; configure the solver key only on the provider engine as ${engineName}.`,
643
+ });
644
+ }
636
645
  if (isEngineOwnedTelemetryEnvName(secret.name)) {
637
646
  throw new ValidationError(`Provider "${config.id}" cannot declare engine-owned telemetry variable "${secret.name}"`, {
638
647
  fix: `Remove "${secret.name}" from provider secrets; trace export is configured only on the provider engine.`,
639
648
  });
640
649
  }
650
+ if (isEngineOwnedRuntimeEnvName(secret.name)) {
651
+ throw new ValidationError(`Provider "${config.id}" cannot declare engine-owned runtime variable "${secret.name}"`, {
652
+ fix: `Remove "${secret.name}" from provider secrets; the provider engine reads it from its own environment.`,
653
+ });
654
+ }
655
+ if (isEngineOwnedEnvName(secret.name) && !isEngineOwnedProxyCredentialName(secret.name)) {
656
+ throw new ValidationError(`Provider "${config.id}" cannot declare engine-owned control variable "${secret.name}"`, {
657
+ fix: `Remove "${secret.name}" from provider secrets; configure it only on the provider engine.`,
658
+ });
659
+ }
641
660
  if (!isEngineOwnedProxyCredentialName(secret.name))
642
661
  continue;
643
662
  throw new ValidationError(`Provider "${config.id}" cannot declare engine-owned proxy credential "${secret.name}"`, {
@@ -785,6 +804,11 @@ function validateProviderResolver(config) {
785
804
  fix: `Set resolver.clientProfile for provider "${config.id}" to a transport-owned profile name.`,
786
805
  });
787
806
  }
807
+ if (resolver.kinds.some(kindRequiresClientProfile) && resolver.clientProfile === undefined) {
808
+ throw new ValidationError(`Provider "${config.id}" must declare resolver.clientProfile for akamai_sbsd.`, {
809
+ fix: `Set resolver.clientProfile for provider "${config.id}" to the transport-owned profile used by its Akamai session.`,
810
+ });
811
+ }
788
812
  }
789
813
  function validateResolverLiteralArray(value, field, validValues, providerId) {
790
814
  if (!Array.isArray(value)) {
package/dist/engine.d.ts CHANGED
@@ -4,6 +4,15 @@ export declare const PROVIDER_ENGINE_PROTOCOL_VERSION: "provider-engine.v1";
4
4
  /** Credential names owned by the engine and forbidden in provider declarations. */
5
5
  export declare const ENGINE_OWNED_PROXY_CREDENTIAL_ENV_NAMES: readonly ["APIFUSE__PROXY__SMARTPROXY_APP_KEY", "APIFUSE__PROXY__NODEMAVEN_USERNAME", "APIFUSE__PROXY__NODEMAVEN_PASSWORD"];
6
6
  export declare function isEngineOwnedProxyCredentialName(name: string): boolean;
7
+ /** Hosted resolver credentials owned by the engine and never projected to providers. */
8
+ export declare const ENGINE_OWNED_RESOLVER_CREDENTIAL_ENV_NAMES: readonly ["APIFUSE__RESOLVER__2CAPTCHA__API_KEY", "APIFUSE__RESOLVER__CAPSOLVER__API_KEY", "APIFUSE__RESOLVER__CAPMONSTER__API_KEY", "APIFUSE__RESOLVER__HYPERSOLUTIONS__API_KEY"];
9
+ /**
10
+ * Engine variable a provider-declared secret name resolves to, or `undefined` when the
11
+ * name is not an engine-owned resolver credential. Provider-scoped Hyper aliases
12
+ * (`APIFUSE__PROVIDER__<ID>__HYPER_API_KEY`, measured on zozotown) map to the shared key.
13
+ */
14
+ export declare function engineOwnedResolverCredentialTarget(name: string): string | undefined;
15
+ export declare function isEngineOwnedResolverCredentialName(name: string): boolean;
7
16
  /**
8
17
  * Trace-export configuration owned by the engine and forbidden in provider
9
18
  * declarations. The header variables carry collector credentials; the rest are
@@ -11,6 +20,13 @@ export declare function isEngineOwnedProxyCredentialName(name: string): boolean;
11
20
  */
12
21
  export declare const ENGINE_OWNED_TELEMETRY_ENV_NAMES: readonly ["OTEL_EXPORTER_OTLP_TRACES_ENDPOINT", "OTEL_EXPORTER_OTLP_ENDPOINT", "OTEL_EXPORTER_OTLP_TRACES_HEADERS", "OTEL_EXPORTER_OTLP_HEADERS", "OTEL_SERVICE_NAME", "OTEL_RESOURCE_ATTRIBUTES"];
13
22
  export declare function isEngineOwnedTelemetryEnvName(name: string): boolean;
23
+ /**
24
+ * Hosted runtime settings the engine reads for OCR, STT, cache keying, choice
25
+ * tokens, and the CDP pool. Providers never own them: declarations are rejected
26
+ * and projections drop them, like the vendor credentials above.
27
+ */
28
+ export declare const ENGINE_OWNED_RUNTIME_ENV_NAMES: readonly ["APIFUSE__STT__CLOUDFLARE_API_TOKEN", "APIFUSE__OCR__CLOUDFLARE_API_TOKEN", "APIFUSE__OCR__API_KEY", "APIFUSE__CLOUDFLARE__ACCOUNT_ID", "APIFUSE__CACHE__KEY_PEPPER", "APIFUSE__PROVIDER_RUNTIME__CHOICE_TOKEN_MASTER_SECRET"];
29
+ export declare function isEngineOwnedRuntimeEnvName(name: string): boolean;
14
30
  /** Every environment name the engine owns: rejected in declarations and filtered from provider projections. */
15
31
  export declare function isEngineOwnedEnvName(name: string): boolean;
16
32
  /** Capture credentials in the engine host before constructing provider bindings. */
package/dist/engine.js CHANGED
@@ -1,4 +1,6 @@
1
+ import { readDiagnosticEnv } from "./runtime/diagnostic-env.js";
1
2
  import { ProviderError } from "./errors.js";
3
+ import { APIFUSE__RESOLVER__2CAPTCHA__API_KEY, APIFUSE__RESOLVER__CAPMONSTER__API_KEY, APIFUSE__RESOLVER__CAPSOLVER__API_KEY, APIFUSE__RESOLVER__HYPERSOLUTIONS__API_KEY, } from "./runtime/resolver-config.js";
2
4
  import { OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_HEADERS, OTEL_EXPORTER_OTLP_TRACES_ENDPOINT, OTEL_EXPORTER_OTLP_TRACES_HEADERS, OTEL_RESOURCE_ATTRIBUTES, OTEL_SERVICE_NAME, } from "./runtime/otlp.js";
3
5
  /** Versioned envelope protocol used by out-of-process engine transports. */
4
6
  export const PROVIDER_ENGINE_PROTOCOL_VERSION = "provider-engine.v1";
@@ -20,6 +22,31 @@ function canonicalEnvName(name) {
20
22
  export function isEngineOwnedProxyCredentialName(name) {
21
23
  return ENGINE_OWNED_PROXY_CREDENTIAL_ENV_NAME_SET.has(canonicalEnvName(name));
22
24
  }
25
+ /** Hosted resolver credentials owned by the engine and never projected to providers. */
26
+ export const ENGINE_OWNED_RESOLVER_CREDENTIAL_ENV_NAMES = [
27
+ APIFUSE__RESOLVER__2CAPTCHA__API_KEY,
28
+ APIFUSE__RESOLVER__CAPSOLVER__API_KEY,
29
+ APIFUSE__RESOLVER__CAPMONSTER__API_KEY,
30
+ APIFUSE__RESOLVER__HYPERSOLUTIONS__API_KEY,
31
+ ];
32
+ const ENGINE_OWNED_RESOLVER_CREDENTIAL_ENV_NAME_SET = new Set(ENGINE_OWNED_RESOLVER_CREDENTIAL_ENV_NAMES);
33
+ /**
34
+ * Engine variable a provider-declared secret name resolves to, or `undefined` when the
35
+ * name is not an engine-owned resolver credential. Provider-scoped Hyper aliases
36
+ * (`APIFUSE__PROVIDER__<ID>__HYPER_API_KEY`, measured on zozotown) map to the shared key.
37
+ */
38
+ export function engineOwnedResolverCredentialTarget(name) {
39
+ const canonical = canonicalEnvName(name);
40
+ if (ENGINE_OWNED_RESOLVER_CREDENTIAL_ENV_NAME_SET.has(canonical))
41
+ return canonical;
42
+ if (/^APIFUSE__PROVIDER__.+__HYPER_API_KEY$/u.test(canonical)) {
43
+ return APIFUSE__RESOLVER__HYPERSOLUTIONS__API_KEY;
44
+ }
45
+ return undefined;
46
+ }
47
+ export function isEngineOwnedResolverCredentialName(name) {
48
+ return engineOwnedResolverCredentialTarget(name) !== undefined;
49
+ }
23
50
  /**
24
51
  * Trace-export configuration owned by the engine and forbidden in provider
25
52
  * declarations. The header variables carry collector credentials; the rest are
@@ -37,14 +64,43 @@ const ENGINE_OWNED_TELEMETRY_ENV_NAME_SET = new Set(ENGINE_OWNED_TELEMETRY_ENV_N
37
64
  export function isEngineOwnedTelemetryEnvName(name) {
38
65
  return ENGINE_OWNED_TELEMETRY_ENV_NAME_SET.has(canonicalEnvName(name));
39
66
  }
67
+ /** Engine control-plane configuration is never declarable or visible to provider code. */
68
+ function isEngineOwnedEngineEnvName(name) {
69
+ return canonicalEnvName(name).startsWith("APIFUSE__ENGINE__");
70
+ }
71
+ /**
72
+ * Hosted runtime settings the engine reads for OCR, STT, cache keying, choice
73
+ * tokens, and the CDP pool. Providers never own them: declarations are rejected
74
+ * and projections drop them, like the vendor credentials above.
75
+ */
76
+ export const ENGINE_OWNED_RUNTIME_ENV_NAMES = [
77
+ "APIFUSE__STT__CLOUDFLARE_API_TOKEN",
78
+ "APIFUSE__OCR__CLOUDFLARE_API_TOKEN",
79
+ "APIFUSE__OCR__API_KEY",
80
+ "APIFUSE__CLOUDFLARE__ACCOUNT_ID",
81
+ "APIFUSE__CACHE__KEY_PEPPER",
82
+ "APIFUSE__PROVIDER_RUNTIME__CHOICE_TOKEN_MASTER_SECRET",
83
+ ];
84
+ const ENGINE_OWNED_RUNTIME_ENV_NAME_SET = new Set(ENGINE_OWNED_RUNTIME_ENV_NAMES);
85
+ /** CDP pool settings form a prefix family (`APIFUSE__CDP_POOL__URL` today); the whole prefix is engine-owned. */
86
+ const ENGINE_OWNED_CDP_POOL_ENV_PREFIX = "APIFUSE__CDP_POOL__";
87
+ export function isEngineOwnedRuntimeEnvName(name) {
88
+ const canonical = canonicalEnvName(name);
89
+ return (ENGINE_OWNED_RUNTIME_ENV_NAME_SET.has(canonical) ||
90
+ canonical.startsWith(ENGINE_OWNED_CDP_POOL_ENV_PREFIX));
91
+ }
40
92
  /** Every environment name the engine owns: rejected in declarations and filtered from provider projections. */
41
93
  export function isEngineOwnedEnvName(name) {
42
- return isEngineOwnedProxyCredentialName(name) || isEngineOwnedTelemetryEnvName(name);
94
+ return (isEngineOwnedEngineEnvName(name) ||
95
+ isEngineOwnedProxyCredentialName(name) ||
96
+ isEngineOwnedResolverCredentialName(name) ||
97
+ isEngineOwnedRuntimeEnvName(name) ||
98
+ isEngineOwnedTelemetryEnvName(name));
43
99
  }
44
100
  /** Capture credentials in the engine host before constructing provider bindings. */
45
101
  export function readEngineProxyCredentials(environment = process.env) {
46
102
  return Object.fromEntries(ENGINE_OWNED_PROXY_CREDENTIAL_ENV_NAMES.flatMap((name) => {
47
- const value = environment[name]?.trim();
103
+ const value = readDiagnosticEnv(name, environment)?.trim();
48
104
  return value ? [[name, value]] : [];
49
105
  }));
50
106
  }
@@ -53,7 +109,7 @@ export function createProviderEnvironment(environment, declaredNames) {
53
109
  return Object.fromEntries(declaredNames.flatMap((name) => {
54
110
  if (isEngineOwnedEnvName(name))
55
111
  return [];
56
- const value = environment[name];
112
+ const value = readDiagnosticEnv(name, environment);
57
113
  return value === undefined ? [] : [[name, value]];
58
114
  }));
59
115
  }
@@ -8,6 +8,7 @@ export const SDK_OWNED_PROVIDER_ERROR_CODES = new Set([
8
8
  "BROWSER_CDP_POOL_REQUIRED",
9
9
  "BROWSER_RUNTIME_UNSUPPORTED",
10
10
  "STEALTH_RUNTIME_UNSUPPORTED",
11
+ "STEALTH_HEADER_OVERRIDE_UNSUPPORTED",
11
12
  "SSE_EVENT_UNDECLARED",
12
13
  "STREAM_EVENT_TOO_LARGE",
13
14
  "STREAM_CHUNK_TOO_LARGE",
@@ -49,6 +50,13 @@ export const SDK_OWNED_PROVIDER_ERROR_CODES = new Set([
49
50
  "http_redirect_missing_location",
50
51
  "http_redirect_loop",
51
52
  "transport_invalid_url",
53
+ "EGRESS_LEASE_INVALID",
54
+ "EGRESS_LEASE_BINDING_INVALID",
55
+ "EGRESS_LEASE_KEY_MISSING",
56
+ "EGRESS_LEASE_KEY_WEAK",
57
+ "STEALTH_BODY_UNSUPPORTED",
58
+ "REPLAY_SESSION_MISMATCH",
59
+ "REPLAY_ALREADY_ATTEMPTED",
52
60
  "retry_exhausted",
53
61
  "auth_abort_unsafe_data",
54
62
  "credentials_auth_missing_credential_keys",
@@ -112,6 +120,11 @@ export const SDK_STATUS_MAPPED_PROVIDER_ERROR_CODES = new Map([
112
120
  // contract): the upstream evaluated the request and said no under its
113
121
  // own rules — a conflict with upstream state, never a 5xx.
114
122
  ["UPSTREAM_REJECTED", 409],
123
+ // Only an unverifiable or foreign handle is the caller's: key and binding
124
+ // faults stay unmapped (500) because the engine host, not the caller, owns them.
125
+ ["EGRESS_LEASE_INVALID", 409],
126
+ ["REPLAY_SESSION_MISMATCH", 409],
127
+ ["REPLAY_ALREADY_ATTEMPTED", 409],
115
128
  ["UPSTREAM_ERROR", 502],
116
129
  ["BLOCKED", 502],
117
130
  ["OCR_UNAVAILABLE", 503],
package/dist/index.d.ts CHANGED
@@ -34,20 +34,23 @@ export type { PrevalidateResult } from "./runtime/prevalidate.js";
34
34
  export { getProviderBaseUrl } from "./runtime/provider.js";
35
35
  export type { ProxyTelemetryHeaderPayload, ProxyHash, ProxyTelemetryLogPayload, ProxyTelemetryResolvedPayload, ProxyTelemetryUnresolvedPayload, } from "./runtime/proxy-telemetry.js";
36
36
  export { RequestTelemetry, closedEnum, type ClosedEnum, type GatewayIngestible, type RequestTelemetryLogPayload, type SpanIndex, type TelemetryContributor, type TelemetryKey, type TenantNeutral, } from "./runtime/request-telemetry.js";
37
- export { APIFUSE__CDP_POOL__URL, APIFUSE__RESOLVER__2CAPTCHA__API_KEY, APIFUSE__RESOLVER__CAPMONSTER__API_KEY, APIFUSE__RESOLVER__CAPSOLVER__API_KEY, APIFUSE__RESOLVER__TIMEOUT_MS, DEFAULT_RESOLVER_TIMEOUT_MS, } from "./runtime/resolver-config.js";
37
+ export { APIFUSE__ENGINE__CEREMONY_LEASE_KEY } from "./runtime/egress-lease.js";
38
+ export { ResolverTelemetryCollector, type ResolverCacheReadTelemetryEvent, type ResolverCacheWriteTelemetryEvent, type ResolverFailoverTelemetryEvent, type ResolverIdentityTelemetryEvent, type ResolverOutcomeTelemetryEvent, type ResolverTelemetryAttemptOutcome, type ResolverAttemptSample, type ResolverTelemetryCacheStatus, type ResolverTelemetryCacheWriteReason, type ResolverTelemetryErrorClass, type ResolverTelemetryHeaderPayload, type ResolverTelemetryIdentitySource, type ResolverTelemetryLogPayload, type ResolverTelemetryOutcome, type ResolverTelemetryPhase, type ResolverTelemetrySink, type ResolverVendorAttemptTelemetryEvent, } from "./runtime/resolver-telemetry.js";
39
+ export { APIFUSE__CDP_POOL__URL, APIFUSE__RESOLVER__2CAPTCHA__API_KEY, APIFUSE__RESOLVER__CAPMONSTER__API_KEY, APIFUSE__RESOLVER__CAPSOLVER__API_KEY, APIFUSE__RESOLVER__HYPERSOLUTIONS__API_KEY, APIFUSE__RESOLVER__TIMEOUT_MS, DEFAULT_RESOLVER_TIMEOUT_MS, } from "./runtime/resolver-config.js";
38
40
  export { createUnsupportedResolverClient } from "./runtime/resolver-shared.js";
39
41
  export type { ResolverRuntimeOptions } from "./runtime/resolver.js";
40
- export type { ResolverVendorTransport } from "./runtime/resolver-vendors/types.js";
42
+ export type { ResolverPaidUsageContext, ResolverVendorTransport, ResolverVendorUnavailableReason, } from "./runtime/resolver-vendors/types.js";
41
43
  export { assertRequiredSecretsPresent, listMissingRequiredSecrets, MISSING_SECRET_CODE, } from "./runtime/secrets.js";
42
44
  export { createUnsupportedProviderRuntimeState, UnsupportedProviderStateError, } from "./runtime/state.js";
43
45
  export { APIFUSE__OCR__API_KEY_ENV, APIFUSE__OCR__BACKEND_ENV, APIFUSE__OCR__BASE_URL_ENV, APIFUSE__OCR__CLOUDFLARE_API_TOKEN_ENV, APIFUSE__OCR__MODEL_ENV, CLOUDFLARE_ACCOUNT_ID_ENV, CLOUDFLARE_WORKERS_AI_OCR_BACKEND, createCloudflareWorkersAiOcrClient, createOcrClientFromEnv, createOpenAiCompatibleOcrClient, createUnsupportedOcrClient, DEFAULT_CLOUDFLARE_WORKERS_AI_OCR_MODEL, extractCaptchaCandidates, OPENAI_COMPATIBLE_OCR_BACKEND, } from "./runtime/ocr.js";
44
46
  export { APIFUSE__STT__BACKEND_ENV, APIFUSE__STT__CLOUDFLARE_API_TOKEN_ENV, APIFUSE__STT__MODEL_ENV, createSttClientFromEnv, createUnsupportedSttClient, extractVerificationCode, resolveSttPrompt, } from "./runtime/stt.js";
45
47
  export { type CreateTraceContextOptions, createTraceContext, type Span, type TraceContext, } from "./runtime/trace.js";
46
- 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";
48
+ export type { DiagnosticRedactor } from "./runtime/diagnostic-redactor.js";
49
+ export { APIFUSE_CONTENT_PROVENANCE_META_KEY, APIFUSE_CONTENT_TRUST_META_KEY, APIFUSE_DESCRIPTION_KEY_META_KEY, APIFUSE_REDACTION_MARKER, APIFUSE_SENSITIVE_KIND_META_KEY, APIFUSE_SENSITIVE_META_KEY, collectSensitivePaths, describeKey, field, fields, isSensitiveSchema, publicField, redactPayload, type SensitiveFieldKind, type SensitiveFieldOptions, type SensitivePath, sensitive, untrustedContent, z, } from "./schema.js";
47
50
  export { createServerApp, createServerAppAsync, ERROR_OBSERVABILITY_HEADER, type ProviderErrorCauseFrame, type ServeOptions, serve, } from "./server/serve.js";
48
51
  export { DEFAULT_STEALTH_BROWSER, DEFAULT_STEALTH_OS, getStealthProfile, listStealthProfiles, } from "./stealth/profiles.js";
49
52
  export * from "./stream.js";
50
- export type { ApiFuseResponse, AuthConfig, AuthContext, AuthFlowDefinition, AuthFlowInputHandler, AuthFlowStartHandler, AuthMode, AuthTurn, Bcp47Locale, BrowserCookie, BrowserEngine, BrowserOptions, BrowserResourceBody, BrowserResourceDecision, BrowserResourceMethod, BrowserResourcePolicy, BrowserResourceRequest, BrowserResourceRoute, ChallengeSolution, 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, NativeProxyDrainHandler, NativeProxyEgressInfo, NativeProxyExpiringEvent, NativeProxyExpiringReason, NativeTcpDynamicEgressRule, NativeTcpEgressGrant, NativeTcpEgressRule, NativeTcpPortRange, NativeTcpTlsMode, NativeTlsConnectOptions, OcrCaptchaCandidate, OcrCaptchaOptions, OcrCaptchaResult, OcrContext, OcrImageInput, OcrRecognizeRequest, OcrResult, OcrWarning, OperationApprovalPolicy, OperationContractMetadata, OperationDefinition, OperationDeprecationMetadata, OperationExample, OperationErrorCode, ProviderErrorStatus, OperationHandlerResult, OperationLifecycle, OperationObservabilityConfig, OperationObservabilitySensitiveConfig, OperationRelationships, OperationRiskClass, OperationSensitivePath, OperationTransport, OperationTransportKind, ProbeInterval, ProviderAccessConfig, ProviderAccessVisibility, ProviderCache, ProviderCacheGetOrSetOptions, ProviderCacheKeyOptions, ProviderCacheLookupMeta, ProviderCacheResponseMeta, ProviderCacheResult, ProviderChoiceBindingOptions, ProviderChoiceConsumeMode, ProviderChoiceConsumeResult, ProviderChoiceContext, ProviderChoiceExplicitParseResult, ProviderChoiceIssueOptions, ProviderChoiceParseOptions, ProviderChallenge, ProviderChallengeKind, ProviderContext, ProviderContextFor, ProviderDefinition, ProviderDeploymentOverrides, ProviderFileRef, ProviderFilesContext, ProviderHealthMonitorConfig, ProviderHealthProbeConfig, ProviderLocale, ProviderLocaleKey, ProviderLocaleKeyInput, ProviderLogoProfile, ProviderLogoSource, ProviderMeta, ProviderOcrConfig, ProviderProxyConfig, ProviderProxyMode, ProviderProxyPolicy, ProxiedOAuthConfig, ProviderProxyProvider, ProviderProxySessionAffinity, ProviderPublicConnectionMode, ProviderPublicProfile, ProviderReviewed, ProviderResolvedFile, ProviderResolverConfig, ProviderResolverVendor, ProviderRuntimeTarget, ProviderRuntimeState, ProviderSecretDeclaration, ProviderStateDurationString, ProviderStateNamespace, ProviderStreamEvent, ProviderSttConfig, ProviderSttMode, ProviderSupportLevel, RequestOptions, RedirectRunReason, ResolverContext, Rfc3339Instant, SchemaLike, SmsOrigin, SmsOtpExtractionPattern, SmsOtpMatcherDefinition, SseMessage, StandardSchemaV1, StateCasResult, StateNamespaceOptions, StateNamespaceScope, StateValue, StateWriteOptions, StealthClient, StealthBrowser, StealthCookieStore, StealthCookieStoreV1, StealthFetchOptions, StealthPlatform, StealthProfile, StealthProfileDescriptor, StealthProfileSelection, StealthOS, 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";
53
+ export type { ApiFuseResponse, AuthConfig, AuthContext, AuthFlowDefinition, AuthFlowInputHandler, AuthFlowStartHandler, AuthMode, AuthTurn, Bcp47Locale, BrowserCookie, BrowserEngine, BrowserOptions, BrowserResourceBody, BrowserResourceDecision, BrowserResourceMethod, BrowserResourcePolicy, BrowserResourceRequest, BrowserResourceRoute, ChallengeSolution, 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, NativeProxyDrainHandler, NativeProxyEgressInfo, NativeProxyExpiringEvent, NativeProxyExpiringReason, NativeTcpDynamicEgressRule, NativeTcpEgressGrant, NativeTcpEgressRule, NativeTcpPortRange, NativeTcpTlsMode, NativeTlsConnectOptions, OcrCaptchaCandidate, OcrCaptchaOptions, OcrCaptchaResult, OcrContext, OcrImageInput, OcrRecognizeRequest, OcrResult, OcrWarning, OperationApprovalPolicy, OperationContractMetadata, OperationDefinition, OperationDeprecationMetadata, OperationExample, OperationErrorCode, ProviderErrorStatus, OperationHandlerResult, OperationLifecycle, OperationObservabilityConfig, OperationObservabilitySensitiveConfig, OperationRelationships, OperationRiskClass, OperationSensitivePath, OperationTransport, OperationTransportKind, ProbeInterval, ProviderAccessConfig, ProviderAccessVisibility, ProviderCache, ProviderCacheGetOrSetOptions, ProviderCacheKeyOptions, ProviderCacheLookupMeta, ProviderCacheResponseMeta, ProviderCacheResult, ProviderChoiceBindingOptions, ProviderChoiceConsumeMode, ProviderChoiceConsumeResult, ProviderChoiceContext, ProviderChoiceExplicitParseResult, ProviderChoiceIssueOptions, ProviderChoiceParseOptions, ProviderChallenge, ProviderChallengeKind, ProviderContext, ProviderContextFor, ProviderDefinition, ProviderDeploymentOverrides, ProviderFileRef, ProviderFilesContext, ProviderHealthMonitorConfig, ProviderHealthProbeConfig, ProviderLocale, ProviderLocaleKey, ProviderLocaleKeyInput, ProviderLogoProfile, ProviderLogoSource, ProviderMeta, ProviderOcrConfig, ProviderProxyConfig, ProviderProxyMode, ProviderProxyPolicy, ProxiedOAuthConfig, ProviderProxyProvider, ProviderProxySessionAffinity, ProviderPublicConnectionMode, ProviderPublicProfile, ProviderReviewed, ProviderResolvedFile, ProviderResolverConfig, ProviderResolverVendor, ProviderRuntimeTarget, ProviderRuntimeState, ProviderSecretDeclaration, ProviderStealthConfig, ProviderStateDurationString, ProviderStateNamespace, ProviderStreamEvent, ProviderSttConfig, ProviderSttMode, ProviderSupportLevel, RequestOptions, RedirectRunReason, ResolverContext, Rfc3339Instant, SchemaLike, SmsOrigin, SmsOtpExtractionPattern, SmsOtpMatcherDefinition, SseMessage, StandardSchemaV1, StateCasResult, StateNamespaceOptions, StateNamespaceScope, StateValue, StateWriteOptions, StealthClient, StealthBrowser, StealthChallengeClassification, StealthCookieStore, StealthCookieStoreV1, StealthFetchOptions, StealthPlatform, StealthProfile, StealthProfileDescriptor, StealthProfileSelection, StealthOS, 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";
51
54
  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";
52
55
  export * from "./utils/date.js";
53
56
  export * from "./utils/parse.js";
package/dist/index.js CHANGED
@@ -27,14 +27,16 @@ export { generateInsights } from "./runtime/insights.js";
27
27
  export { wrapWithInstrumentation, } from "./runtime/instrumentation.js";
28
28
  export { getProviderBaseUrl } from "./runtime/provider.js";
29
29
  export { RequestTelemetry, closedEnum, } from "./runtime/request-telemetry.js";
30
- export { APIFUSE__CDP_POOL__URL, APIFUSE__RESOLVER__2CAPTCHA__API_KEY, APIFUSE__RESOLVER__CAPMONSTER__API_KEY, APIFUSE__RESOLVER__CAPSOLVER__API_KEY, APIFUSE__RESOLVER__TIMEOUT_MS, DEFAULT_RESOLVER_TIMEOUT_MS, } from "./runtime/resolver-config.js";
30
+ export { APIFUSE__ENGINE__CEREMONY_LEASE_KEY } from "./runtime/egress-lease.js";
31
+ export { ResolverTelemetryCollector, } from "./runtime/resolver-telemetry.js";
32
+ export { APIFUSE__CDP_POOL__URL, APIFUSE__RESOLVER__2CAPTCHA__API_KEY, APIFUSE__RESOLVER__CAPMONSTER__API_KEY, APIFUSE__RESOLVER__CAPSOLVER__API_KEY, APIFUSE__RESOLVER__HYPERSOLUTIONS__API_KEY, APIFUSE__RESOLVER__TIMEOUT_MS, DEFAULT_RESOLVER_TIMEOUT_MS, } from "./runtime/resolver-config.js";
31
33
  export { createUnsupportedResolverClient } from "./runtime/resolver-shared.js";
32
34
  export { assertRequiredSecretsPresent, listMissingRequiredSecrets, MISSING_SECRET_CODE, } from "./runtime/secrets.js";
33
35
  export { createUnsupportedProviderRuntimeState, UnsupportedProviderStateError, } from "./runtime/state.js";
34
36
  export { APIFUSE__OCR__API_KEY_ENV, APIFUSE__OCR__BACKEND_ENV, APIFUSE__OCR__BASE_URL_ENV, APIFUSE__OCR__CLOUDFLARE_API_TOKEN_ENV, APIFUSE__OCR__MODEL_ENV, CLOUDFLARE_ACCOUNT_ID_ENV, CLOUDFLARE_WORKERS_AI_OCR_BACKEND, createCloudflareWorkersAiOcrClient, createOcrClientFromEnv, createOpenAiCompatibleOcrClient, createUnsupportedOcrClient, DEFAULT_CLOUDFLARE_WORKERS_AI_OCR_MODEL, extractCaptchaCandidates, OPENAI_COMPATIBLE_OCR_BACKEND, } from "./runtime/ocr.js";
35
37
  export { APIFUSE__STT__BACKEND_ENV, APIFUSE__STT__CLOUDFLARE_API_TOKEN_ENV, APIFUSE__STT__MODEL_ENV, createSttClientFromEnv, createUnsupportedSttClient, extractVerificationCode, resolveSttPrompt, } from "./runtime/stt.js";
36
38
  export { createTraceContext, } 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, sensitive, z, } from "./schema.js";
39
+ export { APIFUSE_CONTENT_PROVENANCE_META_KEY, APIFUSE_CONTENT_TRUST_META_KEY, APIFUSE_DESCRIPTION_KEY_META_KEY, APIFUSE_REDACTION_MARKER, APIFUSE_SENSITIVE_KIND_META_KEY, APIFUSE_SENSITIVE_META_KEY, collectSensitivePaths, describeKey, field, fields, isSensitiveSchema, publicField, redactPayload, sensitive, untrustedContent, z, } from "./schema.js";
38
40
  export { createServerApp, createServerAppAsync, ERROR_OBSERVABILITY_HEADER, serve, } from "./server/serve.js";
39
41
  export { DEFAULT_STEALTH_BROWSER, DEFAULT_STEALTH_OS, getStealthProfile, listStealthProfiles, } from "./stealth/profiles.js";
40
42
  export * from "./stream.js";
package/dist/lint.js CHANGED
@@ -380,17 +380,28 @@ function getChildSchemas(schema) {
380
380
  function uniqueFields(fields) {
381
381
  return Array.from(new Set(fields));
382
382
  }
383
- function isSensitiveSchema(schema) {
384
- if (!schema || typeof schema !== "object" || !("meta" in schema)) {
385
- return false;
383
+ function readSensitivityDeclaration(schema, seen = new Set()) {
384
+ // Declarations sit on the leaf; same-path wrappers such as .optional(),
385
+ // .nullable(), .pipe() or z.lazy() carry no metadata of their own, so look
386
+ // through them.
387
+ if (!isSchema(schema) || seen.has(schema))
388
+ return undefined;
389
+ seen.add(schema);
390
+ const value = Reflect.get(getSchemaMetadata(schema), APIFUSE_SENSITIVE_META_KEY);
391
+ if (typeof value === "boolean")
392
+ return value;
393
+ const def = getSchemaDef(schema);
394
+ const children = def.type === "pipe"
395
+ ? [def.in, def.out]
396
+ : def.type === "lazy" && typeof def.getter === "function"
397
+ ? [def.getter()]
398
+ : [def.innerType];
399
+ for (const child of children) {
400
+ const declaration = readSensitivityDeclaration(child, seen);
401
+ if (declaration !== undefined)
402
+ return declaration;
386
403
  }
387
- const meta = schema.meta;
388
- if (typeof meta !== "function")
389
- return false;
390
- const metadata = meta.call(schema);
391
- return (!!metadata &&
392
- typeof metadata === "object" &&
393
- Reflect.get(metadata, APIFUSE_SENSITIVE_META_KEY) === true);
404
+ return undefined;
394
405
  }
395
406
  function getSchemaMetadata(schema) {
396
407
  return schema.meta?.() ?? {};
@@ -416,9 +427,19 @@ const SENSITIVE_FIELD_NAMES = new Set([
416
427
  "phonenumber",
417
428
  "paymenturl",
418
429
  ]);
430
+ // Only phone-shaped keys can hold reviewed public data (facility phones); the
431
+ // rest are credentials, which a public declaration must not launder.
432
+ const PUBLIC_DECLARABLE_FIELD_NAMES = new Set(["phone", "phonenumber"]);
433
+ function normalizeFieldName(name) {
434
+ return name.toLowerCase().replace(/[-_\s]/g, "");
435
+ }
419
436
  function isSensitiveFieldName(name) {
420
- const normalized = name.toLowerCase().replace(/[-_\s]/g, "");
421
- return SENSITIVE_FIELD_NAMES.has(normalized);
437
+ return SENSITIVE_FIELD_NAMES.has(normalizeFieldName(name));
438
+ }
439
+ function isDeclaredSensitiveField(key, schema) {
440
+ const declaration = readSensitivityDeclaration(schema);
441
+ return (declaration === true ||
442
+ (declaration === false && PUBLIC_DECLARABLE_FIELD_NAMES.has(normalizeFieldName(key))));
422
443
  }
423
444
  function collectUnmarkedSensitiveFields(schema, basePath, seen = new Set()) {
424
445
  if (!isSchema(schema) || seen.has(schema)) {
@@ -428,7 +449,7 @@ function collectUnmarkedSensitiveFields(schema, basePath, seen = new Set()) {
428
449
  const out = [];
429
450
  for (const [key, child] of Object.entries(getObjectShape(schema))) {
430
451
  const childPath = basePath ? `${basePath}.${key}` : key;
431
- if (isSensitiveFieldName(key) && !isSensitiveSchema(child)) {
452
+ if (isSensitiveFieldName(key) && !isDeclaredSensitiveField(key, child)) {
432
453
  out.push(childPath);
433
454
  }
434
455
  out.push(...collectUnmarkedSensitiveFields(child, childPath, seen));
@@ -757,9 +778,9 @@ function browserVersionLiteralMessage(finding) {
757
778
  case "profile":
758
779
  return `Hardcoded stealth profile "${finding.literal}" pins a browser version and will rot. Select the browser and OS structurally, for example stealth: { browser: "chrome", os: "macos" }.`;
759
780
  case "user-agent":
760
- return `Hardcoded User-Agent browser version "${finding.literal}" can disagree with the stealth TLS fingerprint. Remove the literal and derive it from the structured profile, for example getStealthProfile({ browser: "chrome", os: "macos" }).userAgent.`;
781
+ return `Hardcoded User-Agent browser version "${finding.literal}" can disagree with the stealth TLS fingerprint. Remove the literal. ctx.stealth owns User-Agent and rejects a caller value with STEALTH_HEADER_OVERRIDE_UNSUPPORTED, so omit the header there and select the profile with stealth: { browser: "chrome", os: "macos" }. For ctx.http only, derive it from getStealthProfile({ browser: "chrome", os: "macos" }).userAgent.`;
761
782
  case "sec-ch-ua":
762
- return 'Hardcoded sec-ch-ua versions can disagree with the stealth TLS fingerprint. Remove the literal and let ctx.stealth generate client hints from stealth: { browser: "chrome", os: "macos" }; derive any explicit User-Agent with getStealthProfile({ browser: "chrome", os: "macos" }).userAgent.';
783
+ return 'Hardcoded sec-ch-ua versions can disagree with the stealth TLS fingerprint. Remove the literal and let ctx.stealth generate client hints from stealth: { browser: "chrome", os: "macos" }. ctx.stealth also owns User-Agent, so omit that header there as well; for ctx.http only, derive it from getStealthProfile({ browser: "chrome", os: "macos" }).userAgent.';
763
784
  }
764
785
  }
765
786
  function lintBrowserVersionLiterals(provider) {
@@ -1086,7 +1107,7 @@ export function lintOperation(op) {
1086
1107
  rule: "sensitive-field-unmarked",
1087
1108
  level: "warn",
1088
1109
  field,
1089
- message: `Schema field "${field}" looks sensitive; mark it with fields.*(), field(..., { sensitive: true }), or sensitive(...).`,
1110
+ message: `Schema field "${field}" looks sensitive; mark it with fields.*() or sensitive(...); publicField(...) is accepted only for reviewed public phone-shaped fields.`,
1090
1111
  });
1091
1112
  }
1092
1113
  for (const field of uniqueFields(collectUnmarkedSensitiveFields(op.output, "output"))) {
@@ -1094,7 +1115,7 @@ export function lintOperation(op) {
1094
1115
  rule: "sensitive-field-unmarked",
1095
1116
  level: "warn",
1096
1117
  field,
1097
- message: `Schema field "${field}" looks sensitive; mark it with fields.*(), field(..., { sensitive: true }), or sensitive(...).`,
1118
+ message: `Schema field "${field}" looks sensitive; mark it with fields.*() or sensitive(...); publicField(...) is accepted only for reviewed public phone-shaped fields.`,
1098
1119
  });
1099
1120
  }
1100
1121
  return diagnostics;
@@ -8,12 +8,12 @@ export type { JsonPrimitive, JsonValue } from "./contract-json.js";
8
8
  export { AssertionExpressionSchema, AssertionPredicateSchema, AssertStepSchema, BoundedJsonPathSchema, CandidateBlockSchema, CandidatePolicySchema, CredentialRefDeclarationSchema, defineHealthScenario, HealthScenarioSchema, HealthStepSchema, ExtractStepSchema, FindFirstSchema, GuardStepSchema, JournalPolicySchema, JsonTemplateSchema, ManualTriggerPolicySchema, OperandSchema, OperationStepSchema, QuantifierSchema, ReferenceSchema, RetryPolicySchema, SafeRegexSchema, ScopedAssertionExpressionSchema, ScopedAssertionPredicateSchema, ScopedItemReferenceSchema, ScopedOperandSchema, StepReferenceSchema, RelativeDateNodeSchema, ValueTypeSchema, } from "./health-scenario.js";
9
9
  export type { AssertionExpression, AssertionPredicate, AttemptReference, AssertResult, AssertStep, BoundedJsonPath, CandidateBlock, CandidatePolicy, CandidateReference, CredentialReference, CredentialRefDeclaration, EstablishedConnectionReference, ExtractStep, FindFirst, GuardAttribution, GuardReasonCode, GuardResult, GuardStep, HealthScenario, HealthStep, JsonTemplate, JournalPolicy, ManualTriggerPolicy, NonEmpty, OperationResult, OperationStep, Operand, Quantifier, ReferenceNode, Reference, RelativeDateNode, RetryPolicy, SafeRegex, ScopedAssertionExpression, ScopedAssertionPredicate, ScopedItemReference, ScopedOperand, StepBase, StepReference, ExtractResult, ValueType, } from "./health-scenario.js";
10
10
  export { AuthError, HttpRedirectError, isProviderError, isSessionExpiredError, isTransportError, ProviderError, type ProviderErrorObservability, SessionExpiredError, TransportError, ValidationError, } from "./errors.js";
11
- export { createProviderEnvironment, createInProcessProviderEngine, ENGINE_OWNED_PROXY_CREDENTIAL_ENV_NAMES, ENGINE_OWNED_TELEMETRY_ENV_NAMES, isEngineOwnedEnvName, isEngineOwnedProxyCredentialName, isEngineOwnedTelemetryEnvName, PROVIDER_CAPABILITY_KEYS, PROVIDER_ENGINE_PROTOCOL_VERSION, readEngineProxyCredentials, } from "./engine.js";
11
+ export { createProviderEnvironment, createInProcessProviderEngine, ENGINE_OWNED_PROXY_CREDENTIAL_ENV_NAMES, ENGINE_OWNED_RESOLVER_CREDENTIAL_ENV_NAMES, ENGINE_OWNED_RUNTIME_ENV_NAMES, ENGINE_OWNED_TELEMETRY_ENV_NAMES, isEngineOwnedEnvName, isEngineOwnedProxyCredentialName, isEngineOwnedResolverCredentialName, isEngineOwnedRuntimeEnvName, isEngineOwnedTelemetryEnvName, PROVIDER_CAPABILITY_KEYS, PROVIDER_ENGINE_PROTOCOL_VERSION, readEngineProxyCredentials, } from "./engine.js";
12
12
  export type { ProviderCapabilityKey, ProviderEngine, ProviderEngineAttachmentInput, ProviderEngineBindingCandidates, ProviderEngineCapabilitySurface, ProviderEngineRequest, ProviderEngineResidentSurface, ProviderEngineSession, ProviderEngineTransport, } from "./engine.js";
13
13
  export { getProviderLocalePath, providerLocaleKey, qualifyProviderLocaleKey, } from "./i18n/index.js";
14
14
  export { type CreateProviderChoiceContextOptions, createProviderChoiceContext, createTestProviderChoiceContext, PROVIDER_RUNTIME_CHOICE_TOKEN_MASTER_SECRET_ENV, } from "./runtime/choice.js";
15
- 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";
16
- export type { AuthAbortData, AuthAbortRetry, AuthFlowTerminalContext, AuthMode, AuthSafeData, AuthSafeJson, FlowContext, HealthCheckAssertionContext, HealthCheckCase, HealthCheckSuite, HealthCheckUnsupported, HealthJourneyDefinition, HealthJourneyEventContext, HealthJourneyManualTriggerPolicy, HealthJourneyRunContext, HealthJourneyRunResult, HealthScheduleRandomization, HttpRedirectFailureReason, HttpRedirectPolicy, HttpRedirectPolicyMode, HttpRetryOptions, HttpRetrySummary, InferSchemaOutput, NativeContext, NativeNetworkClient, NativeNetworkCloseReason, NativeNetworkConnection, NativeNetworkConnectInput, NativeNetworkConnectOptions, NativeNetworkDynamicGrantOptions, NativeNetworkEgressGrant, NativeProviderConfig, NativeProxyDrainHandler, NativeProxyEgressInfo, NativeProxyExpiringEvent, NativeProxyExpiringReason, NativeTcpDynamicEgressRule, NativeTcpEgressGrant, NativeTcpEgressRule, NativeTcpPortRange, NativeTcpTlsMode, NativeTlsConnectOptions, OperationApprovalPolicy, OperationContractMetadata, OperationDefinition, OperationExample, OperationErrorCode, ProviderErrorStatus, OperationLifecycle, OperationObservabilityConfig, OperationObservabilitySensitiveConfig, OperationRelationships, OperationRiskClass, OperationSensitivePath, OperationTransport, ProviderAccessVisibility, ProviderChoiceBindingOptions, ProviderChoiceConsumeMode, ProviderChoiceConsumeResult, ProviderChoiceContext, ProviderChoiceExplicitParseResult, ProviderChoiceIssueOptions, ProviderChoiceParseOptions, ProviderContext, ProviderContextFor, ProviderDefinition, ProviderDeploymentOverrides, ProviderFileRef, ProviderFilesContext, ProviderLocale, ProviderLocaleKey, ProviderLocaleKeyInput, ProviderLogoProfile, ProviderProxyPolicy, ProxiedOAuthConfig, ProviderPublicConnectionMode, ProviderPublicProfile, ProviderResolvedFile, ProviderRuntimeTarget, ProviderRuntimeState, ProviderStateDurationString, ProviderStateNamespace, ProviderSupportLevel, RedirectRunReason, SchemaLike, SmsOtpMatcherDefinition, StandardSchemaV1, StateCasResult, StateNamespaceOptions, StateNamespaceScope, StateValue, StateWriteOptions, } from "./types.js";
15
+ export { APIFUSE_CONTENT_PROVENANCE_META_KEY, APIFUSE_CONTENT_TRUST_META_KEY, APIFUSE_DESCRIPTION_KEY_META_KEY, APIFUSE_REDACTION_MARKER, APIFUSE_SENSITIVE_KIND_META_KEY, APIFUSE_SENSITIVE_META_KEY, collectSensitivePaths, describeKey, field, fields, isSensitiveSchema, publicField, redactPayload, type SensitiveFieldKind, type SensitiveFieldOptions, type SensitivePath, sensitive, untrustedContent, z, } from "./schema.js";
16
+ export type { AuthAbortData, AuthAbortRetry, AuthFlowTerminalContext, AuthMode, AuthSafeData, AuthSafeJson, FlowContext, HealthCheckAssertionContext, HealthCheckCase, HealthCheckSuite, HealthCheckUnsupported, HealthJourneyDefinition, HealthJourneyEventContext, HealthJourneyManualTriggerPolicy, HealthJourneyRunContext, HealthJourneyRunResult, HealthScheduleRandomization, HttpRedirectFailureReason, HttpRedirectPolicy, HttpRedirectPolicyMode, HttpRetryOptions, HttpRetrySummary, InferSchemaOutput, NativeContext, NativeNetworkClient, NativeNetworkCloseReason, NativeNetworkConnection, NativeNetworkConnectInput, NativeNetworkConnectOptions, NativeNetworkDynamicGrantOptions, NativeNetworkEgressGrant, NativeProviderConfig, NativeProxyDrainHandler, NativeProxyEgressInfo, NativeProxyExpiringEvent, NativeProxyExpiringReason, NativeTcpDynamicEgressRule, NativeTcpEgressGrant, NativeTcpEgressRule, NativeTcpPortRange, NativeTcpTlsMode, NativeTlsConnectOptions, OperationApprovalPolicy, OperationContractMetadata, OperationDefinition, OperationExample, OperationErrorCode, ProviderErrorStatus, OperationLifecycle, OperationObservabilityConfig, OperationObservabilitySensitiveConfig, OperationRelationships, OperationRiskClass, OperationSensitivePath, OperationTransport, ProviderAccessVisibility, ProviderChoiceBindingOptions, ProviderChoiceConsumeMode, ProviderChoiceConsumeResult, ProviderChoiceContext, ProviderChoiceExplicitParseResult, ProviderChoiceIssueOptions, ProviderChoiceParseOptions, ProviderContext, ProviderContextFor, ProviderDefinition, ProviderDeploymentOverrides, ProviderFileRef, ProviderFilesContext, ProviderLocale, ProviderLocaleKey, ProviderLocaleKeyInput, ProviderLogoProfile, ProviderProxyPolicy, ProxiedOAuthConfig, ProviderPublicConnectionMode, ProviderPublicProfile, ProviderResolvedFile, ProviderRuntimeTarget, ProviderRuntimeState, ProviderStealthConfig, ProviderStateDurationString, ProviderStateNamespace, ProviderSupportLevel, RedirectRunReason, SchemaLike, SmsOtpMatcherDefinition, StandardSchemaV1, StateCasResult, StateNamespaceOptions, StateNamespaceScope, StateValue, StateWriteOptions, StealthChallengeClassification, } from "./types.js";
17
17
  export { NativeEgressGrantExpiredError, NativeEgressNotDeclaredError, NativeIdleTimeoutError, NativeNetworkError, NativeProxyExpiredError, } from "./runtime/native-network-errors.js";
18
18
  export type { NativeGatewayProxy, NativeGatewayProxyResolutionInput, NativeGatewayProxySkipReason, NativeGatewayProxySynthesizer, NativeGatewayProxySynthesisResult, NativeGatewayProxySynthesisInput, NativeNetworkClientOptions, NativeNetworkErrorCode, VendorCredentialLookup, VendorCredentialResolver, } from "./runtime/native-network.js";
19
19
  export { HttpRetryAfterPolicy, HttpRetryDelayStrategy, HttpRetryJitter, HttpRetryPreset, HttpRetryUnsafeMethodPolicy, } from "./types.js";
package/dist/provider.js CHANGED
@@ -4,9 +4,9 @@ export { assertFreshProviderChoiceIssuedAt, createProviderChoiceToken, ProviderC
4
4
  export { centered, delayed, defineHealthJourney, defineOperation, defineProvider, defineSmsOtpMatcher, every, } from "./define.js";
5
5
  export { AssertionExpressionSchema, AssertionPredicateSchema, AssertStepSchema, BoundedJsonPathSchema, CandidateBlockSchema, CandidatePolicySchema, CredentialRefDeclarationSchema, defineHealthScenario, HealthScenarioSchema, HealthStepSchema, ExtractStepSchema, FindFirstSchema, GuardStepSchema, JournalPolicySchema, JsonTemplateSchema, ManualTriggerPolicySchema, OperandSchema, OperationStepSchema, QuantifierSchema, ReferenceSchema, RetryPolicySchema, SafeRegexSchema, ScopedAssertionExpressionSchema, ScopedAssertionPredicateSchema, ScopedItemReferenceSchema, ScopedOperandSchema, StepReferenceSchema, RelativeDateNodeSchema, ValueTypeSchema, } from "./health-scenario.js";
6
6
  export { AuthError, HttpRedirectError, isProviderError, isSessionExpiredError, isTransportError, ProviderError, SessionExpiredError, TransportError, ValidationError, } from "./errors.js";
7
- export { createProviderEnvironment, createInProcessProviderEngine, ENGINE_OWNED_PROXY_CREDENTIAL_ENV_NAMES, ENGINE_OWNED_TELEMETRY_ENV_NAMES, isEngineOwnedEnvName, isEngineOwnedProxyCredentialName, isEngineOwnedTelemetryEnvName, PROVIDER_CAPABILITY_KEYS, PROVIDER_ENGINE_PROTOCOL_VERSION, readEngineProxyCredentials, } from "./engine.js";
7
+ export { createProviderEnvironment, createInProcessProviderEngine, ENGINE_OWNED_PROXY_CREDENTIAL_ENV_NAMES, ENGINE_OWNED_RESOLVER_CREDENTIAL_ENV_NAMES, ENGINE_OWNED_RUNTIME_ENV_NAMES, ENGINE_OWNED_TELEMETRY_ENV_NAMES, isEngineOwnedEnvName, isEngineOwnedProxyCredentialName, isEngineOwnedResolverCredentialName, isEngineOwnedRuntimeEnvName, isEngineOwnedTelemetryEnvName, PROVIDER_CAPABILITY_KEYS, PROVIDER_ENGINE_PROTOCOL_VERSION, readEngineProxyCredentials, } from "./engine.js";
8
8
  export { getProviderLocalePath, providerLocaleKey, qualifyProviderLocaleKey, } from "./i18n/index.js";
9
9
  export { createProviderChoiceContext, createTestProviderChoiceContext, PROVIDER_RUNTIME_CHOICE_TOKEN_MASTER_SECRET_ENV, } from "./runtime/choice.js";
10
- 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";
10
+ export { APIFUSE_CONTENT_PROVENANCE_META_KEY, APIFUSE_CONTENT_TRUST_META_KEY, APIFUSE_DESCRIPTION_KEY_META_KEY, APIFUSE_REDACTION_MARKER, APIFUSE_SENSITIVE_KIND_META_KEY, APIFUSE_SENSITIVE_META_KEY, collectSensitivePaths, describeKey, field, fields, isSensitiveSchema, publicField, redactPayload, sensitive, untrustedContent, z, } from "./schema.js";
11
11
  export { NativeEgressGrantExpiredError, NativeEgressNotDeclaredError, NativeIdleTimeoutError, NativeNetworkError, NativeProxyExpiredError, } from "./runtime/native-network-errors.js";
12
12
  export { HttpRetryAfterPolicy, HttpRetryDelayStrategy, HttpRetryJitter, HttpRetryPreset, HttpRetryUnsafeMethodPolicy, } from "./types.js";
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Map whose entries carry an expiry and whose size is capped.
3
+ *
4
+ * Expired entries are dropped when read and swept on every insert, so a
5
+ * process that keeps minting new keys does not retain dead values. When the
6
+ * cap is still exceeded after the sweep, the least recently used entry is
7
+ * evicted and counted in `capacityEvictions` so callers can tell the two
8
+ * kinds of removal apart. Callers pass `now` explicitly so a single timestamp
9
+ * is used across a lookup-then-store sequence.
10
+ */
11
+ export declare class BoundedExpiringMap<K, V> {
12
+ #private;
13
+ constructor(maxEntries: number, expiresAt: (value: V) => number);
14
+ get size(): number;
15
+ /** Entries removed to satisfy `maxEntries`; expiry removals are not counted. */
16
+ get capacityEvictions(): number;
17
+ get(key: K, now: number): V | undefined;
18
+ set(key: K, value: V, now: number): void;
19
+ delete(key: K): boolean;
20
+ clear(): void;
21
+ }
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Map whose entries carry an expiry and whose size is capped.
3
+ *
4
+ * Expired entries are dropped when read and swept on every insert, so a
5
+ * process that keeps minting new keys does not retain dead values. When the
6
+ * cap is still exceeded after the sweep, the least recently used entry is
7
+ * evicted and counted in `capacityEvictions` so callers can tell the two
8
+ * kinds of removal apart. Callers pass `now` explicitly so a single timestamp
9
+ * is used across a lookup-then-store sequence.
10
+ */
11
+ export class BoundedExpiringMap {
12
+ #entries = new Map();
13
+ #maxEntries;
14
+ #expiresAt;
15
+ #capacityEvictions = 0;
16
+ constructor(maxEntries, expiresAt) {
17
+ if (!Number.isInteger(maxEntries) || maxEntries <= 0) {
18
+ throw new RangeError("maxEntries must be a positive integer");
19
+ }
20
+ this.#maxEntries = maxEntries;
21
+ this.#expiresAt = expiresAt;
22
+ }
23
+ get size() {
24
+ return this.#entries.size;
25
+ }
26
+ /** Entries removed to satisfy `maxEntries`; expiry removals are not counted. */
27
+ get capacityEvictions() {
28
+ return this.#capacityEvictions;
29
+ }
30
+ get(key, now) {
31
+ if (!this.#entries.has(key))
32
+ return undefined;
33
+ const value = this.#entries.get(key);
34
+ this.#entries.delete(key);
35
+ if (this.#expiresAt(value) <= now)
36
+ return undefined;
37
+ // Re-insert so Map iteration order doubles as the LRU order.
38
+ this.#entries.set(key, value);
39
+ return value;
40
+ }
41
+ set(key, value, now) {
42
+ for (const [existingKey, existing] of this.#entries) {
43
+ if (this.#expiresAt(existing) <= now)
44
+ this.#entries.delete(existingKey);
45
+ }
46
+ this.#entries.delete(key);
47
+ if (this.#expiresAt(value) <= now)
48
+ return;
49
+ this.#entries.set(key, value);
50
+ if (this.#entries.size > this.#maxEntries) {
51
+ const oldest = this.#entries.keys().next();
52
+ if (!oldest.done) {
53
+ this.#entries.delete(oldest.value);
54
+ this.#capacityEvictions += 1;
55
+ }
56
+ }
57
+ }
58
+ delete(key) {
59
+ return this.#entries.delete(key);
60
+ }
61
+ clear() {
62
+ this.#entries.clear();
63
+ }
64
+ }
@@ -1,3 +1,4 @@
1
+ import { readDiagnosticEnv } from "./diagnostic-env.js";
1
2
  import { createRequire } from "node:module";
2
3
  import { ProviderError } from "../errors.js";
3
4
  const require = createRequire(import.meta.url);
@@ -289,7 +290,7 @@ function createResourcePolicyHandler(policy, allowedMethods) {
289
290
  };
290
291
  }
291
292
  function getDefaultCdpPoolUrl(env = process.env) {
292
- return env.APIFUSE__CDP_POOL__URL;
293
+ return readDiagnosticEnv("APIFUSE__CDP_POOL__URL", env);
293
294
  }
294
295
  async function importOptionalModule(moduleName) {
295
296
  return (await import(moduleName));
@@ -7,5 +7,7 @@ export type ProviderCacheOptions = {
7
7
  };
8
8
  export declare const APIFUSE__CACHE__KEY_PEPPER_ENV = "APIFUSE__CACHE__KEY_PEPPER";
9
9
  export declare function createProviderCache(options: ProviderCacheOptions): ProviderCache;
10
+ /** Internal cache capability, separate from hit/miss metadata. */
11
+ export declare function isProviderCacheBypassed(cache: ProviderCache): boolean;
10
12
  export declare function createBypassProviderCache(options: Pick<ProviderCacheOptions, "providerId">): ProviderCache;
11
13
  export declare function resetProviderCacheForTests(): void;