✨ feat(vscode): 接口卡片找前端调用时,网址最后一段字面量后面紧贴的 ${...}(messages${qs} 这类)当查询串去掉再对接口
This commit is contained in:
1 parent
2c490cac2d
commit
7d5432df3b
2 files changed
+49
-5
No files matched your search
@@ -337,6 +337,40 @@ const SESSION_API = [
|
|||||||
'',
|
'',
|
||||||
].join('\n')
|
].join('\n')
|
||||||
|
|
||||||
|
/** 网址末尾拼查询串:`messages${qs}`;和看着像、却不是查询串的。 */
|
||||||
|
const QUERY = [
|
||||||
|
'const API_PREFIX = "/api/v1";',
|
||||||
|
'const TAIL = "messages";',
|
||||||
|
'',
|
||||||
|
'export async function list(id: string, qs: string, name: string, n: number, a: string) {',
|
||||||
|
` await fetch(\`\${API_PREFIX}/sessions/\${id}/messages\${qs}\`);`,
|
||||||
|
` await fetch(\`/api/v1/sessions/\${id}/\${TAIL}\${qs}\`);`,
|
||||||
|
` await fetch(\`/api/v1/files/\${name}\`);`,
|
||||||
|
` await fetch(\`/api/v\${n}/agents\`);`,
|
||||||
|
` await fetch(\`/api/v1/sessions/\${id}\${qs}\`);`,
|
||||||
|
` await fetch(\`/api/v1/sessions/\${id}messages\${qs}\`);`,
|
||||||
|
` await fetch(\`/api/v1/sessions/messages\${a}\${qs}\`);`,
|
||||||
|
` await fetch(\`/api/v1/sessions/messages\${qs}/\`);`,
|
||||||
|
'}',
|
||||||
|
'',
|
||||||
|
].join('\n')
|
||||||
|
|
||||||
|
describe('网址末尾拼的查询串', () => {
|
||||||
|
it('最后一段是字面量文字(常量展开的也算)后面紧贴一个插值时,插值当查询串去掉;整段就是插值的、这一段前面还有插值的、紧贴两个的、不在末尾的照写', async () => {
|
||||||
|
const file = 'web/src/lib/messages.ts'
|
||||||
|
expect((await requests({ [file]: QUERY }, 'GET')).map(line => line.split(' ')[3])).toEqual([
|
||||||
|
`/api/v1/sessions/\${id}/messages`,
|
||||||
|
`/api/v1/sessions/\${id}/messages`,
|
||||||
|
`/api/v1/files/\${name}`,
|
||||||
|
`/api/v\${n}/agents`,
|
||||||
|
`/api/v1/sessions/\${id}\${qs}`,
|
||||||
|
`/api/v1/sessions/\${id}messages\${qs}`,
|
||||||
|
`/api/v1/sessions/messages\${a}\${qs}`,
|
||||||
|
`/api/v1/sessions/messages\${qs}/`,
|
||||||
|
])
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe('网址里拼的常量', () => {
|
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 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'
|
const API = 'web/src/app/(main)/chat/code/api.ts'
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ type Method = string | typeof FROM_CALLER
|
|||||||
* 不在有名字的函数里时,名字是被调用的 fetch / GET / 包装函数本身。
|
* 不在有名字的函数里时,名字是被调用的 fetch / GET / 包装函数本身。
|
||||||
*/
|
*/
|
||||||
export interface RequestEntry extends IndexEntry {
|
export interface RequestEntry extends IndexEntry {
|
||||||
/** 写的路径:模板里指向字符串常量的 `${名字}` 换成常量的值,别的 `${...}` 照写,`?`、`#` 后面的去掉 */
|
/** 写的路径:模板里指向字符串常量的 `${名字}` 换成常量的值,别的 `${...}` 照写;`?`、`#` 后面的,和最后一段末尾紧贴字面量的 `${...}`(查询串)去掉 */
|
||||||
path: string
|
path: string
|
||||||
/** 发请求那个调用的范围,行和列从 0 起 */
|
/** 发请求那个调用的范围,行和列从 0 起 */
|
||||||
at: CallRange
|
at: CallRange
|
||||||
@@ -494,7 +494,8 @@ async function senders(find: IndexFind, resolve: ModuleResolver): Promise<{ call
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 网址拼成路径(uri 是网址所在的文件):`${名字}` 取得到常量的值就拼进去,取不到的照写;`?`、`#` 后面的去掉,照写的 `${...}` 里的不算。
|
* 网址拼成路径(uri 是网址所在的文件):`${名字}` 取得到常量的值就拼进去,取不到的照写;`?`、`#` 后面的去掉,照写的 `${...}` 里的不算;
|
||||||
|
* 最后一段是字面量文字后面紧贴一个照写的 `${...}`(`messages${qs}`)时,它是拼上去的查询串,也去掉。
|
||||||
* 导入的常量和包装函数一样按 import 来源对到导出它的那处(见 exportOf),它的值里又导入的接着取;对不上、绕回正在取的(循环)取不到。
|
* 导入的常量和包装函数一样按 import 来源对到导出它的那处(见 exportOf),它的值里又导入的接着取;对不上、绕回正在取的(循环)取不到。
|
||||||
* 一份查询里同一个常量只取一次;取值时记着正在取的,所以要一处处拼,不能同时拼。
|
* 一份查询里同一个常量只取一次;取值时记着正在取的,所以要一处处拼,不能同时拼。
|
||||||
*/
|
*/
|
||||||
@@ -534,18 +535,27 @@ function pathsOf(find: IndexFind, resolve: ModuleResolver): (uri: string, url: r
|
|||||||
|
|
||||||
return async (uri, url) => {
|
return async (uri, url) => {
|
||||||
let path = ''
|
let path = ''
|
||||||
|
// 上一个照写的 `${...}` 在 path 里的结尾;末尾照写的 `${...}` 当查询串去掉时从哪截
|
||||||
|
let written = 0
|
||||||
|
let query: number | undefined
|
||||||
for (const piece of url) {
|
for (const piece of url) {
|
||||||
const value = typeof piece === 'string' ? piece : await valueOf(uri, piece.constant)
|
const value = typeof piece === 'string' ? piece : await valueOf(uri, piece.constant)
|
||||||
if (value === undefined) {
|
if (value === undefined) {
|
||||||
|
const segment = path.lastIndexOf('/') + 1
|
||||||
|
query = segment >= written && segment < path.length ? path.length : undefined
|
||||||
path += typeof piece === 'string' ? piece : piece.written
|
path += typeof piece === 'string' ? piece : piece.written
|
||||||
|
written = path.length
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
const end = value.search(/[?#]/)
|
const end = value.search(/[?#]/)
|
||||||
|
const literal = end >= 0 ? value.slice(0, end) : value
|
||||||
|
path += literal
|
||||||
|
if (literal)
|
||||||
|
query = undefined
|
||||||
if (end >= 0)
|
if (end >= 0)
|
||||||
return path + value.slice(0, end)
|
break
|
||||||
path += value
|
|
||||||
}
|
}
|
||||||
return path
|
return query === undefined ? path : path.slice(0, query)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user