@apifuse/provider-sdk 2.1.0-beta.1 → 2.1.0-beta.10

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 (212) hide show
  1. package/AUTHORING.md +208 -2
  2. package/CHANGELOG.md +47 -0
  3. package/README.md +114 -10
  4. package/SUBMISSION.md +87 -0
  5. package/bin/apifuse-check.ts +86 -4
  6. package/bin/apifuse-dev.ts +87 -13
  7. package/bin/apifuse-pack-check.ts +80 -0
  8. package/bin/apifuse-pack-smoke.ts +303 -2
  9. package/bin/apifuse-perf.ts +142 -49
  10. package/bin/apifuse-record.ts +182 -104
  11. package/bin/apifuse-submit-check.ts +2538 -0
  12. package/bin/apifuse.ts +1 -1
  13. package/dist/ceremonies/index.d.ts +41 -0
  14. package/dist/ceremonies/index.js +490 -0
  15. package/dist/choice-token.d.ts +24 -0
  16. package/dist/choice-token.js +74 -0
  17. package/dist/cli/commands.d.ts +10 -0
  18. package/dist/cli/commands.js +80 -0
  19. package/dist/cli/create.d.ts +47 -0
  20. package/dist/cli/create.js +762 -0
  21. package/dist/cli/templates/provider/.dockerignore.tpl +22 -0
  22. package/dist/cli/templates/provider/.gitignore.tpl +22 -0
  23. package/dist/cli/templates/provider/Dockerfile.tpl +7 -0
  24. package/dist/cli/templates/provider/README.md.tpl +160 -0
  25. package/dist/cli/templates/provider/dev.ts.tpl +5 -0
  26. package/dist/cli/templates/provider/domain/README.md.tpl +3 -0
  27. package/dist/cli/templates/provider/index.test.ts.tpl +13 -0
  28. package/dist/cli/templates/provider/index.ts.tpl +15 -0
  29. package/dist/cli/templates/provider/mappers/README.md.tpl +3 -0
  30. package/dist/cli/templates/provider/meta.ts.tpl +7 -0
  31. package/dist/cli/templates/provider/operations/index.ts.tpl +5 -0
  32. package/dist/cli/templates/provider/operations/ping.ts.tpl +24 -0
  33. package/dist/cli/templates/provider/schemas/ping.ts.tpl +24 -0
  34. package/dist/cli/templates/provider/start.ts.tpl +5 -0
  35. package/dist/cli/templates/provider/upstream/README.md.tpl +3 -0
  36. package/dist/config/loader.d.ts +107 -0
  37. package/dist/config/loader.js +935 -0
  38. package/dist/contract-json.d.ts +9 -0
  39. package/dist/contract-json.js +51 -0
  40. package/dist/contract-serialization.d.ts +4 -0
  41. package/dist/contract-serialization.js +78 -0
  42. package/dist/contract-types.d.ts +49 -0
  43. package/dist/contract-types.js +1 -0
  44. package/dist/contract.d.ts +6 -0
  45. package/dist/contract.js +155 -0
  46. package/dist/define.d.ts +97 -0
  47. package/dist/define.js +1320 -0
  48. package/dist/dev.d.ts +9 -0
  49. package/dist/dev.js +15 -0
  50. package/dist/errors.d.ts +59 -0
  51. package/dist/errors.js +97 -0
  52. package/dist/i18n/catalog.d.ts +29 -0
  53. package/dist/i18n/catalog.js +159 -0
  54. package/dist/i18n/index.d.ts +2 -0
  55. package/dist/i18n/index.js +2 -0
  56. package/dist/i18n/keys.d.ts +10 -0
  57. package/dist/i18n/keys.js +34 -0
  58. package/dist/index.d.ts +41 -0
  59. package/dist/index.js +37 -0
  60. package/dist/lint.d.ts +73 -0
  61. package/dist/lint.js +702 -0
  62. package/dist/observability.d.ts +5 -0
  63. package/dist/observability.js +39 -0
  64. package/dist/provider.d.ts +9 -0
  65. package/dist/provider.js +8 -0
  66. package/dist/public-schema-field-lint.d.ts +2 -0
  67. package/dist/public-schema-field-lint.js +158 -0
  68. package/dist/recipes/gov-api.d.ts +19 -0
  69. package/dist/recipes/gov-api.js +72 -0
  70. package/dist/recipes/rest-api.d.ts +21 -0
  71. package/dist/recipes/rest-api.js +115 -0
  72. package/dist/runtime/auth-flow.d.ts +14 -0
  73. package/dist/runtime/auth-flow.js +44 -0
  74. package/dist/runtime/browser.d.ts +25 -0
  75. package/dist/runtime/browser.js +1034 -0
  76. package/dist/runtime/cache.d.ts +10 -0
  77. package/dist/runtime/cache.js +372 -0
  78. package/dist/runtime/choice.d.ts +15 -0
  79. package/dist/runtime/choice.js +435 -0
  80. package/dist/runtime/credential.d.ts +8 -0
  81. package/dist/runtime/credential.js +61 -0
  82. package/dist/runtime/env.d.ts +2 -0
  83. package/dist/runtime/env.js +10 -0
  84. package/dist/runtime/executor.d.ts +16 -0
  85. package/dist/runtime/executor.js +51 -0
  86. package/dist/runtime/http.d.ts +8 -0
  87. package/dist/runtime/http.js +706 -0
  88. package/dist/runtime/insights.d.ts +9 -0
  89. package/dist/runtime/insights.js +324 -0
  90. package/dist/runtime/instrumentation.d.ts +8 -0
  91. package/dist/runtime/instrumentation.js +269 -0
  92. package/dist/runtime/key-derivation.d.ts +24 -0
  93. package/dist/runtime/key-derivation.js +73 -0
  94. package/dist/runtime/keyring.d.ts +25 -0
  95. package/dist/runtime/keyring.js +93 -0
  96. package/dist/runtime/namespace.d.ts +9 -0
  97. package/dist/runtime/namespace.js +19 -0
  98. package/dist/runtime/otlp.d.ts +39 -0
  99. package/dist/runtime/otlp.js +103 -0
  100. package/dist/runtime/perf.d.ts +12 -0
  101. package/dist/runtime/perf.js +52 -0
  102. package/dist/runtime/prevalidate.d.ts +12 -0
  103. package/dist/runtime/prevalidate.js +173 -0
  104. package/dist/runtime/provider.d.ts +2 -0
  105. package/dist/runtime/provider.js +11 -0
  106. package/dist/runtime/proxy-errors.d.ts +21 -0
  107. package/dist/runtime/proxy-errors.js +83 -0
  108. package/dist/runtime/proxy-telemetry.d.ts +8 -0
  109. package/dist/runtime/proxy-telemetry.js +174 -0
  110. package/dist/runtime/redis.d.ts +17 -0
  111. package/dist/runtime/redis.js +82 -0
  112. package/dist/runtime/request-options.d.ts +3 -0
  113. package/dist/runtime/request-options.js +42 -0
  114. package/dist/runtime/state.d.ts +17 -0
  115. package/dist/runtime/state.js +344 -0
  116. package/dist/runtime/stealth.d.ts +18 -0
  117. package/dist/runtime/stealth.js +834 -0
  118. package/dist/runtime/stt.d.ts +22 -0
  119. package/dist/runtime/stt.js +480 -0
  120. package/dist/runtime/trace.d.ts +26 -0
  121. package/dist/runtime/trace.js +142 -0
  122. package/dist/runtime/waterfall.d.ts +12 -0
  123. package/dist/runtime/waterfall.js +147 -0
  124. package/dist/schema.d.ts +74 -0
  125. package/dist/schema.js +243 -0
  126. package/dist/serve.d.ts +1 -0
  127. package/dist/serve.js +1 -0
  128. package/dist/server/index.d.ts +3 -0
  129. package/dist/server/index.js +2 -0
  130. package/dist/server/serve.d.ts +64 -0
  131. package/dist/server/serve.js +1110 -0
  132. package/dist/server/types.d.ts +136 -0
  133. package/dist/server/types.js +86 -0
  134. package/dist/stealth/profiles.d.ts +4 -0
  135. package/dist/stealth/profiles.js +259 -0
  136. package/dist/stream.d.ts +44 -0
  137. package/dist/stream.js +151 -0
  138. package/dist/testing/helpers.d.ts +23 -0
  139. package/dist/testing/helpers.js +95 -0
  140. package/dist/testing/index.d.ts +2 -0
  141. package/dist/testing/index.js +2 -0
  142. package/dist/testing/run.d.ts +34 -0
  143. package/dist/testing/run.js +303 -0
  144. package/dist/types.d.ts +1326 -0
  145. package/dist/types.js +61 -0
  146. package/dist/utils/date.d.ts +6 -0
  147. package/dist/utils/date.js +101 -0
  148. package/dist/utils/parse.d.ts +16 -0
  149. package/dist/utils/parse.js +51 -0
  150. package/dist/utils/text.d.ts +4 -0
  151. package/dist/utils/text.js +14 -0
  152. package/dist/utils/transform.d.ts +8 -0
  153. package/dist/utils/transform.js +48 -0
  154. package/package.json +57 -30
  155. package/src/ceremonies/index.ts +8 -2
  156. package/src/choice-token.ts +165 -0
  157. package/src/cli/commands.ts +34 -11
  158. package/src/cli/create.ts +214 -52
  159. package/src/cli/templates/provider/.dockerignore.tpl +22 -0
  160. package/src/cli/templates/provider/.gitignore.tpl +22 -0
  161. package/src/cli/templates/provider/README.md.tpl +120 -1
  162. package/src/cli/templates/provider/dev.ts.tpl +1 -1
  163. package/src/cli/templates/provider/domain/README.md.tpl +3 -0
  164. package/src/cli/templates/provider/index.ts.tpl +5 -48
  165. package/src/cli/templates/provider/mappers/README.md.tpl +3 -0
  166. package/src/cli/templates/provider/meta.ts.tpl +7 -0
  167. package/src/cli/templates/provider/operations/index.ts.tpl +5 -0
  168. package/src/cli/templates/provider/operations/ping.ts.tpl +24 -0
  169. package/src/cli/templates/provider/schemas/ping.ts.tpl +24 -0
  170. package/src/cli/templates/provider/start.ts.tpl +1 -1
  171. package/src/cli/templates/provider/upstream/README.md.tpl +3 -0
  172. package/src/config/loader.ts +1224 -9
  173. package/src/contract-json.ts +75 -0
  174. package/src/contract-serialization.ts +89 -0
  175. package/src/contract-types.ts +52 -0
  176. package/src/contract.ts +215 -0
  177. package/src/define.ts +1688 -48
  178. package/src/errors.ts +27 -0
  179. package/src/i18n/catalog.ts +277 -0
  180. package/src/i18n/index.ts +2 -0
  181. package/src/i18n/keys.ts +64 -0
  182. package/src/index.ts +174 -9
  183. package/src/lint.ts +547 -73
  184. package/src/observability.ts +41 -0
  185. package/src/provider.ts +104 -4
  186. package/src/public-schema-field-lint.ts +237 -0
  187. package/src/runtime/auth-flow.ts +7 -0
  188. package/src/runtime/browser.ts +762 -51
  189. package/src/runtime/cache.ts +528 -0
  190. package/src/runtime/choice.ts +760 -0
  191. package/src/runtime/executor.ts +32 -3
  192. package/src/runtime/http.ts +939 -195
  193. package/src/runtime/insights.ts +11 -11
  194. package/src/runtime/instrumentation.ts +12 -4
  195. package/src/runtime/key-derivation.ts +1 -1
  196. package/src/runtime/keyring.ts +4 -3
  197. package/src/runtime/proxy-errors.ts +132 -0
  198. package/src/runtime/proxy-telemetry.ts +253 -0
  199. package/src/runtime/redis.ts +116 -0
  200. package/src/runtime/request-options.ts +66 -0
  201. package/src/runtime/state.ts +563 -0
  202. package/src/runtime/stealth.ts +1159 -0
  203. package/src/runtime/stt.ts +629 -0
  204. package/src/runtime/trace.ts +1 -1
  205. package/src/schema.ts +363 -1
  206. package/src/server/serve.ts +1157 -75
  207. package/src/server/types.ts +37 -0
  208. package/src/stream.ts +210 -0
  209. package/src/testing/run.ts +31 -5
  210. package/src/types.ts +1107 -59
  211. package/src/runtime/tls.ts +0 -434
  212. 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,113 @@
1
- export { z } from "zod";
2
-
3
1
  export { createFormCeremony } from "./ceremonies";
4
- export { defineOperation, defineProvider } from "./define";
5
- export { AuthError, ProviderError, ValidationError } from "./errors";
2
+ export {
3
+ assertFreshProviderChoiceIssuedAt,
4
+ createProviderChoiceToken,
5
+ ProviderChoiceTokenError,
6
+ type ProviderChoiceTokenErrorReason,
7
+ type ProviderChoiceTokenPayload,
8
+ parseProviderChoiceToken,
9
+ } from "./choice-token";
10
+ export {
11
+ defineHealthJourney,
12
+ defineOperation,
13
+ defineProvider,
14
+ defineSmsOtpMatcher,
15
+ every,
16
+ } from "./define";
17
+ export {
18
+ AuthError,
19
+ ProviderError,
20
+ SessionExpiredError,
21
+ TransportError,
22
+ ValidationError,
23
+ } from "./errors";
24
+ export {
25
+ getProviderLocalePath,
26
+ providerLocaleKey,
27
+ qualifyProviderLocaleKey,
28
+ } from "./i18n";
29
+ export {
30
+ type CreateProviderChoiceContextOptions,
31
+ createProviderChoiceContext,
32
+ createTestProviderChoiceContext,
33
+ PROVIDER_RUNTIME_CHOICE_TOKEN_MASTER_SECRET_ENV,
34
+ } from "./runtime/choice";
35
+ export {
36
+ APIFUSE_DESCRIPTION_KEY_META_KEY,
37
+ APIFUSE_REDACTION_MARKER,
38
+ APIFUSE_SENSITIVE_KIND_META_KEY,
39
+ APIFUSE_SENSITIVE_META_KEY,
40
+ collectSensitivePaths,
41
+ describeKey,
42
+ field,
43
+ fields,
44
+ isSensitiveSchema,
45
+ redactPayload,
46
+ type SensitiveFieldKind,
47
+ type SensitiveFieldOptions,
48
+ type SensitivePath,
49
+ sensitive,
50
+ z,
51
+ } from "./schema";
6
52
  export type {
53
+ AuthMode,
7
54
  FlowContext,
55
+ HealthCheckAssertionContext,
56
+ HealthCheckCase,
57
+ HealthCheckSuite,
58
+ HealthCheckUnsupported,
59
+ HealthJourneyDefinition,
60
+ HealthJourneyEventContext,
61
+ HealthJourneyManualTriggerPolicy,
62
+ HealthJourneyRunContext,
63
+ HealthJourneyRunResult,
64
+ HttpRetryOptions,
65
+ HttpRetrySummary,
8
66
  InferSchemaOutput,
67
+ OperationApprovalPolicy,
68
+ OperationContractMetadata,
9
69
  OperationDefinition,
70
+ OperationDocMeta,
71
+ OperationErrorCode,
72
+ OperationInputExample,
73
+ OperationLifecycle,
74
+ OperationObservabilityConfig,
75
+ OperationObservabilitySensitiveConfig,
76
+ OperationRelationships,
77
+ OperationRiskClass,
78
+ OperationSensitivePath,
79
+ OperationToolRouterMetadata,
80
+ OperationTransport,
81
+ ProviderAccessVisibility,
82
+ ProviderChoiceBindingOptions,
83
+ ProviderChoiceContext,
84
+ ProviderChoiceIssueOptions,
85
+ ProviderChoiceParseOptions,
10
86
  ProviderContext,
87
+ ProviderDefinition,
88
+ ProviderLocale,
89
+ ProviderLocaleKey,
90
+ ProviderLocaleKeyInput,
91
+ ProviderLogoProfile,
92
+ ProviderProxyPolicy,
93
+ ProviderPublicConnectionMode,
94
+ ProviderPublicProfile,
95
+ ProviderRuntimeState,
96
+ ProviderStateDurationString,
97
+ ProviderStateNamespace,
98
+ ProviderSupportLevel,
11
99
  SchemaLike,
100
+ SmsOtpMatcherDefinition,
12
101
  StandardSchemaV1,
102
+ StateCasResult,
103
+ StateNamespaceOptions,
104
+ StateValue,
105
+ StateWriteOptions,
106
+ } from "./types";
107
+ export {
108
+ HttpRetryAfterPolicy,
109
+ HttpRetryDelayStrategy,
110
+ HttpRetryJitter,
111
+ HttpRetryPreset,
112
+ HttpRetryUnsafeMethodPolicy,
13
113
  } 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
+ }
@@ -4,7 +4,10 @@ import type {
4
4
  EnvContext,
5
5
  FlowContext,
6
6
  HttpClient,
7
+ StealthClient,
8
+ SttContext,
7
9
  } from "../types";
10
+ import { createUnsupportedSttClient } from "./stt";
8
11
 
9
12
  function normalizeAllowedKeys(allowedKeys: string[]): Set<string> {
10
13
  return new Set(allowedKeys.filter((key) => key.trim().length > 0));
@@ -47,6 +50,7 @@ export function createScratchpad(
47
50
 
48
51
  export function createFlowContext(options: {
49
52
  http: HttpClient;
53
+ stealth: StealthClient;
50
54
  env: EnvContext;
51
55
  tenantId: string;
52
56
  providerId: string;
@@ -54,6 +58,7 @@ export function createFlowContext(options: {
54
58
  externalRef?: string;
55
59
  allowedKeys: string[];
56
60
  initialContext?: Record<string, unknown>;
61
+ stt?: SttContext;
57
62
  }): FlowContext {
58
63
  return {
59
64
  connectionId: options.connectionId,
@@ -61,7 +66,9 @@ export function createFlowContext(options: {
61
66
  tenantId: options.tenantId,
62
67
  providerId: options.providerId,
63
68
  http: options.http,
69
+ stealth: options.stealth,
64
70
  env: options.env,
65
71
  context: createScratchpad(options.allowedKeys, options.initialContext),
72
+ stt: options.stt ?? createUnsupportedSttClient(),
66
73
  };
67
74
  }