feat(ui): Steps for servers — route roots, server effects, request/decorator triggers, guards for Python/Java/Kotlin/C#/Go/C
- api/route-roots.ts: the symbol a route runs (references-edge handler, exported page component, or the route itself for an inline handler), shared by steps and screens; the bare Steps tab lists an API's endpoints by router file - api/effects.ts: database / response / queue / email / payments / cache / auth / process / network / storage / device / telemetry, matched on the call as written per language family, with model + read/write and the literal status on a response site - graph/branch-guards.ts: callSitesForFile (the whole member chain), memberTypesInTree, decoratorsForFile, request/decorator triggers with the middleware/guard chain; guard + argument rules for Python, Java, Kotlin, C#, Go and C - steps.ts: classify on the chain before trusting a name match, retarget this.x.y() by declared type, skip test doubles after the effect pre-check, project kind on the wire - viewer: kindWord/kindWords per project kind, endpoint chooser, response boxes labelled by status codes - python.ts: FastAPI detected from a monorepo sub-directory; is-test-file: samples/examples package paths are not tests - tests: ui-steps-api-servers, ui-effects, branch-guards-languages; spec §3.13 Servers paragraph, CHANGELOG, plan doc Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01REFyW9hmNrxhwN5wxRoAkC
This commit is contained in:
co-authored by
Claude Fable 5
parent
5e06204deb
commit
950686def4
@@ -4,7 +4,7 @@
|
||||
* rule, and the panel's two lists.
|
||||
*/
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { buildStepsModel, kindWord, stepLabel, stepNeighbourhood, stepSub, stepViaText, triggerWords } from '../ui/src/lib/steps-model';
|
||||
import { buildStepsModel, countWords, kindWord, kindWords, stepLabel, stepNeighbourhood, stepSub, stepViaText, triggerWords } from '../ui/src/lib/steps-model';
|
||||
import { placeLabels } from '../ui/src/lib/screens-model';
|
||||
import type { WireNodeRef, WireStep, WireStepLink, WireStepsPayload } from '../ui/src/lib/wire';
|
||||
|
||||
@@ -25,6 +25,7 @@ function payload(steps: WireStep[], links: WireStepLink[]): WireStepsPayload {
|
||||
return {
|
||||
anchor: steps[0]!.node!,
|
||||
ambiguous: [],
|
||||
project: 'app',
|
||||
steps,
|
||||
links,
|
||||
depth: 8,
|
||||
@@ -115,3 +116,24 @@ describe('steps model', () => {
|
||||
expect(lists.leadsTo.map((l) => l.to)).toEqual([effect.id, store.id, home.id, store.id]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('words per project', () => {
|
||||
it('names the same box for an app, an API and a web app', () => {
|
||||
expect(kindWord('screen', 'app')).toBe('screen');
|
||||
expect(kindWord('screen', 'api')).toBe('endpoint');
|
||||
expect(kindWord('screen', 'web')).toBe('page');
|
||||
// A route that leads with a verb is an endpoint wherever it is.
|
||||
const endpoint = { id: 'r', kind: 'screen', anchor: false, node: null, label: 'POST /users', sub: 'createUser', depth: 1, cut: null, screen: { path: 'POST /users', component: null, endpoint: true, inline: false } } as const;
|
||||
expect(kindWord('screen', 'web', endpoint)).toBe('endpoint');
|
||||
expect(kindWords('store', 'api')).toEqual(['data call', 'data calls']);
|
||||
expect(kindWords('bridge', 'app')).toEqual(['native call', 'native calls']);
|
||||
expect(countWords(11, 'effect', 'api')).toBe('11 outside the index');
|
||||
expect(countWords(1, 'trigger')).toBe('1 handler');
|
||||
expect(countWords(3, 'trigger')).toBe('3 handlers');
|
||||
});
|
||||
it('says what fires a server-side step', () => {
|
||||
expect(triggerWords({ kind: 'request', name: 'POST', of: '/users', in: 'users.routes.ts', after: ['authenticate', 'validate(…)'] })).toBe('POST /users · after authenticate, validate(…)');
|
||||
expect(triggerWords({ kind: 'decorator', name: 'Process', of: "'email'", in: 'x.ts' })).toBe("@Process('email')");
|
||||
expect(triggerWords({ kind: 'load', name: 'GET', of: '/blog/[slug]', in: 'page.tsx' })).toBe('page load · /blog/[slug]');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user