@sungen/driver-api 3.1.2-beta.124 → 3.1.2-beta.126
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/package.json +2 -2
- package/src/api-harness.ts +5 -1
- package/src/api-repair.ts +2 -0
- package/src/index.ts +10 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sungen/driver-api",
|
|
3
|
-
"version": "3.1.2-beta.
|
|
3
|
+
"version": "3.1.2-beta.126",
|
|
4
4
|
"description": "Sungen API capability — the @api annotation, API catalog, OpenAPI import + `sungen api import`, and the specs/api.ts runtime template. Plugs into @sun-asterisk/sungen via the capability SPI.",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"types": "src/index.ts",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"author": "eqe team (engineer & quality) — Sun Asterisk",
|
|
14
14
|
"license": "MIT",
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@sun-asterisk/sungen": "3.1.2-beta.
|
|
16
|
+
"@sun-asterisk/sungen": "3.1.2-beta.126",
|
|
17
17
|
"commander": "^14.0.2",
|
|
18
18
|
"yaml": "^2.8.2"
|
|
19
19
|
},
|
package/src/api-harness.ts
CHANGED
|
@@ -22,6 +22,7 @@ interface ApiScenario {
|
|
|
22
22
|
queryRefs?: string[];
|
|
23
23
|
casesDataset?: string;
|
|
24
24
|
stepsText?: string; // lowercase steps text
|
|
25
|
+
manual?: boolean; // @manual — not automated, so excluded from automation businessDepth
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
interface ApiGateInput {
|
|
@@ -112,7 +113,10 @@ export function apiGateProvider(input: ApiGateInput): { gate: GateResult; depth:
|
|
|
112
113
|
// An error scenario (a @cases matrix, or one asserting a 4xx/5xx) proves the failure CONTRACT —
|
|
113
114
|
// the status IS its correct assertion (the API analog of UI NAV), so it is not depth-required.
|
|
114
115
|
const errorLike = (s: ApiScenario) => !!s.casesDataset || /\bis\s+["']?[45]\d\d\b/.test(s.stepsText ?? '');
|
|
115
|
-
|
|
116
|
+
// businessDepth measures AUTOMATED proof — a @manual scenario isn't automated, so it can't count
|
|
117
|
+
// toward depth (else deferring an automatable mutation to @manual inflates the score). The
|
|
118
|
+
// api-viewpoints sensor separately flags @manual scenarios whose endpoint resolves (automatable).
|
|
119
|
+
const depthRequired = apiScenarios.filter((s) => !s.manual && (s.apiRefs ?? []).some(isMutating) && !errorLike(s));
|
|
116
120
|
const isDeep = (s: ApiScenario): boolean => {
|
|
117
121
|
const t = s.stepsText ?? '';
|
|
118
122
|
return /\b[a-z_][a-z0-9_]*\.body\b/.test(t) // asserts a response body field
|
package/src/api-repair.ts
CHANGED
|
@@ -21,6 +21,8 @@ export const apiRepair: RepairProvider = {
|
|
|
21
21
|
fix: 'A mutating success scenario only asserts the status — make it PROVE THE EFFECT: assert a response body field, a `@query` DB side-effect, or a `@concurrent` `ok_count` invariant.' },
|
|
22
22
|
{ id: 'api-verification', match: /VERIFICATION-FAIL|does not resolve|not found in/i,
|
|
23
23
|
fix: 'An `@api:<name>` does not resolve in the catalog — fix the name, or add/import the endpoint into `api/apis.yaml` (`sungen api import`).' },
|
|
24
|
+
{ id: 'api-manual-automatable', match: /VIEWPOINT-API-MANUAL-AUTOMATABLE/i,
|
|
25
|
+
fix: 'A @manual scenario is automatable (its endpoint resolves) — drop @manual and use @api (+ @cases for error rows / @concurrent for idempotency). Reserve @manual for genuine judgment cases.' },
|
|
24
26
|
|
|
25
27
|
// ── Runtime failures (from the Playwright test-result) ────────────────────────────────────
|
|
26
28
|
{ id: 'api-auth', match: /\b40[13]\b|unauthor|forbidden/i,
|
package/src/index.ts
CHANGED
|
@@ -159,6 +159,16 @@ const apiViewpointSensor: Sensor<GateInput> = {
|
|
|
159
159
|
}
|
|
160
160
|
}
|
|
161
161
|
|
|
162
|
+
// api-manual-automatable — a @manual scenario whose @api endpoint RESOLVES is automatable; flag it
|
|
163
|
+
// so automatable work isn't deferred to manual (a common run-test reflex when the call failed).
|
|
164
|
+
for (const s of apiScenarios) {
|
|
165
|
+
if (!s.manual) continue;
|
|
166
|
+
const automatable = (s.apiRefs ?? []).filter((r) => { try { resolveApi(r, screenName, cwd); return true; } catch { return false; } });
|
|
167
|
+
if (automatable.length) {
|
|
168
|
+
add('warn', `VIEWPOINT-API-MANUAL-AUTOMATABLE: "${s.name}" is @manual but its endpoint(s) ${automatable.join(', ')} resolve in the catalog — automate with @api (+ @cases for error rows); don't defer an automatable API check to manual.`);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
162
172
|
// Method-aware: error + idempotency only apply when a referenced endpoint MUTATES.
|
|
163
173
|
const mutating: string[] = [];
|
|
164
174
|
for (const name of refs) {
|