@apifuse/provider-sdk 2.2.0-beta.47 → 2.2.0-beta.49

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 (114) hide show
  1. package/AUTHORING.md +91 -36
  2. package/CHANGELOG.md +8 -0
  3. package/README.md +11 -9
  4. package/SUBMISSION.md +1 -1
  5. package/bin/apifuse-dev.ts +24 -13
  6. package/bin/apifuse-migrate-operation-declaration.ts +55 -0
  7. package/bin/apifuse-pack-smoke.ts +1 -1
  8. package/bin/apifuse-pack-types.ts +2 -1
  9. package/bin/apifuse-record.ts +30 -16
  10. package/bin/apifuse-submit-check.ts +20 -35
  11. package/dist/cli/commands.d.ts +1 -1
  12. package/dist/cli/commands.js +11 -0
  13. package/dist/cli/migrate-operation-declaration.d.ts +59 -0
  14. package/dist/cli/migrate-operation-declaration.js +1178 -0
  15. package/dist/cli/templates/provider/README.md.tpl +3 -3
  16. package/dist/cli/templates/provider/operations/ping.ts.tpl +2 -0
  17. package/dist/config/loader.d.ts +2 -0
  18. package/dist/config/loader.js +18 -7
  19. package/dist/contract-types.d.ts +11 -5
  20. package/dist/contract.js +21 -10
  21. package/dist/define.d.ts +25 -22
  22. package/dist/define.js +49 -75
  23. package/dist/dev.d.ts +3 -0
  24. package/dist/dev.js +1 -1
  25. package/dist/engine.d.ts +78 -0
  26. package/dist/engine.js +133 -0
  27. package/dist/index.d.ts +3 -2
  28. package/dist/index.js +2 -1
  29. package/dist/lint.d.ts +7 -15
  30. package/dist/lint.js +45 -70
  31. package/dist/provider.d.ts +3 -1
  32. package/dist/provider.js +1 -0
  33. package/dist/runtime/chrome149-header-order.d.ts +58 -0
  34. package/dist/runtime/chrome149-header-order.js +289 -0
  35. package/dist/runtime/env.js +12 -0
  36. package/dist/runtime/executor.d.ts +2 -1
  37. package/dist/runtime/executor.js +3 -36
  38. package/dist/runtime/insights.js +2 -2
  39. package/dist/runtime/otlp.d.ts +71 -2
  40. package/dist/runtime/otlp.js +397 -16
  41. package/dist/runtime/resolver-public.d.ts +1 -1
  42. package/dist/runtime/resolver-public.js +1 -1
  43. package/dist/runtime/resolver-vendors/capsolver.js +9 -3
  44. package/dist/runtime/resolver-vendors/twocaptcha.js +1 -0
  45. package/dist/runtime/resolver.d.ts +12 -0
  46. package/dist/runtime/resolver.js +45 -11
  47. package/dist/runtime/stealth.d.ts +13 -4
  48. package/dist/runtime/stealth.js +362 -85
  49. package/dist/runtime/trace-config.js +2 -1
  50. package/dist/runtime/trace.d.ts +5 -0
  51. package/dist/runtime/trace.js +43 -10
  52. package/dist/server/self-test.d.ts +1 -3
  53. package/dist/server/self-test.js +2 -12
  54. package/dist/server/serve-implementation.d.ts +6 -1
  55. package/dist/server/serve-implementation.js +55 -40
  56. package/dist/server/trace-output.d.ts +3 -1
  57. package/dist/server/trace-output.js +61 -2
  58. package/dist/stealth/profiles.d.ts +9 -8
  59. package/dist/stealth/profiles.js +123 -286
  60. package/dist/types.d.ts +116 -108
  61. package/package.json +2 -1
  62. package/src/cli/__tests__/fixtures/migrate-operation-declaration/approval-override.ts.txt +6 -0
  63. package/src/cli/__tests__/fixtures/migrate-operation-declaration/codemod-syntax.ts.txt +3 -0
  64. package/src/cli/__tests__/fixtures/migrate-operation-declaration/connection-precedence.ts.txt +10 -0
  65. package/src/cli/__tests__/fixtures/migrate-operation-declaration/docs-conflict.ts.txt +8 -0
  66. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-map.ts.txt +5 -0
  67. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-operation.ts.txt +16 -0
  68. package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-map.ts.txt +3 -0
  69. package/src/cli/__tests__/fixtures/migrate-operation-declaration/hoist-all.ts.txt +31 -0
  70. package/src/cli/__tests__/fixtures/migrate-operation-declaration/hoisted-const.ts.txt +11 -0
  71. package/src/cli/__tests__/fixtures/migrate-operation-declaration/imported-spread.ts.txt +11 -0
  72. package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-map.ts.txt +11 -0
  73. package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-cast-tail.ts.txt +21 -0
  74. package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-ekitan.ts.txt +11 -0
  75. package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-override.ts.txt +14 -0
  76. package/src/cli/__tests__/fixtures/migrate-operation-declaration/missing-english-locale.ts.txt +7 -0
  77. package/src/cli/__tests__/fixtures/migrate-operation-declaration/no-safety.ts.txt +6 -0
  78. package/src/cli/__tests__/fixtures/migrate-operation-declaration/non-literal.ts.txt +7 -0
  79. package/src/cli/__tests__/fixtures/migrate-operation-declaration/redundant-approval.ts.txt +6 -0
  80. package/src/cli/__tests__/fixtures/migrate-operation-declaration/safety-conflict.ts.txt +7 -0
  81. package/src/cli/__tests__/fixtures/migrate-operation-declaration/stream.ts.txt +7 -0
  82. package/src/cli/__tests__/fixtures/migrate-operation-declaration/tool-router-spread.ts.txt +15 -0
  83. package/src/cli/__tests__/fixtures/migrate-operation-declaration/unparseable.ts.txt +4 -0
  84. package/src/cli/__tests__/fixtures/migrate-operation-declaration/verbatim-template.ts.txt +12 -0
  85. package/src/cli/commands.ts +13 -0
  86. package/src/cli/migrate-operation-declaration.ts +1654 -0
  87. package/src/cli/templates/provider/README.md.tpl +3 -3
  88. package/src/cli/templates/provider/operations/ping.ts.tpl +2 -0
  89. package/src/config/loader.ts +31 -6
  90. package/src/contract-types.ts +11 -5
  91. package/src/contract.ts +21 -10
  92. package/src/define.ts +107 -119
  93. package/src/dev.ts +4 -1
  94. package/src/engine.ts +279 -0
  95. package/src/index.ts +13 -5
  96. package/src/lint.ts +58 -92
  97. package/src/provider.ts +25 -3
  98. package/src/runtime/chrome149-header-order.ts +330 -0
  99. package/src/runtime/env.ts +13 -0
  100. package/src/runtime/executor.ts +7 -40
  101. package/src/runtime/insights.ts +2 -2
  102. package/src/runtime/otlp.ts +467 -21
  103. package/src/runtime/resolver-public.ts +3 -0
  104. package/src/runtime/resolver-vendors/capsolver.ts +12 -4
  105. package/src/runtime/resolver-vendors/twocaptcha.ts +1 -0
  106. package/src/runtime/resolver.ts +68 -19
  107. package/src/runtime/stealth.ts +435 -103
  108. package/src/runtime/trace-config.ts +3 -2
  109. package/src/runtime/trace.ts +57 -17
  110. package/src/server/self-test.ts +2 -9
  111. package/src/server/serve-implementation.ts +89 -72
  112. package/src/server/trace-output.ts +99 -2
  113. package/src/stealth/profiles.ts +169 -327
  114. package/src/types.ts +114 -137
package/dist/types.d.ts CHANGED
@@ -34,27 +34,13 @@ export declare namespace StandardSchemaV1 {
34
34
  export type SchemaLike = ZodType | StandardSchemaV1;
35
35
  /** Infer the validated output type produced by a Zod or Standard Schema. */
36
36
  export type InferSchemaOutput<TSchema extends SchemaLike> = TSchema extends ZodType ? ZodInfer<TSchema> : TSchema extends StandardSchemaV1<unknown, infer Output> ? Output : unknown;
37
- export interface OperationInputExample {
38
- scenario: string;
37
+ export interface OperationExample {
38
+ scenarioKey: ProviderLocaleKeyInput;
39
39
  input: unknown;
40
- rationale?: string;
40
+ rationaleKey?: ProviderLocaleKeyInput;
41
41
  }
42
42
  export type OperationRiskClass = "read" | "write" | "destructive" | "external-send";
43
43
  export type OperationApprovalPolicy = "never" | "risk-based" | "always";
44
- export interface OperationToolRouterMetadata {
45
- /** Optional MCP-safe override. Defaults to providerId__operationId. */
46
- name?: string;
47
- /** Safety class exposed to Tool Router clients and approval policy. */
48
- riskClass?: OperationRiskClass;
49
- /** OpenAI remote-MCP approval hint. Defaults from riskClass. */
50
- approval?: OperationApprovalPolicy;
51
- /** Canonical operation-level connection requirement consumed by the registry and Gateway. */
52
- connectionMode?: "none" | "optional" | "required";
53
- /** Override connection requirement when provider auth + openWorld inference is insufficient. */
54
- requiresConnection?: boolean;
55
- /** Public argument used to resolve the tenant-owned connection. Defaults to externalRef. */
56
- connectionExternalRefParam?: string;
57
- }
58
44
  export type OperationSensitivePath = string;
59
45
  export interface OperationObservabilitySensitiveConfig {
60
46
  /**
@@ -76,37 +62,6 @@ export interface OperationObservabilityConfig {
76
62
  */
77
63
  sensitive?: OperationObservabilitySensitiveConfig;
78
64
  }
79
- export interface OperationAnnotations {
80
- readOnly?: boolean;
81
- destructive?: boolean;
82
- idempotent?: boolean;
83
- /**
84
- * Marks the operation as callable without provider-level authentication.
85
- *
86
- * Provider-level `auth.mode` describes the **majority** auth model of a
87
- * provider; individual operations can still opt out via `openWorld: true`
88
- * when their handler does not consume `ctx.credential`. This is the
89
- * canonical way to declare "this operation is public, even though the
90
- * provider is `credentials`-mode" without splitting the provider into two.
91
- *
92
- * Health-check projections treat `openWorld: true` operations as
93
- * connection-free probes (no `requiresConnection` required, no SA token
94
- * lookup). Future gateway work MAY extend this annotation to bypass
95
- * `X-ApiFuse-Connection-Id` enforcement at proxy time.
96
- *
97
- * Example: Naver Map's `search`, `geocode`, and directions operations
98
- * call public Naver endpoints with no cookies, while `collections` and
99
- * `export` consume the user's session cookie — the provider declares
100
- * `auth.mode: "credentials"` (for the latter) and the former mark
101
- * `openWorld: true`.
102
- */
103
- openWorld?: boolean;
104
- rateLimit?: {
105
- calls: number;
106
- window: "minute" | "hour" | "day";
107
- };
108
- timeoutMs?: number;
109
- }
110
65
  export declare const OPERATION_TIMEOUT_MS_MIN = 1;
111
66
  export declare const OPERATION_TIMEOUT_MS_MAX = 60000;
112
67
  export declare const STREAM_HEARTBEAT_MS_MIN = 1000;
@@ -338,6 +293,11 @@ export type ChallengeSolution = {
338
293
  readonly userAgent: string;
339
294
  /** Epoch seconds copied from the upstream cookie's own expiry attribute; never a constant. */
340
295
  readonly expires?: number;
296
+ /**
297
+ * Epoch seconds conservatively estimated by the SDK when a resolver vendor omits
298
+ * the upstream cookie's expiry. `expires` takes precedence when both are present.
299
+ */
300
+ readonly sdkEstimatedExpires?: number;
341
301
  };
342
302
  export interface ProviderResolverConfig {
343
303
  /** Optional ordered override for the SDK-owned vendor fallback chain. */
@@ -786,17 +746,34 @@ export interface OperationErrorCode {
786
746
  description: string;
787
747
  retryable?: boolean;
788
748
  }
789
- export interface OperationDocMeta {
790
- titleKey?: ProviderLocaleKeyInput;
791
- descriptionKey?: ProviderLocaleKeyInput;
792
- summaryKey?: ProviderLocaleKeyInput;
793
- markdownKey?: ProviderLocaleKeyInput;
794
- normalizationNotesKeys?: ProviderLocaleKeyInput[];
795
- requestExample?: Record<string, unknown>;
796
- responseExample?: unknown;
797
- errorCodes?: OperationErrorCode[];
798
- }
799
749
  export type StealthPlatform = "macos" | "windows" | "linux" | "android" | "ios";
750
+ export type StealthBrowser = "chrome" | "firefox" | "safari";
751
+ export type StealthOS = "windows" | "macos" | "linux" | "ios";
752
+ /** A supported, fully resolved browser/OS fingerprint pair. */
753
+ export type StealthProfileDescriptor = {
754
+ browser: "chrome";
755
+ os: "windows" | "macos" | "linux";
756
+ } | {
757
+ browser: "firefox";
758
+ os: "windows" | "macos" | "linux";
759
+ } | {
760
+ browser: "safari";
761
+ os: "macos" | "ios";
762
+ };
763
+ /**
764
+ * Browser/OS fingerprint selection. Chrome and macOS are the named defaults
765
+ * when their respective axes are omitted.
766
+ */
767
+ export type StealthProfileSelection = {
768
+ browser?: "chrome";
769
+ os?: "windows" | "macos" | "linux";
770
+ } | {
771
+ browser: "firefox";
772
+ os?: "windows" | "macos" | "linux";
773
+ } | {
774
+ browser: "safari";
775
+ os?: "macos" | "ios";
776
+ };
800
777
  export type BrowserEngine = "playwright-stealth" | "nodriver" | "selenium-uc";
801
778
  export interface BrowserOptions {
802
779
  headless?: boolean;
@@ -805,9 +782,7 @@ export interface BrowserOptions {
805
782
  engine?: BrowserEngine;
806
783
  requireCdpPool?: boolean;
807
784
  }
808
- export interface StealthProfile {
809
- name: string;
810
- platform: StealthPlatform;
785
+ export type StealthProfile = StealthProfileDescriptor & {
811
786
  version: string;
812
787
  userAgent: string;
813
788
  tlsClientIdentifier?: string;
@@ -815,7 +790,7 @@ export interface StealthProfile {
815
790
  ja4?: string;
816
791
  h2Settings?: Record<string, unknown>;
817
792
  headerOrder?: string[];
818
- }
793
+ };
819
794
  export type AuthMode = "none" | "platform-managed" | "credentials" | "oauth2" | "oauth2_proxied";
820
795
  export type ConnectionMode = AuthMode;
821
796
  export type ProviderReviewed = "first-party" | "community" | "staging";
@@ -890,8 +865,7 @@ export interface ProviderAccessConfig {
890
865
  * active customer organization has a provider-level access grant.
891
866
  *
892
867
  * This is intentionally provider-level only. It does not alter auth mode,
893
- * operation schemas, health-check authoring, `openWorld`, or Connection
894
- * requirements.
868
+ * operation schemas, health-check authoring, or Connection requirements.
895
869
  */
896
870
  visibility?: ProviderAccessVisibility;
897
871
  }
@@ -1052,7 +1026,12 @@ export interface HttpRedirectPolicy {
1052
1026
  }
1053
1027
  export type HttpRedirectFailureReason = Exclude<RedirectRunReason, "completed">;
1054
1028
  export type HttpMethod = "HEAD" | "head" | "GET" | "get" | "POST" | "post" | "PUT" | "put" | "DELETE" | "delete" | "OPTIONS" | "options" | "TRACE" | "trace" | "PATCH" | "patch";
1055
- export interface StealthFetchOptions extends Omit<RequestOptions, "redirectPolicy"> {
1029
+ export interface StealthFetchOptions extends Omit<RequestOptions, "redirectPolicy" | "headers"> {
1030
+ /**
1031
+ * Request headers. Array values and case-insensitive duplicate names are
1032
+ * combined in caller order using `", "`, matching Chrome's Fetch behavior.
1033
+ */
1034
+ headers?: Record<string, string | string[]>;
1056
1035
  method?: HttpMethod;
1057
1036
  body?: string | Buffer;
1058
1037
  redirect?: "follow" | "manual" | "error";
@@ -1069,14 +1048,18 @@ export interface StealthFetchOptions extends Omit<RequestOptions, "redirectPolic
1069
1048
  * operation-affinity proxy.
1070
1049
  */
1071
1050
  proxyAttemptOffset?: number;
1072
- /** Override the configured browser-like stealth profile for this request. */
1073
- profile?: string;
1074
1051
  /**
1075
- * Stealth transport certificate controls. Use only for proxy products that
1076
- * terminate CONNECT with a private CA instead of tunneling the origin
1077
- * certificate chain.
1052
+ * SDK-specific stealth controls. Standard HTTP metadata such as language,
1053
+ * referrer, and content type belongs in `headers`.
1078
1054
  */
1079
- stealth?: {
1055
+ stealth?: StealthProfileSelection & {
1056
+ /** Override the configured browser and/or OS for this request. */
1057
+ /** Declare the Chrome request class when it cannot be inferred from the method. */
1058
+ requestClass?: "navigation" | "xhr" | "post";
1059
+ /**
1060
+ * Use only for proxy products that terminate CONNECT with a private CA
1061
+ * instead of tunneling the origin certificate chain.
1062
+ */
1080
1063
  insecureSkipVerify?: boolean;
1081
1064
  };
1082
1065
  }
@@ -1249,6 +1232,8 @@ export interface ProviderFilesContext {
1249
1232
  has(input: string | ProviderFileRef): boolean;
1250
1233
  resolve(input: string | ProviderFileRef): Promise<ProviderResolvedFile>;
1251
1234
  }
1235
+ /** Where provider business logic executes relative to the capability engine. */
1236
+ export type ProviderRuntimeTarget = "vanilla" | "engine";
1252
1237
  export type NativeTcpTlsMode = "required" | "allowed" | "disabled";
1253
1238
  export interface NativeTcpPortRange {
1254
1239
  readonly start: number;
@@ -1421,7 +1406,7 @@ export interface ProviderCache {
1421
1406
  export interface StealthClient {
1422
1407
  fetch(url: string, options?: StealthFetchOptions): Promise<StealthResponse>;
1423
1408
  createSession(opts?: {
1424
- profile?: string;
1409
+ stealth?: StealthProfileSelection;
1425
1410
  }): StealthSession;
1426
1411
  close?(): void;
1427
1412
  }
@@ -1552,7 +1537,7 @@ export interface TraceConfig {
1552
1537
  exporter?: "console" | "json" | "otlp" | "none";
1553
1538
  endpoint?: string;
1554
1539
  otlp?: {
1555
- endpoint: string;
1540
+ endpoint?: string;
1556
1541
  headers?: Record<string, string>;
1557
1542
  timeout?: number;
1558
1543
  };
@@ -1871,32 +1856,48 @@ export interface ProviderRuntimeState {
1871
1856
  forConnection(connectionId: string | undefined): ProviderRuntimeState;
1872
1857
  namespace(name: string, options: StateNamespaceOptions): ProviderStateNamespace;
1873
1858
  }
1874
- export interface ProviderContext {
1859
+ /**
1860
+ * The operation context exposed for one provider declaration. Capability
1861
+ * bindings are present only when their corresponding declaration is present;
1862
+ * trace and request remain ambient runtime bindings. Omitting the type
1863
+ * parameter preserves the legacy full context shape for existing annotations.
1864
+ */
1865
+ export type ProviderContext<TConfig = Record<string, unknown>> = {
1866
+ request?: ProviderRequestContext;
1867
+ trace: TraceContext;
1868
+ } & ("env" extends keyof TConfig ? {
1875
1869
  env: EnvContext;
1870
+ } : Record<never, never>) & ("credential" extends keyof TConfig ? {
1876
1871
  credential: CredentialContext;
1877
- request?: ProviderRequestContext;
1872
+ } : Record<never, never>) & ("http" extends keyof TConfig ? {
1878
1873
  http: HttpClient;
1879
- /** Present for requests carrying runtime-resolvable file references. */
1874
+ } : Record<never, never>) & ("files" extends keyof TConfig ? string extends keyof TConfig ? {
1880
1875
  readonly files?: ProviderFilesContext;
1881
- /** Native network capability selected by declaration-derived contexts. */
1876
+ } : {
1877
+ readonly files: ProviderFilesContext;
1878
+ } : Record<never, never>) & ("native" extends keyof TConfig ? {
1882
1879
  readonly native: NativeContext;
1880
+ } : Record<never, never>) & ("cache" extends keyof TConfig ? {
1883
1881
  cache: ProviderCache;
1882
+ } : Record<never, never>) & ("state" extends keyof TConfig ? {
1884
1883
  state: ProviderRuntimeState;
1884
+ } : Record<never, never>) & ("stealth" extends keyof TConfig ? {
1885
1885
  stealth: StealthClient;
1886
+ } : Record<never, never>) & ("browser" extends keyof TConfig ? {
1886
1887
  browser: BrowserClient;
1887
- trace: TraceContext;
1888
+ } : Record<never, never>) & ("auth" extends keyof TConfig ? {
1888
1889
  auth: AuthContext;
1890
+ } : Record<never, never>) & ("ocr" extends keyof TConfig ? {
1889
1891
  ocr: OcrContext;
1892
+ } : Record<never, never>) & ("stt" extends keyof TConfig ? {
1890
1893
  stt: SttContext;
1894
+ } : Record<never, never>) & ("resolver" extends keyof TConfig ? {
1891
1895
  resolver: ResolverContext;
1896
+ } : Record<never, never>) & ("choice" extends keyof TConfig ? {
1892
1897
  choice: ProviderChoiceContext;
1893
- }
1894
- /**
1895
- * The operation context exposed for one provider declaration. Capability
1896
- * bindings are present only when their corresponding declaration is present;
1897
- * trace and request remain ambient runtime bindings.
1898
- */
1899
- export type ProviderContextFor<TConfig> = Pick<ProviderContext, "trace" | "request"> & ("env" extends keyof TConfig ? Pick<ProviderContext, "env"> : Record<never, never>) & ("credential" extends keyof TConfig ? Pick<ProviderContext, "credential"> : Record<never, never>) & ("http" extends keyof TConfig ? Pick<ProviderContext, "http"> : Record<never, never>) & ("files" extends keyof TConfig ? Pick<ProviderContext, "files"> : Record<never, never>) & ("native" extends keyof TConfig ? Pick<ProviderContext, "native"> : Record<never, never>) & ("cache" extends keyof TConfig ? Pick<ProviderContext, "cache"> : Record<never, never>) & ("state" extends keyof TConfig ? Pick<ProviderContext, "state"> : Record<never, never>) & ("stealth" extends keyof TConfig ? Pick<ProviderContext, "stealth"> : Record<never, never>) & ("browser" extends keyof TConfig ? Pick<ProviderContext, "browser"> : Record<never, never>) & ("auth" extends keyof TConfig ? Pick<ProviderContext, "auth"> : Record<never, never>) & ("ocr" extends keyof TConfig ? Pick<ProviderContext, "ocr"> : Record<never, never>) & ("stt" extends keyof TConfig ? Pick<ProviderContext, "stt"> : Record<never, never>) & ("resolver" extends keyof TConfig ? Pick<ProviderContext, "resolver"> : Record<never, never>) & ("choice" extends keyof TConfig ? Pick<ProviderContext, "choice"> : Record<never, never>);
1898
+ } : Record<never, never>);
1899
+ /** Backwards-compatible name for a declaration-derived provider context. */
1900
+ export type ProviderContextFor<TConfig> = ProviderContext<TConfig>;
1900
1901
  export interface ProxiedOAuthConfig {
1901
1902
  authorizeUrl: string;
1902
1903
  tokenUrl: string;
@@ -1943,33 +1944,29 @@ export interface OperationContractMetadata {
1943
1944
  deprecation?: OperationDeprecationMetadata;
1944
1945
  }
1945
1946
  export interface OperationDefinition<TInput extends SchemaLike = SchemaLike, TOutput extends SchemaLike = SchemaLike, TContext = ProviderContext> {
1946
- /**
1947
- * Short English display title for the operation. The SDK passes it through
1948
- * verbatim; the APIFuse registry derives the operation's en locale title
1949
- * baseline from it (`docs.titleKey` remains available as an explicit key
1950
- * override).
1951
- */
1952
- title?: string;
1953
- /**
1954
- * Raw English operation description. The SDK passes it through verbatim;
1955
- * keyed descriptions via `descriptionKey` remain the primary flow, and
1956
- * provider lint rules for raw prose descriptions still apply.
1957
- */
1958
- description?: string;
1947
+ /** Canonical operation-level connection requirement. */
1948
+ connectionMode?: "none" | "optional" | "required";
1949
+ /** Public argument used to resolve the tenant-owned connection. Defaults to externalRef. */
1950
+ connectionExternalRefParam?: string;
1951
+ /** Safety source of truth exposed to clients and approval policy. */
1952
+ riskClass: OperationRiskClass;
1953
+ /** Approval override. Omit when the risk-class default is correct. */
1954
+ approval?: OperationApprovalPolicy;
1955
+ timeoutMs?: number;
1956
+ titleKey?: ProviderLocaleKeyInput;
1959
1957
  descriptionKey?: ProviderLocaleKeyInput;
1960
- docs?: OperationDocMeta;
1958
+ summaryKey?: ProviderLocaleKeyInput;
1959
+ markdownKey?: ProviderLocaleKeyInput;
1961
1960
  whenToUseKeys?: readonly ProviderLocaleKeyInput[];
1962
1961
  whenNotToUseKeys?: readonly ProviderLocaleKeyInput[];
1963
- derivations?: Record<string, string>;
1964
- inputExamples?: readonly OperationInputExample[];
1965
- annotations?: OperationAnnotations;
1962
+ normalizationNotesKeys?: readonly ProviderLocaleKeyInput[];
1963
+ errorCodes?: readonly OperationErrorCode[];
1964
+ examples?: readonly OperationExample[];
1966
1965
  contract?: OperationContractMetadata;
1967
1966
  tags?: readonly string[];
1968
1967
  relatedOperations?: OperationRelationships;
1969
- toolRouter?: OperationToolRouterMetadata;
1970
1968
  observability?: OperationObservabilityConfig;
1971
1969
  transport?: OperationTransport;
1972
- retryOnAuthRefresh?: boolean;
1973
1970
  input: TInput;
1974
1971
  output: TOutput;
1975
1972
  handler(ctx: TContext, input: InferSchemaOutput<TInput>): OperationHandlerResult<InferSchemaOutput<TOutput>> | Promise<OperationHandlerResult<InferSchemaOutput<TOutput>>>;
@@ -2032,18 +2029,24 @@ export interface ProviderDefinition<TContext = ProviderContext> {
2032
2029
  id: string;
2033
2030
  version: string;
2034
2031
  runtime: "standard" | "shared" | "browser";
2032
+ /**
2033
+ * `vanilla` executes provider business logic outside the engine; `engine`
2034
+ * keeps session-bearing provider logic in the engine process.
2035
+ *
2036
+ * Omitted only for definitions authored before the engine migration. New
2037
+ * providers should declare the target explicitly.
2038
+ */
2039
+ runtimeTarget?: ProviderRuntimeTarget;
2035
2040
  /**
2036
2041
  * Optional deployment overrides, passed through verbatim from
2037
2042
  * `defineProvider({ deployment })`. Validation and profile resolution are
2038
2043
  * owned by the APIFuse registry builder, not the SDK.
2039
2044
  */
2040
2045
  deployment?: ProviderDeploymentOverrides;
2046
+ http?: Record<string, never> | true;
2041
2047
  allowedHosts?: string[];
2042
2048
  native?: NativeProviderConfig;
2043
- stealth?: {
2044
- profile: string;
2045
- platform: StealthPlatform;
2046
- };
2049
+ stealth?: StealthProfileSelection;
2047
2050
  proxy?: ProviderProxyConfig;
2048
2051
  ocr?: ProviderOcrConfig;
2049
2052
  stt?: ProviderSttConfig;
@@ -2052,11 +2055,16 @@ export interface ProviderDefinition<TContext = ProviderContext> {
2052
2055
  engine: BrowserEngine;
2053
2056
  };
2054
2057
  auth?: AuthConfig;
2058
+ choice?: Record<string, never> | true;
2055
2059
  reviewed?: ProviderReviewed;
2056
2060
  access?: ProviderAccessConfig;
2057
2061
  secrets?: ProviderSecretDeclaration[];
2062
+ env?: Record<string, never> | true;
2058
2063
  credential?: CredentialDeclaration;
2059
2064
  context?: ContextDeclaration;
2065
+ state?: Record<string, never> | true;
2066
+ cache?: Record<string, never> | true;
2067
+ files?: Record<string, never> | true;
2060
2068
  meta: ProviderMeta;
2061
2069
  operations: Record<string, OperationDefinition<SchemaLike, SchemaLike, TContext>>;
2062
2070
  healthMonitor?: ProviderHealthMonitorConfig;
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.2.0-beta.47",
2
+ "version": "2.2.0-beta.49",
3
3
  "name": "@apifuse/provider-sdk",
4
4
  "private": false,
5
5
  "type": "module",
@@ -113,6 +113,7 @@
113
113
  "check": "bun run lint && bun run type-check && bun run lint:deprecated && bun run lint:test-typesafety && bun run build",
114
114
  "api:update": "bun run build && bun scripts/api-reports.ts update",
115
115
  "api:check": "bun run build && bun scripts/api-reports.ts check",
116
+ "verify:chrome-headers": "bun scripts/verify-chrome-header-parity.ts",
116
117
  "changeset:check": "bun scripts/check-changeset.ts",
117
118
  "pack:check": "bun run build && bun bin/apifuse-pack-check.ts",
118
119
  "pack:smoke": "bun run build && bun bin/apifuse-pack-smoke.ts",
@@ -0,0 +1,6 @@
1
+ const reserveOperation = defineOperation<ProviderContext>()({
2
+ toolRouter: { riskClass: "write", approval: "always" },
3
+ input: InputSchema,
4
+ output: OutputSchema,
5
+ handler,
6
+ });
@@ -0,0 +1,3 @@
1
+ const migrated = {
2
+ riskClass: "read",;
3
+ };
@@ -0,0 +1,10 @@
1
+ const connectOperation = defineOperation<ProviderContext>()({
2
+ annotations: { readOnly: true },
3
+ toolRouter: {
4
+ connectionMode: "optional",
5
+ requiresConnection: true,
6
+ },
7
+ input: InputSchema,
8
+ output: OutputSchema,
9
+ handler,
10
+ });
@@ -0,0 +1,8 @@
1
+ const searchOperation = defineOperation<ProviderContext>()({
2
+ riskClass: "read",
3
+ titleKey: "operations.search.title",
4
+ docs: { titleKey: "operations.search.otherTitle" },
5
+ input: InputSchema,
6
+ output: OutputSchema,
7
+ handler,
8
+ });
@@ -0,0 +1,5 @@
1
+ import { searchOperation } from "./search";
2
+
3
+ export const operations = {
4
+ search: searchOperation,
5
+ };
@@ -0,0 +1,16 @@
1
+ export const searchOperation = defineOperation<ProviderContext>()({
2
+ annotations: { readOnly: true },
3
+ inputExamples: [
4
+ {
5
+ scenario: "Search by a precise phrase",
6
+ input: {
7
+ query: `京都
8
+ ホテル`,
9
+ },
10
+ rationale: "Shows whitespace preservation",
11
+ },
12
+ ],
13
+ input: InputSchema,
14
+ output: OutputSchema,
15
+ handler,
16
+ });
@@ -0,0 +1,3 @@
1
+ export default buildProvider({
2
+ operations: createTabelogProvider(client),
3
+ });
@@ -0,0 +1,31 @@
1
+ const searchOperation = defineOperation<ProviderContext>()({
2
+ annotations: {
3
+ readOnly: true,
4
+ openWorld: true,
5
+ idempotent: true,
6
+ rateLimit: { requests: 10 },
7
+ timeoutMs: 30_000,
8
+ },
9
+ toolRouter: {
10
+ name: "ignored",
11
+ requiresConnection: false,
12
+ connectionExternalRefParam: "accountId",
13
+ },
14
+ docs: {
15
+ titleKey: "operations.search.title",
16
+ descriptionKey: "operations.search.description",
17
+ summaryKey: "operations.search.summary",
18
+ markdownKey: "operations.search.markdown",
19
+ normalizationNotesKeys: ["operations.search.normalization.one"],
20
+ errorCodes: [{ code: "UPSTREAM" }],
21
+ requestExample: { query: "old" },
22
+ responseExample: { items: [] },
23
+ },
24
+ derivations: { value: "unused" } as unknown as Derivations,
25
+ retryOnAuthRefresh: true as unknown as boolean,
26
+ title: "Raw title" as unknown as string,
27
+ description: "Raw description" as unknown as string,
28
+ input: InputSchema,
29
+ output: OutputSchema,
30
+ handler,
31
+ });
@@ -0,0 +1,11 @@
1
+ const annotations = {
2
+ readOnly: true,
3
+ timeoutMs: 15_000,
4
+ } as const;
5
+
6
+ const detailOperation = defineOperation<ProviderContext>()({
7
+ annotations,
8
+ input: InputSchema,
9
+ output: OutputSchema,
10
+ handler,
11
+ });
@@ -0,0 +1,11 @@
1
+ import { toolRouterDefaults } from "./tool-router-defaults.js";
2
+
3
+ const importedSpreadOperation = defineOperation<ProviderContext>()({
4
+ annotations: { readOnly: true },
5
+ toolRouter: {
6
+ ...toolRouterDefaults,
7
+ },
8
+ input: InputSchema,
9
+ output: OutputSchema,
10
+ handler,
11
+ });
@@ -0,0 +1,11 @@
1
+ const provider = buildProvider({
2
+ operations: {
3
+ ping: {
4
+ annotations: { readOnly: true },
5
+ docs: { descriptionKey: "operations.ping.description" },
6
+ input: InputSchema,
7
+ output: OutputSchema,
8
+ handler,
9
+ },
10
+ },
11
+ });
@@ -0,0 +1,21 @@
1
+ const castTailOperation = defineOperation<ProviderContext>()({
2
+ annotations: {
3
+ ...({ timeoutMs: 15_000 as Milliseconds } as unknown as LegacyAnnotations),
4
+ },
5
+ toolRouter: {
6
+ ...({
7
+ riskClass: "write" as const,
8
+ approval: "always" as ApprovalMode,
9
+ connectionMode: "none" as ConnectionMode,
10
+ } as unknown as LegacyToolRouter),
11
+ },
12
+ docs: {
13
+ ...({
14
+ titleKey: "operations.castTail.title" as const,
15
+ descriptionKey: "operations.castTail.description" as LocaleKey,
16
+ } as unknown as LegacyDocs),
17
+ },
18
+ input: InputSchema,
19
+ output: OutputSchema,
20
+ handler,
21
+ });
@@ -0,0 +1,11 @@
1
+ const getStationInfoOperation = defineOperation<ProviderContext>()({
2
+ toolRouter: {
3
+ riskClass: "read",
4
+ approval: "never",
5
+ requiresConnection: false,
6
+ ...{ connectionMode: "none" as const },
7
+ },
8
+ input: InputSchema,
9
+ output: OutputSchema,
10
+ handler,
11
+ });
@@ -0,0 +1,14 @@
1
+ const overrideOperation = defineOperation<ProviderContext>()({
2
+ toolRouter: {
3
+ riskClass: "read",
4
+ connectionMode: "required" as const,
5
+ ...{
6
+ connectionMode: "none" as const,
7
+ approval: "never" as const,
8
+ },
9
+ approval: "always" as const,
10
+ },
11
+ input: InputSchema,
12
+ output: OutputSchema,
13
+ handler,
14
+ });
@@ -0,0 +1,7 @@
1
+ const searchOperation = defineOperation<ProviderContext>()({
2
+ annotations: { readOnly: true },
3
+ inputExamples: [{ scenario: "Search by title", input: { query: "castle" } }],
4
+ input: InputSchema,
5
+ output: OutputSchema,
6
+ handler,
7
+ });
@@ -0,0 +1,6 @@
1
+ const unknownOperation = defineOperation<ProviderContext>()({
2
+ annotations: { readOnly: false, destructive: false },
3
+ input: InputSchema,
4
+ output: OutputSchema,
5
+ handler,
6
+ });
@@ -0,0 +1,7 @@
1
+ const READ_ONLY = true;
2
+ const searchOperation = defineOperation<ProviderContext>()({
3
+ annotations: { readOnly: READ_ONLY },
4
+ input: InputSchema,
5
+ output: OutputSchema,
6
+ handler,
7
+ });
@@ -0,0 +1,6 @@
1
+ const searchOperation = defineOperation<ProviderContext>()({
2
+ toolRouter: { riskClass: "read", approval: "never" },
3
+ input: InputSchema,
4
+ output: OutputSchema,
5
+ handler,
6
+ });
@@ -0,0 +1,7 @@
1
+ const cancelOperation = defineOperation<ProviderContext>()({
2
+ annotations: { destructive: true },
3
+ toolRouter: { riskClass: "write" },
4
+ input: InputSchema,
5
+ output: OutputSchema,
6
+ handler,
7
+ });
@@ -0,0 +1,7 @@
1
+ const downloadOperation = defineStreamOperation<ProviderContext>()({
2
+ annotations: { readOnly: true },
3
+ toolRouter: { connectionMode: "optional" },
4
+ input: InputSchema,
5
+ output: OutputSchema,
6
+ handler,
7
+ });
@@ -0,0 +1,15 @@
1
+ const requiredConnection = {
2
+ requiresConnection: true,
3
+ connectionExternalRefParam: "profileId",
4
+ } as const;
5
+
6
+ const updateOperation = defineOperation<ProviderContext>()({
7
+ annotations: { destructive: true },
8
+ toolRouter: {
9
+ ...requiredConnection,
10
+ approval: "always",
11
+ },
12
+ input: InputSchema,
13
+ output: OutputSchema,
14
+ handler,
15
+ });
@@ -0,0 +1,4 @@
1
+ const brokenOperation = defineOperation<ProviderContext>()({
2
+ annotations: { readOnly: true },
3
+ input:,
4
+ });