✨ feat(vscode): FastAPI 接口卡片的调用树带上前端调用它的地方
This commit is contained in:
1 parent
d4459e93b3
commit
29cedcb751
30 files changed
+1316
-130
No files matched your search
@@ -0,0 +1,95 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { INDEX_GRAMMARS, MemoryIndexHost } from '../testSupport'
|
||||
import { WorkspaceIndexes } from '../workspaceIndex'
|
||||
import { REQUESTS_INDEX } from './requests'
|
||||
|
||||
const STORE = [
|
||||
'export function useAgentStore() {',
|
||||
' let later = () => fetch("/api/v1/agents/later", { method: "PATCH" })',
|
||||
' return later',
|
||||
'}',
|
||||
'',
|
||||
'class AgentApi {',
|
||||
` rename = async (id: string) => { await this.http.PATCH(\`/api/v1/agents/\${id}\`) }`,
|
||||
'}',
|
||||
'',
|
||||
].join('\n')
|
||||
|
||||
const PAGE = [
|
||||
'import { api } from "@/lib/api"',
|
||||
'',
|
||||
'const MyAgentsPage = async () => {',
|
||||
' const { data } = await api.GET("/api/v1/agents", { params: { query: {} } })',
|
||||
' return <div>{data?.length}</div>',
|
||||
'}',
|
||||
'',
|
||||
'export default MyAgentsPage',
|
||||
'',
|
||||
].join('\n')
|
||||
|
||||
const AGENTS = [
|
||||
'export async function fetchDefaultAgent() {',
|
||||
' const res = await fetch("/api/v1/agents/default", { credentials: "include" })',
|
||||
' return res.json()',
|
||||
'}',
|
||||
'',
|
||||
'export const createAgent = async (body: unknown) => {',
|
||||
` await fetch(\`/api/v1/agents?force=\${1}\`, { method: "POST", body: JSON.stringify(body) })`,
|
||||
'}',
|
||||
'',
|
||||
'export function useRemoveAgent(id: string) {',
|
||||
` return useMutation({ mutationFn: () => api.DELETE(\`/api/v1/agents/\${id}\`) })`,
|
||||
'}',
|
||||
'',
|
||||
'export async function guessed(method: string, init: RequestInit) {',
|
||||
' await fetch("/api/v1/agents", { method })',
|
||||
' await fetch("/api/v1/agents", init)',
|
||||
' await fetch("/api/v1/agents", { ...init })',
|
||||
' await fetch(url)',
|
||||
' await axios.get("/api/v1/agents")',
|
||||
'}',
|
||||
'',
|
||||
'class Client {',
|
||||
` load(orderId: string) { /* 中文 */ return this.http.GET(\`/api/v1/commerce/orders/\${orderId}\` as never) }`,
|
||||
'}',
|
||||
'',
|
||||
'const pending = fetch(\'/api/v1/health#top\')',
|
||||
'',
|
||||
].join('\n')
|
||||
|
||||
async function requests(files: Record<string, string>, method: string): Promise<string[]> {
|
||||
const found = await new WorkspaceIndexes(new MemoryIndexHost(files, INDEX_GRAMMARS)).find(REQUESTS_INDEX, method)
|
||||
return found.map(({ location, entry }) => {
|
||||
const file = location.uri.replace(`${MemoryIndexHost.FOLDER}/`, '')
|
||||
const call = `${entry.at.line}:${entry.at.character}`
|
||||
return `${file} ${entry.caller ?? '(顶层)'}@${location.start.line}:${location.start.character} ${entry.key} ${entry.path} ${call}`
|
||||
})
|
||||
}
|
||||
|
||||
describe('前端发请求的地方', () => {
|
||||
const files = { 'web/src/app/(main)/my-agents/page.tsx': PAGE, 'web/src/lib/agents.ts': AGENTS }
|
||||
|
||||
it('认 X.GET 这类成员名是大写 HTTP 方法的调用,名字归最内层有名字的函数(箭头函数取赋值的名字)', async () => {
|
||||
expect(await requests(files, 'GET')).toEqual([
|
||||
'web/src/app/(main)/my-agents/page.tsx MyAgentsPage@2:6 GET /api/v1/agents 3:25',
|
||||
'web/src/lib/agents.ts fetchDefaultAgent@0:22 GET /api/v1/agents/default 1:20',
|
||||
`web/src/lib/agents.ts load@22:2 GET /api/v1/commerce/orders/\${orderId} 22:42`,
|
||||
'web/src/lib/agents.ts (顶层)@25:16 GET /api/v1/health 25:16',
|
||||
])
|
||||
})
|
||||
|
||||
it('fetch 的方法看 method 字面量,没写是 GET;method 不是字面量、第二个参数不是对象字面量、带展开的都不认;查询串去掉', async () => {
|
||||
expect(await requests(files, 'POST')).toEqual(['web/src/lib/agents.ts createAgent@5:13 POST /api/v1/agents 6:8'])
|
||||
})
|
||||
|
||||
it('赋给 let 的箭头函数不算有名字,归到外层;赋给类字段的取字段名', async () => {
|
||||
expect(await requests({ 'web/src/lib/store.ts': STORE }, 'PATCH')).toEqual([
|
||||
'web/src/lib/store.ts useAgentStore@0:16 PATCH /api/v1/agents/later 1:20',
|
||||
`web/src/lib/store.ts rename@6:2 PATCH /api/v1/agents/\${id} 6:41`,
|
||||
])
|
||||
})
|
||||
|
||||
it('匿名回调里发的请求归到外层有名字的函数', async () => {
|
||||
expect(await requests(files, 'DELETE')).toEqual([`web/src/lib/agents.ts useRemoveAgent@9:16 DELETE /api/v1/agents/\${id} 10:41`])
|
||||
})
|
||||
})
|
||||
Reference in new issue
Block a user