Skip to content

Commit 66a5cb3

Browse files
committed
feat: add AI Generate Mock command and integrate comment-json for improved JSON handling
1 parent ce941ec commit 66a5cb3

File tree

7 files changed

+89
-12
lines changed

7 files changed

+89
-12
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ A VS Code extension for managing and generating code from YAPI APIs.
4040
| `crabu.genBusinessCode` | Generate Business Code |
4141
| `crabu.compareWithLatestVersion` | Compare with Latest Version |
4242
| `crabu.copyApiPath` | Copy API Path |
43+
| `crabu.aiGenerateMock` | AI Generate Mock |
4344

4445
<!-- commands -->
4546

package.json

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,12 @@
135135
"title": "Copy API Path",
136136
"icon": "$(copy)",
137137
"enablement": "viewItem == apiItem || viewItem == mockItem"
138+
},
139+
{
140+
"command": "crabu.aiGenerateMock",
141+
"title": "AI Generate Mock",
142+
"icon": "$(copilot)",
143+
"enablement": "viewItem == mockItem"
138144
}
139145
],
140146
"configuration": {
@@ -268,9 +274,14 @@
268274
},
269275
{
270276
"command": "crabu.removeFromMock",
271-
"when": "view == mockTreeView && (viewItem == mockNode || viewItem == mockItem)",
277+
"when": "view == mockTreeView && viewItem == mockItem",
272278
"group": "context"
273279
},
280+
{
281+
"command": "crabu.removeFromMock",
282+
"when": "view == mockTreeView && viewItem == mockNode",
283+
"group": "inline"
284+
},
274285
{
275286
"command": "crabu.updateMockToLatestVersion",
276287
"when": "view == mockTreeView && viewItem == mockItem",
@@ -289,6 +300,11 @@
289300
{
290301
"command": "crabu.copyApiPath",
291302
"when": "viewItem == apiItem || viewItem == mockItem",
303+
"group": "context"
304+
},
305+
{
306+
"command": "crabu.aiGenerateMock",
307+
"when": "viewItem == mockItem",
292308
"group": "inline"
293309
}
294310
]
@@ -314,6 +330,7 @@
314330
"@types/vscode": "^1.99.3",
315331
"@vscode/vsce": "catalog:dev",
316332
"bumpp": "catalog:dev",
333+
"comment-json": "catalog:build",
317334
"eslint": "catalog:dev",
318335
"esno": "catalog:dev",
319336
"pnpm": "catalog:dev",

pnpm-lock.yaml

Lines changed: 40 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pnpm-workspace.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ catalogs:
66
'@tomjs/vscode-extension-webview': ^2.0.0
77
'@vitejs/plugin-vue': ^6.0.1
88
'@vitejs/plugin-vue-jsx': ^5.0.1
9+
comment-json: ^4.2.5
910
tsdown: ^0.13.0
1011
unocss: ^66.3.3
1112
unplugin-auto-import: ^19.3.0

src/annotations.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export async function useAnnotations() {
4848
const { document } = editor.value
4949

5050
const matchedApiData = allApiData.value.map((item) => {
51-
const regex = new RegExp(`'${item.path}'`, 'g')
51+
const regex = new RegExp(`['"\`]${item.path}['"\`]`, 'g')
5252
const match = regex.exec(document.getText())
5353

5454
if (!match) {

src/types.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import type { CommentJSONValue } from 'comment-json'
2+
13
export interface FetchResponse<T> {
24
data: T
35
errcode: number
@@ -100,8 +102,8 @@ export interface YApiDetail {
100102
export interface ApiDetail {
101103
path: string
102104
tags: string[]
103-
req_body: string
104-
res_body: string
105+
req_body: string | CommentJSONValue
106+
res_body: string | CommentJSONValue
105107
}
106108

107109
export interface ApiDetailRaw {

src/views/mock.ts

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { TreeViewNode } from 'reactive-vscode'
22
import type { ApiDetail, MockApiData } from '../types'
3+
import { parse, stringify } from 'comment-json'
34
import { createSingletonComposable, executeCommand, ref, useCommand, useTreeView } from 'reactive-vscode'
45
import { TreeItemCollapsibleState, Uri, window, workspace } from 'vscode'
56
import { config } from '../config'
@@ -151,6 +152,21 @@ export const useMockTreeView = createSingletonComposable(async () => {
151152
})
152153
})
153154

155+
useCommand(commands.aiGenerateMock, async (event) => {
156+
if (!event.treeItem || !event.treeItem.mockItem) {
157+
logger.error('No mock item found in the event.')
158+
return
159+
}
160+
161+
const mockItem = event.treeItem.mockItem as MockApiData
162+
const [projectId, catId, interfaceId] = mockItem.key.split('/')
163+
await ofetch(`${crabuApiBaseUrl}/mock/template/ai/${projectId}/${catId}/${interfaceId}`, {
164+
method: 'POST',
165+
})
166+
167+
window.showInformationMessage('正在使用AI生成Mock数据,请稍后...')
168+
})
169+
154170
useCommand(commands.compareWithLatestVersion, async (event) => {
155171
if (!event.treeItem || !event.treeItem.mockItem) {
156172
logger.error('No mock item found in the event.')
@@ -162,25 +178,25 @@ export const useMockTreeView = createSingletonComposable(async () => {
162178
const oldDetail = await ofetch<ApiDetail>(`${crabuApiBaseUrl}/interface/local/json/${mockItem.key}`)
163179
const newDetail = await ofetch<ApiDetail>(`${crabuApiBaseUrl}/interface/json/${projectId}/${interfaceId}`)
164180

165-
oldDetail.req_body = JSON.parse(oldDetail.req_body)
166-
oldDetail.res_body = JSON.parse(oldDetail.res_body)
167-
newDetail.req_body = JSON.parse(newDetail.req_body)
168-
newDetail.res_body = JSON.parse(newDetail.res_body)
181+
oldDetail.req_body = parse(oldDetail.req_body as string)
182+
oldDetail.res_body = parse(oldDetail.res_body as string)
183+
newDetail.req_body = parse(newDetail.req_body as string)
184+
newDetail.res_body = parse(newDetail.res_body as string)
169185

170186
workspace.registerTextDocumentContentProvider(crabuDiffOldScheme, {
171187
provideTextDocumentContent: () => {
172-
return JSON.stringify(oldDetail, null, 2)
188+
return stringify(oldDetail, null, 2)
173189
},
174190
})
175191

176192
workspace.registerTextDocumentContentProvider(crabuDiffNewScheme, {
177193
provideTextDocumentContent: () => {
178-
return JSON.stringify(newDetail, null, 2)
194+
return stringify(newDetail, null, 2)
179195
},
180196
})
181197

182-
const oldUri = Uri.parse(`${crabuDiffOldScheme}:${mockItem.label}.json`)
183-
const newUri = Uri.parse(`${crabuDiffNewScheme}:${mockItem.label}.json`)
198+
const oldUri = Uri.parse(`${crabuDiffOldScheme}:${mockItem.label}.jsonc`)
199+
const newUri = Uri.parse(`${crabuDiffNewScheme}:${mockItem.label}.jsonc`)
184200

185201
executeCommand('vscode.diff', oldUri, newUri, `检查变更:${mockItem.label}`)
186202
})

0 commit comments

Comments
 (0)