@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.
- package/AUTHORING.md +208 -2
- package/CHANGELOG.md +47 -0
- package/README.md +114 -10
- package/SUBMISSION.md +87 -0
- package/bin/apifuse-check.ts +86 -4
- package/bin/apifuse-dev.ts +87 -13
- package/bin/apifuse-pack-check.ts +80 -0
- package/bin/apifuse-pack-smoke.ts +303 -2
- package/bin/apifuse-perf.ts +142 -49
- package/bin/apifuse-record.ts +182 -104
- package/bin/apifuse-submit-check.ts +2538 -0
- package/bin/apifuse.ts +1 -1
- package/dist/ceremonies/index.d.ts +41 -0
- package/dist/ceremonies/index.js +490 -0
- package/dist/choice-token.d.ts +24 -0
- package/dist/choice-token.js +74 -0
- package/dist/cli/commands.d.ts +10 -0
- package/dist/cli/commands.js +80 -0
- package/dist/cli/create.d.ts +47 -0
- package/dist/cli/create.js +762 -0
- package/dist/cli/templates/provider/.dockerignore.tpl +22 -0
- package/dist/cli/templates/provider/.gitignore.tpl +22 -0
- package/dist/cli/templates/provider/Dockerfile.tpl +7 -0
- package/dist/cli/templates/provider/README.md.tpl +160 -0
- package/dist/cli/templates/provider/dev.ts.tpl +5 -0
- package/dist/cli/templates/provider/domain/README.md.tpl +3 -0
- package/dist/cli/templates/provider/index.test.ts.tpl +13 -0
- package/dist/cli/templates/provider/index.ts.tpl +15 -0
- package/dist/cli/templates/provider/mappers/README.md.tpl +3 -0
- package/dist/cli/templates/provider/meta.ts.tpl +7 -0
- package/dist/cli/templates/provider/operations/index.ts.tpl +5 -0
- package/dist/cli/templates/provider/operations/ping.ts.tpl +24 -0
- package/dist/cli/templates/provider/schemas/ping.ts.tpl +24 -0
- package/dist/cli/templates/provider/start.ts.tpl +5 -0
- package/dist/cli/templates/provider/upstream/README.md.tpl +3 -0
- package/dist/config/loader.d.ts +107 -0
- package/dist/config/loader.js +935 -0
- package/dist/contract-json.d.ts +9 -0
- package/dist/contract-json.js +51 -0
- package/dist/contract-serialization.d.ts +4 -0
- package/dist/contract-serialization.js +78 -0
- package/dist/contract-types.d.ts +49 -0
- package/dist/contract-types.js +1 -0
- package/dist/contract.d.ts +6 -0
- package/dist/contract.js +155 -0
- package/dist/define.d.ts +97 -0
- package/dist/define.js +1320 -0
- package/dist/dev.d.ts +9 -0
- package/dist/dev.js +15 -0
- package/dist/errors.d.ts +59 -0
- package/dist/errors.js +97 -0
- package/dist/i18n/catalog.d.ts +29 -0
- package/dist/i18n/catalog.js +159 -0
- package/dist/i18n/index.d.ts +2 -0
- package/dist/i18n/index.js +2 -0
- package/dist/i18n/keys.d.ts +10 -0
- package/dist/i18n/keys.js +34 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.js +37 -0
- package/dist/lint.d.ts +73 -0
- package/dist/lint.js +702 -0
- package/dist/observability.d.ts +5 -0
- package/dist/observability.js +39 -0
- package/dist/provider.d.ts +9 -0
- package/dist/provider.js +8 -0
- package/dist/public-schema-field-lint.d.ts +2 -0
- package/dist/public-schema-field-lint.js +158 -0
- package/dist/recipes/gov-api.d.ts +19 -0
- package/dist/recipes/gov-api.js +72 -0
- package/dist/recipes/rest-api.d.ts +21 -0
- package/dist/recipes/rest-api.js +115 -0
- package/dist/runtime/auth-flow.d.ts +14 -0
- package/dist/runtime/auth-flow.js +44 -0
- package/dist/runtime/browser.d.ts +25 -0
- package/dist/runtime/browser.js +1034 -0
- package/dist/runtime/cache.d.ts +10 -0
- package/dist/runtime/cache.js +372 -0
- package/dist/runtime/choice.d.ts +15 -0
- package/dist/runtime/choice.js +435 -0
- package/dist/runtime/credential.d.ts +8 -0
- package/dist/runtime/credential.js +61 -0
- package/dist/runtime/env.d.ts +2 -0
- package/dist/runtime/env.js +10 -0
- package/dist/runtime/executor.d.ts +16 -0
- package/dist/runtime/executor.js +51 -0
- package/dist/runtime/http.d.ts +8 -0
- package/dist/runtime/http.js +706 -0
- package/dist/runtime/insights.d.ts +9 -0
- package/dist/runtime/insights.js +324 -0
- package/dist/runtime/instrumentation.d.ts +8 -0
- package/dist/runtime/instrumentation.js +269 -0
- package/dist/runtime/key-derivation.d.ts +24 -0
- package/dist/runtime/key-derivation.js +73 -0
- package/dist/runtime/keyring.d.ts +25 -0
- package/dist/runtime/keyring.js +93 -0
- package/dist/runtime/namespace.d.ts +9 -0
- package/dist/runtime/namespace.js +19 -0
- package/dist/runtime/otlp.d.ts +39 -0
- package/dist/runtime/otlp.js +103 -0
- package/dist/runtime/perf.d.ts +12 -0
- package/dist/runtime/perf.js +52 -0
- package/dist/runtime/prevalidate.d.ts +12 -0
- package/dist/runtime/prevalidate.js +173 -0
- package/dist/runtime/provider.d.ts +2 -0
- package/dist/runtime/provider.js +11 -0
- package/dist/runtime/proxy-errors.d.ts +21 -0
- package/dist/runtime/proxy-errors.js +83 -0
- package/dist/runtime/proxy-telemetry.d.ts +8 -0
- package/dist/runtime/proxy-telemetry.js +174 -0
- package/dist/runtime/redis.d.ts +17 -0
- package/dist/runtime/redis.js +82 -0
- package/dist/runtime/request-options.d.ts +3 -0
- package/dist/runtime/request-options.js +42 -0
- package/dist/runtime/state.d.ts +17 -0
- package/dist/runtime/state.js +344 -0
- package/dist/runtime/stealth.d.ts +18 -0
- package/dist/runtime/stealth.js +834 -0
- package/dist/runtime/stt.d.ts +22 -0
- package/dist/runtime/stt.js +480 -0
- package/dist/runtime/trace.d.ts +26 -0
- package/dist/runtime/trace.js +142 -0
- package/dist/runtime/waterfall.d.ts +12 -0
- package/dist/runtime/waterfall.js +147 -0
- package/dist/schema.d.ts +74 -0
- package/dist/schema.js +243 -0
- package/dist/serve.d.ts +1 -0
- package/dist/serve.js +1 -0
- package/dist/server/index.d.ts +3 -0
- package/dist/server/index.js +2 -0
- package/dist/server/serve.d.ts +64 -0
- package/dist/server/serve.js +1110 -0
- package/dist/server/types.d.ts +136 -0
- package/dist/server/types.js +86 -0
- package/dist/stealth/profiles.d.ts +4 -0
- package/dist/stealth/profiles.js +259 -0
- package/dist/stream.d.ts +44 -0
- package/dist/stream.js +151 -0
- package/dist/testing/helpers.d.ts +23 -0
- package/dist/testing/helpers.js +95 -0
- package/dist/testing/index.d.ts +2 -0
- package/dist/testing/index.js +2 -0
- package/dist/testing/run.d.ts +34 -0
- package/dist/testing/run.js +303 -0
- package/dist/types.d.ts +1326 -0
- package/dist/types.js +61 -0
- package/dist/utils/date.d.ts +6 -0
- package/dist/utils/date.js +101 -0
- package/dist/utils/parse.d.ts +16 -0
- package/dist/utils/parse.js +51 -0
- package/dist/utils/text.d.ts +4 -0
- package/dist/utils/text.js +14 -0
- package/dist/utils/transform.d.ts +8 -0
- package/dist/utils/transform.js +48 -0
- package/package.json +57 -30
- package/src/ceremonies/index.ts +8 -2
- package/src/choice-token.ts +165 -0
- package/src/cli/commands.ts +34 -11
- package/src/cli/create.ts +214 -52
- package/src/cli/templates/provider/.dockerignore.tpl +22 -0
- package/src/cli/templates/provider/.gitignore.tpl +22 -0
- package/src/cli/templates/provider/README.md.tpl +120 -1
- package/src/cli/templates/provider/dev.ts.tpl +1 -1
- package/src/cli/templates/provider/domain/README.md.tpl +3 -0
- package/src/cli/templates/provider/index.ts.tpl +5 -48
- package/src/cli/templates/provider/mappers/README.md.tpl +3 -0
- package/src/cli/templates/provider/meta.ts.tpl +7 -0
- package/src/cli/templates/provider/operations/index.ts.tpl +5 -0
- package/src/cli/templates/provider/operations/ping.ts.tpl +24 -0
- package/src/cli/templates/provider/schemas/ping.ts.tpl +24 -0
- package/src/cli/templates/provider/start.ts.tpl +1 -1
- package/src/cli/templates/provider/upstream/README.md.tpl +3 -0
- package/src/config/loader.ts +1224 -9
- package/src/contract-json.ts +75 -0
- package/src/contract-serialization.ts +89 -0
- package/src/contract-types.ts +52 -0
- package/src/contract.ts +215 -0
- package/src/define.ts +1688 -48
- package/src/errors.ts +27 -0
- package/src/i18n/catalog.ts +277 -0
- package/src/i18n/index.ts +2 -0
- package/src/i18n/keys.ts +64 -0
- package/src/index.ts +174 -9
- package/src/lint.ts +547 -73
- package/src/observability.ts +41 -0
- package/src/provider.ts +104 -4
- package/src/public-schema-field-lint.ts +237 -0
- package/src/runtime/auth-flow.ts +7 -0
- package/src/runtime/browser.ts +762 -51
- package/src/runtime/cache.ts +528 -0
- package/src/runtime/choice.ts +760 -0
- package/src/runtime/executor.ts +32 -3
- package/src/runtime/http.ts +939 -195
- package/src/runtime/insights.ts +11 -11
- package/src/runtime/instrumentation.ts +12 -4
- package/src/runtime/key-derivation.ts +1 -1
- package/src/runtime/keyring.ts +4 -3
- package/src/runtime/proxy-errors.ts +132 -0
- package/src/runtime/proxy-telemetry.ts +253 -0
- package/src/runtime/redis.ts +116 -0
- package/src/runtime/request-options.ts +66 -0
- package/src/runtime/state.ts +563 -0
- package/src/runtime/stealth.ts +1159 -0
- package/src/runtime/stt.ts +629 -0
- package/src/runtime/trace.ts +1 -1
- package/src/schema.ts +363 -1
- package/src/server/serve.ts +1157 -75
- package/src/server/types.ts +37 -0
- package/src/stream.ts +210 -0
- package/src/testing/run.ts +31 -5
- package/src/types.ts +1107 -59
- package/src/runtime/tls.ts +0 -434
- package/src/types/playwright-stealth.d.ts +0 -9
package/AUTHORING.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
## Generator and runtime alignment
|
|
2
2
|
|
|
3
3
|
- Canonical scaffolding command: `apifuse create`
|
|
4
|
-
-
|
|
4
|
+
- External bounty workspaces are one-provider repositories initialized with the standalone create flow. `--preset monorepo` is an internal APIFuse maintainer path only and must reject outside the private monorepo detected by `packages/provider-sdk/package.json`.
|
|
5
5
|
- Standalone bounty contributors should use `bunx @apifuse/provider-sdk@beta create <name> --yes` until this release is promoted to `latest`
|
|
6
6
|
- Provider server contract is:
|
|
7
7
|
- dev default `3900`
|
|
@@ -47,12 +47,36 @@ description:
|
|
|
47
47
|
- `description` — 150+ chars English (error-level rule)
|
|
48
48
|
- Every Zod field in input AND output has `.describe()` including nested objects + array items (error-level rule)
|
|
49
49
|
- `fixtures.request` + `fixtures.response` both present (error-level rule)
|
|
50
|
-
- Exactly one of `healthCheck` or `
|
|
50
|
+
- Exactly one of `healthCheck`, `healthCheckUnsupported`, or `healthJourneys[].coversOperations` coverage per operation. Prefer `healthCheck` for safe read-only upstream probes; use `healthCheckUnsupported` only with a specific reason for destructive, paid, credential-sensitive, flaky, or otherwise unsafe probes. Use a provider-level health journey when a destructive or credential-sensitive flow can be proven safely only as a multi-step boundary test, such as stopping at a payment WebView URL.
|
|
51
51
|
|
|
52
52
|
### Factored operations
|
|
53
53
|
|
|
54
54
|
Use `defineOperation()` when an operation is large enough to live beside helper functions or in a separate module. It preserves the same type inference as inline `defineProvider()` operations and can be placed directly in the provider `operations` map. `defineProvider()` accepts Zod and Standard Schema v1-compatible schemas. If config validation fails, the SDK names the field to fix, for example `runtime`, `auth.mode`, `operations.<id>.handler`, or `operations.<id>.fixtures.response`.
|
|
55
55
|
|
|
56
|
+
### Health assertion context
|
|
57
|
+
|
|
58
|
+
`healthCheck.cases[].assertions` receives a `HealthCheckAssertionContext` with
|
|
59
|
+
`data`, `status`, `durationMs`, and optional `meta`. `data` is typed from the
|
|
60
|
+
operation output schema, so assertions should inspect normalized output instead
|
|
61
|
+
of reaching into transport internals.
|
|
62
|
+
|
|
63
|
+
<!-- @magic-start:sample -->
|
|
64
|
+
```ts
|
|
65
|
+
healthCheck: {
|
|
66
|
+
interval: "5m",
|
|
67
|
+
cases: [{
|
|
68
|
+
name: "lookup baseline",
|
|
69
|
+
input: { q: "btc" },
|
|
70
|
+
assertions: ({ data, status, durationMs }) => {
|
|
71
|
+
if (status !== 200 || data.results.length === 0 || durationMs > 3000) {
|
|
72
|
+
return { status: "degraded", label: "lookup baseline changed" };
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
}],
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
<!-- @magic-end:sample -->
|
|
79
|
+
|
|
56
80
|
### Strongly recommended (warn-level rules)
|
|
57
81
|
|
|
58
82
|
- `description` includes "use" AND "when" phrasing
|
|
@@ -65,6 +89,158 @@ Use `defineOperation()` when an operation is large enough to live beside helper
|
|
|
65
89
|
- `tags`: operation-level semantic tags for retrieval (e.g., `["weather", "korea", "realtime"]`)
|
|
66
90
|
- `relatedOperations`: `{ alternatives?: string[] }` — links to fallback/sibling operations
|
|
67
91
|
|
|
92
|
+
### STT runtime capability for audio OTP and short transcription
|
|
93
|
+
|
|
94
|
+
Providers that need speech-to-text should use the SDK runtime capability instead
|
|
95
|
+
of constructing a vendor client inside provider code. Declare STT at the provider
|
|
96
|
+
level, then call `ctx.stt` from operation handlers or auth-flow handlers.
|
|
97
|
+
|
|
98
|
+
<!-- @magic-start:sample -->
|
|
99
|
+
```ts
|
|
100
|
+
export default defineProvider({
|
|
101
|
+
id: "example-provider",
|
|
102
|
+
// ...metadata, auth, operations, allowedHosts
|
|
103
|
+
stt: { mode: "required" },
|
|
104
|
+
operations: {
|
|
105
|
+
verifyAudioOtp: {
|
|
106
|
+
input: z.object({
|
|
107
|
+
audioBase64: z.string().describe("Base64-encoded short OTP audio"),
|
|
108
|
+
mediaType: z.string().optional().describe("Audio MIME type"),
|
|
109
|
+
}),
|
|
110
|
+
output: z.object({ code: z.string().describe("Verification code") }),
|
|
111
|
+
async handler(ctx, input) {
|
|
112
|
+
const transcript = await ctx.stt.transcribe({
|
|
113
|
+
audio: {
|
|
114
|
+
kind: "base64",
|
|
115
|
+
data: input.audioBase64,
|
|
116
|
+
mediaType: input.mediaType,
|
|
117
|
+
},
|
|
118
|
+
language: "ko-KR",
|
|
119
|
+
mode: "otp",
|
|
120
|
+
verificationCode: { codeLengths: [4, 6] },
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
const code =
|
|
124
|
+
transcript.verificationCode?.code ??
|
|
125
|
+
ctx.stt.extractVerificationCode(transcript.text, {
|
|
126
|
+
locale: "ko-KR",
|
|
127
|
+
codeLengths: [4, 6],
|
|
128
|
+
}).code;
|
|
129
|
+
|
|
130
|
+
return { code };
|
|
131
|
+
},
|
|
132
|
+
healthCheckUnsupported: {
|
|
133
|
+
reason: "Audio OTP transcription is cost-bearing and requires explicit smoke evidence.",
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
```
|
|
139
|
+
<!-- @magic-end:sample -->
|
|
140
|
+
|
|
141
|
+
Best-practice rules:
|
|
142
|
+
|
|
143
|
+
- `stt: { mode: "required" }` is the production path for providers that depend
|
|
144
|
+
on STT; APIFuse provider manifests project STT credentials, model config, and
|
|
145
|
+
Cloudflare egress only for required STT. Use `mode: "optional"` only when STT
|
|
146
|
+
is a host/test override or truly best-effort capability that can remain
|
|
147
|
+
unavailable in production.
|
|
148
|
+
- Do not assume OTPs are always four digits. Configure accepted lengths, for
|
|
149
|
+
example `[4, 6]`, and keep the returned code as a string to preserve leading
|
|
150
|
+
zeros.
|
|
151
|
+
- Prompts are hints, not correctness guarantees. General transcription sends no
|
|
152
|
+
prompt by default. OTP mode may send a default digit-preserving hint. Use a
|
|
153
|
+
custom `initialPrompt` only with `promptPolicy: "custom-hint"`, and do not log
|
|
154
|
+
prompts, transcripts, raw audio, or OTP values.
|
|
155
|
+
- STT v1 accepts JSON-safe base64 audio only. Do not fetch arbitrary audio URLs
|
|
156
|
+
from provider code; URL input needs separate SSRF/private-network policy.
|
|
157
|
+
- Local and production wiring use the same env-backed runtime path. For the
|
|
158
|
+
Cloudflare Workers AI backend, set `APIFUSE__STT__BACKEND=cloudflare-workers-ai`,
|
|
159
|
+
`APIFUSE__STT__MODEL=@cf/openai/whisper-large-v3-turbo`,
|
|
160
|
+
`APIFUSE__CLOUDFLARE__ACCOUNT_ID`, and `APIFUSE__STT__CLOUDFLARE_API_TOKEN` in `.env.local` or the
|
|
161
|
+
provider workload environment. Do not deploy a Cloudflare Worker proxy for the
|
|
162
|
+
MVP; the SDK runtime calls Workers AI REST directly.
|
|
163
|
+
- Submission checks and health checks must not invoke live STT by default.
|
|
164
|
+
Provide explicit smoke evidence when a provider depends on audio OTP behavior.
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
### Health journey DX for SMS/payment flows
|
|
168
|
+
|
|
169
|
+
Use `defineSmsOtpMatcher()` plus `defineHealthJourney()` when a real health signal requires an OTP ceremony and a safe handoff boundary. Keep matcher fields standards-backed: ISO 3166-1 alpha-2 `country`, BCP 47 `locale`, E.164 `phoneNumber` when present, ISO 8601 durations, and `nationalServiceCode` origins for local service senders. Do not add custom allowlist fields such as `senderAllowlist`; model the sender as an origin instead.
|
|
170
|
+
|
|
171
|
+
<!-- @magic-start:sample -->
|
|
172
|
+
```ts
|
|
173
|
+
import {
|
|
174
|
+
defineHealthJourney,
|
|
175
|
+
defineProvider,
|
|
176
|
+
defineSmsOtpMatcher,
|
|
177
|
+
every,
|
|
178
|
+
} from "@apifuse/provider-sdk";
|
|
179
|
+
|
|
180
|
+
const phoneOtp = defineSmsOtpMatcher({
|
|
181
|
+
id: "phone-otp",
|
|
182
|
+
country: "KR",
|
|
183
|
+
locale: "ko-KR",
|
|
184
|
+
origins: [
|
|
185
|
+
{
|
|
186
|
+
kind: "nationalServiceCode",
|
|
187
|
+
country: "KR",
|
|
188
|
+
value: "16615270",
|
|
189
|
+
display: "1661-5270",
|
|
190
|
+
},
|
|
191
|
+
],
|
|
192
|
+
code: { pattern: /인증번호는\s*\[([0-9]{4})\]/, capture: 1 },
|
|
193
|
+
maxAge: "PT5M",
|
|
194
|
+
waitTimeout: "PT2M30S",
|
|
195
|
+
clockSkew: "PT10S",
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
const paymentWebviewJourney = defineHealthJourney({
|
|
199
|
+
id: "sms-payment-webview",
|
|
200
|
+
schedule: every("8h", { jitter: "PT20M" }),
|
|
201
|
+
timeout: "PT5M",
|
|
202
|
+
cooldown: "PT8H",
|
|
203
|
+
requiredSecrets: [
|
|
204
|
+
"APIFUSE__HEALTH_MONITOR__PROVIDER_PHONE",
|
|
205
|
+
"APIFUSE__HEALTH_MONITOR__PROVIDER_PASSWORD",
|
|
206
|
+
"APIFUSE__HEALTH_MONITOR__PROVIDER_CANARY_ORDER_JSON",
|
|
207
|
+
],
|
|
208
|
+
coversOperations: ["verify-phone", "confirm-phone", "place-order"],
|
|
209
|
+
smsMatchers: [phoneOtp],
|
|
210
|
+
steps: [
|
|
211
|
+
{ id: "send-phone-otp", kind: "operation", operationId: "verify-phone" },
|
|
212
|
+
{ id: "wait-phone-otp", kind: "smsOtp", usesSmsMatcher: "phone-otp" },
|
|
213
|
+
{ id: "confirm-phone-otp", kind: "operation", operationId: "confirm-phone" },
|
|
214
|
+
{
|
|
215
|
+
id: "create-payment-webview",
|
|
216
|
+
kind: "operation",
|
|
217
|
+
operationId: "place-order",
|
|
218
|
+
safeBoundary: "paymentWebviewUrl",
|
|
219
|
+
},
|
|
220
|
+
],
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
export default defineProvider({
|
|
224
|
+
id: "example-provider",
|
|
225
|
+
// ...metadata, auth, operations, allowedHosts
|
|
226
|
+
healthJourneys: [paymentWebviewJourney],
|
|
227
|
+
});
|
|
228
|
+
```
|
|
229
|
+
<!-- @magic-end:sample -->
|
|
230
|
+
|
|
231
|
+
The journey runner supplies `ctx.gateway`, `ctx.sms.waitForOtp()`, `ctx.journal.sideEffect()`, `ctx.state`, and `ctx.event.operation()` to the optional journey `run` function. Provider authors should keep `run` small: call the covered operations in step order, stop at the declared safe boundary, and let the generated health metadata carry schedule, timeout, required secret, and SMS matcher information to the health monitor.
|
|
232
|
+
|
|
233
|
+
For authenticated journeys, open a fresh connection inside `run` with `ctx.gateway.connect({ input: { ... } })`, execute covered operations with the returned `connectionId`, and disconnect in a `finally` block. Do not require or store long-lived `HEALTH_MONITOR_*_CONNECTION_ID` secrets; those stale connection IDs can hide broken login ceremonies.
|
|
234
|
+
|
|
235
|
+
Use the runtime capabilities narrowly:
|
|
236
|
+
|
|
237
|
+
- `ctx.gateway.execute()` is the default path for operation health evidence; the runner records operation success/failure automatically.
|
|
238
|
+
- `ctx.journal.sideEffect()` wraps non-replayable provider mutations such as create/cancel/send operations.
|
|
239
|
+
- `ctx.state.namespace(name, policy)` stores bounded lifecycle memory and recovery cursors with TTL/quota/value-size policy. It is not a replacement for the side-effect journal.
|
|
240
|
+
- `ctx.event.operation()` records only synthetic operation outcomes proven by the journey, such as recovery/manual-review checks that are not direct gateway calls. The runtime rejects events for operations outside `coversOperations`.
|
|
241
|
+
|
|
242
|
+
Do not import `apps/health-monitor`, generated health artifacts, database repositories, schedulers, or recorders from provider code. If a journey needs provider-specific helper code, place it under the provider package (for example `providers/<id>/health-journeys/*`) and keep the SDK boundary generic.
|
|
243
|
+
|
|
68
244
|
### External bounty submission evidence
|
|
69
245
|
|
|
70
246
|
External contributors are expected to submit standalone Provider source plus:
|
|
@@ -74,11 +250,41 @@ External contributors are expected to submit standalone Provider source plus:
|
|
|
74
250
|
- Health coverage table for every Operation.
|
|
75
251
|
- `bun run check` output.
|
|
76
252
|
- `bun run test` output.
|
|
253
|
+
- `bun run submit-check` score/verdict and generated `submission-report.md`.
|
|
77
254
|
- Fixture evidence and known upstream constraints.
|
|
78
255
|
|
|
79
256
|
Maintainers own monorepo import under `providers/<id>/`, registry generation,
|
|
80
257
|
deployment projection checks, and release workflows.
|
|
81
258
|
|
|
259
|
+
### Public local debugging checklist
|
|
260
|
+
|
|
261
|
+
- Operation smoke requests use the provider server envelope:
|
|
262
|
+
`{"requestId":"req_local_<operation>","input":{...},"headers":{}}`.
|
|
263
|
+
Omit `connection` for public/no-auth operations; do not send `connection: null`.
|
|
264
|
+
- Credential-backed smoke requests pass local-only credential material in
|
|
265
|
+
`connection.secrets`. Keep real values in shell env or `.env`, never in source
|
|
266
|
+
or fixtures.
|
|
267
|
+
- Auth-flow debugging starts with `/auth/start`, continues with
|
|
268
|
+
`/auth/continue`, and carries returned `contextPatch` values into the next
|
|
269
|
+
request's `context`.
|
|
270
|
+
- Stealth/browser providers may require local runtime setup outside Provider code:
|
|
271
|
+
keep access-sensitive operations on `ctx.stealth.fetch()` with an SDK stealth
|
|
272
|
+
`profile`; the TypeScript runtime uses `impit` behind that interface, so do
|
|
273
|
+
not add per-operation JA3, HTTP/2 SETTINGS, or pseudo-header tuning. `ctx.stealth`
|
|
274
|
+
supports Chrome/Firefox-style profiles; use `browser.engine:
|
|
275
|
+
"playwright-stealth"` for Safari-specific or real browser Providers
|
|
276
|
+
(`nodriver` is Python-runtime only); install local browser assets with
|
|
277
|
+
`bunx playwright install chromium`, or set
|
|
278
|
+
`APIFUSE__CDP_POOL__URL` for remote browser debugging.
|
|
279
|
+
|
|
280
|
+
### Running the pre-submission report
|
|
281
|
+
|
|
282
|
+
```bash
|
|
283
|
+
bun run submit-check
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
The report scores review readiness across definition metadata, operation/schema quality, fixtures/tests, health coverage, local smoke evidence, auth safety, secret hygiene, and submission docs. It is not a payout guarantee; any blocker must be fixed before review. For the complete public-only submission checklist, see `SUBMISSION.md` in the SDK package.
|
|
287
|
+
|
|
82
288
|
### Running the lint locally
|
|
83
289
|
|
|
84
290
|
```bash
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,52 @@
|
|
|
1
1
|
# @apifuse/provider-sdk Changelog
|
|
2
2
|
|
|
3
|
+
## 2.1.0-beta.9
|
|
4
|
+
|
|
5
|
+
- Preserve raw stealth response bytes through the public SDK response wrapper.
|
|
6
|
+
- Add `arrayBuffer()` and `bytes()` to `StealthResponse` so consumers can inspect binary-safe upstream bodies.
|
|
7
|
+
|
|
8
|
+
## 2.1.0-beta.8
|
|
9
|
+
|
|
10
|
+
- Fix release automation for compiled `dist` package exports by building before package self-tests.
|
|
11
|
+
- Provide `GH_TOKEN` to the GitHub release creation step.
|
|
12
|
+
|
|
13
|
+
## 2.1.0-beta.7
|
|
14
|
+
|
|
15
|
+
- Publish compiled `dist` exports for npm consumers so Next.js/Vercel builds do not parse TypeScript from `node_modules`.
|
|
16
|
+
- Keep public CLI/template source files in the package while routing library exports through generated JavaScript and declarations.
|
|
17
|
+
|
|
18
|
+
## 2.1.0-beta.6
|
|
19
|
+
|
|
20
|
+
- Public repository clean-import release for `APIFuseHQ/provider-sdk`.
|
|
21
|
+
- Preserves the monorepo SDK exports required by ApiFuse provider registry cutover, including `./contract` and provider i18n helpers.
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
## 2.1.0-beta.5
|
|
25
|
+
|
|
26
|
+
- Republish the bounty workspace DX hardening that accepts generated readonly metadata and factored `defineOperation()` maps during standalone TypeScript checks.
|
|
27
|
+
- Ensure new bounty workspaces can install the public SDK version that matches their generated scaffold and pass `bun run check` immediately after bootstrap.
|
|
28
|
+
|
|
29
|
+
## 2.1.0-beta.4
|
|
30
|
+
|
|
31
|
+
- Align `apifuse create` with the bounty program topology: external contributors use the standalone one-provider-repository scaffold even when their assigned repo contains workspace-like files.
|
|
32
|
+
- Stop auto-detecting `providers/` directories as public monorepo scaffolds. `--preset monorepo` is now reserved for the private APIFuse monorepo where `packages/provider-sdk` is actually present.
|
|
33
|
+
- Remove public CLI/docs examples that present monorepo placement as a contributor workflow.
|
|
34
|
+
|
|
35
|
+
## 2.1.0-beta.3
|
|
36
|
+
|
|
37
|
+
- Replace the legacy TypeScript request transport with `ctx.stealth`, backed by `impit` browser-grade TLS/HTTP2 impersonation without Python runtime dependencies.
|
|
38
|
+
- Add the public `apifuse submit-check` / `apifuse bounty-check` CLI for score-based pre-submission provider quality checks.
|
|
39
|
+
- Ship `SUBMISSION.md` in the npm package so bounty contributors can follow the checklist without access to the private monorepo.
|
|
40
|
+
- Include submit-check in generated provider validation scripts and packed-artifact smoke coverage.
|
|
41
|
+
- Warn, instead of hard-block, generated OAuth starters that have not yet declared persisted credential keys.
|
|
42
|
+
|
|
43
|
+
## 2.1.0-beta.2
|
|
44
|
+
|
|
45
|
+
- Harden public bounty contributor DX with server-contract accurate README and generated Provider smoke examples.
|
|
46
|
+
- Add packed-artifact regression checks so stale `connection: null` or missing `requestId` examples cannot ship again.
|
|
47
|
+
- Extend clean-room packed SDK smoke coverage to boot the generated dev server and call `/health` plus `POST /v1/ping`.
|
|
48
|
+
- Document credential, auth-flow, stealth, browser, and Bun trusted-dependency troubleshooting for SDK-only local development.
|
|
49
|
+
|
|
3
50
|
## 2.1.0-beta.1
|
|
4
51
|
|
|
5
52
|
- Fix public `apifuse create` runtime packaging by publishing `@clack/prompts` as a production dependency.
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @apifuse/provider-sdk
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
APIFuse Provider SDK — build provider declarations and runtimes with one public SDK surface and one canonical CLI.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -29,13 +29,11 @@ The canonical `create` flow:
|
|
|
29
29
|
3. runs baseline validation,
|
|
30
30
|
4. prints the exact next local-dev command.
|
|
31
31
|
|
|
32
|
-
###
|
|
32
|
+
### Repository shape
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
The Provider SDK is a public bounty-contributor tool first. External bounty workspaces are one-provider repositories initialized from the standalone create flow. The generated provider must be installable without private APIFuse monorepo access.
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
apifuse create my-provider --preset monorepo
|
|
38
|
-
```
|
|
36
|
+
Do not use internal monorepo placement for bounty workspaces. Accepted provider work is imported into the private APIFuse monorepo later by maintainers or trusted automation.
|
|
39
37
|
|
|
40
38
|
## Provider server contract
|
|
41
39
|
|
|
@@ -58,6 +56,7 @@ Removed legacy runtime paths are not supported:
|
|
|
58
56
|
cd my-provider
|
|
59
57
|
bun run check
|
|
60
58
|
bun run test
|
|
59
|
+
bun run submit-check
|
|
61
60
|
bun run dev
|
|
62
61
|
```
|
|
63
62
|
|
|
@@ -67,9 +66,76 @@ Smoke the generated local server:
|
|
|
67
66
|
curl -s http://localhost:3900/health
|
|
68
67
|
curl -s -X POST http://localhost:3900/v1/ping \
|
|
69
68
|
-H 'Content-Type: application/json' \
|
|
70
|
-
-d '{"input":{"value":"hello"},"headers":{}
|
|
69
|
+
-d '{"requestId":"req_local_ping","input":{"value":"hello"},"headers":{}}'
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
The operation request body is the same envelope used by the APIFuse gateway:
|
|
73
|
+
|
|
74
|
+
| Field | Required | Notes |
|
|
75
|
+
|---|---:|---|
|
|
76
|
+
| `requestId` | yes | Any unique string is fine for local debugging; it is echoed in structured errors. |
|
|
77
|
+
| `input` | yes | The operation input after schema validation. |
|
|
78
|
+
| `headers` | no | Extra caller headers to expose through `ctx.request.headers`. |
|
|
79
|
+
| `connection` | no | Omit for no-auth/public operations. For credential debugging, pass an object with `id`, `mode`, `secrets`, `metadata`, and `externalRef`. Do not pass `null`. |
|
|
80
|
+
|
|
81
|
+
Credential-bearing local smoke example:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
curl -s -X POST http://localhost:3900/v1/me \
|
|
85
|
+
-H 'Content-Type: application/json' \
|
|
86
|
+
-d '{
|
|
87
|
+
"requestId":"req_local_me",
|
|
88
|
+
"input":{},
|
|
89
|
+
"connection":{
|
|
90
|
+
"id":"af_con_local_debug",
|
|
91
|
+
"mode":"credentials",
|
|
92
|
+
"secrets":{"apiKey":"dev-only-secret"},
|
|
93
|
+
"scopes":[],
|
|
94
|
+
"metadata":{},
|
|
95
|
+
"externalRef":"local-debug"
|
|
96
|
+
}
|
|
97
|
+
}'
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Auth-flow endpoints use the same `requestId` convention:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
curl -s -X POST http://localhost:3900/auth/start \
|
|
104
|
+
-H 'Content-Type: application/json' \
|
|
105
|
+
-d '{"requestId":"req_auth_start","flowId":"flow_local_1","providerId":"my-provider","context":{}}'
|
|
71
106
|
```
|
|
72
107
|
|
|
108
|
+
If a local smoke returns `{"error":...}`, inspect the JSON error body and the
|
|
109
|
+
`apifuse dev` server log. Validation failures include a `details` array with
|
|
110
|
+
the bad request path; provider/runtime failures include `code`, `message`, and
|
|
111
|
+
`requestId`.
|
|
112
|
+
|
|
113
|
+
### Local debugging checklist
|
|
114
|
+
|
|
115
|
+
- **`invalid_request` on `/v1/{operation}`**: confirm the request body includes
|
|
116
|
+
`requestId` and `input`. Omit `connection` for public/no-auth operations;
|
|
117
|
+
never send `connection: null`.
|
|
118
|
+
- **Credential-backed operations**: declare `credential.keys`, then pass matching
|
|
119
|
+
local-only values through `connection.secrets`. Read them in handlers with
|
|
120
|
+
`ctx.credential.get("key")` or `ctx.credential.getAccessToken()`.
|
|
121
|
+
- **Provider env secrets**: declare `secrets[]`, set values in your shell or
|
|
122
|
+
`.env`, and read only those names through `ctx.env.get("NAME")`.
|
|
123
|
+
- **Auth flows**: call `/auth/start`, then `/auth/continue` with the same
|
|
124
|
+
`flowId`; preserve any returned `contextPatch` in the next local request's
|
|
125
|
+
`context` object.
|
|
126
|
+
- **Stealth-sensitive providers**: use `ctx.http` for normal JSON/REST calls and
|
|
127
|
+
`ctx.stealth.fetch()` when you need browser-like session or cookie control. `ctx.stealth.fetch()` uses the impit-backed browser stealth transport and accepts request
|
|
128
|
+
controls for `params`, `proxy`, `timeout`, `profile`, `throwOnHttpError`, and
|
|
129
|
+
`stealth.insecureSkipVerify`. Select an SDK stealth `profile` such as
|
|
130
|
+
`chrome-146`; do not tune JA3, HTTP/2 SETTINGS, or pseudo-header order in
|
|
131
|
+
provider code. Chrome/Firefox-style profiles are supported; use `ctx.browser`
|
|
132
|
+
when Safari-specific behavior is required.
|
|
133
|
+
- **Browser providers**: for TypeScript Providers use `runtime: "browser"` plus
|
|
134
|
+
`browser.engine: "playwright-stealth"`; `nodriver` is a Python-runtime path.
|
|
135
|
+
Install local browser assets with `bunx playwright install chromium` when
|
|
136
|
+
using the Playwright runtime, or set `APIFUSE__CDP_POOL__URL`
|
|
137
|
+
when debugging against a remote browser pool.
|
|
138
|
+
|
|
73
139
|
## Authoring ergonomics
|
|
74
140
|
|
|
75
141
|
`defineProvider()` infers each operation handler input from the operation `input` schema. For larger providers, factor operations with `defineOperation()` and compose them later:
|
|
@@ -83,6 +149,9 @@ const search = defineOperation({
|
|
|
83
149
|
async handler(ctx, input) {
|
|
84
150
|
return { count: input.q.length }
|
|
85
151
|
},
|
|
152
|
+
healthCheckUnsupported: {
|
|
153
|
+
reason: "Example operation only; replace with a real upstream probe.",
|
|
154
|
+
},
|
|
86
155
|
})
|
|
87
156
|
|
|
88
157
|
export default defineProvider({
|
|
@@ -108,6 +177,24 @@ Every operation must declare exactly one of:
|
|
|
108
177
|
The generated `ping` operation uses `healthCheckUnsupported` only because it is
|
|
109
178
|
a local scaffold check, not a real upstream API probe.
|
|
110
179
|
|
|
180
|
+
`healthCheck.cases[].assertions` receives `{ data, status, durationMs, meta }`.
|
|
181
|
+
`data` is the operation output parsed by the declared output schema:
|
|
182
|
+
|
|
183
|
+
```ts
|
|
184
|
+
healthCheck: {
|
|
185
|
+
interval: "5m",
|
|
186
|
+
cases: [{
|
|
187
|
+
name: "search responds",
|
|
188
|
+
input: { q: "weather" },
|
|
189
|
+
assertions: ({ data, status, durationMs }) => {
|
|
190
|
+
if (status !== 200 || data.count < 1 || durationMs > 3000) {
|
|
191
|
+
return { status: "degraded", label: "unexpected search baseline" }
|
|
192
|
+
}
|
|
193
|
+
},
|
|
194
|
+
}],
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
111
198
|
### Operation annotations
|
|
112
199
|
|
|
113
200
|
Operations declare non-functional metadata via `annotations`:
|
|
@@ -129,11 +216,28 @@ Operations declare non-functional metadata via `annotations`:
|
|
|
129
216
|
apifuse create <name>
|
|
130
217
|
apifuse dev [path]
|
|
131
218
|
apifuse check [path]
|
|
132
|
-
apifuse record
|
|
219
|
+
apifuse record providers/korea-air-quality --operation realtime --params '{"stationName":"종로구"}'
|
|
133
220
|
apifuse test [path]
|
|
134
|
-
apifuse
|
|
221
|
+
apifuse submit-check [path] --tier bronze --markdown submission-report.md
|
|
222
|
+
apifuse bounty-check [path]
|
|
223
|
+
apifuse perf providers/korea-air-quality --operation realtime --params '{"stationName":"종로구"}'
|
|
135
224
|
```
|
|
136
225
|
|
|
226
|
+
`apifuse record` is for real upstream-backed operations that declare
|
|
227
|
+
`upstream.baseUrl` and call the upstream through `ctx.http` or `ctx.stealth`. The
|
|
228
|
+
generated local-only `ping` operation intentionally has no upstream and should
|
|
229
|
+
be replaced before recording fixtures.
|
|
230
|
+
|
|
231
|
+
## Bounty submission readiness
|
|
232
|
+
|
|
233
|
+
Standalone providers include a pre-submission script:
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
bun run submit-check
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
This runs the public review-readiness evaluator and writes `submission-report.md`. The report contains provider metadata, a 100-point readiness score, hard blockers, warnings, checklist evidence, and remediation. Blockers override the score; fix them before posting bounty evidence. The command is offline-safe by default and does not execute arbitrary upstream calls. Add local smoke notes to your assigned workspace PR after testing `/health` and `POST /v1/{operation}`. See [`SUBMISSION.md`](./SUBMISSION.md) for the full public-only bounty submission checklist shipped in the npm package.
|
|
240
|
+
|
|
137
241
|
## Scope boundary
|
|
138
242
|
|
|
139
243
|
Generator v1 scaffolds **TypeScript providers only** for this redesign. Python generation remains future work.
|
|
@@ -144,6 +248,6 @@ Generator v1 scaffolds **TypeScript providers only** for this redesign. Python g
|
|
|
144
248
|
Provider cataloging, deployment enrollment, docs indexing, and runtime discovery are internal platform-registry responsibilities and are not part of the public `@apifuse/provider-sdk` contract.
|
|
145
249
|
|
|
146
250
|
External bounty contributors should submit standalone Provider source plus
|
|
147
|
-
`bun run check` / `bun run test` evidence.
|
|
251
|
+
`bun run check` / `bun run test` evidence. APIFuse maintainers own monorepo
|
|
148
252
|
import, registry generation, deployment projection checks, and release
|
|
149
253
|
publishing.
|
package/SUBMISSION.md
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Provider bounty submission guide
|
|
2
|
+
|
|
3
|
+
This guide is for public bounty contributors who only have access to the published `@apifuse/provider-sdk` package. You do **not** need the private APIFuse monorepo to build or pre-check a Provider.
|
|
4
|
+
|
|
5
|
+
## SDK-only workspace workflow
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
bunx @apifuse/provider-sdk@beta create my-provider --yes
|
|
9
|
+
cd my-provider
|
|
10
|
+
bun run check
|
|
11
|
+
bun run test
|
|
12
|
+
bun run submit-check
|
|
13
|
+
bun run dev
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
`bun run submit-check` runs `apifuse submit-check . --markdown submission-report.md` in generated Providers.
|
|
17
|
+
|
|
18
|
+
## What submit-check scores
|
|
19
|
+
|
|
20
|
+
`apifuse submit-check` produces a 100-point review-readiness score and a verdict:
|
|
21
|
+
|
|
22
|
+
- `ready` — no blockers or warnings and score is at least 90.
|
|
23
|
+
- `reviewable_with_warnings` — no blockers, but reviewers should inspect the warnings.
|
|
24
|
+
- `blocked` — at least one hard blocker must be fixed before review.
|
|
25
|
+
|
|
26
|
+
The score is a triage aid, not a payout guarantee. Maintainers still review correctness, upstream behavior, policy fit, and bounty scope.
|
|
27
|
+
|
|
28
|
+
| Category | Points | Examples |
|
|
29
|
+
|---|---:|---|
|
|
30
|
+
| Definition & metadata | 15 | `defineProvider`, package, Dockerfile, SDK structural checks |
|
|
31
|
+
| Operations & schemas | 15 | strong descriptions, annotations, input/output schemas |
|
|
32
|
+
| Fixtures & tests | 15 | bidirectional fixtures that parse against schemas |
|
|
33
|
+
| Health coverage | 15 | real `healthCheck` or specific `healthCheckUnsupported.reason` |
|
|
34
|
+
| Runtime/local smoke | 10 | `/health` and at least one `POST /v1/{operation}` note |
|
|
35
|
+
| Auth/credential safety | 10 | auth mode and credential declarations are consistent |
|
|
36
|
+
| Security hygiene | 10 | no high-confidence secrets in shareable files |
|
|
37
|
+
| Docs/submission evidence | 10 | README Parameters, Response, Example, submit-check guidance |
|
|
38
|
+
|
|
39
|
+
## Hard blockers
|
|
40
|
+
|
|
41
|
+
Fix all blockers before submitting:
|
|
42
|
+
|
|
43
|
+
- `bun run check` failures.
|
|
44
|
+
- Provider cannot be imported from `index.ts`.
|
|
45
|
+
- Missing handler/input/output for any Operation.
|
|
46
|
+
- Missing fixture request or response.
|
|
47
|
+
- Fixture data does not parse against schemas.
|
|
48
|
+
- Missing `healthCheck` or `healthCheckUnsupported` on any Operation.
|
|
49
|
+
- Credential-backed auth mode without declared credential keys.
|
|
50
|
+
- High-confidence secret or token material in source, README, package metadata, or fixtures.
|
|
51
|
+
- SDK-native source blockers: prefixed Provider ids, `vendor/` SDK shims or imports, raw `.describe()` prose instead of `describeKey`, raw global `fetch()` calls, and excessive `as Type` assertions.
|
|
52
|
+
|
|
53
|
+
Warnings do not fail the command, but they should be addressed when practical. For example, the generated starter `ping` operation warns because it is not a real upstream-backed bounty Operation. SDK-native warnings also flag moderate `as Type` assertion counts and credentialed Providers that never reference `ctx.credential`.
|
|
54
|
+
|
|
55
|
+
## Safe local smoke evidence
|
|
56
|
+
|
|
57
|
+
`submit-check` does not call arbitrary live upstream APIs by default. After replacing starter logic, run the Provider locally and record a short evidence note:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
bun run dev
|
|
61
|
+
curl -s http://localhost:3900/health
|
|
62
|
+
curl -s -X POST http://localhost:3900/v1/<operation> \
|
|
63
|
+
-H 'Content-Type: application/json' \
|
|
64
|
+
-d '{"requestId":"req_local_smoke","input":{...},"headers":{}}'
|
|
65
|
+
|
|
66
|
+
bun run submit-check -- --smoke-note "GET /health and POST /v1/<operation> passed locally with redacted input."
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Never paste real credentials, personal data, account numbers, access tokens, cookies, or unredacted upstream responses into workspace PR comments, chat, or reports.
|
|
70
|
+
|
|
71
|
+
## Submission evidence checklist
|
|
72
|
+
|
|
73
|
+
Include the following when you submit a Provider for review:
|
|
74
|
+
|
|
75
|
+
- Provider SDK version, for example `bun pm ls @apifuse/provider-sdk` or package.json dependency.
|
|
76
|
+
- Provider id, version, runtime, and auth mode.
|
|
77
|
+
- Operation list with input/output summaries.
|
|
78
|
+
- Health coverage table: one row per Operation with `healthCheck` or `healthCheckUnsupported` and rationale.
|
|
79
|
+
- `bun run check` output.
|
|
80
|
+
- `bun run test` output.
|
|
81
|
+
- `submission-report.md` generated by `bun run submit-check`.
|
|
82
|
+
- Local smoke evidence for `/health` and at least one `POST /v1/{operation}` call.
|
|
83
|
+
- Known upstream constraints: rate limits, paid/destructive calls, auth limits, flaky endpoints, or unsupported probes.
|
|
84
|
+
|
|
85
|
+
## Maintainer-owned follow-up
|
|
86
|
+
|
|
87
|
+
After workspace evidence is submitted, APIFuse maintainers import accepted standalone Provider work into the private monorepo and run internal registry, generated artifact, deployment projection, and CI checks. External contributors are not expected to run those private checks.
|