@apifuse/provider-sdk 2.1.0-beta.2 → 2.1.0-beta.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (231) hide show
  1. package/AUTHORING.md +330 -8
  2. package/CHANGELOG.md +89 -1
  3. package/README.md +64 -17
  4. package/SUBMISSION.md +86 -0
  5. package/bin/apifuse-check.ts +60 -6
  6. package/bin/apifuse-dev.ts +58 -8
  7. package/bin/apifuse-pack-check.ts +32 -2
  8. package/bin/apifuse-pack-smoke.ts +133 -6
  9. package/bin/apifuse-perf.ts +142 -49
  10. package/bin/apifuse-record.ts +182 -104
  11. package/bin/apifuse-submit-check.ts +3243 -0
  12. package/bin/apifuse.ts +1 -1
  13. package/dist/auth.d.ts +76 -0
  14. package/dist/auth.js +436 -0
  15. package/dist/ceremonies/index.d.ts +41 -0
  16. package/dist/ceremonies/index.js +490 -0
  17. package/dist/choice-token.d.ts +24 -0
  18. package/dist/choice-token.js +74 -0
  19. package/dist/cli/commands.d.ts +10 -0
  20. package/dist/cli/commands.js +80 -0
  21. package/dist/cli/create.d.ts +47 -0
  22. package/dist/cli/create.js +777 -0
  23. package/dist/cli/templates/provider/.dockerignore.tpl +22 -0
  24. package/dist/cli/templates/provider/.gitignore.tpl +22 -0
  25. package/dist/cli/templates/provider/AGENTS.md.tpl +87 -0
  26. package/dist/cli/templates/provider/CLAUDE.md.tpl +1 -0
  27. package/dist/cli/templates/provider/Dockerfile.tpl +7 -0
  28. package/dist/cli/templates/provider/README.md.tpl +163 -0
  29. package/dist/cli/templates/provider/dev.ts.tpl +5 -0
  30. package/dist/cli/templates/provider/domain/README.md.tpl +3 -0
  31. package/dist/cli/templates/provider/index.test.ts.tpl +13 -0
  32. package/dist/cli/templates/provider/index.ts.tpl +15 -0
  33. package/dist/cli/templates/provider/mappers/README.md.tpl +3 -0
  34. package/dist/cli/templates/provider/meta.ts.tpl +7 -0
  35. package/dist/cli/templates/provider/operations/index.ts.tpl +5 -0
  36. package/dist/cli/templates/provider/operations/ping.ts.tpl +24 -0
  37. package/dist/cli/templates/provider/schemas/ping.ts.tpl +24 -0
  38. package/dist/cli/templates/provider/skills/fixtures-and-recording/SKILL.md.tpl +58 -0
  39. package/dist/cli/templates/provider/skills/health-checks-and-fail-closed/SKILL.md.tpl +65 -0
  40. package/dist/cli/templates/provider/skills/normalization-standards/SKILL.md.tpl +57 -0
  41. package/dist/cli/templates/provider/skills/pagination-and-counts/SKILL.md.tpl +52 -0
  42. package/dist/cli/templates/provider/skills/upstream-contract-verification/SKILL.md.tpl +45 -0
  43. package/dist/cli/templates/provider/skills/upstream-notes/README.md.tpl +13 -0
  44. package/dist/cli/templates/provider/start.ts.tpl +5 -0
  45. package/dist/cli/templates/provider/upstream/README.md.tpl +3 -0
  46. package/dist/config/loader.d.ts +107 -0
  47. package/dist/config/loader.js +935 -0
  48. package/dist/contract-json.d.ts +9 -0
  49. package/dist/contract-json.js +51 -0
  50. package/dist/contract-serialization.d.ts +4 -0
  51. package/dist/contract-serialization.js +78 -0
  52. package/dist/contract-types.d.ts +49 -0
  53. package/dist/contract-types.js +1 -0
  54. package/dist/contract.d.ts +6 -0
  55. package/dist/contract.js +156 -0
  56. package/dist/define.d.ts +100 -0
  57. package/dist/define.js +1383 -0
  58. package/dist/dev.d.ts +9 -0
  59. package/dist/dev.js +15 -0
  60. package/dist/errors.d.ts +59 -0
  61. package/dist/errors.js +97 -0
  62. package/dist/i18n/catalog.d.ts +29 -0
  63. package/dist/i18n/catalog.js +159 -0
  64. package/dist/i18n/index.d.ts +2 -0
  65. package/dist/i18n/index.js +2 -0
  66. package/dist/i18n/keys.d.ts +10 -0
  67. package/dist/i18n/keys.js +34 -0
  68. package/dist/index.d.ts +42 -0
  69. package/dist/index.js +38 -0
  70. package/dist/lint.d.ts +74 -0
  71. package/dist/lint.js +729 -0
  72. package/dist/observability.d.ts +5 -0
  73. package/dist/observability.js +39 -0
  74. package/dist/provider.d.ts +11 -0
  75. package/dist/provider.js +9 -0
  76. package/dist/public-schema-field-lint.d.ts +2 -0
  77. package/dist/public-schema-field-lint.js +158 -0
  78. package/dist/recipes/gov-api.d.ts +19 -0
  79. package/dist/recipes/gov-api.js +72 -0
  80. package/dist/recipes/rest-api.d.ts +21 -0
  81. package/dist/recipes/rest-api.js +115 -0
  82. package/dist/runtime/auth-flow.d.ts +14 -0
  83. package/dist/runtime/auth-flow.js +46 -0
  84. package/dist/runtime/browser.d.ts +25 -0
  85. package/dist/runtime/browser.js +1237 -0
  86. package/dist/runtime/cache.d.ts +10 -0
  87. package/dist/runtime/cache.js +372 -0
  88. package/dist/runtime/choice.d.ts +15 -0
  89. package/dist/runtime/choice.js +435 -0
  90. package/dist/runtime/credential.d.ts +8 -0
  91. package/dist/runtime/credential.js +61 -0
  92. package/dist/runtime/env.d.ts +2 -0
  93. package/dist/runtime/env.js +10 -0
  94. package/dist/runtime/executor.d.ts +16 -0
  95. package/dist/runtime/executor.js +51 -0
  96. package/dist/runtime/http.d.ts +8 -0
  97. package/dist/runtime/http.js +726 -0
  98. package/dist/runtime/insights.d.ts +9 -0
  99. package/dist/runtime/insights.js +324 -0
  100. package/dist/runtime/instrumentation.d.ts +8 -0
  101. package/dist/runtime/instrumentation.js +269 -0
  102. package/dist/runtime/key-derivation.d.ts +24 -0
  103. package/dist/runtime/key-derivation.js +73 -0
  104. package/dist/runtime/keyring.d.ts +25 -0
  105. package/dist/runtime/keyring.js +93 -0
  106. package/dist/runtime/namespace.d.ts +9 -0
  107. package/dist/runtime/namespace.js +19 -0
  108. package/dist/runtime/otlp.d.ts +39 -0
  109. package/dist/runtime/otlp.js +103 -0
  110. package/dist/runtime/perf.d.ts +12 -0
  111. package/dist/runtime/perf.js +52 -0
  112. package/dist/runtime/prevalidate.d.ts +12 -0
  113. package/dist/runtime/prevalidate.js +173 -0
  114. package/dist/runtime/provider.d.ts +2 -0
  115. package/dist/runtime/provider.js +11 -0
  116. package/dist/runtime/proxy-errors.d.ts +21 -0
  117. package/dist/runtime/proxy-errors.js +83 -0
  118. package/dist/runtime/proxy-telemetry.d.ts +8 -0
  119. package/dist/runtime/proxy-telemetry.js +174 -0
  120. package/dist/runtime/redis.d.ts +17 -0
  121. package/dist/runtime/redis.js +82 -0
  122. package/dist/runtime/request-options.d.ts +3 -0
  123. package/dist/runtime/request-options.js +42 -0
  124. package/dist/runtime/state.d.ts +17 -0
  125. package/dist/runtime/state.js +344 -0
  126. package/dist/runtime/stealth.d.ts +21 -0
  127. package/dist/runtime/stealth.js +980 -0
  128. package/dist/runtime/stt.d.ts +22 -0
  129. package/dist/runtime/stt.js +480 -0
  130. package/dist/runtime/trace.d.ts +26 -0
  131. package/dist/runtime/trace.js +142 -0
  132. package/dist/runtime/waterfall.d.ts +12 -0
  133. package/dist/runtime/waterfall.js +147 -0
  134. package/dist/schema.d.ts +74 -0
  135. package/dist/schema.js +243 -0
  136. package/dist/serve.d.ts +1 -0
  137. package/dist/serve.js +1 -0
  138. package/dist/server/index.d.ts +3 -0
  139. package/dist/server/index.js +2 -0
  140. package/dist/server/serve.d.ts +64 -0
  141. package/dist/server/serve.js +1118 -0
  142. package/dist/server/types.d.ts +136 -0
  143. package/dist/server/types.js +86 -0
  144. package/dist/stealth/profiles.d.ts +4 -0
  145. package/dist/stealth/profiles.js +259 -0
  146. package/dist/stream.d.ts +44 -0
  147. package/dist/stream.js +151 -0
  148. package/dist/testing/helpers.d.ts +23 -0
  149. package/dist/testing/helpers.js +95 -0
  150. package/dist/testing/index.d.ts +2 -0
  151. package/dist/testing/index.js +2 -0
  152. package/dist/testing/run.d.ts +34 -0
  153. package/dist/testing/run.js +307 -0
  154. package/dist/types.d.ts +1467 -0
  155. package/dist/types.js +61 -0
  156. package/dist/utils/date.d.ts +6 -0
  157. package/dist/utils/date.js +101 -0
  158. package/dist/utils/parse.d.ts +16 -0
  159. package/dist/utils/parse.js +51 -0
  160. package/dist/utils/text.d.ts +4 -0
  161. package/dist/utils/text.js +14 -0
  162. package/dist/utils/transform.d.ts +8 -0
  163. package/dist/utils/transform.js +48 -0
  164. package/package.json +57 -29
  165. package/src/auth.ts +786 -0
  166. package/src/ceremonies/index.ts +8 -2
  167. package/src/choice-token.ts +165 -0
  168. package/src/cli/commands.ts +34 -11
  169. package/src/cli/create.ts +254 -128
  170. package/src/cli/templates/provider/.dockerignore.tpl +22 -0
  171. package/src/cli/templates/provider/.gitignore.tpl +22 -0
  172. package/src/cli/templates/provider/AGENTS.md.tpl +87 -0
  173. package/src/cli/templates/provider/CLAUDE.md.tpl +1 -0
  174. package/src/cli/templates/provider/README.md.tpl +87 -7
  175. package/src/cli/templates/provider/dev.ts.tpl +1 -1
  176. package/src/cli/templates/provider/domain/README.md.tpl +3 -0
  177. package/src/cli/templates/provider/index.ts.tpl +5 -47
  178. package/src/cli/templates/provider/mappers/README.md.tpl +3 -0
  179. package/src/cli/templates/provider/meta.ts.tpl +7 -0
  180. package/src/cli/templates/provider/operations/index.ts.tpl +5 -0
  181. package/src/cli/templates/provider/operations/ping.ts.tpl +24 -0
  182. package/src/cli/templates/provider/schemas/ping.ts.tpl +24 -0
  183. package/src/cli/templates/provider/skills/fixtures-and-recording/SKILL.md.tpl +58 -0
  184. package/src/cli/templates/provider/skills/health-checks-and-fail-closed/SKILL.md.tpl +65 -0
  185. package/src/cli/templates/provider/skills/normalization-standards/SKILL.md.tpl +57 -0
  186. package/src/cli/templates/provider/skills/pagination-and-counts/SKILL.md.tpl +52 -0
  187. package/src/cli/templates/provider/skills/upstream-contract-verification/SKILL.md.tpl +45 -0
  188. package/src/cli/templates/provider/skills/upstream-notes/README.md.tpl +13 -0
  189. package/src/cli/templates/provider/start.ts.tpl +1 -1
  190. package/src/cli/templates/provider/upstream/README.md.tpl +3 -0
  191. package/src/config/loader.ts +1224 -9
  192. package/src/contract-json.ts +75 -0
  193. package/src/contract-serialization.ts +89 -0
  194. package/src/contract-types.ts +52 -0
  195. package/src/contract.ts +216 -0
  196. package/src/define.ts +1820 -70
  197. package/src/errors.ts +27 -0
  198. package/src/i18n/catalog.ts +277 -0
  199. package/src/i18n/index.ts +2 -0
  200. package/src/i18n/keys.ts +64 -0
  201. package/src/index.ts +189 -9
  202. package/src/lint.ts +580 -73
  203. package/src/observability.ts +41 -0
  204. package/src/provider.ts +131 -4
  205. package/src/public-schema-field-lint.ts +237 -0
  206. package/src/runtime/auth-flow.ts +9 -0
  207. package/src/runtime/browser.ts +1054 -51
  208. package/src/runtime/cache.ts +528 -0
  209. package/src/runtime/choice.ts +760 -0
  210. package/src/runtime/executor.ts +32 -3
  211. package/src/runtime/http.ts +980 -195
  212. package/src/runtime/insights.ts +11 -11
  213. package/src/runtime/instrumentation.ts +12 -4
  214. package/src/runtime/key-derivation.ts +1 -1
  215. package/src/runtime/keyring.ts +4 -3
  216. package/src/runtime/proxy-errors.ts +132 -0
  217. package/src/runtime/proxy-telemetry.ts +253 -0
  218. package/src/runtime/redis.ts +116 -0
  219. package/src/runtime/request-options.ts +66 -0
  220. package/src/runtime/state.ts +563 -0
  221. package/src/runtime/stealth.ts +1336 -0
  222. package/src/runtime/stt.ts +629 -0
  223. package/src/runtime/trace.ts +1 -1
  224. package/src/schema.ts +363 -1
  225. package/src/server/serve.ts +1192 -75
  226. package/src/server/types.ts +37 -0
  227. package/src/stream.ts +210 -0
  228. package/src/testing/run.ts +40 -6
  229. package/src/types.ts +1283 -59
  230. package/src/runtime/tls.ts +0 -434
  231. package/src/types/playwright-stealth.d.ts +0 -9
@@ -0,0 +1,41 @@
1
+ export const PROVIDER_OBSERVABILITY_TAXONOMY_VERSION = "2026-05-26";
2
+
3
+ export const PROVIDER_ERROR_CATEGORIES = [
4
+ "ok",
5
+ "timeout",
6
+ "network",
7
+ "upstream_http",
8
+ "upstream_rate_limited",
9
+ "upstream_auth",
10
+ "upstream_schema_drift",
11
+ "proxy_pool",
12
+ "anti_bot_blocked",
13
+ "credential_expired",
14
+ "credential_unavailable",
15
+ "input_validation",
16
+ "output_validation",
17
+ "provider_error",
18
+ "internal_error",
19
+ "unclassified",
20
+ ] as const;
21
+
22
+ export type ProviderErrorCategory = (typeof PROVIDER_ERROR_CATEGORIES)[number];
23
+
24
+ export function categoryForStatus(status: number): ProviderErrorCategory {
25
+ if (status >= 200 && status < 400) return "ok";
26
+ if (status === 408 || status === 504) return "timeout";
27
+ if (status === 429) return "upstream_rate_limited";
28
+ if (status === 401 || status === 403) return "upstream_auth";
29
+ if (status >= 400) return "upstream_http";
30
+ return "unclassified";
31
+ }
32
+
33
+ export function isRetryableCategory(category: ProviderErrorCategory): boolean {
34
+ return (
35
+ category === "timeout" ||
36
+ category === "network" ||
37
+ category === "upstream_rate_limited" ||
38
+ category === "upstream_http" ||
39
+ category === "proxy_pool"
40
+ );
41
+ }
package/src/provider.ts CHANGED
@@ -1,13 +1,140 @@
1
- export { z } from "zod";
2
-
1
+ export {
2
+ AuthAbortError,
3
+ credentialsAuthChallenge,
4
+ createAuthFlowHelpers,
5
+ defineCredentialsAuth,
6
+ } from "./auth";
7
+ export type {
8
+ CredentialsAuthChallengeDefinition,
9
+ CredentialsAuthChallengeRequest,
10
+ CredentialsAuthCompleteResult,
11
+ CredentialsAuthCredential,
12
+ CredentialsAuthField,
13
+ CredentialsAuthFields,
14
+ CredentialsAuthFieldType,
15
+ CredentialsAuthInput,
16
+ CredentialsAuthLoginResult,
17
+ DefineCredentialsAuthOptions,
18
+ DefinedCredentialsAuth,
19
+ } from "./auth";
3
20
  export { createFormCeremony } from "./ceremonies";
4
- export { defineOperation, defineProvider } from "./define";
5
- export { AuthError, ProviderError, ValidationError } from "./errors";
21
+ export {
22
+ assertFreshProviderChoiceIssuedAt,
23
+ createProviderChoiceToken,
24
+ ProviderChoiceTokenError,
25
+ type ProviderChoiceTokenErrorReason,
26
+ type ProviderChoiceTokenPayload,
27
+ parseProviderChoiceToken,
28
+ } from "./choice-token";
29
+ export {
30
+ centered,
31
+ delayed,
32
+ defineHealthJourney,
33
+ defineOperation,
34
+ defineProvider,
35
+ defineSmsOtpMatcher,
36
+ every,
37
+ } from "./define";
38
+ export {
39
+ AuthError,
40
+ ProviderError,
41
+ SessionExpiredError,
42
+ TransportError,
43
+ ValidationError,
44
+ } from "./errors";
45
+ export {
46
+ getProviderLocalePath,
47
+ providerLocaleKey,
48
+ qualifyProviderLocaleKey,
49
+ } from "./i18n";
50
+ export {
51
+ type CreateProviderChoiceContextOptions,
52
+ createProviderChoiceContext,
53
+ createTestProviderChoiceContext,
54
+ PROVIDER_RUNTIME_CHOICE_TOKEN_MASTER_SECRET_ENV,
55
+ } from "./runtime/choice";
56
+ export {
57
+ APIFUSE_DESCRIPTION_KEY_META_KEY,
58
+ APIFUSE_REDACTION_MARKER,
59
+ APIFUSE_SENSITIVE_KIND_META_KEY,
60
+ APIFUSE_SENSITIVE_META_KEY,
61
+ collectSensitivePaths,
62
+ describeKey,
63
+ field,
64
+ fields,
65
+ isSensitiveSchema,
66
+ redactPayload,
67
+ type SensitiveFieldKind,
68
+ type SensitiveFieldOptions,
69
+ type SensitivePath,
70
+ sensitive,
71
+ z,
72
+ } from "./schema";
6
73
  export type {
74
+ AuthAbortData,
75
+ AuthAbortRetry,
76
+ AuthFlowTerminalContext,
77
+ AuthMode,
78
+ AuthSafeData,
79
+ AuthSafeJson,
7
80
  FlowContext,
81
+ HealthCheckAssertionContext,
82
+ HealthCheckCase,
83
+ HealthCheckSuite,
84
+ HealthCheckUnsupported,
85
+ HealthJourneyDefinition,
86
+ HealthJourneyEventContext,
87
+ HealthJourneyManualTriggerPolicy,
88
+ HealthJourneyRunContext,
89
+ HealthJourneyRunResult,
90
+ HealthScheduleRandomization,
91
+ HttpRetryOptions,
92
+ HttpRetrySummary,
8
93
  InferSchemaOutput,
94
+ OperationApprovalPolicy,
95
+ OperationContractMetadata,
9
96
  OperationDefinition,
97
+ OperationDocMeta,
98
+ OperationErrorCode,
99
+ OperationInputExample,
100
+ OperationLifecycle,
101
+ OperationObservabilityConfig,
102
+ OperationObservabilitySensitiveConfig,
103
+ OperationRelationships,
104
+ OperationRiskClass,
105
+ OperationSensitivePath,
106
+ OperationToolRouterMetadata,
107
+ OperationTransport,
108
+ ProviderAccessVisibility,
109
+ ProviderChoiceBindingOptions,
110
+ ProviderChoiceContext,
111
+ ProviderChoiceIssueOptions,
112
+ ProviderChoiceParseOptions,
10
113
  ProviderContext,
114
+ ProviderDefinition,
115
+ ProviderLocale,
116
+ ProviderLocaleKey,
117
+ ProviderLocaleKeyInput,
118
+ ProviderLogoProfile,
119
+ ProviderProxyPolicy,
120
+ ProviderPublicConnectionMode,
121
+ ProviderPublicProfile,
122
+ ProviderRuntimeState,
123
+ ProviderStateDurationString,
124
+ ProviderStateNamespace,
125
+ ProviderSupportLevel,
11
126
  SchemaLike,
127
+ SmsOtpMatcherDefinition,
12
128
  StandardSchemaV1,
129
+ StateCasResult,
130
+ StateNamespaceOptions,
131
+ StateValue,
132
+ StateWriteOptions,
133
+ } from "./types";
134
+ export {
135
+ HttpRetryAfterPolicy,
136
+ HttpRetryDelayStrategy,
137
+ HttpRetryJitter,
138
+ HttpRetryPreset,
139
+ HttpRetryUnsafeMethodPolicy,
13
140
  } from "./types";
@@ -0,0 +1,237 @@
1
+ import type { ZodType } from "zod";
2
+
3
+ import type { LintDiagnostic } from "./lint";
4
+
5
+ type SchemaLike = ZodType & {
6
+ def?: Record<string, unknown>;
7
+ _def?: Record<string, unknown>;
8
+ shape?: Record<string, SchemaLike> | (() => Record<string, SchemaLike>);
9
+ element?: SchemaLike;
10
+ items?: SchemaLike[];
11
+ options?: SchemaLike[] | Set<SchemaLike> | Map<string, SchemaLike>;
12
+ innerType?: SchemaLike;
13
+ sourceType?: () => SchemaLike;
14
+ unwrap?: () => SchemaLike;
15
+ in?: SchemaLike;
16
+ out?: SchemaLike;
17
+ left?: SchemaLike;
18
+ right?: SchemaLike;
19
+ };
20
+
21
+ const ESTABLISHED_APIFUSE_PROTOCOL_FIELDS = new Set(["externalRef"]);
22
+
23
+ const UPSTREAM_FIELD_REPLACEMENTS = new Map<string, string>([
24
+ ["display", "limit"],
25
+ ["start", "offset"],
26
+ ["sort", "sort_by"],
27
+ ["lprice", "lowest_price"],
28
+ ["hprice", "highest_price"],
29
+ ["mallName", "mall_name"],
30
+ ["productId", "product_id"],
31
+ ["productType", "product_type_code"],
32
+ ["lastBuildDate", "upstream_generated_at"],
33
+ ["meta", "summary"],
34
+ ]);
35
+
36
+ function isSchema(value: unknown): value is SchemaLike {
37
+ return (
38
+ !!value &&
39
+ typeof value === "object" &&
40
+ "safeParse" in value &&
41
+ typeof value.safeParse === "function"
42
+ );
43
+ }
44
+
45
+ function getSchemaDef(schema: SchemaLike): Record<string, unknown> {
46
+ const def = schema.def ?? schema._def;
47
+ return def && typeof def === "object" ? def : {};
48
+ }
49
+
50
+ function isSchemaRecord(value: unknown): value is Record<string, SchemaLike> {
51
+ if (!value || typeof value !== "object") {
52
+ return false;
53
+ }
54
+ return Object.values(value).every(isSchema);
55
+ }
56
+
57
+ function getObjectShape(schema: SchemaLike): Record<string, SchemaLike> {
58
+ const rawShape =
59
+ typeof schema.shape === "function" ? schema.shape() : schema.shape;
60
+ if (isSchemaRecord(rawShape)) {
61
+ return rawShape;
62
+ }
63
+
64
+ const defShape = getSchemaDef(schema).shape;
65
+ if (typeof defShape === "function") {
66
+ const resolved = defShape();
67
+ return isSchemaRecord(resolved) ? resolved : {};
68
+ }
69
+ return isSchemaRecord(defShape) ? defShape : {};
70
+ }
71
+
72
+ function appendSchemaChildren(
73
+ children: SchemaLike[],
74
+ value: unknown,
75
+ ): SchemaLike[] {
76
+ if (isSchema(value)) {
77
+ children.push(value);
78
+ return children;
79
+ }
80
+ if (Array.isArray(value)) {
81
+ children.push(...value.filter(isSchema));
82
+ return children;
83
+ }
84
+ if (value instanceof Set) {
85
+ children.push(...Array.from(value).filter(isSchema));
86
+ return children;
87
+ }
88
+ if (value instanceof Map) {
89
+ children.push(...Array.from(value.values()).filter(isSchema));
90
+ return children;
91
+ }
92
+ return children;
93
+ }
94
+
95
+ function safeSourceType(schema: SchemaLike): SchemaLike | undefined {
96
+ try {
97
+ return schema.sourceType?.();
98
+ } catch {
99
+ return undefined;
100
+ }
101
+ }
102
+
103
+ function safeUnwrap(schema: SchemaLike): SchemaLike | undefined {
104
+ try {
105
+ return schema.unwrap?.();
106
+ } catch {
107
+ return undefined;
108
+ }
109
+ }
110
+
111
+ function getTransparentChildSchemas(schema: SchemaLike): SchemaLike[] {
112
+ const def = getSchemaDef(schema);
113
+ const children: SchemaLike[] = [];
114
+ for (const value of [
115
+ schema.element,
116
+ schema.items,
117
+ schema.options,
118
+ schema.innerType,
119
+ safeSourceType(schema),
120
+ safeUnwrap(schema),
121
+ schema.in,
122
+ schema.out,
123
+ schema.left,
124
+ schema.right,
125
+ def.schema,
126
+ def.innerType,
127
+ def.type,
128
+ def.valueType,
129
+ def.item,
130
+ def.items,
131
+ def.rest,
132
+ def.catchall,
133
+ def.option,
134
+ def.options,
135
+ def.pipe,
136
+ def.payload,
137
+ def.sourceType,
138
+ def.left,
139
+ def.right,
140
+ ]) {
141
+ appendSchemaChildren(children, value);
142
+ }
143
+ return children;
144
+ }
145
+
146
+ function recommendedReplacement(fieldName: string): string | undefined {
147
+ if (/^category\d+$/.test(fieldName)) {
148
+ return "category_path";
149
+ }
150
+ if (UPSTREAM_FIELD_REPLACEMENTS.has(fieldName)) {
151
+ return UPSTREAM_FIELD_REPLACEMENTS.get(fieldName);
152
+ }
153
+ if (/[a-z][A-Z]/.test(fieldName)) {
154
+ return fieldName.replace(/([a-z0-9])([A-Z])/g, "$1_$2").toLowerCase();
155
+ }
156
+ return undefined;
157
+ }
158
+
159
+ function collectPublicSchemaFieldDiagnostics(
160
+ providerId: string,
161
+ operationId: string,
162
+ schema: unknown,
163
+ basePath: string,
164
+ seen = new Set<SchemaLike>(),
165
+ ): LintDiagnostic[] {
166
+ if (!isSchema(schema) || seen.has(schema)) {
167
+ return [];
168
+ }
169
+
170
+ seen.add(schema);
171
+ const diagnostics: LintDiagnostic[] = [];
172
+ for (const [fieldName, child] of Object.entries(getObjectShape(schema))) {
173
+ const fieldPath = `${basePath}.${fieldName}`;
174
+ const replacement = ESTABLISHED_APIFUSE_PROTOCOL_FIELDS.has(fieldName)
175
+ ? undefined
176
+ : recommendedReplacement(fieldName);
177
+ if (replacement) {
178
+ diagnostics.push({
179
+ rule: "public-schema-upstream-field",
180
+ level: "error",
181
+ field: fieldPath,
182
+ message: `Provider "${providerId}" operation "${operationId}" public schema field "${fieldPath}" uses upstream-shaped field "${fieldName}"; use APIFuse field "${replacement}" instead.`,
183
+ });
184
+ }
185
+ diagnostics.push(
186
+ ...collectPublicSchemaFieldDiagnostics(
187
+ providerId,
188
+ operationId,
189
+ child,
190
+ fieldPath,
191
+ seen,
192
+ ),
193
+ );
194
+ }
195
+
196
+ for (const child of getTransparentChildSchemas(schema)) {
197
+ const childPath = schema.element === child ? `${basePath}[]` : basePath;
198
+ diagnostics.push(
199
+ ...collectPublicSchemaFieldDiagnostics(
200
+ providerId,
201
+ operationId,
202
+ child,
203
+ childPath,
204
+ seen,
205
+ ),
206
+ );
207
+ }
208
+
209
+ return diagnostics;
210
+ }
211
+
212
+ export function lintPublicSchemaFieldNames(
213
+ providerId: string | undefined,
214
+ operationId: string,
215
+ input: unknown,
216
+ output: unknown,
217
+ enforce: boolean,
218
+ ): LintDiagnostic[] {
219
+ if (!providerId || !enforce) {
220
+ return [];
221
+ }
222
+
223
+ return [
224
+ ...collectPublicSchemaFieldDiagnostics(
225
+ providerId,
226
+ operationId,
227
+ input,
228
+ "input",
229
+ ),
230
+ ...collectPublicSchemaFieldDiagnostics(
231
+ providerId,
232
+ operationId,
233
+ output,
234
+ "output",
235
+ ),
236
+ ];
237
+ }
@@ -1,10 +1,14 @@
1
1
  import { ContextAccessError } from "../errors";
2
+ import { createAuthFlowHelpers } from "../auth";
2
3
  import type {
3
4
  ContextScratchpad,
4
5
  EnvContext,
5
6
  FlowContext,
6
7
  HttpClient,
8
+ StealthClient,
9
+ SttContext,
7
10
  } from "../types";
11
+ import { createUnsupportedSttClient } from "./stt";
8
12
 
9
13
  function normalizeAllowedKeys(allowedKeys: string[]): Set<string> {
10
14
  return new Set(allowedKeys.filter((key) => key.trim().length > 0));
@@ -47,6 +51,7 @@ export function createScratchpad(
47
51
 
48
52
  export function createFlowContext(options: {
49
53
  http: HttpClient;
54
+ stealth: StealthClient;
50
55
  env: EnvContext;
51
56
  tenantId: string;
52
57
  providerId: string;
@@ -54,6 +59,7 @@ export function createFlowContext(options: {
54
59
  externalRef?: string;
55
60
  allowedKeys: string[];
56
61
  initialContext?: Record<string, unknown>;
62
+ stt?: SttContext;
57
63
  }): FlowContext {
58
64
  return {
59
65
  connectionId: options.connectionId,
@@ -61,7 +67,10 @@ export function createFlowContext(options: {
61
67
  tenantId: options.tenantId,
62
68
  providerId: options.providerId,
63
69
  http: options.http,
70
+ stealth: options.stealth,
64
71
  env: options.env,
65
72
  context: createScratchpad(options.allowedKeys, options.initialContext),
73
+ stt: options.stt ?? createUnsupportedSttClient(),
74
+ auth: createAuthFlowHelpers(),
66
75
  };
67
76
  }