@apifuse/provider-sdk 2.1.0-beta.17 → 2.1.0-beta.18
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/CHANGELOG.md +4 -0
- package/bin/apifuse-submit-check.ts +43 -14
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -435,13 +435,14 @@ function scoreDescribeKey(providerRoot: string): SubmitCheck {
|
|
|
435
435
|
function scoreNoRawFetch(providerRoot: string): SubmitCheck {
|
|
436
436
|
const findings = findSourceLineMatches(providerRoot, /(?<![.\w])fetch\s*\(/);
|
|
437
437
|
if (findings.length > 0) {
|
|
438
|
+
const evidence = formatSourceFindings(findings);
|
|
438
439
|
return blocker(
|
|
439
440
|
"no-raw-fetch",
|
|
440
441
|
SDK_NATIVE_CATEGORY,
|
|
441
442
|
"Provider source calls raw fetch().",
|
|
442
|
-
|
|
443
|
+
`Replace raw fetch() in ${evidence.join(", ")} with ctx.stealth.fetch() for stealth/cloud-IP-sensitive calls or ctx.http.get/post/request for ordinary HTTP calls.`,
|
|
443
444
|
0,
|
|
444
|
-
|
|
445
|
+
evidence,
|
|
445
446
|
);
|
|
446
447
|
}
|
|
447
448
|
|
|
@@ -1790,6 +1791,10 @@ function scoreManagedBrowserRuntime(providerRoot: string): SubmitCheck {
|
|
|
1790
1791
|
function scoreBaseChecks(results: CheckResult[]): SubmitCheck[] {
|
|
1791
1792
|
const failed = results.filter((result) => !result.passed);
|
|
1792
1793
|
if (failed.length > 0) {
|
|
1794
|
+
const remediation = [
|
|
1795
|
+
"Run `bunx apifuse check .` from the provider root.",
|
|
1796
|
+
...Array.from(new Set(failed.map(baseCheckRemediation))),
|
|
1797
|
+
].join(" ");
|
|
1793
1798
|
return [
|
|
1794
1799
|
{
|
|
1795
1800
|
id: "base-checks",
|
|
@@ -1799,8 +1804,7 @@ function scoreBaseChecks(results: CheckResult[]): SubmitCheck[] {
|
|
|
1799
1804
|
points: 0,
|
|
1800
1805
|
maxPoints: CATEGORY_MAX_POINTS.definition,
|
|
1801
1806
|
message: "Base provider checks failed.",
|
|
1802
|
-
remediation
|
|
1803
|
-
"Run `bun run check` and fix every failing item before bounty submission.",
|
|
1807
|
+
remediation,
|
|
1804
1808
|
evidence: failed.map((result) =>
|
|
1805
1809
|
redact(`${result.message}: ${(result.details ?? []).join("; ")}`),
|
|
1806
1810
|
),
|
|
@@ -1822,6 +1826,31 @@ function scoreBaseChecks(results: CheckResult[]): SubmitCheck[] {
|
|
|
1822
1826
|
];
|
|
1823
1827
|
}
|
|
1824
1828
|
|
|
1829
|
+
function baseCheckRemediation(result: CheckResult): string {
|
|
1830
|
+
switch (result.message) {
|
|
1831
|
+
case "index.ts exists and exports default defineProvider":
|
|
1832
|
+
return "Fix `index.ts` so it default-exports `defineProvider({...})`.";
|
|
1833
|
+
case "All operations have handler, input, output":
|
|
1834
|
+
return "For each operation named in evidence, add `handler`, `input`, and `output` fields to `defineProvider({ operations })`.";
|
|
1835
|
+
case "All operations have fixtures":
|
|
1836
|
+
return "For each operation named in evidence, add `fixtures.request` and `fixtures.response` values that exercise the operation schemas.";
|
|
1837
|
+
case "Zod schemas parse fixtures without error":
|
|
1838
|
+
return "Update the failing fixture values or their zod schemas until `fixtures.request` and `fixtures.response` parse cleanly.";
|
|
1839
|
+
case "Provider authoring lint has no error-level diagnostics":
|
|
1840
|
+
return "Fix each lint diagnostic shown in evidence, then rerun `bunx apifuse check .`.";
|
|
1841
|
+
case "Provider metadata is declared in defineProvider":
|
|
1842
|
+
return "Fill the missing `defineProvider` metadata fields: `id`, `meta.displayName`, `meta.category`, `runtime`, and `auth.mode`.";
|
|
1843
|
+
case "Dockerfile exists":
|
|
1844
|
+
return "Add a provider-root `Dockerfile` based on the current `apifuse create` template.";
|
|
1845
|
+
case "package.json exists with @apifuse/provider-sdk dependency":
|
|
1846
|
+
return "Add `@apifuse/provider-sdk` to `package.json` dependencies.";
|
|
1847
|
+
case "Base provider checks can run":
|
|
1848
|
+
return "Fix the import/runtime error shown in evidence so `apifuse check` can load the provider.";
|
|
1849
|
+
default:
|
|
1850
|
+
return `Fix the failing base check "${result.message}" shown in evidence.`;
|
|
1851
|
+
}
|
|
1852
|
+
}
|
|
1853
|
+
|
|
1825
1854
|
function scoreLocaleCatalog(
|
|
1826
1855
|
providerRoot: string,
|
|
1827
1856
|
provider: ProviderDefinition,
|
|
@@ -2001,7 +2030,7 @@ function scoreOperationMetadata(provider: ProviderDefinition): SubmitCheck {
|
|
|
2001
2030
|
maxPoints: CATEGORY_MAX_POINTS.operations,
|
|
2002
2031
|
message: "One or more operations have weak descriptions.",
|
|
2003
2032
|
remediation:
|
|
2004
|
-
"
|
|
2033
|
+
`For ${weakDescriptions.join(", ")}, add an operation \`descriptionKey\` backed by \`locales/en.json\` and \`locales/ko.json\`, or add a 150+ character \`description\` explaining when to use it, when not to use it, outputs, and caveats.`,
|
|
2005
2034
|
evidence: weakDescriptions,
|
|
2006
2035
|
};
|
|
2007
2036
|
}
|
|
@@ -2021,7 +2050,7 @@ function scoreOperationMetadata(provider: ProviderDefinition): SubmitCheck {
|
|
|
2021
2050
|
: "Operation descriptions and metadata are review-ready.",
|
|
2022
2051
|
remediation:
|
|
2023
2052
|
missingAnnotations.length > 0
|
|
2024
|
-
? "
|
|
2053
|
+
? `For ${missingAnnotations.join(", ")}, add \`annotations\` with the applicable safety fields, such as \`readOnly\`, \`destructive\`, \`idempotent\`, \`openWorld\`, \`rateLimit\`, or \`timeoutMs\`.`
|
|
2025
2054
|
: undefined,
|
|
2026
2055
|
evidence:
|
|
2027
2056
|
missingAnnotations.length > 0
|
|
@@ -2044,7 +2073,7 @@ function scoreFixtureCoverage(provider: ProviderDefinition): SubmitCheck {
|
|
|
2044
2073
|
"fixtures",
|
|
2045
2074
|
"fixtures",
|
|
2046
2075
|
"One or more operations are missing bidirectional fixtures.",
|
|
2047
|
-
"
|
|
2076
|
+
`For ${missing.join(", ")}, add \`fixtures.request\` and \`fixtures.response\` values that parse against the operation input and output schemas.`,
|
|
2048
2077
|
CATEGORY_MAX_POINTS.fixtures,
|
|
2049
2078
|
missing,
|
|
2050
2079
|
);
|
|
@@ -2092,7 +2121,7 @@ function scoreHealthCoverage(provider: ProviderDefinition): SubmitCheck {
|
|
|
2092
2121
|
"health-coverage",
|
|
2093
2122
|
"health",
|
|
2094
2123
|
"One or more operations lack healthCheck or healthCheckUnsupported.",
|
|
2095
|
-
"
|
|
2124
|
+
`For ${missing.join(", ")}, add \`healthCheck: { interval, cases }\` for safe read-only upstream probes, or add \`healthCheckUnsupported: { reason: "<specific reason>" }\`.`,
|
|
2096
2125
|
CATEGORY_MAX_POINTS.health,
|
|
2097
2126
|
missing,
|
|
2098
2127
|
);
|
|
@@ -2108,7 +2137,7 @@ function scoreHealthCoverage(provider: ProviderDefinition): SubmitCheck {
|
|
|
2108
2137
|
maxPoints: CATEGORY_MAX_POINTS.health,
|
|
2109
2138
|
message: "Some healthCheckUnsupported reasons look placeholder-like.",
|
|
2110
2139
|
remediation:
|
|
2111
|
-
"
|
|
2140
|
+
`For ${placeholder.join(", ")}, replace the placeholder \`healthCheckUnsupported.reason\` with a specific reason such as destructive mutation, paid call, credential sensitivity, or upstream flakiness.`,
|
|
2112
2141
|
evidence: placeholder,
|
|
2113
2142
|
};
|
|
2114
2143
|
}
|
|
@@ -2124,7 +2153,7 @@ function scoreHealthCoverage(provider: ProviderDefinition): SubmitCheck {
|
|
|
2124
2153
|
message:
|
|
2125
2154
|
"Generated starter operation health rationale is present; replace starter logic before bounty submission.",
|
|
2126
2155
|
remediation:
|
|
2127
|
-
|
|
2156
|
+
`Replace generated starter operation(s) ${generatedStarter.join(", ")} with real upstream-backed operations and add \`healthCheck\` for safe read-only probes.`,
|
|
2128
2157
|
evidence: generatedStarter,
|
|
2129
2158
|
};
|
|
2130
2159
|
}
|
|
@@ -2140,7 +2169,7 @@ function scoreHealthCoverage(provider: ProviderDefinition): SubmitCheck {
|
|
|
2140
2169
|
message:
|
|
2141
2170
|
"Health coverage is declared, with one or more unsupported probes.",
|
|
2142
2171
|
remediation:
|
|
2143
|
-
"
|
|
2172
|
+
`For ${unsupported.join(", ")}, replace \`healthCheckUnsupported\` with \`healthCheck: { interval, cases }\` when the upstream operation is safe and read-only; keep unsupported only for destructive, paid, credential-sensitive, or flaky probes with a specific reason.`,
|
|
2144
2173
|
evidence: unsupported.map(
|
|
2145
2174
|
(operationId) => `${operationId}: healthCheckUnsupported`,
|
|
2146
2175
|
),
|
|
@@ -2205,7 +2234,7 @@ function scoreAuthSafety(provider: ProviderDefinition): SubmitCheck {
|
|
|
2205
2234
|
maxPoints: CATEGORY_MAX_POINTS.auth,
|
|
2206
2235
|
message: "OAuth auth mode does not declare persisted credential.keys.",
|
|
2207
2236
|
remediation:
|
|
2208
|
-
"
|
|
2237
|
+
"Add `credential: { keys: [...] }` to `defineProvider` with the persisted OAuth token fields returned by the real token exchange.",
|
|
2209
2238
|
};
|
|
2210
2239
|
}
|
|
2211
2240
|
|
|
@@ -2224,7 +2253,7 @@ function scoreAuthSafety(provider: ProviderDefinition): SubmitCheck {
|
|
|
2224
2253
|
message:
|
|
2225
2254
|
"Provider is no-auth but at least one operation is not marked openWorld.",
|
|
2226
2255
|
remediation:
|
|
2227
|
-
|
|
2256
|
+
`Either set \`auth.mode\` to the upstream auth model, or mark these public no-auth operations with \`annotations.openWorld: true\`: ${securedOperations.map(([operationId]) => operationId).join(", ")}.`,
|
|
2228
2257
|
evidence: securedOperations.map(([operationId]) => operationId),
|
|
2229
2258
|
};
|
|
2230
2259
|
}
|
|
@@ -2285,7 +2314,7 @@ function scoreProviderDocs(providerRoot: string): SubmitCheck[] {
|
|
|
2285
2314
|
: "Provider README includes expected submission guidance.",
|
|
2286
2315
|
remediation:
|
|
2287
2316
|
missing.length > 0 || !mentionsSubmitCheck
|
|
2288
|
-
? "
|
|
2317
|
+
? "Update `README.md` to include `Parameters`, `Response`, `Example`, and submit-check evidence guidance sections."
|
|
2289
2318
|
: undefined,
|
|
2290
2319
|
evidence: [
|
|
2291
2320
|
...missing.map(([, label]) => `missing ${label}`),
|
package/package.json
CHANGED