✨ feat(vscode): 接口卡片找前端调用时,网址模板里拼的字符串常量(${API_PREFIX} 这类)换成它的值再对接口,本文件定义的、import 进来的、常量引用常量的都算
This commit is contained in:
1 parent
5426c50cd9
commit
50672c70d1
3 files changed
+324
-61
No files matched your search
@@ -280,3 +280,114 @@ describe('经包装函数发的请求', () => {
|
||||
expect(await sent(indexes, 'POST')).toEqual([])
|
||||
})
|
||||
})
|
||||
|
||||
/** 导出的常量,值引用另一份文件导出的常量;PONG 和 config.ts 的 PING 互相引用。 */
|
||||
const ROOT = [
|
||||
'import { PING } from "./config";',
|
||||
'',
|
||||
'export const API_ROOT = "/api";',
|
||||
`export const PONG = \`\${PING}/pong\`;`,
|
||||
'',
|
||||
].join('\n')
|
||||
|
||||
const CONFIG = [
|
||||
'import { API_ROOT, PONG } from "./root";',
|
||||
'',
|
||||
`export const API_V1 = \`\${API_ROOT}/v1\`;`,
|
||||
`export const PING = \`\${PONG}/ping\`;`,
|
||||
'',
|
||||
].join('\n')
|
||||
|
||||
/** 照搬 luffy 的 chat/code/api.ts:网址开头拼本文件的 API_PREFIX;也拼导入的、引用常量的,和取不到值的。 */
|
||||
const SESSION_API = [
|
||||
'import { API_V1, PING } from "@/lib/config";',
|
||||
'import { API_ROOT } from "../../../../lib/root";',
|
||||
'import { BASE } from "some-lib";',
|
||||
'',
|
||||
'const API_PREFIX = "/api/v1";',
|
||||
'const VERSION = `v2`;',
|
||||
`const SESSIONS = \`\${API_PREFIX}/sessions\` as const;`,
|
||||
'const DYNAMIC = process.env.API ?? "/api";',
|
||||
`const DERIVED = \`\${DYNAMIC}/v1\`;`,
|
||||
'let MUTABLE = "/api/v1";',
|
||||
`const LOOP_A = \`\${LOOP_B}/a\`;`,
|
||||
`const LOOP_B = \`\${LOOP_A}/b\`;`,
|
||||
'',
|
||||
`export const cancel = (id: string) => fetch(\`\${API_PREFIX}/sessions/\${id}/cancel\`, { method: "POST" });`,
|
||||
`export const versioned = (id: string) => fetch(\`/api/\${VERSION}/agents/\${id}\`);`,
|
||||
`export const stream = (id: string) => fetch(\`\${SESSIONS}/\${id}/stream\`);`,
|
||||
`export const models = (id: string) => fetch(\`\${API_V1}/agents/\${id}/models\`);`,
|
||||
`export const health = () => fetch(\`\${API_ROOT}/health\`);`,
|
||||
'',
|
||||
'export function shadowed(API_PREFIX: string) {',
|
||||
' const API_V1 = DYNAMIC;',
|
||||
` return [fetch(\`\${API_PREFIX}/agents\`), fetch(\`\${API_V1}/agents\`)];`,
|
||||
'}',
|
||||
'',
|
||||
'export const unresolved = (cfg: { prefix: string }) => [',
|
||||
` fetch(\`\${DYNAMIC}/agents\`),`,
|
||||
` fetch(\`\${DERIVED}/agents\`),`,
|
||||
` fetch(\`\${MUTABLE}/agents\`),`,
|
||||
` fetch(\`\${LOOP_A}/agents\`),`,
|
||||
` fetch(\`\${PING}/agents\`),`,
|
||||
` fetch(\`\${BASE}/agents\`),`,
|
||||
` fetch(\`\${cfg.prefix}/agents\`),`,
|
||||
` fetch(\`\${String(API_PREFIX)}/agents\`),`,
|
||||
'];',
|
||||
'',
|
||||
].join('\n')
|
||||
|
||||
describe('网址里拼的常量', () => {
|
||||
const files = { 'web/tsconfig.json': TSCONFIG, 'web/src/lib/root.ts': ROOT, 'web/src/lib/config.ts': CONFIG, 'web/src/app/(main)/chat/code/api.ts': SESSION_API }
|
||||
const API = 'web/src/app/(main)/chat/code/api.ts'
|
||||
|
||||
it('网址模板里拼的名字指向本文件的字符串常量就拼进它的值,开头、中间段都算,值引用常量的逐层展开', async () => {
|
||||
expect(await requests(files, 'POST')).toEqual([`${API} cancel@13:13 POST /api/v1/sessions/\${id}/cancel 13:38`])
|
||||
expect((await requests(files, 'GET')).slice(0, 2)).toEqual([
|
||||
`${API} versioned@14:13 GET /api/v2/agents/\${id} 14:41`,
|
||||
`${API} stream@15:13 GET /api/v1/sessions/\${id}/stream 15:38`,
|
||||
])
|
||||
})
|
||||
|
||||
it('导入的常量(路径别名、相对路径)按 import 来源对到导出它的文件,值里又导入的接着展开', async () => {
|
||||
expect((await requests(files, 'GET')).slice(2, 4)).toEqual([
|
||||
`${API} models@16:13 GET /api/v1/agents/\${id}/models 16:38`,
|
||||
`${API} health@17:13 GET /api/health 17:28`,
|
||||
])
|
||||
})
|
||||
|
||||
it('被参数、局部变量挡住的,不是字面量的,有循环的,包里导入的,不是名字本身的,都照写成参数段', async () => {
|
||||
expect((await requests(files, 'GET')).slice(4)).toEqual([
|
||||
`${API} shadowed@19:16 GET \${API_PREFIX}/agents 21:10`,
|
||||
`${API} shadowed@19:16 GET \${API_V1}/agents 21:41`,
|
||||
`${API} unresolved@24:13 GET \${DYNAMIC}/agents 25:2`,
|
||||
`${API} unresolved@24:13 GET \${DERIVED}/agents 26:2`,
|
||||
`${API} unresolved@24:13 GET \${MUTABLE}/agents 27:2`,
|
||||
`${API} unresolved@24:13 GET \${LOOP_A}/agents 28:2`,
|
||||
`${API} unresolved@24:13 GET \${PING}/agents 29:2`,
|
||||
`${API} unresolved@24:13 GET \${BASE}/agents 30:2`,
|
||||
`${API} unresolved@24:13 GET \${cfg.prefix}/agents 31:2`,
|
||||
`${API} unresolved@24:13 GET \${String(API_PREFIX)}/agents 32:2`,
|
||||
])
|
||||
})
|
||||
|
||||
it('导出常量的文件改了,结果跟着变', async () => {
|
||||
const host = new MemoryIndexHost(files, INDEX_GRAMMARS)
|
||||
const indexes = new WorkspaceIndexes(host)
|
||||
const imported = async (): Promise<string[]> => (await sent(indexes, 'GET')).filter(line => / (?:models|health)@/.test(line))
|
||||
expect(await imported()).toEqual([
|
||||
`${API} models@16:13 GET /api/v1/agents/\${id}/models 16:38`,
|
||||
`${API} health@17:13 GET /api/health 17:28`,
|
||||
])
|
||||
host.emit('change', 'web/src/lib/root.ts', 'export const API_ROOT = "/gateway";\n')
|
||||
expect(await imported()).toEqual([
|
||||
`${API} models@16:13 GET /gateway/v1/agents/\${id}/models 16:38`,
|
||||
`${API} health@17:13 GET /gateway/health 17:28`,
|
||||
])
|
||||
host.emit('change', 'web/src/lib/root.ts', 'const API_ROOT = "/gateway";\n')
|
||||
expect(await imported()).toEqual([
|
||||
`${API} models@16:13 GET \${API_V1}/agents/\${id}/models 16:38`,
|
||||
`${API} health@17:13 GET \${API_ROOT}/health 17:28`,
|
||||
])
|
||||
})
|
||||
})
|
||||
Reference in new issue
Block a user