@apifuse/provider-sdk 2.2.0-beta.5 → 2.2.0-beta.8
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 +53 -0
- package/CHANGELOG.md +12 -0
- package/README.md +5 -1
- package/SUBMISSION.md +1 -1
- package/bin/apifuse-check.ts +26 -1
- package/bin/apifuse-pack-check.ts +14 -0
- package/bin/apifuse-submit-check.ts +193 -2
- package/bin/apifuse-sync-assets.ts +117 -0
- package/dist/auth-turn/index.d.ts +2 -2
- package/dist/cli/commands.d.ts +1 -1
- package/dist/cli/commands.js +8 -0
- package/dist/cli/create.d.ts +3 -0
- package/dist/cli/create.js +34 -35
- package/dist/cli/prompt-assets.d.ts +80 -0
- package/dist/cli/prompt-assets.js +743 -0
- package/dist/cli/templates/provider/AGENTS.md.tpl +17 -8
- package/dist/config/loader.d.ts +79 -6
- package/dist/config/loader.js +272 -48
- package/dist/define.js +27 -3
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/runtime/executor.js +7 -0
- package/dist/runtime/http.js +3 -0
- package/dist/runtime/proxy-errors.js +6 -2
- package/dist/runtime/proxy-nodemaven.d.ts +34 -0
- package/dist/runtime/proxy-nodemaven.js +128 -0
- package/dist/runtime/proxy-telemetry.d.ts +2 -1
- package/dist/runtime/proxy-telemetry.js +39 -4
- package/dist/runtime/secrets.d.ts +27 -0
- package/dist/runtime/secrets.js +51 -0
- package/dist/runtime/stealth.js +20 -9
- package/dist/server/serve.d.ts +5 -0
- package/dist/server/serve.js +39 -0
- package/dist/server/types.d.ts +9 -9
- package/dist/types.d.ts +30 -1
- package/package.json +4 -3
- package/src/cli/commands.ts +10 -0
- package/src/cli/create.ts +42 -35
- package/src/cli/prompt-assets.ts +865 -0
- package/src/cli/templates/provider/AGENTS.md.tpl +17 -8
- package/src/config/loader.ts +405 -61
- package/src/define.ts +35 -3
- package/src/index.ts +5 -0
- package/src/runtime/executor.ts +8 -0
- package/src/runtime/http.ts +3 -0
- package/src/runtime/proxy-errors.ts +12 -4
- package/src/runtime/proxy-nodemaven.ts +178 -0
- package/src/runtime/proxy-telemetry.ts +56 -5
- package/src/runtime/secrets.ts +64 -0
- package/src/runtime/stealth.ts +26 -10
- package/src/server/serve.ts +53 -0
- package/src/types.ts +30 -1
- package/dist/cli/templates/provider/CLAUDE.md.tpl +0 -1
- package/src/cli/templates/provider/CLAUDE.md.tpl +0 -1
- /package/dist/cli/templates/provider/{skills → .agents/skills}/fixtures-and-recording/SKILL.md.tpl +0 -0
- /package/dist/cli/templates/provider/{skills → .agents/skills}/health-checks-and-fail-closed/SKILL.md.tpl +0 -0
- /package/dist/cli/templates/provider/{skills → .agents/skills}/normalization-standards/SKILL.md.tpl +0 -0
- /package/dist/cli/templates/provider/{skills → .agents/skills}/pagination-and-counts/SKILL.md.tpl +0 -0
- /package/dist/cli/templates/provider/{skills → .agents/skills}/upstream-contract-verification/SKILL.md.tpl +0 -0
- /package/dist/cli/templates/provider/{skills → .agents/skills}/upstream-notes/README.md.tpl +0 -0
- /package/src/cli/templates/provider/{skills → .agents/skills}/fixtures-and-recording/SKILL.md.tpl +0 -0
- /package/src/cli/templates/provider/{skills → .agents/skills}/health-checks-and-fail-closed/SKILL.md.tpl +0 -0
- /package/src/cli/templates/provider/{skills → .agents/skills}/normalization-standards/SKILL.md.tpl +0 -0
- /package/src/cli/templates/provider/{skills → .agents/skills}/pagination-and-counts/SKILL.md.tpl +0 -0
- /package/src/cli/templates/provider/{skills → .agents/skills}/upstream-contract-verification/SKILL.md.tpl +0 -0
- /package/src/cli/templates/provider/{skills → .agents/skills}/upstream-notes/README.md.tpl +0 -0
package/src/server/serve.ts
CHANGED
|
@@ -42,6 +42,11 @@ import {
|
|
|
42
42
|
PROXY_POOL_EXHAUSTED_CODE,
|
|
43
43
|
} from "../runtime/proxy-errors.js";
|
|
44
44
|
import { PROVIDER_TELEMETRY_HEADER, ProxyTelemetryCollector } from "../runtime/proxy-telemetry.js";
|
|
45
|
+
import {
|
|
46
|
+
assertRequiredSecretsPresent,
|
|
47
|
+
listMissingRequiredSecrets,
|
|
48
|
+
MISSING_SECRET_CODE,
|
|
49
|
+
} from "../runtime/secrets.js";
|
|
45
50
|
import {
|
|
46
51
|
createProviderRuntimeStateFromEnv,
|
|
47
52
|
createUnsupportedProviderRuntimeState,
|
|
@@ -408,6 +413,12 @@ export type ProviderServerLogEvent =
|
|
|
408
413
|
retryable?: boolean;
|
|
409
414
|
issues?: Array<{ path: string; code: string; message: string }>;
|
|
410
415
|
})
|
|
416
|
+
| {
|
|
417
|
+
level: "warn";
|
|
418
|
+
event: "provider_secrets_missing";
|
|
419
|
+
providerId: string;
|
|
420
|
+
missingSecrets: string[];
|
|
421
|
+
}
|
|
411
422
|
| {
|
|
412
423
|
level: "warn";
|
|
413
424
|
event: "provider_cleanup_failed";
|
|
@@ -558,6 +569,18 @@ function providerObservabilityDetails(error: unknown):
|
|
|
558
569
|
retryable: error.options?.retryable ?? false,
|
|
559
570
|
};
|
|
560
571
|
}
|
|
572
|
+
// Missing-secret errors carry the canonical credential_unavailable category
|
|
573
|
+
// so Gateway/observability can attribute the failure to provisioning, not
|
|
574
|
+
// the upstream. Matched by code (not constructor) so both the SDK-owned
|
|
575
|
+
// runtime gate and any not-yet-migrated provider-thrown MISSING_SECRET
|
|
576
|
+
// serialize identically, including across duplicate SDK module instances.
|
|
577
|
+
if (isProviderError(error) && error.code === MISSING_SECRET_CODE) {
|
|
578
|
+
return {
|
|
579
|
+
category: error.options?.category ?? "credential_unavailable",
|
|
580
|
+
taxonomyVersion: PROVIDER_OBSERVABILITY_TAXONOMY_VERSION,
|
|
581
|
+
retryable: error.options?.retryable ?? false,
|
|
582
|
+
};
|
|
583
|
+
}
|
|
561
584
|
if (!isTransportError(error)) {
|
|
562
585
|
return undefined;
|
|
563
586
|
}
|
|
@@ -628,6 +651,10 @@ function toStatusCode(error: unknown): 400 | 401 | 404 | 429 | 500 | 502 | 503 |
|
|
|
628
651
|
case "AUTH_REQUIRED":
|
|
629
652
|
case "reauth_required":
|
|
630
653
|
return 401;
|
|
654
|
+
// Unprovisioned declared secret: a deployment/config defect, never an
|
|
655
|
+
// upstream failure — explicit 400 (was only reached via fallthrough).
|
|
656
|
+
case MISSING_SECRET_CODE:
|
|
657
|
+
return 400;
|
|
631
658
|
case "NOT_FOUND":
|
|
632
659
|
case "not_found":
|
|
633
660
|
case "NO_DATA":
|
|
@@ -1224,8 +1251,16 @@ async function handleAuthFlow(
|
|
|
1224
1251
|
});
|
|
1225
1252
|
}
|
|
1226
1253
|
|
|
1254
|
+
// Same SDK-owned gate as executeOperation: OAuth/credentials ceremonies
|
|
1255
|
+
// depend on declared secrets (client ids/secrets), so fail structured before
|
|
1256
|
+
// any flow code runs instead of at whatever point the ceremony first reads
|
|
1257
|
+
// the env. `abort` stays exempt: a user must always be able to cancel a
|
|
1258
|
+
// stranded flow even when provisioning is broken.
|
|
1227
1259
|
const { context, getPatch } = createAuthFlowContext(provider, request, options, signal);
|
|
1228
1260
|
try {
|
|
1261
|
+
if (route !== "abort") {
|
|
1262
|
+
assertRequiredSecretsPresent(provider, context.env);
|
|
1263
|
+
}
|
|
1229
1264
|
const result =
|
|
1230
1265
|
route === "start"
|
|
1231
1266
|
? await flow.start(context)
|
|
@@ -1280,6 +1315,24 @@ export function createServerApp(
|
|
|
1280
1315
|
allowMemoryFallback: options.allowMemoryStateFallback === true,
|
|
1281
1316
|
});
|
|
1282
1317
|
|
|
1318
|
+
// Boot-time visibility for unprovisioned declared secrets: emit a structured
|
|
1319
|
+
// warn so deploy tooling/alerting sees the gap the moment the pod boots,
|
|
1320
|
+
// instead of discovering it request-by-request. Deliberately log-only — a
|
|
1321
|
+
// boot crash would trade a structured MISSING_SECRET signal for
|
|
1322
|
+
// CrashLoopBackOff. Requests still fail closed via the executeOperation gate.
|
|
1323
|
+
const missingSecretsAtBoot = listMissingRequiredSecrets(
|
|
1324
|
+
provider,
|
|
1325
|
+
createEnvContext(provider.secrets?.map((secret) => secret.name)),
|
|
1326
|
+
);
|
|
1327
|
+
if (missingSecretsAtBoot.length > 0) {
|
|
1328
|
+
logger({
|
|
1329
|
+
level: "warn",
|
|
1330
|
+
event: "provider_secrets_missing",
|
|
1331
|
+
providerId: provider.id,
|
|
1332
|
+
missingSecrets: missingSecretsAtBoot,
|
|
1333
|
+
});
|
|
1334
|
+
}
|
|
1335
|
+
|
|
1283
1336
|
app.notFound((c) =>
|
|
1284
1337
|
c.json(
|
|
1285
1338
|
{
|
package/src/types.ts
CHANGED
|
@@ -769,7 +769,25 @@ export type ProviderAccessVisibility = "public" | "early_access";
|
|
|
769
769
|
|
|
770
770
|
export type ProviderProxyMode = "disabled" | "optional" | "required";
|
|
771
771
|
|
|
772
|
-
|
|
772
|
+
/**
|
|
773
|
+
* Proxy egress vendors. These are FOUR DISTINCT services — do not conflate them
|
|
774
|
+
* (a common mistake because the names collide with a well-known rebrand):
|
|
775
|
+
*
|
|
776
|
+
* - `smartproxy` — **api.smartproxy.org**, a residential proxy with an IP
|
|
777
|
+
* *extraction/allocation* API (app_key → a pool of raw `ip:port` CONNECT
|
|
778
|
+
* endpoints). This is our own vendor. It is NOT the company formerly named
|
|
779
|
+
* "Smartproxy". Credentials: `APIFUSE__PROXY__SMARTPROXY_APP_KEY`.
|
|
780
|
+
* - `nodemaven` — **gate.nodemaven.com**, a *gateway* proxy with static
|
|
781
|
+
* credentials; geo/session encoded in the username, no allocation API.
|
|
782
|
+
* - `decodo` — **decodo.com**, the *gateway* proxy that was named "Smartproxy"
|
|
783
|
+
* (smartproxy.com) before its 2025 rebrand to Decodo. Sticky sessions via
|
|
784
|
+
* username params. A different company from `smartproxy` above.
|
|
785
|
+
* **@deprecated** — unused; no managed adapter. Use `smartproxy`/`nodemaven`,
|
|
786
|
+
* or the `APIFUSE__PROXY__URL` bring-your-own escape hatch.
|
|
787
|
+
* - `custom` — **@deprecated** bring-your-own static proxy URL marker. The
|
|
788
|
+
* `APIFUSE__PROXY__URL` env still works without declaring this value.
|
|
789
|
+
*/
|
|
790
|
+
export type ProviderProxyProvider = "smartproxy" | "nodemaven" | "decodo" | "custom";
|
|
773
791
|
|
|
774
792
|
export type ProviderProxySessionAffinity =
|
|
775
793
|
| "request"
|
|
@@ -783,7 +801,18 @@ export interface ProviderProxyPolicy {
|
|
|
783
801
|
* certificate verification, and vendor allocator endpoints are SDK-owned.
|
|
784
802
|
*/
|
|
785
803
|
mode: ProviderProxyMode;
|
|
804
|
+
/**
|
|
805
|
+
* @deprecated Use `providers: [...]` to declare an ordered vendor fallback
|
|
806
|
+
* chain. A single-element `providers` list is equivalent to this field.
|
|
807
|
+
*/
|
|
786
808
|
provider?: ProviderProxyProvider;
|
|
809
|
+
/**
|
|
810
|
+
* Ordered proxy-vendor fallback chain. The SDK tries each vendor in order and
|
|
811
|
+
* fails over to the next when a vendor lacks credentials or its allocation /
|
|
812
|
+
* transport is exhausted. When omitted, `provider` (or the platform default)
|
|
813
|
+
* is used as a single-vendor chain.
|
|
814
|
+
*/
|
|
815
|
+
providers?: ProviderProxyProvider[];
|
|
787
816
|
geo?: {
|
|
788
817
|
/** ISO 3166-1 alpha-2 country code, for example KR or US. */
|
|
789
818
|
country?: Iso3166Alpha2CountryCode;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
@AGENTS.md
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
@AGENTS.md
|
/package/dist/cli/templates/provider/{skills → .agents/skills}/fixtures-and-recording/SKILL.md.tpl
RENAMED
|
File without changes
|
|
File without changes
|
/package/dist/cli/templates/provider/{skills → .agents/skills}/normalization-standards/SKILL.md.tpl
RENAMED
|
File without changes
|
/package/dist/cli/templates/provider/{skills → .agents/skills}/pagination-and-counts/SKILL.md.tpl
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/src/cli/templates/provider/{skills → .agents/skills}/fixtures-and-recording/SKILL.md.tpl
RENAMED
|
File without changes
|
|
File without changes
|
/package/src/cli/templates/provider/{skills → .agents/skills}/normalization-standards/SKILL.md.tpl
RENAMED
|
File without changes
|
/package/src/cli/templates/provider/{skills → .agents/skills}/pagination-and-counts/SKILL.md.tpl
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|