vite-plugin-ai-mock-generator 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -186,9 +186,7 @@ declare class MockStorage {
186
186
  */
187
187
 
188
188
  declare class MockDataGenerator {
189
- private apiKey;
190
- private apiUrl;
191
- private model;
189
+ private llm;
192
190
  constructor(options: {
193
191
  apiKey: string;
194
192
  apiUrl: string;
@@ -269,4 +267,4 @@ declare class MockServer {
269
267
 
270
268
  declare function vitePluginAIMockGenerator(options?: MockGeneratorOptions): Plugin;
271
269
 
272
- export { type EndpointConfig, MockDataGenerator, type MockGeneratorOptions, MockServer, MockStorage, vitePluginAIMockGenerator };
270
+ export { type EndpointConfig, MockDataGenerator, type MockGeneratorOptions, MockServer, MockStorage, vitePluginAIMockGenerator as default, vitePluginAIMockGenerator };
package/dist/index.d.ts CHANGED
@@ -186,9 +186,7 @@ declare class MockStorage {
186
186
  */
187
187
 
188
188
  declare class MockDataGenerator {
189
- private apiKey;
190
- private apiUrl;
191
- private model;
189
+ private llm;
192
190
  constructor(options: {
193
191
  apiKey: string;
194
192
  apiUrl: string;
@@ -269,4 +267,4 @@ declare class MockServer {
269
267
 
270
268
  declare function vitePluginAIMockGenerator(options?: MockGeneratorOptions): Plugin;
271
269
 
272
- export { type EndpointConfig, MockDataGenerator, type MockGeneratorOptions, MockServer, MockStorage, vitePluginAIMockGenerator };
270
+ export { type EndpointConfig, MockDataGenerator, type MockGeneratorOptions, MockServer, MockStorage, vitePluginAIMockGenerator as default, vitePluginAIMockGenerator };
package/dist/index.js CHANGED
@@ -1,21 +1,53 @@
1
- 'use strict';
2
-
3
- var fs = require('fs');
4
- var path = require('path');
5
-
6
- function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
7
29
 
8
- var fs__default = /*#__PURE__*/_interopDefault(fs);
9
- var path__default = /*#__PURE__*/_interopDefault(path);
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ MockDataGenerator: () => MockDataGenerator,
34
+ MockServer: () => MockServer,
35
+ MockStorage: () => MockStorage,
36
+ default: () => index_default,
37
+ vitePluginAIMockGenerator: () => vitePluginAIMockGenerator
38
+ });
39
+ module.exports = __toCommonJS(index_exports);
10
40
 
11
41
  // src/storage.ts
42
+ var import_fs = __toESM(require("fs"));
43
+ var import_path = __toESM(require("path"));
12
44
  var MockStorage = class {
13
45
  constructor(options = {}) {
14
46
  this.storageDir = options.dir || "mock-data";
15
47
  this.persist = options.persist !== false;
16
48
  this.cache = /* @__PURE__ */ new Map();
17
- if (this.persist && !fs__default.default.existsSync(this.storageDir)) {
18
- fs__default.default.mkdirSync(this.storageDir, { recursive: true });
49
+ if (this.persist && !import_fs.default.existsSync(this.storageDir)) {
50
+ import_fs.default.mkdirSync(this.storageDir, { recursive: true });
19
51
  }
20
52
  this.load();
21
53
  }
@@ -70,9 +102,9 @@ var MockStorage = class {
70
102
  this.cache.delete(key);
71
103
  if (this.persist) {
72
104
  const fileName = this.getFileName(endpoint, method);
73
- const filePath = path__default.default.join(this.storageDir, fileName);
74
- if (fs__default.default.existsSync(filePath)) {
75
- fs__default.default.unlinkSync(filePath);
105
+ const filePath = import_path.default.join(this.storageDir, fileName);
106
+ if (import_fs.default.existsSync(filePath)) {
107
+ import_fs.default.unlinkSync(filePath);
76
108
  }
77
109
  }
78
110
  }
@@ -81,10 +113,10 @@ var MockStorage = class {
81
113
  */
82
114
  clear() {
83
115
  this.cache.clear();
84
- if (this.persist && fs__default.default.existsSync(this.storageDir)) {
85
- const files = fs__default.default.readdirSync(this.storageDir);
116
+ if (this.persist && import_fs.default.existsSync(this.storageDir)) {
117
+ const files = import_fs.default.readdirSync(this.storageDir);
86
118
  for (const file of files) {
87
- fs__default.default.unlinkSync(path__default.default.join(this.storageDir, file));
119
+ import_fs.default.unlinkSync(import_path.default.join(this.storageDir, file));
88
120
  }
89
121
  }
90
122
  }
@@ -99,22 +131,22 @@ var MockStorage = class {
99
131
  */
100
132
  save(endpoint, method, store) {
101
133
  const fileName = this.getFileName(endpoint, method);
102
- const filePath = path__default.default.join(this.storageDir, fileName);
103
- fs__default.default.writeFileSync(filePath, JSON.stringify(store, null, 2), "utf-8");
134
+ const filePath = import_path.default.join(this.storageDir, fileName);
135
+ import_fs.default.writeFileSync(filePath, JSON.stringify(store, null, 2), "utf-8");
104
136
  }
105
137
  /**
106
138
  * 从文件加载
107
139
  */
108
140
  load() {
109
- if (!this.persist || !fs__default.default.existsSync(this.storageDir)) {
141
+ if (!this.persist || !import_fs.default.existsSync(this.storageDir)) {
110
142
  return;
111
143
  }
112
- const files = fs__default.default.readdirSync(this.storageDir);
144
+ const files = import_fs.default.readdirSync(this.storageDir);
113
145
  for (const file of files) {
114
146
  if (!file.endsWith(".json")) continue;
115
147
  try {
116
- const filePath = path__default.default.join(this.storageDir, file);
117
- const content = fs__default.default.readFileSync(filePath, "utf-8");
148
+ const filePath = import_path.default.join(this.storageDir, file);
149
+ const content = import_fs.default.readFileSync(filePath, "utf-8");
118
150
  const store = JSON.parse(content);
119
151
  const key = this.getKey(store.endpoint, store.method);
120
152
  this.cache.set(key, store);
@@ -128,13 +160,13 @@ var MockStorage = class {
128
160
  */
129
161
  export(outputPath) {
130
162
  const allData = this.getAll();
131
- fs__default.default.writeFileSync(outputPath, JSON.stringify(allData, null, 2), "utf-8");
163
+ import_fs.default.writeFileSync(outputPath, JSON.stringify(allData, null, 2), "utf-8");
132
164
  }
133
165
  /**
134
166
  * 导入数据
135
167
  */
136
168
  import(inputPath) {
137
- const content = fs__default.default.readFileSync(inputPath, "utf-8");
169
+ const content = import_fs.default.readFileSync(inputPath, "utf-8");
138
170
  const allData = JSON.parse(content);
139
171
  for (const store of allData) {
140
172
  const key = this.getKey(store.endpoint, store.method);
@@ -147,11 +179,19 @@ var MockStorage = class {
147
179
  };
148
180
 
149
181
  // src/generator.ts
182
+ var import_openai = require("@langchain/openai");
183
+ var import_messages = require("@langchain/core/messages");
150
184
  var MockDataGenerator = class {
151
185
  constructor(options) {
152
- this.apiKey = options.apiKey;
153
- this.apiUrl = options.apiUrl;
154
- this.model = options.model;
186
+ this.llm = new import_openai.ChatOpenAI({
187
+ openAIApiKey: options.apiKey,
188
+ configuration: {
189
+ baseURL: options.apiUrl
190
+ },
191
+ modelName: options.model,
192
+ temperature: 0.7,
193
+ maxTokens: 4e3
194
+ });
155
195
  }
156
196
  /**
157
197
  * 生成 Mock 数据
@@ -168,34 +208,34 @@ var MockDataGenerator = class {
168
208
  buildPrompt(type, count, locale, quality) {
169
209
  const properties = type.properties.map((p) => this.formatProperty(p)).join("\n");
170
210
  return `
171
- \u4F60\u662F\u4E00\u4E2A\u4E13\u4E1A\u7684 Mock \u6570\u636E\u751F\u6210\u5668\u3002\u8BF7\u6839\u636E\u4EE5\u4E0B\u7C7B\u578B\u5B9A\u4E49\u751F\u6210\u771F\u5B9E\u3001\u5408\u7406\u7684\u6D4B\u8BD5\u6570\u636E\u3002
211
+ 你是一个专业的 Mock 数据生成器。请根据以下类型定义生成真实、合理的测试数据。
172
212
 
173
- \u7C7B\u578B\u540D\u79F0: ${type.name}
174
- \u6570\u636E\u8BED\u8A00: ${locale === "zh-CN" ? "\u4E2D\u6587" : "\u82F1\u6587"}
175
- \u6570\u636E\u6570\u91CF: ${count}
176
- \u8D28\u91CF\u8981\u6C42: ${quality === "high" ? "\u9AD8\u8D28\u91CF\uFF08\u771F\u5B9E\u4E1A\u52A1\u6570\u636E\uFF09" : quality === "fast" ? "\u5FEB\u901F\u751F\u6210" : "\u5E73\u8861\u8D28\u91CF\u548C\u901F\u5EA6"}
213
+ 类型名称: ${type.name}
214
+ 数据语言: ${locale === "zh-CN" ? "中文" : "英文"}
215
+ 数据数量: ${count}
216
+ 质量要求: ${quality === "high" ? "高质量(真实业务数据)" : quality === "fast" ? "快速生成" : "平衡质量和速度"}
177
217
 
178
- \u7C7B\u578B\u5B9A\u4E49:
218
+ 类型定义:
179
219
  ${properties}
180
220
 
181
- \u8981\u6C42:
182
- 1. \u751F\u6210 ${count} \u6761\u6570\u636E
183
- 2. \u6570\u636E\u8981\u7B26\u5408\u4E1A\u52A1\u903B\u8F91\u548C\u771F\u5B9E\u573A\u666F
184
- 3. \u5B57\u6BB5\u503C\u8981\u5408\u7406\uFF08\u5982\u4EF7\u683C\u4E0D\u80FD\u4E3A\u8D1F\u6570\uFF0C\u5E74\u9F84\u5728\u5408\u7406\u8303\u56F4\uFF09
185
- 4. \u65E5\u671F\u683C\u5F0F\u4F7F\u7528 ISO 8601
186
- 5. \u8FD4\u56DE JSON \u6570\u7EC4\u683C\u5F0F\uFF0C\u4E0D\u8981\u5305\u542B\u4EFB\u4F55\u5176\u4ED6\u6587\u5B57
187
- 6. \u7406\u89E3\u5B57\u6BB5\u8BED\u4E49\uFF0C\u751F\u6210\u771F\u5B9E\u6570\u636E\uFF08\u5982 userName \u751F\u6210\u771F\u5B9E\u59D3\u540D\uFF09
221
+ 要求:
222
+ 1. 生成 ${count} 条数据
223
+ 2. 数据要符合业务逻辑和真实场景
224
+ 3. 字段值要合理(如价格不能为负数,年龄在合理范围)
225
+ 4. 日期格式使用 ISO 8601
226
+ 5. 返回 JSON 数组格式,不要包含任何其他文字
227
+ 6. 理解字段语义,生成真实数据(如 userName 生成真实姓名)
188
228
 
189
- \u793A\u4F8B\u683C\u5F0F:
229
+ 示例格式:
190
230
  [
191
231
  {
192
232
  "id": 1,
193
- "name": "\u5F20\u4E09",
233
+ "name": "张三",
194
234
  ...
195
235
  }
196
236
  ]
197
237
 
198
- \u8BF7\u751F\u6210\u6570\u636E:
238
+ 请生成数据:
199
239
  `.trim();
200
240
  }
201
241
  /**
@@ -231,30 +271,16 @@ ${properties}
231
271
  */
232
272
  async callAI(prompt) {
233
273
  try {
234
- const response = await fetch(`${this.apiUrl}/chat/completions`, {
235
- method: "POST",
236
- headers: {
237
- "Content-Type": "application/json",
238
- Authorization: `Bearer ${this.apiKey}`
239
- },
240
- body: JSON.stringify({
241
- model: this.model,
242
- messages: [
243
- {
244
- role: "user",
245
- content: prompt
246
- }
247
- ],
248
- temperature: 0.7
249
- })
250
- });
251
- if (!response.ok) {
252
- throw new Error(`AI API error: ${response.statusText}`);
253
- }
254
- const data = await response.json();
255
- return data.choices[0].message.content;
274
+ const messages = [
275
+ new import_messages.SystemMessage(
276
+ "你是一个专业的 Mock 数据生成器,擅长生成真实、合理的测试数据。"
277
+ ),
278
+ new import_messages.HumanMessage(prompt)
279
+ ];
280
+ const response = await this.llm.invoke(messages);
281
+ return response.content;
256
282
  } catch (error) {
257
- console.error("Failed to call AI API:", error);
283
+ console.error(" AI API 调用失败:", error.message);
258
284
  throw error;
259
285
  }
260
286
  }
@@ -274,8 +300,8 @@ ${properties}
274
300
  const data = JSON.parse(jsonMatch[0]);
275
301
  return isArray ? data : data[0];
276
302
  } catch (error) {
277
- console.error("Failed to parse AI response:", error);
278
- console.error("Response:", response);
303
+ console.error(" 解析 AI 响应失败:", error.message);
304
+ console.error("响应内容:", response);
279
305
  throw error;
280
306
  }
281
307
  }
@@ -433,7 +459,7 @@ var MockServer = class {
433
459
  res.statusCode = 200;
434
460
  res.end(JSON.stringify(data));
435
461
  if (this.options.output?.logs) {
436
- console.log(`[Mock] ${method} ${url} \u2192 ${data ? "OK" : "Empty"}`);
462
+ console.log(`[Mock] ${method} ${url} ${data ? "OK" : "Empty"}`);
437
463
  }
438
464
  } catch (error) {
439
465
  console.error(`[Mock] Error handling ${method} ${url}:`, error);
@@ -446,8 +472,8 @@ var MockServer = class {
446
472
  );
447
473
  }
448
474
  });
449
- console.log("\n\u{1F3AD} Mock \u670D\u52A1\u5668\u5DF2\u542F\u52A8");
450
- console.log(`\u{1F4CD} \u5DF2\u6CE8\u518C ${this.endpoints.length} \u4E2A\u7AEF\u70B9
475
+ console.log("\n🎭 Mock 服务器已启动");
476
+ console.log(`📍 已注册 ${this.endpoints.length} 个端点
451
477
  `);
452
478
  }
453
479
  /**
@@ -575,34 +601,32 @@ function vitePluginAIMockGenerator(options = {}) {
575
601
  enforce: "pre",
576
602
  configResolved(config) {
577
603
  if (output.console) {
578
- console.log("\n\u{1F916} AI Mock Generator \u5DF2\u542F\u52A8");
579
- console.log(`\u{1F4C2} \u5B58\u50A8\u76EE\u5F55: ${storageOptions.dir}`);
580
- console.log(`\u{1F30D} \u6570\u636E\u8BED\u8A00: ${generation.locale}`);
581
- console.log(`\u{1F4CA} \u9ED8\u8BA4\u6570\u91CF: ${generation.count}`);
582
- console.log(`\u{1F511} API Key: ${apiKey ? "\u5DF2\u914D\u7F6E" : "\u672A\u914D\u7F6E"}`);
583
- console.log(
584
- `\u{1F4CD} \u7AEF\u70B9\u6570\u91CF: ${options.endpoints?.length || 0}`
585
- );
604
+ console.log("\n🤖 AI Mock Generator 已启动");
605
+ console.log(`📂 存储目录: ${storageOptions.dir}`);
606
+ console.log(`🌍 数据语言: ${generation.locale}`);
607
+ console.log(`📊 默认数量: ${generation.count}`);
608
+ console.log(`🔑 API Key: ${apiKey ? "已配置" : "未配置"}`);
609
+ console.log(`📍 端点数量: ${options.endpoints?.length || 0}`);
586
610
  }
587
611
  },
588
612
  async buildStart() {
589
613
  if (autoGenerate && options.endpoints) {
590
614
  if (output.console) {
591
- console.log("\n\u{1F504} \u5F00\u59CB\u81EA\u52A8\u751F\u6210 Mock \u6570\u636E...\n");
615
+ console.log("\n🔄 开始自动生成 Mock 数据...\n");
592
616
  }
593
617
  for (const endpoint of options.endpoints) {
594
618
  const existingData = storage.get(endpoint.path, endpoint.method);
595
619
  if (existingData) {
596
620
  if (output.console) {
597
621
  console.log(
598
- `\u23ED\uFE0F \u8DF3\u8FC7 ${endpoint.method} ${endpoint.path} (\u5DF2\u6709\u6570\u636E)`
622
+ `⏭️ 跳过 ${endpoint.method} ${endpoint.path} (已有数据)`
599
623
  );
600
624
  }
601
625
  continue;
602
626
  }
603
627
  try {
604
628
  if (output.console) {
605
- console.log(`\u{1F3B2} \u751F\u6210 ${endpoint.method} ${endpoint.path}...`);
629
+ console.log(`🎲 生成 ${endpoint.method} ${endpoint.path}...`);
606
630
  }
607
631
  const typeDefinition = parseTypeDefinition(endpoint.response);
608
632
  const count = endpoint.count || generation.count || 20;
@@ -622,18 +646,18 @@ function vitePluginAIMockGenerator(options = {}) {
622
646
  });
623
647
  if (output.console) {
624
648
  console.log(
625
- `\u2705 \u5DF2\u751F\u6210 ${count} \u6761\u6570\u636E: ${endpoint.method} ${endpoint.path}`
649
+ `✅ 已生成 ${count} 条数据: ${endpoint.method} ${endpoint.path}`
626
650
  );
627
651
  }
628
652
  } catch (error) {
629
653
  console.error(
630
- `\u274C \u751F\u6210\u5931\u8D25 ${endpoint.method} ${endpoint.path}:`,
654
+ `❌ 生成失败 ${endpoint.method} ${endpoint.path}:`,
631
655
  error.message
632
656
  );
633
657
  }
634
658
  }
635
659
  if (output.console) {
636
- console.log("\n\u2728 Mock \u6570\u636E\u751F\u6210\u5B8C\u6210\n");
660
+ console.log("\n Mock 数据生成完成\n");
637
661
  }
638
662
  }
639
663
  },
@@ -654,10 +678,12 @@ function parseTypeDefinition(typeStr) {
654
678
  isArray
655
679
  };
656
680
  }
657
-
658
- exports.MockDataGenerator = MockDataGenerator;
659
- exports.MockServer = MockServer;
660
- exports.MockStorage = MockStorage;
661
- exports.vitePluginAIMockGenerator = vitePluginAIMockGenerator;
662
- //# sourceMappingURL=index.js.map
681
+ var index_default = vitePluginAIMockGenerator;
682
+ // Annotate the CommonJS export names for ESM import in node:
683
+ 0 && (module.exports = {
684
+ MockDataGenerator,
685
+ MockServer,
686
+ MockStorage,
687
+ vitePluginAIMockGenerator
688
+ });
663
689
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/storage.ts","../src/generator.ts","../src/utils.ts","../src/server.ts","../src/index.ts"],"names":["fs","path"],"mappings":"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","file":"index.js","sourcesContent":["/**\r\n * AI Mock Generator - 数据存储\r\n */\r\n\r\nimport fs from 'fs';\r\nimport path from 'path';\r\nimport type { MockDataStore, HttpMethod } from './types';\r\n\r\nexport class MockStorage {\r\n private storageDir: string;\r\n private cache: Map<string, MockDataStore>;\r\n private persist: boolean;\r\n\r\n constructor(options: { dir?: string; persist?: boolean } = {}) {\r\n this.storageDir = options.dir || 'mock-data';\r\n this.persist = options.persist !== false;\r\n this.cache = new Map();\r\n\r\n // 确保存储目录存在\r\n if (this.persist && !fs.existsSync(this.storageDir)) {\r\n fs.mkdirSync(this.storageDir, { recursive: true });\r\n }\r\n\r\n // 加载已有数据\r\n this.load();\r\n }\r\n\r\n /**\r\n * 生成存储 key\r\n */\r\n private getKey(endpoint: string, method: HttpMethod): string {\r\n return `${method}:${endpoint}`;\r\n }\r\n\r\n /**\r\n * 生成文件名\r\n */\r\n private getFileName(endpoint: string, method: HttpMethod): string {\r\n const sanitized = endpoint\r\n .replace(/^\\//, '')\r\n .replace(/\\//g, '_')\r\n .replace(/:/g, '_');\r\n return `${method}_${sanitized}.json`;\r\n }\r\n\r\n /**\r\n * 获取数据\r\n */\r\n get(endpoint: string, method: HttpMethod = 'GET'): any {\r\n const key = this.getKey(endpoint, method);\r\n const store = this.cache.get(key);\r\n return store?.data;\r\n }\r\n\r\n /**\r\n * 设置数据\r\n */\r\n set(\r\n endpoint: string,\r\n method: HttpMethod,\r\n data: any,\r\n metadata?: Partial<MockDataStore['metadata']>\r\n ): void {\r\n const key = this.getKey(endpoint, method);\r\n\r\n const store: MockDataStore = {\r\n endpoint,\r\n method,\r\n data,\r\n metadata: {\r\n count: Array.isArray(data) ? data.length : 1,\r\n generatedAt: new Date().toISOString(),\r\n version: '1.0.0',\r\n type: typeof data,\r\n ...metadata,\r\n },\r\n };\r\n\r\n this.cache.set(key, store);\r\n\r\n // 持久化\r\n if (this.persist) {\r\n this.save(endpoint, method, store);\r\n }\r\n }\r\n\r\n /**\r\n * 删除数据\r\n */\r\n delete(endpoint: string, method: HttpMethod = 'GET'): void {\r\n const key = this.getKey(endpoint, method);\r\n this.cache.delete(key);\r\n\r\n // 删除文件\r\n if (this.persist) {\r\n const fileName = this.getFileName(endpoint, method);\r\n const filePath = path.join(this.storageDir, fileName);\r\n if (fs.existsSync(filePath)) {\r\n fs.unlinkSync(filePath);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 清空所有数据\r\n */\r\n clear(): void {\r\n this.cache.clear();\r\n\r\n // 清空目录\r\n if (this.persist && fs.existsSync(this.storageDir)) {\r\n const files = fs.readdirSync(this.storageDir);\r\n for (const file of files) {\r\n fs.unlinkSync(path.join(this.storageDir, file));\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 获取所有端点\r\n */\r\n getAll(): MockDataStore[] {\r\n return Array.from(this.cache.values());\r\n }\r\n\r\n /**\r\n * 保存到文件\r\n */\r\n private save(\r\n endpoint: string,\r\n method: HttpMethod,\r\n store: MockDataStore\r\n ): void {\r\n const fileName = this.getFileName(endpoint, method);\r\n const filePath = path.join(this.storageDir, fileName);\r\n\r\n fs.writeFileSync(filePath, JSON.stringify(store, null, 2), 'utf-8');\r\n }\r\n\r\n /**\r\n * 从文件加载\r\n */\r\n private load(): void {\r\n if (!this.persist || !fs.existsSync(this.storageDir)) {\r\n return;\r\n }\r\n\r\n const files = fs.readdirSync(this.storageDir);\r\n\r\n for (const file of files) {\r\n if (!file.endsWith('.json')) continue;\r\n\r\n try {\r\n const filePath = path.join(this.storageDir, file);\r\n const content = fs.readFileSync(filePath, 'utf-8');\r\n const store: MockDataStore = JSON.parse(content);\r\n\r\n const key = this.getKey(store.endpoint, store.method);\r\n this.cache.set(key, store);\r\n } catch (error) {\r\n console.warn(`Failed to load mock data from ${file}:`, error);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 导出所有数据\r\n */\r\n export(outputPath: string): void {\r\n const allData = this.getAll();\r\n fs.writeFileSync(outputPath, JSON.stringify(allData, null, 2), 'utf-8');\r\n }\r\n\r\n /**\r\n * 导入数据\r\n */\r\n import(inputPath: string): void {\r\n const content = fs.readFileSync(inputPath, 'utf-8');\r\n const allData: MockDataStore[] = JSON.parse(content);\r\n\r\n for (const store of allData) {\r\n const key = this.getKey(store.endpoint, store.method);\r\n this.cache.set(key, store);\r\n\r\n if (this.persist) {\r\n this.save(store.endpoint, store.method, store);\r\n }\r\n }\r\n }\r\n}\r\n","/**\r\n * AI Mock Generator - 数据生成器\r\n */\r\n\r\nimport type {\r\n TypeDefinition,\r\n GenerationContext,\r\n PropertyDefinition,\r\n} from './types';\r\n\r\nexport class MockDataGenerator {\r\n private apiKey: string;\r\n private apiUrl: string;\r\n private model: string;\r\n\r\n constructor(options: { apiKey: string; apiUrl: string; model: string }) {\r\n this.apiKey = options.apiKey;\r\n this.apiUrl = options.apiUrl;\r\n this.model = options.model;\r\n }\r\n\r\n /**\r\n * 生成 Mock 数据\r\n */\r\n async generate(context: GenerationContext): Promise<any> {\r\n const { type, count, locale, quality } = context;\r\n\r\n // 构建 AI Prompt\r\n const prompt = this.buildPrompt(type, count, locale, quality);\r\n\r\n // 调用 AI API\r\n const response = await this.callAI(prompt);\r\n\r\n // 解析响应\r\n return this.parseResponse(response, type.isArray);\r\n }\r\n\r\n /**\r\n * 构建 AI Prompt\r\n */\r\n private buildPrompt(\r\n type: TypeDefinition,\r\n count: number,\r\n locale: string,\r\n quality: string\r\n ): string {\r\n const properties = type.properties\r\n .map((p) => this.formatProperty(p))\r\n .join('\\n');\r\n\r\n return `\r\n你是一个专业的 Mock 数据生成器。请根据以下类型定义生成真实、合理的测试数据。\r\n\r\n类型名称: ${type.name}\r\n数据语言: ${locale === 'zh-CN' ? '中文' : '英文'}\r\n数据数量: ${count}\r\n质量要求: ${quality === 'high' ? '高质量(真实业务数据)' : quality === 'fast' ? '快速生成' : '平衡质量和速度'}\r\n\r\n类型定义:\r\n${properties}\r\n\r\n要求:\r\n1. 生成 ${count} 条数据\r\n2. 数据要符合业务逻辑和真实场景\r\n3. 字段值要合理(如价格不能为负数,年龄在合理范围)\r\n4. 日期格式使用 ISO 8601\r\n5. 返回 JSON 数组格式,不要包含任何其他文字\r\n6. 理解字段语义,生成真实数据(如 userName 生成真实姓名)\r\n\r\n示例格式:\r\n[\r\n {\r\n \"id\": 1,\r\n \"name\": \"张三\",\r\n ...\r\n }\r\n]\r\n\r\n请生成数据:\r\n`.trim();\r\n }\r\n\r\n /**\r\n * 格式化属性\r\n */\r\n private formatProperty(prop: PropertyDefinition): string {\r\n let line = `- ${prop.name}: ${prop.type}`;\r\n\r\n if (prop.comment) {\r\n line += ` // ${prop.comment}`;\r\n }\r\n\r\n if (prop.constraints) {\r\n const constraints = [];\r\n if (prop.constraints.min !== undefined) {\r\n constraints.push(`min: ${prop.constraints.min}`);\r\n }\r\n if (prop.constraints.max !== undefined) {\r\n constraints.push(`max: ${prop.constraints.max}`);\r\n }\r\n if (prop.constraints.unique) {\r\n constraints.push('unique');\r\n }\r\n if (prop.constraints.enum) {\r\n constraints.push(`enum: [${prop.constraints.enum.join(', ')}]`);\r\n }\r\n if (constraints.length > 0) {\r\n line += ` (${constraints.join(', ')})`;\r\n }\r\n }\r\n\r\n return line;\r\n }\r\n\r\n /**\r\n * 调用 AI API\r\n */\r\n private async callAI(prompt: string): Promise<string> {\r\n try {\r\n const response = await fetch(`${this.apiUrl}/chat/completions`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n Authorization: `Bearer ${this.apiKey}`,\r\n },\r\n body: JSON.stringify({\r\n model: this.model,\r\n messages: [\r\n {\r\n role: 'user',\r\n content: prompt,\r\n },\r\n ],\r\n temperature: 0.7,\r\n }),\r\n });\r\n\r\n if (!response.ok) {\r\n throw new Error(`AI API error: ${response.statusText}`);\r\n }\r\n\r\n const data = await response.json();\r\n return data.choices[0].message.content;\r\n } catch (error: any) {\r\n console.error('Failed to call AI API:', error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * 解析 AI 响应\r\n */\r\n private parseResponse(response: string, isArray: boolean = true): any {\r\n try {\r\n // 移除 markdown 代码块标记\r\n let cleanedResponse = response.trim();\r\n \r\n // 移除开头的 ```json 或 ```\r\n cleanedResponse = cleanedResponse.replace(/^```json\\s*/i, '');\r\n cleanedResponse = cleanedResponse.replace(/^```\\s*/, '');\r\n \r\n // 移除结尾的 ```\r\n cleanedResponse = cleanedResponse.replace(/\\s*```$/, '');\r\n \r\n // 提取 JSON 部分(查找数组或对象)\r\n const jsonMatch = cleanedResponse.match(/(\\[[\\s\\S]*\\]|\\{[\\s\\S]*\\})/);\r\n if (!jsonMatch) {\r\n throw new Error('No JSON array or object found in response');\r\n }\r\n\r\n const data = JSON.parse(jsonMatch[0]);\r\n\r\n return isArray ? data : data[0];\r\n } catch (error: any) {\r\n console.error('Failed to parse AI response:', error);\r\n console.error('Response:', response);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * 生成基础数据(不使用 AI)\r\n */\r\n generateBasic(type: TypeDefinition, count: number): any[] {\r\n const data = [];\r\n\r\n for (let i = 0; i < count; i++) {\r\n const item: any = {};\r\n\r\n for (const prop of type.properties) {\r\n item[prop.name] = this.generateBasicValue(prop, i);\r\n }\r\n\r\n data.push(item);\r\n }\r\n\r\n return data;\r\n }\r\n\r\n /**\r\n * 生成基础值\r\n */\r\n private generateBasicValue(prop: PropertyDefinition, index: number): any {\r\n const { type, constraints } = prop;\r\n\r\n // 处理枚举\r\n if (constraints?.enum) {\r\n return constraints.enum[index % constraints.enum.length];\r\n }\r\n\r\n // 根据类型生成\r\n switch (type) {\r\n case 'number':\r\n const min = constraints?.min ?? 0;\r\n const max = constraints?.max ?? 100;\r\n return Math.floor(Math.random() * (max - min + 1)) + min;\r\n\r\n case 'string':\r\n return `${prop.name}_${index + 1}`;\r\n\r\n case 'boolean':\r\n return Math.random() > 0.5;\r\n\r\n case 'Date':\r\n return new Date().toISOString();\r\n\r\n default:\r\n return null;\r\n }\r\n }\r\n}\r\n","/**\r\n * AI Mock Generator - 工具函数\r\n */\r\n\r\nimport type { HttpMethod, RequestParams } from './types';\r\n\r\n/**\r\n * 延迟函数\r\n */\r\nexport function delay(ms: number | [number, number]): Promise<void> {\r\n const delayTime = Array.isArray(ms)\r\n ? Math.random() * (ms[1] - ms[0]) + ms[0]\r\n : ms;\r\n\r\n return new Promise((resolve) => setTimeout(resolve, delayTime));\r\n}\r\n\r\n/**\r\n * 匹配路径参数\r\n * @example\r\n * matchPathParams('/api/users/:id', '/api/users/123') // { id: '123' }\r\n */\r\nexport function matchPathParams(\r\n pattern: string,\r\n path: string\r\n): Record<string, string> | null {\r\n const patternParts = pattern.split('/');\r\n const pathParts = path.split('/');\r\n\r\n if (patternParts.length !== pathParts.length) {\r\n return null;\r\n }\r\n\r\n const params: Record<string, string> = {};\r\n\r\n for (let i = 0; i < patternParts.length; i++) {\r\n const patternPart = patternParts[i];\r\n const pathPart = pathParts[i];\r\n\r\n if (patternPart.startsWith(':')) {\r\n // 路径参数\r\n const paramName = patternPart.slice(1);\r\n params[paramName] = pathPart;\r\n } else if (patternPart !== pathPart) {\r\n // 不匹配\r\n return null;\r\n }\r\n }\r\n\r\n return params;\r\n}\r\n\r\n/**\r\n * 解析查询参数\r\n */\r\nexport function parseQueryParams(url: string): Record<string, any> {\r\n const queryString = url.split('?')[1];\r\n if (!queryString) return {};\r\n\r\n const params: Record<string, any> = {};\r\n const pairs = queryString.split('&');\r\n\r\n for (const pair of pairs) {\r\n const [key, value] = pair.split('=');\r\n params[decodeURIComponent(key)] = decodeURIComponent(value || '');\r\n }\r\n\r\n return params;\r\n}\r\n\r\n/**\r\n * 生成唯一 ID\r\n */\r\nexport function generateId(): string {\r\n return `${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;\r\n}\r\n\r\n/**\r\n * 深度克隆\r\n */\r\nexport function deepClone<T>(obj: T): T {\r\n return JSON.parse(JSON.stringify(obj));\r\n}\r\n\r\n/**\r\n * 应用过滤\r\n */\r\nexport function applyFilters(data: any[], filters: Record<string, any>): any[] {\r\n if (!filters || Object.keys(filters).length === 0) {\r\n return data;\r\n }\r\n\r\n return data.filter((item) => {\r\n for (const [key, value] of Object.entries(filters)) {\r\n if (item[key] !== value) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n });\r\n}\r\n\r\n/**\r\n * 应用排序\r\n */\r\nexport function applySorting(\r\n data: any[],\r\n sort?: string | { field: string; order: 'asc' | 'desc' }\r\n): any[] {\r\n if (!sort) return data;\r\n\r\n const sortConfig =\r\n typeof sort === 'string'\r\n ? { field: sort, order: 'asc' as const }\r\n : sort;\r\n\r\n return [...data].sort((a, b) => {\r\n const aValue = a[sortConfig.field];\r\n const bValue = b[sortConfig.field];\r\n\r\n if (aValue < bValue) return sortConfig.order === 'asc' ? -1 : 1;\r\n if (aValue > bValue) return sortConfig.order === 'asc' ? 1 : -1;\r\n return 0;\r\n });\r\n}\r\n\r\n/**\r\n * 应用分页\r\n */\r\nexport function applyPagination(\r\n data: any[],\r\n page: number = 1,\r\n pageSize: number = 20\r\n): {\r\n data: any[];\r\n pagination: {\r\n page: number;\r\n pageSize: number;\r\n total: number;\r\n totalPages: number;\r\n };\r\n} {\r\n const total = data.length;\r\n const totalPages = Math.ceil(total / pageSize);\r\n const start = (page - 1) * pageSize;\r\n const end = start + pageSize;\r\n\r\n return {\r\n data: data.slice(start, end),\r\n pagination: {\r\n page,\r\n pageSize,\r\n total,\r\n totalPages,\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * 格式化响应\r\n */\r\nexport function formatResponse(\r\n data: any,\r\n success: boolean = true,\r\n message?: string\r\n) {\r\n return {\r\n code: success ? 200 : 500,\r\n data,\r\n message: message || (success ? 'Success' : 'Error'),\r\n };\r\n}\r\n\r\n/**\r\n * 生成随机种子\r\n */\r\nexport function generateSeed(): number {\r\n return Math.floor(Math.random() * 1000000);\r\n}\r\n\r\n/**\r\n * 设置随机种子\r\n */\r\nexport function setSeed(seed: number): void {\r\n // 简单的伪随机数生成器\r\n let currentSeed = seed;\r\n Math.random = () => {\r\n currentSeed = (currentSeed * 9301 + 49297) % 233280;\r\n return currentSeed / 233280;\r\n };\r\n}\r\n","/**\r\n * AI Mock Generator - Mock 服务器\r\n */\r\n\r\nimport type { ViteDevServer } from 'vite';\r\nimport type {\r\n EndpointConfig,\r\n HttpMethod,\r\n MockGeneratorOptions,\r\n} from './types';\r\nimport { MockStorage } from './storage';\r\nimport {\r\n delay,\r\n matchPathParams,\r\n parseQueryParams,\r\n applyFilters,\r\n applySorting,\r\n applyPagination,\r\n formatResponse,\r\n} from './utils';\r\n\r\nexport class MockServer {\r\n private storage: MockStorage;\r\n private endpoints: EndpointConfig[];\r\n private options: MockGeneratorOptions;\r\n\r\n constructor(storage: MockStorage, options: MockGeneratorOptions) {\r\n this.storage = storage;\r\n this.endpoints = options.endpoints || [];\r\n this.options = options;\r\n }\r\n\r\n /**\r\n * 配置服务器中间件\r\n */\r\n configureServer(server: ViteDevServer): void {\r\n server.middlewares.use(async (req, res, next) => {\r\n const url = req.url || '';\r\n const method = req.method as HttpMethod;\r\n\r\n // 检查是否匹配 Mock 端点\r\n const endpoint = this.matchEndpoint(url, method);\r\n\r\n if (!endpoint) {\r\n return next();\r\n }\r\n\r\n try {\r\n // 解析请求参数\r\n const params = this.parseRequest(req, url);\r\n\r\n // 获取 Mock 数据\r\n const data = await this.getMockData(endpoint, params);\r\n\r\n // 模拟延迟\r\n if (this.options.server?.delay) {\r\n await delay(this.options.server.delay);\r\n }\r\n\r\n // 设置响应头\r\n res.setHeader('Content-Type', 'application/json');\r\n if (this.options.server?.cors) {\r\n res.setHeader('Access-Control-Allow-Origin', '*');\r\n res.setHeader('Access-Control-Allow-Methods', '*');\r\n res.setHeader('Access-Control-Allow-Headers', '*');\r\n }\r\n\r\n // 返回响应\r\n res.statusCode = 200;\r\n res.end(JSON.stringify(data));\r\n\r\n // 日志\r\n if (this.options.output?.logs) {\r\n console.log(`[Mock] ${method} ${url} → ${data ? 'OK' : 'Empty'}`);\r\n }\r\n } catch (error: any) {\r\n console.error(`[Mock] Error handling ${method} ${url}:`, error);\r\n res.statusCode = 500;\r\n res.end(\r\n JSON.stringify({\r\n code: 500,\r\n message: error.message,\r\n })\r\n );\r\n }\r\n });\r\n\r\n console.log('\\n🎭 Mock 服务器已启动');\r\n console.log(`📍 已注册 ${this.endpoints.length} 个端点\\n`);\r\n }\r\n\r\n /**\r\n * 匹配端点\r\n */\r\n private matchEndpoint(\r\n url: string,\r\n method: HttpMethod\r\n ): EndpointConfig | null {\r\n // 移除查询参数\r\n const path = url.split('?')[0];\r\n\r\n // 移除前缀\r\n const prefix = this.options.server?.prefix || '';\r\n const cleanPath = prefix ? path.replace(new RegExp(`^${prefix}`), '') : path;\r\n\r\n for (const endpoint of this.endpoints) {\r\n // 检查是否禁用\r\n if (endpoint.enabled === false) continue;\r\n\r\n // 检查方法\r\n if (endpoint.method !== method) continue;\r\n\r\n // 精确匹配\r\n if (endpoint.path === cleanPath) {\r\n return endpoint;\r\n }\r\n\r\n // 路径参数匹配\r\n if (matchPathParams(endpoint.path, cleanPath)) {\r\n return endpoint;\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n /**\r\n * 解析请求\r\n */\r\n private parseRequest(req: any, url: string): any {\r\n const query = parseQueryParams(url);\r\n const path = url.split('?')[0];\r\n\r\n // 查找匹配的端点以提取路径参数\r\n const endpoint = this.matchEndpoint(path, req.method);\r\n const pathParams = endpoint\r\n ? matchPathParams(endpoint.path, path.split('?')[0])\r\n : null;\r\n\r\n return {\r\n query,\r\n params: pathParams || {},\r\n body: req.body,\r\n headers: req.headers,\r\n };\r\n }\r\n\r\n /**\r\n * 获取 Mock 数据\r\n */\r\n private async getMockData(\r\n endpoint: EndpointConfig,\r\n params: any\r\n ): Promise<any> {\r\n // 从存储获取数据\r\n let data = this.storage.get(endpoint.path, endpoint.method);\r\n\r\n if (!data) {\r\n console.warn(\r\n `[Mock] No data found for ${endpoint.method} ${endpoint.path}`\r\n );\r\n return formatResponse([], false, 'No mock data available');\r\n }\r\n\r\n // 如果是数组,应用过滤、排序、分页\r\n if (Array.isArray(data)) {\r\n // 过滤\r\n if (params.query.filter) {\r\n data = applyFilters(data, JSON.parse(params.query.filter));\r\n }\r\n\r\n // 排序\r\n if (params.query.sort) {\r\n data = applySorting(data, params.query.sort);\r\n }\r\n\r\n // 分页\r\n if (params.query.page || params.query.pageSize) {\r\n const page = parseInt(params.query.page) || 1;\r\n const pageSize = parseInt(params.query.pageSize) || 20;\r\n const result = applyPagination(data, page, pageSize);\r\n\r\n return formatResponse({\r\n list: result.data,\r\n pagination: result.pagination,\r\n });\r\n }\r\n }\r\n\r\n // 应用自定义处理\r\n if (endpoint.custom) {\r\n data = await endpoint.custom(data, params);\r\n }\r\n\r\n // 格式化响应\r\n return formatResponse(data);\r\n }\r\n\r\n /**\r\n * 添加端点\r\n */\r\n addEndpoint(endpoint: EndpointConfig): void {\r\n this.endpoints.push(endpoint);\r\n }\r\n\r\n /**\r\n * 移除端点\r\n */\r\n removeEndpoint(path: string, method: HttpMethod): void {\r\n this.endpoints = this.endpoints.filter(\r\n (e) => !(e.path === path && e.method === method)\r\n );\r\n }\r\n\r\n /**\r\n * 获取所有端点\r\n */\r\n getEndpoints(): EndpointConfig[] {\r\n return this.endpoints;\r\n }\r\n}\r\n","/**\r\n * AI Mock Generator - Vite 插件入口\r\n */\r\n\r\nimport type { Plugin } from 'vite';\r\nimport type { MockGeneratorOptions, TypeDefinition } from './types';\r\nimport { MockStorage } from './storage';\r\nimport { MockDataGenerator } from './generator';\r\nimport { MockServer } from './server';\r\n\r\nexport function vitePluginAIMockGenerator(\r\n options: MockGeneratorOptions = {}\r\n): Plugin {\r\n const {\r\n apiKey = process.env.OPENAI_API_KEY || '',\r\n apiUrl = process.env.OPENAI_API_URL || 'https://api.openai.com/v1',\r\n model = process.env.OPENAI_MODEL || 'gpt-4',\r\n enabled = true,\r\n autoGenerate = false,\r\n generation = {\r\n locale: 'zh-CN',\r\n count: 20,\r\n quality: 'balanced',\r\n },\r\n storage: storageOptions = {\r\n dir: 'mock-data',\r\n persist: true,\r\n cache: true,\r\n },\r\n output = {\r\n console: true,\r\n logs: false,\r\n },\r\n } = options;\r\n\r\n // 如果未启用,返回空插件\r\n if (!enabled) {\r\n return {\r\n name: 'vite-plugin-ai-mock-generator',\r\n };\r\n }\r\n\r\n // 初始化组件\r\n const storage = new MockStorage(storageOptions);\r\n const generator = new MockDataGenerator({ apiKey, apiUrl, model });\r\n const server = new MockServer(storage, options);\r\n\r\n return {\r\n name: 'vite-plugin-ai-mock-generator',\r\n enforce: 'pre',\r\n\r\n configResolved(config) {\r\n if (output.console) {\r\n console.log('\\n🤖 AI Mock Generator 已启动');\r\n console.log(`📂 存储目录: ${storageOptions.dir}`);\r\n console.log(`🌍 数据语言: ${generation.locale}`);\r\n console.log(`📊 默认数量: ${generation.count}`);\r\n console.log(`🔑 API Key: ${apiKey ? '已配置' : '未配置'}`);\r\n console.log(\r\n `📍 端点数量: ${options.endpoints?.length || 0}`\r\n );\r\n }\r\n },\r\n\r\n async buildStart() {\r\n // 如果启用自动生成\r\n if (autoGenerate && options.endpoints) {\r\n if (output.console) {\r\n console.log('\\n🔄 开始自动生成 Mock 数据...\\n');\r\n }\r\n\r\n for (const endpoint of options.endpoints) {\r\n // 检查是否已有数据\r\n const existingData = storage.get(endpoint.path, endpoint.method);\r\n if (existingData) {\r\n if (output.console) {\r\n console.log(\r\n `⏭️ 跳过 ${endpoint.method} ${endpoint.path} (已有数据)`\r\n );\r\n }\r\n continue;\r\n }\r\n\r\n try {\r\n if (output.console) {\r\n console.log(`🎲 生成 ${endpoint.method} ${endpoint.path}...`);\r\n }\r\n\r\n // 解析类型定义\r\n const typeDefinition = parseTypeDefinition(endpoint.response);\r\n\r\n // 生成数据\r\n const count = endpoint.count || generation.count || 20;\r\n let data;\r\n \r\n // 根据质量设置选择生成方式\r\n if (generation.quality === 'fast') {\r\n // 使用基础生成器(不需要 AI)\r\n data = generator.generateBasic(typeDefinition, count);\r\n } else {\r\n // 使用 AI 生成\r\n data = await generator.generate({\r\n type: typeDefinition,\r\n count,\r\n locale: generation.locale || 'zh-CN',\r\n quality: generation.quality || 'balanced',\r\n });\r\n }\r\n\r\n // 存储数据\r\n storage.set(endpoint.path, endpoint.method, data, {\r\n type: endpoint.response as string,\r\n });\r\n\r\n if (output.console) {\r\n console.log(\r\n `✅ 已生成 ${count} 条数据: ${endpoint.method} ${endpoint.path}`\r\n );\r\n }\r\n } catch (error: any) {\r\n console.error(\r\n `❌ 生成失败 ${endpoint.method} ${endpoint.path}:`,\r\n error.message\r\n );\r\n }\r\n }\r\n\r\n if (output.console) {\r\n console.log('\\n✨ Mock 数据生成完成\\n');\r\n }\r\n }\r\n },\r\n\r\n configureServer(viteServer) {\r\n // 配置 Mock 服务器中间件\r\n server.configureServer(viteServer);\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * 解析类型定义\r\n * 简化版本,实际应该使用 TypeScript Compiler API\r\n */\r\nfunction parseTypeDefinition(typeStr: string | TypeDefinition): TypeDefinition {\r\n if (typeof typeStr === 'object') {\r\n return typeStr;\r\n }\r\n\r\n // 简单解析(实际应该更复杂)\r\n const isArray = typeStr.endsWith('[]');\r\n const typeName = isArray ? typeStr.slice(0, -2) : typeStr;\r\n\r\n // 返回基础类型定义\r\n return {\r\n name: typeName,\r\n properties: [],\r\n isArray,\r\n };\r\n}\r\n\r\n// 导出类型\r\nexport type { MockGeneratorOptions, EndpointConfig } from './types';\r\nexport { MockStorage } from './storage';\r\nexport { MockDataGenerator } from './generator';\r\nexport { MockServer } from './server';\r\n"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/storage.ts","../src/generator.ts","../src/utils.ts","../src/server.ts"],"sourcesContent":["/**\r\n * AI Mock Generator - Vite 插件入口\r\n */\r\n\r\nimport type { Plugin } from \"vite\";\r\nimport type { MockGeneratorOptions, TypeDefinition } from \"./types\";\r\nimport { MockStorage } from \"./storage\";\r\nimport { MockDataGenerator } from \"./generator\";\r\nimport { MockServer } from \"./server\";\r\n\r\nexport function vitePluginAIMockGenerator(\r\n options: MockGeneratorOptions = {},\r\n): Plugin {\r\n const {\r\n apiKey = process.env.OPENAI_API_KEY || \"\",\r\n apiUrl = process.env.OPENAI_API_URL || \"https://api.openai.com/v1\",\r\n model = process.env.OPENAI_MODEL || \"gpt-4\",\r\n enabled = true,\r\n autoGenerate = false,\r\n generation = {\r\n locale: \"zh-CN\",\r\n count: 20,\r\n quality: \"balanced\",\r\n },\r\n storage: storageOptions = {\r\n dir: \"mock-data\",\r\n persist: true,\r\n cache: true,\r\n },\r\n output = {\r\n console: true,\r\n logs: false,\r\n },\r\n } = options;\r\n\r\n // 如果未启用,返回空插件\r\n if (!enabled) {\r\n return {\r\n name: \"vite-plugin-ai-mock-generator\",\r\n };\r\n }\r\n\r\n // 初始化组件\r\n const storage = new MockStorage(storageOptions);\r\n const generator = new MockDataGenerator({ apiKey, apiUrl, model });\r\n const server = new MockServer(storage, options);\r\n\r\n return {\r\n name: \"vite-plugin-ai-mock-generator\",\r\n enforce: \"pre\",\r\n\r\n configResolved(config) {\r\n if (output.console) {\r\n console.log(\"\\n🤖 AI Mock Generator 已启动\");\r\n console.log(`📂 存储目录: ${storageOptions.dir}`);\r\n console.log(`🌍 数据语言: ${generation.locale}`);\r\n console.log(`📊 默认数量: ${generation.count}`);\r\n console.log(`🔑 API Key: ${apiKey ? \"已配置\" : \"未配置\"}`);\r\n console.log(`📍 端点数量: ${options.endpoints?.length || 0}`);\r\n }\r\n },\r\n\r\n async buildStart() {\r\n // 如果启用自动生成\r\n if (autoGenerate && options.endpoints) {\r\n if (output.console) {\r\n console.log(\"\\n🔄 开始自动生成 Mock 数据...\\n\");\r\n }\r\n\r\n for (const endpoint of options.endpoints) {\r\n // 检查是否已有数据\r\n const existingData = storage.get(endpoint.path, endpoint.method);\r\n if (existingData) {\r\n if (output.console) {\r\n console.log(\r\n `⏭️ 跳过 ${endpoint.method} ${endpoint.path} (已有数据)`,\r\n );\r\n }\r\n continue;\r\n }\r\n\r\n try {\r\n if (output.console) {\r\n console.log(`🎲 生成 ${endpoint.method} ${endpoint.path}...`);\r\n }\r\n\r\n // 解析类型定义\r\n const typeDefinition = parseTypeDefinition(endpoint.response);\r\n\r\n // 生成数据\r\n const count = endpoint.count || generation.count || 20;\r\n let data;\r\n\r\n // 根据质量设置选择生成方式\r\n if (generation.quality === \"fast\") {\r\n // 使用基础生成器(不需要 AI)\r\n data = generator.generateBasic(typeDefinition, count);\r\n } else {\r\n // 使用 AI 生成\r\n data = await generator.generate({\r\n type: typeDefinition,\r\n count,\r\n locale: generation.locale || \"zh-CN\",\r\n quality: generation.quality || \"balanced\",\r\n });\r\n }\r\n\r\n // 存储数据\r\n storage.set(endpoint.path, endpoint.method, data, {\r\n type: endpoint.response as string,\r\n });\r\n\r\n if (output.console) {\r\n console.log(\r\n `✅ 已生成 ${count} 条数据: ${endpoint.method} ${endpoint.path}`,\r\n );\r\n }\r\n } catch (error: any) {\r\n console.error(\r\n `❌ 生成失败 ${endpoint.method} ${endpoint.path}:`,\r\n error.message,\r\n );\r\n }\r\n }\r\n\r\n if (output.console) {\r\n console.log(\"\\n✨ Mock 数据生成完成\\n\");\r\n }\r\n }\r\n },\r\n\r\n configureServer(viteServer) {\r\n // 配置 Mock 服务器中间件\r\n server.configureServer(viteServer);\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * 解析类型定义\r\n * 简化版本,实际应该使用 TypeScript Compiler API\r\n */\r\nfunction parseTypeDefinition(typeStr: string | TypeDefinition): TypeDefinition {\r\n if (typeof typeStr === \"object\") {\r\n return typeStr;\r\n }\r\n\r\n // 简单解析(实际应该更复杂)\r\n const isArray = typeStr.endsWith(\"[]\");\r\n const typeName = isArray ? typeStr.slice(0, -2) : typeStr;\r\n\r\n // 返回基础类型定义\r\n return {\r\n name: typeName,\r\n properties: [],\r\n isArray,\r\n };\r\n}\r\n\r\n// 导出类型\r\nexport type { MockGeneratorOptions, EndpointConfig } from \"./types\";\r\nexport { MockStorage } from \"./storage\";\r\nexport { MockDataGenerator } from \"./generator\";\r\nexport { MockServer } from \"./server\";\r\n\r\n// 默认导出\r\nexport default vitePluginAIMockGenerator;\r\n","/**\r\n * AI Mock Generator - 数据存储\r\n */\r\n\r\nimport fs from 'fs';\r\nimport path from 'path';\r\nimport type { MockDataStore, HttpMethod } from './types';\r\n\r\nexport class MockStorage {\r\n private storageDir: string;\r\n private cache: Map<string, MockDataStore>;\r\n private persist: boolean;\r\n\r\n constructor(options: { dir?: string; persist?: boolean } = {}) {\r\n this.storageDir = options.dir || 'mock-data';\r\n this.persist = options.persist !== false;\r\n this.cache = new Map();\r\n\r\n // 确保存储目录存在\r\n if (this.persist && !fs.existsSync(this.storageDir)) {\r\n fs.mkdirSync(this.storageDir, { recursive: true });\r\n }\r\n\r\n // 加载已有数据\r\n this.load();\r\n }\r\n\r\n /**\r\n * 生成存储 key\r\n */\r\n private getKey(endpoint: string, method: HttpMethod): string {\r\n return `${method}:${endpoint}`;\r\n }\r\n\r\n /**\r\n * 生成文件名\r\n */\r\n private getFileName(endpoint: string, method: HttpMethod): string {\r\n const sanitized = endpoint\r\n .replace(/^\\//, '')\r\n .replace(/\\//g, '_')\r\n .replace(/:/g, '_');\r\n return `${method}_${sanitized}.json`;\r\n }\r\n\r\n /**\r\n * 获取数据\r\n */\r\n get(endpoint: string, method: HttpMethod = 'GET'): any {\r\n const key = this.getKey(endpoint, method);\r\n const store = this.cache.get(key);\r\n return store?.data;\r\n }\r\n\r\n /**\r\n * 设置数据\r\n */\r\n set(\r\n endpoint: string,\r\n method: HttpMethod,\r\n data: any,\r\n metadata?: Partial<MockDataStore['metadata']>\r\n ): void {\r\n const key = this.getKey(endpoint, method);\r\n\r\n const store: MockDataStore = {\r\n endpoint,\r\n method,\r\n data,\r\n metadata: {\r\n count: Array.isArray(data) ? data.length : 1,\r\n generatedAt: new Date().toISOString(),\r\n version: '1.0.0',\r\n type: typeof data,\r\n ...metadata,\r\n },\r\n };\r\n\r\n this.cache.set(key, store);\r\n\r\n // 持久化\r\n if (this.persist) {\r\n this.save(endpoint, method, store);\r\n }\r\n }\r\n\r\n /**\r\n * 删除数据\r\n */\r\n delete(endpoint: string, method: HttpMethod = 'GET'): void {\r\n const key = this.getKey(endpoint, method);\r\n this.cache.delete(key);\r\n\r\n // 删除文件\r\n if (this.persist) {\r\n const fileName = this.getFileName(endpoint, method);\r\n const filePath = path.join(this.storageDir, fileName);\r\n if (fs.existsSync(filePath)) {\r\n fs.unlinkSync(filePath);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 清空所有数据\r\n */\r\n clear(): void {\r\n this.cache.clear();\r\n\r\n // 清空目录\r\n if (this.persist && fs.existsSync(this.storageDir)) {\r\n const files = fs.readdirSync(this.storageDir);\r\n for (const file of files) {\r\n fs.unlinkSync(path.join(this.storageDir, file));\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 获取所有端点\r\n */\r\n getAll(): MockDataStore[] {\r\n return Array.from(this.cache.values());\r\n }\r\n\r\n /**\r\n * 保存到文件\r\n */\r\n private save(\r\n endpoint: string,\r\n method: HttpMethod,\r\n store: MockDataStore\r\n ): void {\r\n const fileName = this.getFileName(endpoint, method);\r\n const filePath = path.join(this.storageDir, fileName);\r\n\r\n fs.writeFileSync(filePath, JSON.stringify(store, null, 2), 'utf-8');\r\n }\r\n\r\n /**\r\n * 从文件加载\r\n */\r\n private load(): void {\r\n if (!this.persist || !fs.existsSync(this.storageDir)) {\r\n return;\r\n }\r\n\r\n const files = fs.readdirSync(this.storageDir);\r\n\r\n for (const file of files) {\r\n if (!file.endsWith('.json')) continue;\r\n\r\n try {\r\n const filePath = path.join(this.storageDir, file);\r\n const content = fs.readFileSync(filePath, 'utf-8');\r\n const store: MockDataStore = JSON.parse(content);\r\n\r\n const key = this.getKey(store.endpoint, store.method);\r\n this.cache.set(key, store);\r\n } catch (error) {\r\n console.warn(`Failed to load mock data from ${file}:`, error);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 导出所有数据\r\n */\r\n export(outputPath: string): void {\r\n const allData = this.getAll();\r\n fs.writeFileSync(outputPath, JSON.stringify(allData, null, 2), 'utf-8');\r\n }\r\n\r\n /**\r\n * 导入数据\r\n */\r\n import(inputPath: string): void {\r\n const content = fs.readFileSync(inputPath, 'utf-8');\r\n const allData: MockDataStore[] = JSON.parse(content);\r\n\r\n for (const store of allData) {\r\n const key = this.getKey(store.endpoint, store.method);\r\n this.cache.set(key, store);\r\n\r\n if (this.persist) {\r\n this.save(store.endpoint, store.method, store);\r\n }\r\n }\r\n }\r\n}\r\n","/**\r\n * AI Mock Generator - 数据生成器\r\n */\r\n\r\nimport { ChatOpenAI } from \"@langchain/openai\";\r\nimport { HumanMessage, SystemMessage } from \"@langchain/core/messages\";\r\nimport type {\r\n TypeDefinition,\r\n GenerationContext,\r\n PropertyDefinition,\r\n} from \"./types\";\r\n\r\nexport class MockDataGenerator {\r\n private llm: ChatOpenAI;\r\n\r\n constructor(options: { apiKey: string; apiUrl: string; model: string }) {\r\n this.llm = new ChatOpenAI({\r\n openAIApiKey: options.apiKey,\r\n configuration: {\r\n baseURL: options.apiUrl,\r\n },\r\n modelName: options.model,\r\n temperature: 0.7,\r\n maxTokens: 4000,\r\n });\r\n }\r\n\r\n /**\r\n * 生成 Mock 数据\r\n */\r\n async generate(context: GenerationContext): Promise<any> {\r\n const { type, count, locale, quality } = context;\r\n\r\n // 构建 AI Prompt\r\n const prompt = this.buildPrompt(type, count, locale, quality);\r\n\r\n // 调用 AI API\r\n const response = await this.callAI(prompt);\r\n\r\n // 解析响应\r\n return this.parseResponse(response, type.isArray);\r\n }\r\n\r\n /**\r\n * 构建 AI Prompt\r\n */\r\n private buildPrompt(\r\n type: TypeDefinition,\r\n count: number,\r\n locale: string,\r\n quality: string,\r\n ): string {\r\n const properties = type.properties\r\n .map((p) => this.formatProperty(p))\r\n .join(\"\\n\");\r\n\r\n return `\r\n你是一个专业的 Mock 数据生成器。请根据以下类型定义生成真实、合理的测试数据。\r\n\r\n类型名称: ${type.name}\r\n数据语言: ${locale === \"zh-CN\" ? \"中文\" : \"英文\"}\r\n数据数量: ${count}\r\n质量要求: ${\r\n quality === \"high\"\r\n ? \"高质量(真实业务数据)\"\r\n : quality === \"fast\"\r\n ? \"快速生成\"\r\n : \"平衡质量和速度\"\r\n }\r\n\r\n类型定义:\r\n${properties}\r\n\r\n要求:\r\n1. 生成 ${count} 条数据\r\n2. 数据要符合业务逻辑和真实场景\r\n3. 字段值要合理(如价格不能为负数,年龄在合理范围)\r\n4. 日期格式使用 ISO 8601\r\n5. 返回 JSON 数组格式,不要包含任何其他文字\r\n6. 理解字段语义,生成真实数据(如 userName 生成真实姓名)\r\n\r\n示例格式:\r\n[\r\n {\r\n \"id\": 1,\r\n \"name\": \"张三\",\r\n ...\r\n }\r\n]\r\n\r\n请生成数据:\r\n`.trim();\r\n }\r\n\r\n /**\r\n * 格式化属性\r\n */\r\n private formatProperty(prop: PropertyDefinition): string {\r\n let line = `- ${prop.name}: ${prop.type}`;\r\n\r\n if (prop.comment) {\r\n line += ` // ${prop.comment}`;\r\n }\r\n\r\n if (prop.constraints) {\r\n const constraints = [];\r\n if (prop.constraints.min !== undefined) {\r\n constraints.push(`min: ${prop.constraints.min}`);\r\n }\r\n if (prop.constraints.max !== undefined) {\r\n constraints.push(`max: ${prop.constraints.max}`);\r\n }\r\n if (prop.constraints.unique) {\r\n constraints.push(\"unique\");\r\n }\r\n if (prop.constraints.enum) {\r\n constraints.push(`enum: [${prop.constraints.enum.join(\", \")}]`);\r\n }\r\n if (constraints.length > 0) {\r\n line += ` (${constraints.join(\", \")})`;\r\n }\r\n }\r\n\r\n return line;\r\n }\r\n\r\n /**\r\n * 调用 AI API\r\n */\r\n private async callAI(prompt: string): Promise<string> {\r\n try {\r\n const messages = [\r\n new SystemMessage(\r\n \"你是一个专业的 Mock 数据生成器,擅长生成真实、合理的测试数据。\",\r\n ),\r\n new HumanMessage(prompt),\r\n ];\r\n\r\n const response = await this.llm.invoke(messages);\r\n return response.content as string;\r\n } catch (error: any) {\r\n console.error(\"❌ AI API 调用失败:\", error.message);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * 解析 AI 响应\r\n */\r\n private parseResponse(response: string, isArray: boolean = true): any {\r\n try {\r\n // 移除 markdown 代码块标记\r\n let cleanedResponse = response.trim();\r\n\r\n // 移除开头的 ```json 或 ```\r\n cleanedResponse = cleanedResponse.replace(/^```json\\s*/i, \"\");\r\n cleanedResponse = cleanedResponse.replace(/^```\\s*/, \"\");\r\n\r\n // 移除结尾的 ```\r\n cleanedResponse = cleanedResponse.replace(/\\s*```$/, \"\");\r\n\r\n // 提取 JSON 部分(查找数组或对象)\r\n const jsonMatch = cleanedResponse.match(/(\\[[\\s\\S]*\\]|\\{[\\s\\S]*\\})/);\r\n if (!jsonMatch) {\r\n throw new Error(\"No JSON array or object found in response\");\r\n }\r\n\r\n const data = JSON.parse(jsonMatch[0]);\r\n\r\n return isArray ? data : data[0];\r\n } catch (error: any) {\r\n console.error(\"❌ 解析 AI 响应失败:\", error.message);\r\n console.error(\"响应内容:\", response);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * 生成基础数据(不使用 AI)\r\n */\r\n generateBasic(type: TypeDefinition, count: number): any[] {\r\n const data = [];\r\n\r\n for (let i = 0; i < count; i++) {\r\n const item: any = {};\r\n\r\n for (const prop of type.properties) {\r\n item[prop.name] = this.generateBasicValue(prop, i);\r\n }\r\n\r\n data.push(item);\r\n }\r\n\r\n return data;\r\n }\r\n\r\n /**\r\n * 生成基础值\r\n */\r\n private generateBasicValue(prop: PropertyDefinition, index: number): any {\r\n const { type, constraints } = prop;\r\n\r\n // 处理枚举\r\n if (constraints?.enum) {\r\n return constraints.enum[index % constraints.enum.length];\r\n }\r\n\r\n // 根据类型生成\r\n switch (type) {\r\n case \"number\":\r\n const min = constraints?.min ?? 0;\r\n const max = constraints?.max ?? 100;\r\n return Math.floor(Math.random() * (max - min + 1)) + min;\r\n\r\n case \"string\":\r\n return `${prop.name}_${index + 1}`;\r\n\r\n case \"boolean\":\r\n return Math.random() > 0.5;\r\n\r\n case \"Date\":\r\n return new Date().toISOString();\r\n\r\n default:\r\n return null;\r\n }\r\n }\r\n}\r\n","/**\r\n * AI Mock Generator - 工具函数\r\n */\r\n\r\nimport type { HttpMethod, RequestParams } from './types';\r\n\r\n/**\r\n * 延迟函数\r\n */\r\nexport function delay(ms: number | [number, number]): Promise<void> {\r\n const delayTime = Array.isArray(ms)\r\n ? Math.random() * (ms[1] - ms[0]) + ms[0]\r\n : ms;\r\n\r\n return new Promise((resolve) => setTimeout(resolve, delayTime));\r\n}\r\n\r\n/**\r\n * 匹配路径参数\r\n * @example\r\n * matchPathParams('/api/users/:id', '/api/users/123') // { id: '123' }\r\n */\r\nexport function matchPathParams(\r\n pattern: string,\r\n path: string\r\n): Record<string, string> | null {\r\n const patternParts = pattern.split('/');\r\n const pathParts = path.split('/');\r\n\r\n if (patternParts.length !== pathParts.length) {\r\n return null;\r\n }\r\n\r\n const params: Record<string, string> = {};\r\n\r\n for (let i = 0; i < patternParts.length; i++) {\r\n const patternPart = patternParts[i];\r\n const pathPart = pathParts[i];\r\n\r\n if (patternPart.startsWith(':')) {\r\n // 路径参数\r\n const paramName = patternPart.slice(1);\r\n params[paramName] = pathPart;\r\n } else if (patternPart !== pathPart) {\r\n // 不匹配\r\n return null;\r\n }\r\n }\r\n\r\n return params;\r\n}\r\n\r\n/**\r\n * 解析查询参数\r\n */\r\nexport function parseQueryParams(url: string): Record<string, any> {\r\n const queryString = url.split('?')[1];\r\n if (!queryString) return {};\r\n\r\n const params: Record<string, any> = {};\r\n const pairs = queryString.split('&');\r\n\r\n for (const pair of pairs) {\r\n const [key, value] = pair.split('=');\r\n params[decodeURIComponent(key)] = decodeURIComponent(value || '');\r\n }\r\n\r\n return params;\r\n}\r\n\r\n/**\r\n * 生成唯一 ID\r\n */\r\nexport function generateId(): string {\r\n return `${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;\r\n}\r\n\r\n/**\r\n * 深度克隆\r\n */\r\nexport function deepClone<T>(obj: T): T {\r\n return JSON.parse(JSON.stringify(obj));\r\n}\r\n\r\n/**\r\n * 应用过滤\r\n */\r\nexport function applyFilters(data: any[], filters: Record<string, any>): any[] {\r\n if (!filters || Object.keys(filters).length === 0) {\r\n return data;\r\n }\r\n\r\n return data.filter((item) => {\r\n for (const [key, value] of Object.entries(filters)) {\r\n if (item[key] !== value) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n });\r\n}\r\n\r\n/**\r\n * 应用排序\r\n */\r\nexport function applySorting(\r\n data: any[],\r\n sort?: string | { field: string; order: 'asc' | 'desc' }\r\n): any[] {\r\n if (!sort) return data;\r\n\r\n const sortConfig =\r\n typeof sort === 'string'\r\n ? { field: sort, order: 'asc' as const }\r\n : sort;\r\n\r\n return [...data].sort((a, b) => {\r\n const aValue = a[sortConfig.field];\r\n const bValue = b[sortConfig.field];\r\n\r\n if (aValue < bValue) return sortConfig.order === 'asc' ? -1 : 1;\r\n if (aValue > bValue) return sortConfig.order === 'asc' ? 1 : -1;\r\n return 0;\r\n });\r\n}\r\n\r\n/**\r\n * 应用分页\r\n */\r\nexport function applyPagination(\r\n data: any[],\r\n page: number = 1,\r\n pageSize: number = 20\r\n): {\r\n data: any[];\r\n pagination: {\r\n page: number;\r\n pageSize: number;\r\n total: number;\r\n totalPages: number;\r\n };\r\n} {\r\n const total = data.length;\r\n const totalPages = Math.ceil(total / pageSize);\r\n const start = (page - 1) * pageSize;\r\n const end = start + pageSize;\r\n\r\n return {\r\n data: data.slice(start, end),\r\n pagination: {\r\n page,\r\n pageSize,\r\n total,\r\n totalPages,\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * 格式化响应\r\n */\r\nexport function formatResponse(\r\n data: any,\r\n success: boolean = true,\r\n message?: string\r\n) {\r\n return {\r\n code: success ? 200 : 500,\r\n data,\r\n message: message || (success ? 'Success' : 'Error'),\r\n };\r\n}\r\n\r\n/**\r\n * 生成随机种子\r\n */\r\nexport function generateSeed(): number {\r\n return Math.floor(Math.random() * 1000000);\r\n}\r\n\r\n/**\r\n * 设置随机种子\r\n */\r\nexport function setSeed(seed: number): void {\r\n // 简单的伪随机数生成器\r\n let currentSeed = seed;\r\n Math.random = () => {\r\n currentSeed = (currentSeed * 9301 + 49297) % 233280;\r\n return currentSeed / 233280;\r\n };\r\n}\r\n","/**\r\n * AI Mock Generator - Mock 服务器\r\n */\r\n\r\nimport type { ViteDevServer } from 'vite';\r\nimport type {\r\n EndpointConfig,\r\n HttpMethod,\r\n MockGeneratorOptions,\r\n} from './types';\r\nimport { MockStorage } from './storage';\r\nimport {\r\n delay,\r\n matchPathParams,\r\n parseQueryParams,\r\n applyFilters,\r\n applySorting,\r\n applyPagination,\r\n formatResponse,\r\n} from './utils';\r\n\r\nexport class MockServer {\r\n private storage: MockStorage;\r\n private endpoints: EndpointConfig[];\r\n private options: MockGeneratorOptions;\r\n\r\n constructor(storage: MockStorage, options: MockGeneratorOptions) {\r\n this.storage = storage;\r\n this.endpoints = options.endpoints || [];\r\n this.options = options;\r\n }\r\n\r\n /**\r\n * 配置服务器中间件\r\n */\r\n configureServer(server: ViteDevServer): void {\r\n server.middlewares.use(async (req, res, next) => {\r\n const url = req.url || '';\r\n const method = req.method as HttpMethod;\r\n\r\n // 检查是否匹配 Mock 端点\r\n const endpoint = this.matchEndpoint(url, method);\r\n\r\n if (!endpoint) {\r\n return next();\r\n }\r\n\r\n try {\r\n // 解析请求参数\r\n const params = this.parseRequest(req, url);\r\n\r\n // 获取 Mock 数据\r\n const data = await this.getMockData(endpoint, params);\r\n\r\n // 模拟延迟\r\n if (this.options.server?.delay) {\r\n await delay(this.options.server.delay);\r\n }\r\n\r\n // 设置响应头\r\n res.setHeader('Content-Type', 'application/json');\r\n if (this.options.server?.cors) {\r\n res.setHeader('Access-Control-Allow-Origin', '*');\r\n res.setHeader('Access-Control-Allow-Methods', '*');\r\n res.setHeader('Access-Control-Allow-Headers', '*');\r\n }\r\n\r\n // 返回响应\r\n res.statusCode = 200;\r\n res.end(JSON.stringify(data));\r\n\r\n // 日志\r\n if (this.options.output?.logs) {\r\n console.log(`[Mock] ${method} ${url} → ${data ? 'OK' : 'Empty'}`);\r\n }\r\n } catch (error: any) {\r\n console.error(`[Mock] Error handling ${method} ${url}:`, error);\r\n res.statusCode = 500;\r\n res.end(\r\n JSON.stringify({\r\n code: 500,\r\n message: error.message,\r\n })\r\n );\r\n }\r\n });\r\n\r\n console.log('\\n🎭 Mock 服务器已启动');\r\n console.log(`📍 已注册 ${this.endpoints.length} 个端点\\n`);\r\n }\r\n\r\n /**\r\n * 匹配端点\r\n */\r\n private matchEndpoint(\r\n url: string,\r\n method: HttpMethod\r\n ): EndpointConfig | null {\r\n // 移除查询参数\r\n const path = url.split('?')[0];\r\n\r\n // 移除前缀\r\n const prefix = this.options.server?.prefix || '';\r\n const cleanPath = prefix ? path.replace(new RegExp(`^${prefix}`), '') : path;\r\n\r\n for (const endpoint of this.endpoints) {\r\n // 检查是否禁用\r\n if (endpoint.enabled === false) continue;\r\n\r\n // 检查方法\r\n if (endpoint.method !== method) continue;\r\n\r\n // 精确匹配\r\n if (endpoint.path === cleanPath) {\r\n return endpoint;\r\n }\r\n\r\n // 路径参数匹配\r\n if (matchPathParams(endpoint.path, cleanPath)) {\r\n return endpoint;\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n /**\r\n * 解析请求\r\n */\r\n private parseRequest(req: any, url: string): any {\r\n const query = parseQueryParams(url);\r\n const path = url.split('?')[0];\r\n\r\n // 查找匹配的端点以提取路径参数\r\n const endpoint = this.matchEndpoint(path, req.method);\r\n const pathParams = endpoint\r\n ? matchPathParams(endpoint.path, path.split('?')[0])\r\n : null;\r\n\r\n return {\r\n query,\r\n params: pathParams || {},\r\n body: req.body,\r\n headers: req.headers,\r\n };\r\n }\r\n\r\n /**\r\n * 获取 Mock 数据\r\n */\r\n private async getMockData(\r\n endpoint: EndpointConfig,\r\n params: any\r\n ): Promise<any> {\r\n // 从存储获取数据\r\n let data = this.storage.get(endpoint.path, endpoint.method);\r\n\r\n if (!data) {\r\n console.warn(\r\n `[Mock] No data found for ${endpoint.method} ${endpoint.path}`\r\n );\r\n return formatResponse([], false, 'No mock data available');\r\n }\r\n\r\n // 如果是数组,应用过滤、排序、分页\r\n if (Array.isArray(data)) {\r\n // 过滤\r\n if (params.query.filter) {\r\n data = applyFilters(data, JSON.parse(params.query.filter));\r\n }\r\n\r\n // 排序\r\n if (params.query.sort) {\r\n data = applySorting(data, params.query.sort);\r\n }\r\n\r\n // 分页\r\n if (params.query.page || params.query.pageSize) {\r\n const page = parseInt(params.query.page) || 1;\r\n const pageSize = parseInt(params.query.pageSize) || 20;\r\n const result = applyPagination(data, page, pageSize);\r\n\r\n return formatResponse({\r\n list: result.data,\r\n pagination: result.pagination,\r\n });\r\n }\r\n }\r\n\r\n // 应用自定义处理\r\n if (endpoint.custom) {\r\n data = await endpoint.custom(data, params);\r\n }\r\n\r\n // 格式化响应\r\n return formatResponse(data);\r\n }\r\n\r\n /**\r\n * 添加端点\r\n */\r\n addEndpoint(endpoint: EndpointConfig): void {\r\n this.endpoints.push(endpoint);\r\n }\r\n\r\n /**\r\n * 移除端点\r\n */\r\n removeEndpoint(path: string, method: HttpMethod): void {\r\n this.endpoints = this.endpoints.filter(\r\n (e) => !(e.path === path && e.method === method)\r\n );\r\n }\r\n\r\n /**\r\n * 获取所有端点\r\n */\r\n getEndpoints(): EndpointConfig[] {\r\n return this.endpoints;\r\n }\r\n}\r\n"],"mappings":"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","names":["fs","path","path","path"]}
package/dist/index.mjs CHANGED
@@ -1,7 +1,6 @@
1
- import fs from 'fs';
2
- import path from 'path';
3
-
4
1
  // src/storage.ts
2
+ import fs from "fs";
3
+ import path from "path";
5
4
  var MockStorage = class {
6
5
  constructor(options = {}) {
7
6
  this.storageDir = options.dir || "mock-data";
@@ -140,11 +139,19 @@ var MockStorage = class {
140
139
  };
141
140
 
142
141
  // src/generator.ts
142
+ import { ChatOpenAI } from "@langchain/openai";
143
+ import { HumanMessage, SystemMessage } from "@langchain/core/messages";
143
144
  var MockDataGenerator = class {
144
145
  constructor(options) {
145
- this.apiKey = options.apiKey;
146
- this.apiUrl = options.apiUrl;
147
- this.model = options.model;
146
+ this.llm = new ChatOpenAI({
147
+ openAIApiKey: options.apiKey,
148
+ configuration: {
149
+ baseURL: options.apiUrl
150
+ },
151
+ modelName: options.model,
152
+ temperature: 0.7,
153
+ maxTokens: 4e3
154
+ });
148
155
  }
149
156
  /**
150
157
  * 生成 Mock 数据
@@ -161,34 +168,34 @@ var MockDataGenerator = class {
161
168
  buildPrompt(type, count, locale, quality) {
162
169
  const properties = type.properties.map((p) => this.formatProperty(p)).join("\n");
163
170
  return `
164
- \u4F60\u662F\u4E00\u4E2A\u4E13\u4E1A\u7684 Mock \u6570\u636E\u751F\u6210\u5668\u3002\u8BF7\u6839\u636E\u4EE5\u4E0B\u7C7B\u578B\u5B9A\u4E49\u751F\u6210\u771F\u5B9E\u3001\u5408\u7406\u7684\u6D4B\u8BD5\u6570\u636E\u3002
171
+ 你是一个专业的 Mock 数据生成器。请根据以下类型定义生成真实、合理的测试数据。
165
172
 
166
- \u7C7B\u578B\u540D\u79F0: ${type.name}
167
- \u6570\u636E\u8BED\u8A00: ${locale === "zh-CN" ? "\u4E2D\u6587" : "\u82F1\u6587"}
168
- \u6570\u636E\u6570\u91CF: ${count}
169
- \u8D28\u91CF\u8981\u6C42: ${quality === "high" ? "\u9AD8\u8D28\u91CF\uFF08\u771F\u5B9E\u4E1A\u52A1\u6570\u636E\uFF09" : quality === "fast" ? "\u5FEB\u901F\u751F\u6210" : "\u5E73\u8861\u8D28\u91CF\u548C\u901F\u5EA6"}
173
+ 类型名称: ${type.name}
174
+ 数据语言: ${locale === "zh-CN" ? "中文" : "英文"}
175
+ 数据数量: ${count}
176
+ 质量要求: ${quality === "high" ? "高质量(真实业务数据)" : quality === "fast" ? "快速生成" : "平衡质量和速度"}
170
177
 
171
- \u7C7B\u578B\u5B9A\u4E49:
178
+ 类型定义:
172
179
  ${properties}
173
180
 
174
- \u8981\u6C42:
175
- 1. \u751F\u6210 ${count} \u6761\u6570\u636E
176
- 2. \u6570\u636E\u8981\u7B26\u5408\u4E1A\u52A1\u903B\u8F91\u548C\u771F\u5B9E\u573A\u666F
177
- 3. \u5B57\u6BB5\u503C\u8981\u5408\u7406\uFF08\u5982\u4EF7\u683C\u4E0D\u80FD\u4E3A\u8D1F\u6570\uFF0C\u5E74\u9F84\u5728\u5408\u7406\u8303\u56F4\uFF09
178
- 4. \u65E5\u671F\u683C\u5F0F\u4F7F\u7528 ISO 8601
179
- 5. \u8FD4\u56DE JSON \u6570\u7EC4\u683C\u5F0F\uFF0C\u4E0D\u8981\u5305\u542B\u4EFB\u4F55\u5176\u4ED6\u6587\u5B57
180
- 6. \u7406\u89E3\u5B57\u6BB5\u8BED\u4E49\uFF0C\u751F\u6210\u771F\u5B9E\u6570\u636E\uFF08\u5982 userName \u751F\u6210\u771F\u5B9E\u59D3\u540D\uFF09
181
+ 要求:
182
+ 1. 生成 ${count} 条数据
183
+ 2. 数据要符合业务逻辑和真实场景
184
+ 3. 字段值要合理(如价格不能为负数,年龄在合理范围)
185
+ 4. 日期格式使用 ISO 8601
186
+ 5. 返回 JSON 数组格式,不要包含任何其他文字
187
+ 6. 理解字段语义,生成真实数据(如 userName 生成真实姓名)
181
188
 
182
- \u793A\u4F8B\u683C\u5F0F:
189
+ 示例格式:
183
190
  [
184
191
  {
185
192
  "id": 1,
186
- "name": "\u5F20\u4E09",
193
+ "name": "张三",
187
194
  ...
188
195
  }
189
196
  ]
190
197
 
191
- \u8BF7\u751F\u6210\u6570\u636E:
198
+ 请生成数据:
192
199
  `.trim();
193
200
  }
194
201
  /**
@@ -224,30 +231,16 @@ ${properties}
224
231
  */
225
232
  async callAI(prompt) {
226
233
  try {
227
- const response = await fetch(`${this.apiUrl}/chat/completions`, {
228
- method: "POST",
229
- headers: {
230
- "Content-Type": "application/json",
231
- Authorization: `Bearer ${this.apiKey}`
232
- },
233
- body: JSON.stringify({
234
- model: this.model,
235
- messages: [
236
- {
237
- role: "user",
238
- content: prompt
239
- }
240
- ],
241
- temperature: 0.7
242
- })
243
- });
244
- if (!response.ok) {
245
- throw new Error(`AI API error: ${response.statusText}`);
246
- }
247
- const data = await response.json();
248
- return data.choices[0].message.content;
234
+ const messages = [
235
+ new SystemMessage(
236
+ "你是一个专业的 Mock 数据生成器,擅长生成真实、合理的测试数据。"
237
+ ),
238
+ new HumanMessage(prompt)
239
+ ];
240
+ const response = await this.llm.invoke(messages);
241
+ return response.content;
249
242
  } catch (error) {
250
- console.error("Failed to call AI API:", error);
243
+ console.error(" AI API 调用失败:", error.message);
251
244
  throw error;
252
245
  }
253
246
  }
@@ -267,8 +260,8 @@ ${properties}
267
260
  const data = JSON.parse(jsonMatch[0]);
268
261
  return isArray ? data : data[0];
269
262
  } catch (error) {
270
- console.error("Failed to parse AI response:", error);
271
- console.error("Response:", response);
263
+ console.error(" 解析 AI 响应失败:", error.message);
264
+ console.error("响应内容:", response);
272
265
  throw error;
273
266
  }
274
267
  }
@@ -426,7 +419,7 @@ var MockServer = class {
426
419
  res.statusCode = 200;
427
420
  res.end(JSON.stringify(data));
428
421
  if (this.options.output?.logs) {
429
- console.log(`[Mock] ${method} ${url} \u2192 ${data ? "OK" : "Empty"}`);
422
+ console.log(`[Mock] ${method} ${url} ${data ? "OK" : "Empty"}`);
430
423
  }
431
424
  } catch (error) {
432
425
  console.error(`[Mock] Error handling ${method} ${url}:`, error);
@@ -439,8 +432,8 @@ var MockServer = class {
439
432
  );
440
433
  }
441
434
  });
442
- console.log("\n\u{1F3AD} Mock \u670D\u52A1\u5668\u5DF2\u542F\u52A8");
443
- console.log(`\u{1F4CD} \u5DF2\u6CE8\u518C ${this.endpoints.length} \u4E2A\u7AEF\u70B9
435
+ console.log("\n🎭 Mock 服务器已启动");
436
+ console.log(`📍 已注册 ${this.endpoints.length} 个端点
444
437
  `);
445
438
  }
446
439
  /**
@@ -568,34 +561,32 @@ function vitePluginAIMockGenerator(options = {}) {
568
561
  enforce: "pre",
569
562
  configResolved(config) {
570
563
  if (output.console) {
571
- console.log("\n\u{1F916} AI Mock Generator \u5DF2\u542F\u52A8");
572
- console.log(`\u{1F4C2} \u5B58\u50A8\u76EE\u5F55: ${storageOptions.dir}`);
573
- console.log(`\u{1F30D} \u6570\u636E\u8BED\u8A00: ${generation.locale}`);
574
- console.log(`\u{1F4CA} \u9ED8\u8BA4\u6570\u91CF: ${generation.count}`);
575
- console.log(`\u{1F511} API Key: ${apiKey ? "\u5DF2\u914D\u7F6E" : "\u672A\u914D\u7F6E"}`);
576
- console.log(
577
- `\u{1F4CD} \u7AEF\u70B9\u6570\u91CF: ${options.endpoints?.length || 0}`
578
- );
564
+ console.log("\n🤖 AI Mock Generator 已启动");
565
+ console.log(`📂 存储目录: ${storageOptions.dir}`);
566
+ console.log(`🌍 数据语言: ${generation.locale}`);
567
+ console.log(`📊 默认数量: ${generation.count}`);
568
+ console.log(`🔑 API Key: ${apiKey ? "已配置" : "未配置"}`);
569
+ console.log(`📍 端点数量: ${options.endpoints?.length || 0}`);
579
570
  }
580
571
  },
581
572
  async buildStart() {
582
573
  if (autoGenerate && options.endpoints) {
583
574
  if (output.console) {
584
- console.log("\n\u{1F504} \u5F00\u59CB\u81EA\u52A8\u751F\u6210 Mock \u6570\u636E...\n");
575
+ console.log("\n🔄 开始自动生成 Mock 数据...\n");
585
576
  }
586
577
  for (const endpoint of options.endpoints) {
587
578
  const existingData = storage.get(endpoint.path, endpoint.method);
588
579
  if (existingData) {
589
580
  if (output.console) {
590
581
  console.log(
591
- `\u23ED\uFE0F \u8DF3\u8FC7 ${endpoint.method} ${endpoint.path} (\u5DF2\u6709\u6570\u636E)`
582
+ `⏭️ 跳过 ${endpoint.method} ${endpoint.path} (已有数据)`
592
583
  );
593
584
  }
594
585
  continue;
595
586
  }
596
587
  try {
597
588
  if (output.console) {
598
- console.log(`\u{1F3B2} \u751F\u6210 ${endpoint.method} ${endpoint.path}...`);
589
+ console.log(`🎲 生成 ${endpoint.method} ${endpoint.path}...`);
599
590
  }
600
591
  const typeDefinition = parseTypeDefinition(endpoint.response);
601
592
  const count = endpoint.count || generation.count || 20;
@@ -615,18 +606,18 @@ function vitePluginAIMockGenerator(options = {}) {
615
606
  });
616
607
  if (output.console) {
617
608
  console.log(
618
- `\u2705 \u5DF2\u751F\u6210 ${count} \u6761\u6570\u636E: ${endpoint.method} ${endpoint.path}`
609
+ `✅ 已生成 ${count} 条数据: ${endpoint.method} ${endpoint.path}`
619
610
  );
620
611
  }
621
612
  } catch (error) {
622
613
  console.error(
623
- `\u274C \u751F\u6210\u5931\u8D25 ${endpoint.method} ${endpoint.path}:`,
614
+ `❌ 生成失败 ${endpoint.method} ${endpoint.path}:`,
624
615
  error.message
625
616
  );
626
617
  }
627
618
  }
628
619
  if (output.console) {
629
- console.log("\n\u2728 Mock \u6570\u636E\u751F\u6210\u5B8C\u6210\n");
620
+ console.log("\n Mock 数据生成完成\n");
630
621
  }
631
622
  }
632
623
  },
@@ -647,7 +638,12 @@ function parseTypeDefinition(typeStr) {
647
638
  isArray
648
639
  };
649
640
  }
650
-
651
- export { MockDataGenerator, MockServer, MockStorage, vitePluginAIMockGenerator };
652
- //# sourceMappingURL=index.mjs.map
641
+ var index_default = vitePluginAIMockGenerator;
642
+ export {
643
+ MockDataGenerator,
644
+ MockServer,
645
+ MockStorage,
646
+ index_default as default,
647
+ vitePluginAIMockGenerator
648
+ };
653
649
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/storage.ts","../src/generator.ts","../src/utils.ts","../src/server.ts","../src/index.ts"],"names":["path"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\r\n * AI Mock Generator - 数据存储\r\n */\r\n\r\nimport fs from 'fs';\r\nimport path from 'path';\r\nimport type { MockDataStore, HttpMethod } from './types';\r\n\r\nexport class MockStorage {\r\n private storageDir: string;\r\n private cache: Map<string, MockDataStore>;\r\n private persist: boolean;\r\n\r\n constructor(options: { dir?: string; persist?: boolean } = {}) {\r\n this.storageDir = options.dir || 'mock-data';\r\n this.persist = options.persist !== false;\r\n this.cache = new Map();\r\n\r\n // 确保存储目录存在\r\n if (this.persist && !fs.existsSync(this.storageDir)) {\r\n fs.mkdirSync(this.storageDir, { recursive: true });\r\n }\r\n\r\n // 加载已有数据\r\n this.load();\r\n }\r\n\r\n /**\r\n * 生成存储 key\r\n */\r\n private getKey(endpoint: string, method: HttpMethod): string {\r\n return `${method}:${endpoint}`;\r\n }\r\n\r\n /**\r\n * 生成文件名\r\n */\r\n private getFileName(endpoint: string, method: HttpMethod): string {\r\n const sanitized = endpoint\r\n .replace(/^\\//, '')\r\n .replace(/\\//g, '_')\r\n .replace(/:/g, '_');\r\n return `${method}_${sanitized}.json`;\r\n }\r\n\r\n /**\r\n * 获取数据\r\n */\r\n get(endpoint: string, method: HttpMethod = 'GET'): any {\r\n const key = this.getKey(endpoint, method);\r\n const store = this.cache.get(key);\r\n return store?.data;\r\n }\r\n\r\n /**\r\n * 设置数据\r\n */\r\n set(\r\n endpoint: string,\r\n method: HttpMethod,\r\n data: any,\r\n metadata?: Partial<MockDataStore['metadata']>\r\n ): void {\r\n const key = this.getKey(endpoint, method);\r\n\r\n const store: MockDataStore = {\r\n endpoint,\r\n method,\r\n data,\r\n metadata: {\r\n count: Array.isArray(data) ? data.length : 1,\r\n generatedAt: new Date().toISOString(),\r\n version: '1.0.0',\r\n type: typeof data,\r\n ...metadata,\r\n },\r\n };\r\n\r\n this.cache.set(key, store);\r\n\r\n // 持久化\r\n if (this.persist) {\r\n this.save(endpoint, method, store);\r\n }\r\n }\r\n\r\n /**\r\n * 删除数据\r\n */\r\n delete(endpoint: string, method: HttpMethod = 'GET'): void {\r\n const key = this.getKey(endpoint, method);\r\n this.cache.delete(key);\r\n\r\n // 删除文件\r\n if (this.persist) {\r\n const fileName = this.getFileName(endpoint, method);\r\n const filePath = path.join(this.storageDir, fileName);\r\n if (fs.existsSync(filePath)) {\r\n fs.unlinkSync(filePath);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 清空所有数据\r\n */\r\n clear(): void {\r\n this.cache.clear();\r\n\r\n // 清空目录\r\n if (this.persist && fs.existsSync(this.storageDir)) {\r\n const files = fs.readdirSync(this.storageDir);\r\n for (const file of files) {\r\n fs.unlinkSync(path.join(this.storageDir, file));\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 获取所有端点\r\n */\r\n getAll(): MockDataStore[] {\r\n return Array.from(this.cache.values());\r\n }\r\n\r\n /**\r\n * 保存到文件\r\n */\r\n private save(\r\n endpoint: string,\r\n method: HttpMethod,\r\n store: MockDataStore\r\n ): void {\r\n const fileName = this.getFileName(endpoint, method);\r\n const filePath = path.join(this.storageDir, fileName);\r\n\r\n fs.writeFileSync(filePath, JSON.stringify(store, null, 2), 'utf-8');\r\n }\r\n\r\n /**\r\n * 从文件加载\r\n */\r\n private load(): void {\r\n if (!this.persist || !fs.existsSync(this.storageDir)) {\r\n return;\r\n }\r\n\r\n const files = fs.readdirSync(this.storageDir);\r\n\r\n for (const file of files) {\r\n if (!file.endsWith('.json')) continue;\r\n\r\n try {\r\n const filePath = path.join(this.storageDir, file);\r\n const content = fs.readFileSync(filePath, 'utf-8');\r\n const store: MockDataStore = JSON.parse(content);\r\n\r\n const key = this.getKey(store.endpoint, store.method);\r\n this.cache.set(key, store);\r\n } catch (error) {\r\n console.warn(`Failed to load mock data from ${file}:`, error);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 导出所有数据\r\n */\r\n export(outputPath: string): void {\r\n const allData = this.getAll();\r\n fs.writeFileSync(outputPath, JSON.stringify(allData, null, 2), 'utf-8');\r\n }\r\n\r\n /**\r\n * 导入数据\r\n */\r\n import(inputPath: string): void {\r\n const content = fs.readFileSync(inputPath, 'utf-8');\r\n const allData: MockDataStore[] = JSON.parse(content);\r\n\r\n for (const store of allData) {\r\n const key = this.getKey(store.endpoint, store.method);\r\n this.cache.set(key, store);\r\n\r\n if (this.persist) {\r\n this.save(store.endpoint, store.method, store);\r\n }\r\n }\r\n }\r\n}\r\n","/**\r\n * AI Mock Generator - 数据生成器\r\n */\r\n\r\nimport type {\r\n TypeDefinition,\r\n GenerationContext,\r\n PropertyDefinition,\r\n} from './types';\r\n\r\nexport class MockDataGenerator {\r\n private apiKey: string;\r\n private apiUrl: string;\r\n private model: string;\r\n\r\n constructor(options: { apiKey: string; apiUrl: string; model: string }) {\r\n this.apiKey = options.apiKey;\r\n this.apiUrl = options.apiUrl;\r\n this.model = options.model;\r\n }\r\n\r\n /**\r\n * 生成 Mock 数据\r\n */\r\n async generate(context: GenerationContext): Promise<any> {\r\n const { type, count, locale, quality } = context;\r\n\r\n // 构建 AI Prompt\r\n const prompt = this.buildPrompt(type, count, locale, quality);\r\n\r\n // 调用 AI API\r\n const response = await this.callAI(prompt);\r\n\r\n // 解析响应\r\n return this.parseResponse(response, type.isArray);\r\n }\r\n\r\n /**\r\n * 构建 AI Prompt\r\n */\r\n private buildPrompt(\r\n type: TypeDefinition,\r\n count: number,\r\n locale: string,\r\n quality: string\r\n ): string {\r\n const properties = type.properties\r\n .map((p) => this.formatProperty(p))\r\n .join('\\n');\r\n\r\n return `\r\n你是一个专业的 Mock 数据生成器。请根据以下类型定义生成真实、合理的测试数据。\r\n\r\n类型名称: ${type.name}\r\n数据语言: ${locale === 'zh-CN' ? '中文' : '英文'}\r\n数据数量: ${count}\r\n质量要求: ${quality === 'high' ? '高质量(真实业务数据)' : quality === 'fast' ? '快速生成' : '平衡质量和速度'}\r\n\r\n类型定义:\r\n${properties}\r\n\r\n要求:\r\n1. 生成 ${count} 条数据\r\n2. 数据要符合业务逻辑和真实场景\r\n3. 字段值要合理(如价格不能为负数,年龄在合理范围)\r\n4. 日期格式使用 ISO 8601\r\n5. 返回 JSON 数组格式,不要包含任何其他文字\r\n6. 理解字段语义,生成真实数据(如 userName 生成真实姓名)\r\n\r\n示例格式:\r\n[\r\n {\r\n \"id\": 1,\r\n \"name\": \"张三\",\r\n ...\r\n }\r\n]\r\n\r\n请生成数据:\r\n`.trim();\r\n }\r\n\r\n /**\r\n * 格式化属性\r\n */\r\n private formatProperty(prop: PropertyDefinition): string {\r\n let line = `- ${prop.name}: ${prop.type}`;\r\n\r\n if (prop.comment) {\r\n line += ` // ${prop.comment}`;\r\n }\r\n\r\n if (prop.constraints) {\r\n const constraints = [];\r\n if (prop.constraints.min !== undefined) {\r\n constraints.push(`min: ${prop.constraints.min}`);\r\n }\r\n if (prop.constraints.max !== undefined) {\r\n constraints.push(`max: ${prop.constraints.max}`);\r\n }\r\n if (prop.constraints.unique) {\r\n constraints.push('unique');\r\n }\r\n if (prop.constraints.enum) {\r\n constraints.push(`enum: [${prop.constraints.enum.join(', ')}]`);\r\n }\r\n if (constraints.length > 0) {\r\n line += ` (${constraints.join(', ')})`;\r\n }\r\n }\r\n\r\n return line;\r\n }\r\n\r\n /**\r\n * 调用 AI API\r\n */\r\n private async callAI(prompt: string): Promise<string> {\r\n try {\r\n const response = await fetch(`${this.apiUrl}/chat/completions`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n Authorization: `Bearer ${this.apiKey}`,\r\n },\r\n body: JSON.stringify({\r\n model: this.model,\r\n messages: [\r\n {\r\n role: 'user',\r\n content: prompt,\r\n },\r\n ],\r\n temperature: 0.7,\r\n }),\r\n });\r\n\r\n if (!response.ok) {\r\n throw new Error(`AI API error: ${response.statusText}`);\r\n }\r\n\r\n const data = await response.json();\r\n return data.choices[0].message.content;\r\n } catch (error: any) {\r\n console.error('Failed to call AI API:', error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * 解析 AI 响应\r\n */\r\n private parseResponse(response: string, isArray: boolean = true): any {\r\n try {\r\n // 移除 markdown 代码块标记\r\n let cleanedResponse = response.trim();\r\n \r\n // 移除开头的 ```json 或 ```\r\n cleanedResponse = cleanedResponse.replace(/^```json\\s*/i, '');\r\n cleanedResponse = cleanedResponse.replace(/^```\\s*/, '');\r\n \r\n // 移除结尾的 ```\r\n cleanedResponse = cleanedResponse.replace(/\\s*```$/, '');\r\n \r\n // 提取 JSON 部分(查找数组或对象)\r\n const jsonMatch = cleanedResponse.match(/(\\[[\\s\\S]*\\]|\\{[\\s\\S]*\\})/);\r\n if (!jsonMatch) {\r\n throw new Error('No JSON array or object found in response');\r\n }\r\n\r\n const data = JSON.parse(jsonMatch[0]);\r\n\r\n return isArray ? data : data[0];\r\n } catch (error: any) {\r\n console.error('Failed to parse AI response:', error);\r\n console.error('Response:', response);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * 生成基础数据(不使用 AI)\r\n */\r\n generateBasic(type: TypeDefinition, count: number): any[] {\r\n const data = [];\r\n\r\n for (let i = 0; i < count; i++) {\r\n const item: any = {};\r\n\r\n for (const prop of type.properties) {\r\n item[prop.name] = this.generateBasicValue(prop, i);\r\n }\r\n\r\n data.push(item);\r\n }\r\n\r\n return data;\r\n }\r\n\r\n /**\r\n * 生成基础值\r\n */\r\n private generateBasicValue(prop: PropertyDefinition, index: number): any {\r\n const { type, constraints } = prop;\r\n\r\n // 处理枚举\r\n if (constraints?.enum) {\r\n return constraints.enum[index % constraints.enum.length];\r\n }\r\n\r\n // 根据类型生成\r\n switch (type) {\r\n case 'number':\r\n const min = constraints?.min ?? 0;\r\n const max = constraints?.max ?? 100;\r\n return Math.floor(Math.random() * (max - min + 1)) + min;\r\n\r\n case 'string':\r\n return `${prop.name}_${index + 1}`;\r\n\r\n case 'boolean':\r\n return Math.random() > 0.5;\r\n\r\n case 'Date':\r\n return new Date().toISOString();\r\n\r\n default:\r\n return null;\r\n }\r\n }\r\n}\r\n","/**\r\n * AI Mock Generator - 工具函数\r\n */\r\n\r\nimport type { HttpMethod, RequestParams } from './types';\r\n\r\n/**\r\n * 延迟函数\r\n */\r\nexport function delay(ms: number | [number, number]): Promise<void> {\r\n const delayTime = Array.isArray(ms)\r\n ? Math.random() * (ms[1] - ms[0]) + ms[0]\r\n : ms;\r\n\r\n return new Promise((resolve) => setTimeout(resolve, delayTime));\r\n}\r\n\r\n/**\r\n * 匹配路径参数\r\n * @example\r\n * matchPathParams('/api/users/:id', '/api/users/123') // { id: '123' }\r\n */\r\nexport function matchPathParams(\r\n pattern: string,\r\n path: string\r\n): Record<string, string> | null {\r\n const patternParts = pattern.split('/');\r\n const pathParts = path.split('/');\r\n\r\n if (patternParts.length !== pathParts.length) {\r\n return null;\r\n }\r\n\r\n const params: Record<string, string> = {};\r\n\r\n for (let i = 0; i < patternParts.length; i++) {\r\n const patternPart = patternParts[i];\r\n const pathPart = pathParts[i];\r\n\r\n if (patternPart.startsWith(':')) {\r\n // 路径参数\r\n const paramName = patternPart.slice(1);\r\n params[paramName] = pathPart;\r\n } else if (patternPart !== pathPart) {\r\n // 不匹配\r\n return null;\r\n }\r\n }\r\n\r\n return params;\r\n}\r\n\r\n/**\r\n * 解析查询参数\r\n */\r\nexport function parseQueryParams(url: string): Record<string, any> {\r\n const queryString = url.split('?')[1];\r\n if (!queryString) return {};\r\n\r\n const params: Record<string, any> = {};\r\n const pairs = queryString.split('&');\r\n\r\n for (const pair of pairs) {\r\n const [key, value] = pair.split('=');\r\n params[decodeURIComponent(key)] = decodeURIComponent(value || '');\r\n }\r\n\r\n return params;\r\n}\r\n\r\n/**\r\n * 生成唯一 ID\r\n */\r\nexport function generateId(): string {\r\n return `${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;\r\n}\r\n\r\n/**\r\n * 深度克隆\r\n */\r\nexport function deepClone<T>(obj: T): T {\r\n return JSON.parse(JSON.stringify(obj));\r\n}\r\n\r\n/**\r\n * 应用过滤\r\n */\r\nexport function applyFilters(data: any[], filters: Record<string, any>): any[] {\r\n if (!filters || Object.keys(filters).length === 0) {\r\n return data;\r\n }\r\n\r\n return data.filter((item) => {\r\n for (const [key, value] of Object.entries(filters)) {\r\n if (item[key] !== value) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n });\r\n}\r\n\r\n/**\r\n * 应用排序\r\n */\r\nexport function applySorting(\r\n data: any[],\r\n sort?: string | { field: string; order: 'asc' | 'desc' }\r\n): any[] {\r\n if (!sort) return data;\r\n\r\n const sortConfig =\r\n typeof sort === 'string'\r\n ? { field: sort, order: 'asc' as const }\r\n : sort;\r\n\r\n return [...data].sort((a, b) => {\r\n const aValue = a[sortConfig.field];\r\n const bValue = b[sortConfig.field];\r\n\r\n if (aValue < bValue) return sortConfig.order === 'asc' ? -1 : 1;\r\n if (aValue > bValue) return sortConfig.order === 'asc' ? 1 : -1;\r\n return 0;\r\n });\r\n}\r\n\r\n/**\r\n * 应用分页\r\n */\r\nexport function applyPagination(\r\n data: any[],\r\n page: number = 1,\r\n pageSize: number = 20\r\n): {\r\n data: any[];\r\n pagination: {\r\n page: number;\r\n pageSize: number;\r\n total: number;\r\n totalPages: number;\r\n };\r\n} {\r\n const total = data.length;\r\n const totalPages = Math.ceil(total / pageSize);\r\n const start = (page - 1) * pageSize;\r\n const end = start + pageSize;\r\n\r\n return {\r\n data: data.slice(start, end),\r\n pagination: {\r\n page,\r\n pageSize,\r\n total,\r\n totalPages,\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * 格式化响应\r\n */\r\nexport function formatResponse(\r\n data: any,\r\n success: boolean = true,\r\n message?: string\r\n) {\r\n return {\r\n code: success ? 200 : 500,\r\n data,\r\n message: message || (success ? 'Success' : 'Error'),\r\n };\r\n}\r\n\r\n/**\r\n * 生成随机种子\r\n */\r\nexport function generateSeed(): number {\r\n return Math.floor(Math.random() * 1000000);\r\n}\r\n\r\n/**\r\n * 设置随机种子\r\n */\r\nexport function setSeed(seed: number): void {\r\n // 简单的伪随机数生成器\r\n let currentSeed = seed;\r\n Math.random = () => {\r\n currentSeed = (currentSeed * 9301 + 49297) % 233280;\r\n return currentSeed / 233280;\r\n };\r\n}\r\n","/**\r\n * AI Mock Generator - Mock 服务器\r\n */\r\n\r\nimport type { ViteDevServer } from 'vite';\r\nimport type {\r\n EndpointConfig,\r\n HttpMethod,\r\n MockGeneratorOptions,\r\n} from './types';\r\nimport { MockStorage } from './storage';\r\nimport {\r\n delay,\r\n matchPathParams,\r\n parseQueryParams,\r\n applyFilters,\r\n applySorting,\r\n applyPagination,\r\n formatResponse,\r\n} from './utils';\r\n\r\nexport class MockServer {\r\n private storage: MockStorage;\r\n private endpoints: EndpointConfig[];\r\n private options: MockGeneratorOptions;\r\n\r\n constructor(storage: MockStorage, options: MockGeneratorOptions) {\r\n this.storage = storage;\r\n this.endpoints = options.endpoints || [];\r\n this.options = options;\r\n }\r\n\r\n /**\r\n * 配置服务器中间件\r\n */\r\n configureServer(server: ViteDevServer): void {\r\n server.middlewares.use(async (req, res, next) => {\r\n const url = req.url || '';\r\n const method = req.method as HttpMethod;\r\n\r\n // 检查是否匹配 Mock 端点\r\n const endpoint = this.matchEndpoint(url, method);\r\n\r\n if (!endpoint) {\r\n return next();\r\n }\r\n\r\n try {\r\n // 解析请求参数\r\n const params = this.parseRequest(req, url);\r\n\r\n // 获取 Mock 数据\r\n const data = await this.getMockData(endpoint, params);\r\n\r\n // 模拟延迟\r\n if (this.options.server?.delay) {\r\n await delay(this.options.server.delay);\r\n }\r\n\r\n // 设置响应头\r\n res.setHeader('Content-Type', 'application/json');\r\n if (this.options.server?.cors) {\r\n res.setHeader('Access-Control-Allow-Origin', '*');\r\n res.setHeader('Access-Control-Allow-Methods', '*');\r\n res.setHeader('Access-Control-Allow-Headers', '*');\r\n }\r\n\r\n // 返回响应\r\n res.statusCode = 200;\r\n res.end(JSON.stringify(data));\r\n\r\n // 日志\r\n if (this.options.output?.logs) {\r\n console.log(`[Mock] ${method} ${url} → ${data ? 'OK' : 'Empty'}`);\r\n }\r\n } catch (error: any) {\r\n console.error(`[Mock] Error handling ${method} ${url}:`, error);\r\n res.statusCode = 500;\r\n res.end(\r\n JSON.stringify({\r\n code: 500,\r\n message: error.message,\r\n })\r\n );\r\n }\r\n });\r\n\r\n console.log('\\n🎭 Mock 服务器已启动');\r\n console.log(`📍 已注册 ${this.endpoints.length} 个端点\\n`);\r\n }\r\n\r\n /**\r\n * 匹配端点\r\n */\r\n private matchEndpoint(\r\n url: string,\r\n method: HttpMethod\r\n ): EndpointConfig | null {\r\n // 移除查询参数\r\n const path = url.split('?')[0];\r\n\r\n // 移除前缀\r\n const prefix = this.options.server?.prefix || '';\r\n const cleanPath = prefix ? path.replace(new RegExp(`^${prefix}`), '') : path;\r\n\r\n for (const endpoint of this.endpoints) {\r\n // 检查是否禁用\r\n if (endpoint.enabled === false) continue;\r\n\r\n // 检查方法\r\n if (endpoint.method !== method) continue;\r\n\r\n // 精确匹配\r\n if (endpoint.path === cleanPath) {\r\n return endpoint;\r\n }\r\n\r\n // 路径参数匹配\r\n if (matchPathParams(endpoint.path, cleanPath)) {\r\n return endpoint;\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n /**\r\n * 解析请求\r\n */\r\n private parseRequest(req: any, url: string): any {\r\n const query = parseQueryParams(url);\r\n const path = url.split('?')[0];\r\n\r\n // 查找匹配的端点以提取路径参数\r\n const endpoint = this.matchEndpoint(path, req.method);\r\n const pathParams = endpoint\r\n ? matchPathParams(endpoint.path, path.split('?')[0])\r\n : null;\r\n\r\n return {\r\n query,\r\n params: pathParams || {},\r\n body: req.body,\r\n headers: req.headers,\r\n };\r\n }\r\n\r\n /**\r\n * 获取 Mock 数据\r\n */\r\n private async getMockData(\r\n endpoint: EndpointConfig,\r\n params: any\r\n ): Promise<any> {\r\n // 从存储获取数据\r\n let data = this.storage.get(endpoint.path, endpoint.method);\r\n\r\n if (!data) {\r\n console.warn(\r\n `[Mock] No data found for ${endpoint.method} ${endpoint.path}`\r\n );\r\n return formatResponse([], false, 'No mock data available');\r\n }\r\n\r\n // 如果是数组,应用过滤、排序、分页\r\n if (Array.isArray(data)) {\r\n // 过滤\r\n if (params.query.filter) {\r\n data = applyFilters(data, JSON.parse(params.query.filter));\r\n }\r\n\r\n // 排序\r\n if (params.query.sort) {\r\n data = applySorting(data, params.query.sort);\r\n }\r\n\r\n // 分页\r\n if (params.query.page || params.query.pageSize) {\r\n const page = parseInt(params.query.page) || 1;\r\n const pageSize = parseInt(params.query.pageSize) || 20;\r\n const result = applyPagination(data, page, pageSize);\r\n\r\n return formatResponse({\r\n list: result.data,\r\n pagination: result.pagination,\r\n });\r\n }\r\n }\r\n\r\n // 应用自定义处理\r\n if (endpoint.custom) {\r\n data = await endpoint.custom(data, params);\r\n }\r\n\r\n // 格式化响应\r\n return formatResponse(data);\r\n }\r\n\r\n /**\r\n * 添加端点\r\n */\r\n addEndpoint(endpoint: EndpointConfig): void {\r\n this.endpoints.push(endpoint);\r\n }\r\n\r\n /**\r\n * 移除端点\r\n */\r\n removeEndpoint(path: string, method: HttpMethod): void {\r\n this.endpoints = this.endpoints.filter(\r\n (e) => !(e.path === path && e.method === method)\r\n );\r\n }\r\n\r\n /**\r\n * 获取所有端点\r\n */\r\n getEndpoints(): EndpointConfig[] {\r\n return this.endpoints;\r\n }\r\n}\r\n","/**\r\n * AI Mock Generator - Vite 插件入口\r\n */\r\n\r\nimport type { Plugin } from 'vite';\r\nimport type { MockGeneratorOptions, TypeDefinition } from './types';\r\nimport { MockStorage } from './storage';\r\nimport { MockDataGenerator } from './generator';\r\nimport { MockServer } from './server';\r\n\r\nexport function vitePluginAIMockGenerator(\r\n options: MockGeneratorOptions = {}\r\n): Plugin {\r\n const {\r\n apiKey = process.env.OPENAI_API_KEY || '',\r\n apiUrl = process.env.OPENAI_API_URL || 'https://api.openai.com/v1',\r\n model = process.env.OPENAI_MODEL || 'gpt-4',\r\n enabled = true,\r\n autoGenerate = false,\r\n generation = {\r\n locale: 'zh-CN',\r\n count: 20,\r\n quality: 'balanced',\r\n },\r\n storage: storageOptions = {\r\n dir: 'mock-data',\r\n persist: true,\r\n cache: true,\r\n },\r\n output = {\r\n console: true,\r\n logs: false,\r\n },\r\n } = options;\r\n\r\n // 如果未启用,返回空插件\r\n if (!enabled) {\r\n return {\r\n name: 'vite-plugin-ai-mock-generator',\r\n };\r\n }\r\n\r\n // 初始化组件\r\n const storage = new MockStorage(storageOptions);\r\n const generator = new MockDataGenerator({ apiKey, apiUrl, model });\r\n const server = new MockServer(storage, options);\r\n\r\n return {\r\n name: 'vite-plugin-ai-mock-generator',\r\n enforce: 'pre',\r\n\r\n configResolved(config) {\r\n if (output.console) {\r\n console.log('\\n🤖 AI Mock Generator 已启动');\r\n console.log(`📂 存储目录: ${storageOptions.dir}`);\r\n console.log(`🌍 数据语言: ${generation.locale}`);\r\n console.log(`📊 默认数量: ${generation.count}`);\r\n console.log(`🔑 API Key: ${apiKey ? '已配置' : '未配置'}`);\r\n console.log(\r\n `📍 端点数量: ${options.endpoints?.length || 0}`\r\n );\r\n }\r\n },\r\n\r\n async buildStart() {\r\n // 如果启用自动生成\r\n if (autoGenerate && options.endpoints) {\r\n if (output.console) {\r\n console.log('\\n🔄 开始自动生成 Mock 数据...\\n');\r\n }\r\n\r\n for (const endpoint of options.endpoints) {\r\n // 检查是否已有数据\r\n const existingData = storage.get(endpoint.path, endpoint.method);\r\n if (existingData) {\r\n if (output.console) {\r\n console.log(\r\n `⏭️ 跳过 ${endpoint.method} ${endpoint.path} (已有数据)`\r\n );\r\n }\r\n continue;\r\n }\r\n\r\n try {\r\n if (output.console) {\r\n console.log(`🎲 生成 ${endpoint.method} ${endpoint.path}...`);\r\n }\r\n\r\n // 解析类型定义\r\n const typeDefinition = parseTypeDefinition(endpoint.response);\r\n\r\n // 生成数据\r\n const count = endpoint.count || generation.count || 20;\r\n let data;\r\n \r\n // 根据质量设置选择生成方式\r\n if (generation.quality === 'fast') {\r\n // 使用基础生成器(不需要 AI)\r\n data = generator.generateBasic(typeDefinition, count);\r\n } else {\r\n // 使用 AI 生成\r\n data = await generator.generate({\r\n type: typeDefinition,\r\n count,\r\n locale: generation.locale || 'zh-CN',\r\n quality: generation.quality || 'balanced',\r\n });\r\n }\r\n\r\n // 存储数据\r\n storage.set(endpoint.path, endpoint.method, data, {\r\n type: endpoint.response as string,\r\n });\r\n\r\n if (output.console) {\r\n console.log(\r\n `✅ 已生成 ${count} 条数据: ${endpoint.method} ${endpoint.path}`\r\n );\r\n }\r\n } catch (error: any) {\r\n console.error(\r\n `❌ 生成失败 ${endpoint.method} ${endpoint.path}:`,\r\n error.message\r\n );\r\n }\r\n }\r\n\r\n if (output.console) {\r\n console.log('\\n✨ Mock 数据生成完成\\n');\r\n }\r\n }\r\n },\r\n\r\n configureServer(viteServer) {\r\n // 配置 Mock 服务器中间件\r\n server.configureServer(viteServer);\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * 解析类型定义\r\n * 简化版本,实际应该使用 TypeScript Compiler API\r\n */\r\nfunction parseTypeDefinition(typeStr: string | TypeDefinition): TypeDefinition {\r\n if (typeof typeStr === 'object') {\r\n return typeStr;\r\n }\r\n\r\n // 简单解析(实际应该更复杂)\r\n const isArray = typeStr.endsWith('[]');\r\n const typeName = isArray ? typeStr.slice(0, -2) : typeStr;\r\n\r\n // 返回基础类型定义\r\n return {\r\n name: typeName,\r\n properties: [],\r\n isArray,\r\n };\r\n}\r\n\r\n// 导出类型\r\nexport type { MockGeneratorOptions, EndpointConfig } from './types';\r\nexport { MockStorage } from './storage';\r\nexport { MockDataGenerator } from './generator';\r\nexport { MockServer } from './server';\r\n"]}
1
+ {"version":3,"sources":["../src/storage.ts","../src/generator.ts","../src/utils.ts","../src/server.ts","../src/index.ts"],"sourcesContent":["/**\r\n * AI Mock Generator - 数据存储\r\n */\r\n\r\nimport fs from 'fs';\r\nimport path from 'path';\r\nimport type { MockDataStore, HttpMethod } from './types';\r\n\r\nexport class MockStorage {\r\n private storageDir: string;\r\n private cache: Map<string, MockDataStore>;\r\n private persist: boolean;\r\n\r\n constructor(options: { dir?: string; persist?: boolean } = {}) {\r\n this.storageDir = options.dir || 'mock-data';\r\n this.persist = options.persist !== false;\r\n this.cache = new Map();\r\n\r\n // 确保存储目录存在\r\n if (this.persist && !fs.existsSync(this.storageDir)) {\r\n fs.mkdirSync(this.storageDir, { recursive: true });\r\n }\r\n\r\n // 加载已有数据\r\n this.load();\r\n }\r\n\r\n /**\r\n * 生成存储 key\r\n */\r\n private getKey(endpoint: string, method: HttpMethod): string {\r\n return `${method}:${endpoint}`;\r\n }\r\n\r\n /**\r\n * 生成文件名\r\n */\r\n private getFileName(endpoint: string, method: HttpMethod): string {\r\n const sanitized = endpoint\r\n .replace(/^\\//, '')\r\n .replace(/\\//g, '_')\r\n .replace(/:/g, '_');\r\n return `${method}_${sanitized}.json`;\r\n }\r\n\r\n /**\r\n * 获取数据\r\n */\r\n get(endpoint: string, method: HttpMethod = 'GET'): any {\r\n const key = this.getKey(endpoint, method);\r\n const store = this.cache.get(key);\r\n return store?.data;\r\n }\r\n\r\n /**\r\n * 设置数据\r\n */\r\n set(\r\n endpoint: string,\r\n method: HttpMethod,\r\n data: any,\r\n metadata?: Partial<MockDataStore['metadata']>\r\n ): void {\r\n const key = this.getKey(endpoint, method);\r\n\r\n const store: MockDataStore = {\r\n endpoint,\r\n method,\r\n data,\r\n metadata: {\r\n count: Array.isArray(data) ? data.length : 1,\r\n generatedAt: new Date().toISOString(),\r\n version: '1.0.0',\r\n type: typeof data,\r\n ...metadata,\r\n },\r\n };\r\n\r\n this.cache.set(key, store);\r\n\r\n // 持久化\r\n if (this.persist) {\r\n this.save(endpoint, method, store);\r\n }\r\n }\r\n\r\n /**\r\n * 删除数据\r\n */\r\n delete(endpoint: string, method: HttpMethod = 'GET'): void {\r\n const key = this.getKey(endpoint, method);\r\n this.cache.delete(key);\r\n\r\n // 删除文件\r\n if (this.persist) {\r\n const fileName = this.getFileName(endpoint, method);\r\n const filePath = path.join(this.storageDir, fileName);\r\n if (fs.existsSync(filePath)) {\r\n fs.unlinkSync(filePath);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 清空所有数据\r\n */\r\n clear(): void {\r\n this.cache.clear();\r\n\r\n // 清空目录\r\n if (this.persist && fs.existsSync(this.storageDir)) {\r\n const files = fs.readdirSync(this.storageDir);\r\n for (const file of files) {\r\n fs.unlinkSync(path.join(this.storageDir, file));\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 获取所有端点\r\n */\r\n getAll(): MockDataStore[] {\r\n return Array.from(this.cache.values());\r\n }\r\n\r\n /**\r\n * 保存到文件\r\n */\r\n private save(\r\n endpoint: string,\r\n method: HttpMethod,\r\n store: MockDataStore\r\n ): void {\r\n const fileName = this.getFileName(endpoint, method);\r\n const filePath = path.join(this.storageDir, fileName);\r\n\r\n fs.writeFileSync(filePath, JSON.stringify(store, null, 2), 'utf-8');\r\n }\r\n\r\n /**\r\n * 从文件加载\r\n */\r\n private load(): void {\r\n if (!this.persist || !fs.existsSync(this.storageDir)) {\r\n return;\r\n }\r\n\r\n const files = fs.readdirSync(this.storageDir);\r\n\r\n for (const file of files) {\r\n if (!file.endsWith('.json')) continue;\r\n\r\n try {\r\n const filePath = path.join(this.storageDir, file);\r\n const content = fs.readFileSync(filePath, 'utf-8');\r\n const store: MockDataStore = JSON.parse(content);\r\n\r\n const key = this.getKey(store.endpoint, store.method);\r\n this.cache.set(key, store);\r\n } catch (error) {\r\n console.warn(`Failed to load mock data from ${file}:`, error);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 导出所有数据\r\n */\r\n export(outputPath: string): void {\r\n const allData = this.getAll();\r\n fs.writeFileSync(outputPath, JSON.stringify(allData, null, 2), 'utf-8');\r\n }\r\n\r\n /**\r\n * 导入数据\r\n */\r\n import(inputPath: string): void {\r\n const content = fs.readFileSync(inputPath, 'utf-8');\r\n const allData: MockDataStore[] = JSON.parse(content);\r\n\r\n for (const store of allData) {\r\n const key = this.getKey(store.endpoint, store.method);\r\n this.cache.set(key, store);\r\n\r\n if (this.persist) {\r\n this.save(store.endpoint, store.method, store);\r\n }\r\n }\r\n }\r\n}\r\n","/**\r\n * AI Mock Generator - 数据生成器\r\n */\r\n\r\nimport { ChatOpenAI } from \"@langchain/openai\";\r\nimport { HumanMessage, SystemMessage } from \"@langchain/core/messages\";\r\nimport type {\r\n TypeDefinition,\r\n GenerationContext,\r\n PropertyDefinition,\r\n} from \"./types\";\r\n\r\nexport class MockDataGenerator {\r\n private llm: ChatOpenAI;\r\n\r\n constructor(options: { apiKey: string; apiUrl: string; model: string }) {\r\n this.llm = new ChatOpenAI({\r\n openAIApiKey: options.apiKey,\r\n configuration: {\r\n baseURL: options.apiUrl,\r\n },\r\n modelName: options.model,\r\n temperature: 0.7,\r\n maxTokens: 4000,\r\n });\r\n }\r\n\r\n /**\r\n * 生成 Mock 数据\r\n */\r\n async generate(context: GenerationContext): Promise<any> {\r\n const { type, count, locale, quality } = context;\r\n\r\n // 构建 AI Prompt\r\n const prompt = this.buildPrompt(type, count, locale, quality);\r\n\r\n // 调用 AI API\r\n const response = await this.callAI(prompt);\r\n\r\n // 解析响应\r\n return this.parseResponse(response, type.isArray);\r\n }\r\n\r\n /**\r\n * 构建 AI Prompt\r\n */\r\n private buildPrompt(\r\n type: TypeDefinition,\r\n count: number,\r\n locale: string,\r\n quality: string,\r\n ): string {\r\n const properties = type.properties\r\n .map((p) => this.formatProperty(p))\r\n .join(\"\\n\");\r\n\r\n return `\r\n你是一个专业的 Mock 数据生成器。请根据以下类型定义生成真实、合理的测试数据。\r\n\r\n类型名称: ${type.name}\r\n数据语言: ${locale === \"zh-CN\" ? \"中文\" : \"英文\"}\r\n数据数量: ${count}\r\n质量要求: ${\r\n quality === \"high\"\r\n ? \"高质量(真实业务数据)\"\r\n : quality === \"fast\"\r\n ? \"快速生成\"\r\n : \"平衡质量和速度\"\r\n }\r\n\r\n类型定义:\r\n${properties}\r\n\r\n要求:\r\n1. 生成 ${count} 条数据\r\n2. 数据要符合业务逻辑和真实场景\r\n3. 字段值要合理(如价格不能为负数,年龄在合理范围)\r\n4. 日期格式使用 ISO 8601\r\n5. 返回 JSON 数组格式,不要包含任何其他文字\r\n6. 理解字段语义,生成真实数据(如 userName 生成真实姓名)\r\n\r\n示例格式:\r\n[\r\n {\r\n \"id\": 1,\r\n \"name\": \"张三\",\r\n ...\r\n }\r\n]\r\n\r\n请生成数据:\r\n`.trim();\r\n }\r\n\r\n /**\r\n * 格式化属性\r\n */\r\n private formatProperty(prop: PropertyDefinition): string {\r\n let line = `- ${prop.name}: ${prop.type}`;\r\n\r\n if (prop.comment) {\r\n line += ` // ${prop.comment}`;\r\n }\r\n\r\n if (prop.constraints) {\r\n const constraints = [];\r\n if (prop.constraints.min !== undefined) {\r\n constraints.push(`min: ${prop.constraints.min}`);\r\n }\r\n if (prop.constraints.max !== undefined) {\r\n constraints.push(`max: ${prop.constraints.max}`);\r\n }\r\n if (prop.constraints.unique) {\r\n constraints.push(\"unique\");\r\n }\r\n if (prop.constraints.enum) {\r\n constraints.push(`enum: [${prop.constraints.enum.join(\", \")}]`);\r\n }\r\n if (constraints.length > 0) {\r\n line += ` (${constraints.join(\", \")})`;\r\n }\r\n }\r\n\r\n return line;\r\n }\r\n\r\n /**\r\n * 调用 AI API\r\n */\r\n private async callAI(prompt: string): Promise<string> {\r\n try {\r\n const messages = [\r\n new SystemMessage(\r\n \"你是一个专业的 Mock 数据生成器,擅长生成真实、合理的测试数据。\",\r\n ),\r\n new HumanMessage(prompt),\r\n ];\r\n\r\n const response = await this.llm.invoke(messages);\r\n return response.content as string;\r\n } catch (error: any) {\r\n console.error(\"❌ AI API 调用失败:\", error.message);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * 解析 AI 响应\r\n */\r\n private parseResponse(response: string, isArray: boolean = true): any {\r\n try {\r\n // 移除 markdown 代码块标记\r\n let cleanedResponse = response.trim();\r\n\r\n // 移除开头的 ```json 或 ```\r\n cleanedResponse = cleanedResponse.replace(/^```json\\s*/i, \"\");\r\n cleanedResponse = cleanedResponse.replace(/^```\\s*/, \"\");\r\n\r\n // 移除结尾的 ```\r\n cleanedResponse = cleanedResponse.replace(/\\s*```$/, \"\");\r\n\r\n // 提取 JSON 部分(查找数组或对象)\r\n const jsonMatch = cleanedResponse.match(/(\\[[\\s\\S]*\\]|\\{[\\s\\S]*\\})/);\r\n if (!jsonMatch) {\r\n throw new Error(\"No JSON array or object found in response\");\r\n }\r\n\r\n const data = JSON.parse(jsonMatch[0]);\r\n\r\n return isArray ? data : data[0];\r\n } catch (error: any) {\r\n console.error(\"❌ 解析 AI 响应失败:\", error.message);\r\n console.error(\"响应内容:\", response);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * 生成基础数据(不使用 AI)\r\n */\r\n generateBasic(type: TypeDefinition, count: number): any[] {\r\n const data = [];\r\n\r\n for (let i = 0; i < count; i++) {\r\n const item: any = {};\r\n\r\n for (const prop of type.properties) {\r\n item[prop.name] = this.generateBasicValue(prop, i);\r\n }\r\n\r\n data.push(item);\r\n }\r\n\r\n return data;\r\n }\r\n\r\n /**\r\n * 生成基础值\r\n */\r\n private generateBasicValue(prop: PropertyDefinition, index: number): any {\r\n const { type, constraints } = prop;\r\n\r\n // 处理枚举\r\n if (constraints?.enum) {\r\n return constraints.enum[index % constraints.enum.length];\r\n }\r\n\r\n // 根据类型生成\r\n switch (type) {\r\n case \"number\":\r\n const min = constraints?.min ?? 0;\r\n const max = constraints?.max ?? 100;\r\n return Math.floor(Math.random() * (max - min + 1)) + min;\r\n\r\n case \"string\":\r\n return `${prop.name}_${index + 1}`;\r\n\r\n case \"boolean\":\r\n return Math.random() > 0.5;\r\n\r\n case \"Date\":\r\n return new Date().toISOString();\r\n\r\n default:\r\n return null;\r\n }\r\n }\r\n}\r\n","/**\r\n * AI Mock Generator - 工具函数\r\n */\r\n\r\nimport type { HttpMethod, RequestParams } from './types';\r\n\r\n/**\r\n * 延迟函数\r\n */\r\nexport function delay(ms: number | [number, number]): Promise<void> {\r\n const delayTime = Array.isArray(ms)\r\n ? Math.random() * (ms[1] - ms[0]) + ms[0]\r\n : ms;\r\n\r\n return new Promise((resolve) => setTimeout(resolve, delayTime));\r\n}\r\n\r\n/**\r\n * 匹配路径参数\r\n * @example\r\n * matchPathParams('/api/users/:id', '/api/users/123') // { id: '123' }\r\n */\r\nexport function matchPathParams(\r\n pattern: string,\r\n path: string\r\n): Record<string, string> | null {\r\n const patternParts = pattern.split('/');\r\n const pathParts = path.split('/');\r\n\r\n if (patternParts.length !== pathParts.length) {\r\n return null;\r\n }\r\n\r\n const params: Record<string, string> = {};\r\n\r\n for (let i = 0; i < patternParts.length; i++) {\r\n const patternPart = patternParts[i];\r\n const pathPart = pathParts[i];\r\n\r\n if (patternPart.startsWith(':')) {\r\n // 路径参数\r\n const paramName = patternPart.slice(1);\r\n params[paramName] = pathPart;\r\n } else if (patternPart !== pathPart) {\r\n // 不匹配\r\n return null;\r\n }\r\n }\r\n\r\n return params;\r\n}\r\n\r\n/**\r\n * 解析查询参数\r\n */\r\nexport function parseQueryParams(url: string): Record<string, any> {\r\n const queryString = url.split('?')[1];\r\n if (!queryString) return {};\r\n\r\n const params: Record<string, any> = {};\r\n const pairs = queryString.split('&');\r\n\r\n for (const pair of pairs) {\r\n const [key, value] = pair.split('=');\r\n params[decodeURIComponent(key)] = decodeURIComponent(value || '');\r\n }\r\n\r\n return params;\r\n}\r\n\r\n/**\r\n * 生成唯一 ID\r\n */\r\nexport function generateId(): string {\r\n return `${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;\r\n}\r\n\r\n/**\r\n * 深度克隆\r\n */\r\nexport function deepClone<T>(obj: T): T {\r\n return JSON.parse(JSON.stringify(obj));\r\n}\r\n\r\n/**\r\n * 应用过滤\r\n */\r\nexport function applyFilters(data: any[], filters: Record<string, any>): any[] {\r\n if (!filters || Object.keys(filters).length === 0) {\r\n return data;\r\n }\r\n\r\n return data.filter((item) => {\r\n for (const [key, value] of Object.entries(filters)) {\r\n if (item[key] !== value) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n });\r\n}\r\n\r\n/**\r\n * 应用排序\r\n */\r\nexport function applySorting(\r\n data: any[],\r\n sort?: string | { field: string; order: 'asc' | 'desc' }\r\n): any[] {\r\n if (!sort) return data;\r\n\r\n const sortConfig =\r\n typeof sort === 'string'\r\n ? { field: sort, order: 'asc' as const }\r\n : sort;\r\n\r\n return [...data].sort((a, b) => {\r\n const aValue = a[sortConfig.field];\r\n const bValue = b[sortConfig.field];\r\n\r\n if (aValue < bValue) return sortConfig.order === 'asc' ? -1 : 1;\r\n if (aValue > bValue) return sortConfig.order === 'asc' ? 1 : -1;\r\n return 0;\r\n });\r\n}\r\n\r\n/**\r\n * 应用分页\r\n */\r\nexport function applyPagination(\r\n data: any[],\r\n page: number = 1,\r\n pageSize: number = 20\r\n): {\r\n data: any[];\r\n pagination: {\r\n page: number;\r\n pageSize: number;\r\n total: number;\r\n totalPages: number;\r\n };\r\n} {\r\n const total = data.length;\r\n const totalPages = Math.ceil(total / pageSize);\r\n const start = (page - 1) * pageSize;\r\n const end = start + pageSize;\r\n\r\n return {\r\n data: data.slice(start, end),\r\n pagination: {\r\n page,\r\n pageSize,\r\n total,\r\n totalPages,\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * 格式化响应\r\n */\r\nexport function formatResponse(\r\n data: any,\r\n success: boolean = true,\r\n message?: string\r\n) {\r\n return {\r\n code: success ? 200 : 500,\r\n data,\r\n message: message || (success ? 'Success' : 'Error'),\r\n };\r\n}\r\n\r\n/**\r\n * 生成随机种子\r\n */\r\nexport function generateSeed(): number {\r\n return Math.floor(Math.random() * 1000000);\r\n}\r\n\r\n/**\r\n * 设置随机种子\r\n */\r\nexport function setSeed(seed: number): void {\r\n // 简单的伪随机数生成器\r\n let currentSeed = seed;\r\n Math.random = () => {\r\n currentSeed = (currentSeed * 9301 + 49297) % 233280;\r\n return currentSeed / 233280;\r\n };\r\n}\r\n","/**\r\n * AI Mock Generator - Mock 服务器\r\n */\r\n\r\nimport type { ViteDevServer } from 'vite';\r\nimport type {\r\n EndpointConfig,\r\n HttpMethod,\r\n MockGeneratorOptions,\r\n} from './types';\r\nimport { MockStorage } from './storage';\r\nimport {\r\n delay,\r\n matchPathParams,\r\n parseQueryParams,\r\n applyFilters,\r\n applySorting,\r\n applyPagination,\r\n formatResponse,\r\n} from './utils';\r\n\r\nexport class MockServer {\r\n private storage: MockStorage;\r\n private endpoints: EndpointConfig[];\r\n private options: MockGeneratorOptions;\r\n\r\n constructor(storage: MockStorage, options: MockGeneratorOptions) {\r\n this.storage = storage;\r\n this.endpoints = options.endpoints || [];\r\n this.options = options;\r\n }\r\n\r\n /**\r\n * 配置服务器中间件\r\n */\r\n configureServer(server: ViteDevServer): void {\r\n server.middlewares.use(async (req, res, next) => {\r\n const url = req.url || '';\r\n const method = req.method as HttpMethod;\r\n\r\n // 检查是否匹配 Mock 端点\r\n const endpoint = this.matchEndpoint(url, method);\r\n\r\n if (!endpoint) {\r\n return next();\r\n }\r\n\r\n try {\r\n // 解析请求参数\r\n const params = this.parseRequest(req, url);\r\n\r\n // 获取 Mock 数据\r\n const data = await this.getMockData(endpoint, params);\r\n\r\n // 模拟延迟\r\n if (this.options.server?.delay) {\r\n await delay(this.options.server.delay);\r\n }\r\n\r\n // 设置响应头\r\n res.setHeader('Content-Type', 'application/json');\r\n if (this.options.server?.cors) {\r\n res.setHeader('Access-Control-Allow-Origin', '*');\r\n res.setHeader('Access-Control-Allow-Methods', '*');\r\n res.setHeader('Access-Control-Allow-Headers', '*');\r\n }\r\n\r\n // 返回响应\r\n res.statusCode = 200;\r\n res.end(JSON.stringify(data));\r\n\r\n // 日志\r\n if (this.options.output?.logs) {\r\n console.log(`[Mock] ${method} ${url} → ${data ? 'OK' : 'Empty'}`);\r\n }\r\n } catch (error: any) {\r\n console.error(`[Mock] Error handling ${method} ${url}:`, error);\r\n res.statusCode = 500;\r\n res.end(\r\n JSON.stringify({\r\n code: 500,\r\n message: error.message,\r\n })\r\n );\r\n }\r\n });\r\n\r\n console.log('\\n🎭 Mock 服务器已启动');\r\n console.log(`📍 已注册 ${this.endpoints.length} 个端点\\n`);\r\n }\r\n\r\n /**\r\n * 匹配端点\r\n */\r\n private matchEndpoint(\r\n url: string,\r\n method: HttpMethod\r\n ): EndpointConfig | null {\r\n // 移除查询参数\r\n const path = url.split('?')[0];\r\n\r\n // 移除前缀\r\n const prefix = this.options.server?.prefix || '';\r\n const cleanPath = prefix ? path.replace(new RegExp(`^${prefix}`), '') : path;\r\n\r\n for (const endpoint of this.endpoints) {\r\n // 检查是否禁用\r\n if (endpoint.enabled === false) continue;\r\n\r\n // 检查方法\r\n if (endpoint.method !== method) continue;\r\n\r\n // 精确匹配\r\n if (endpoint.path === cleanPath) {\r\n return endpoint;\r\n }\r\n\r\n // 路径参数匹配\r\n if (matchPathParams(endpoint.path, cleanPath)) {\r\n return endpoint;\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n /**\r\n * 解析请求\r\n */\r\n private parseRequest(req: any, url: string): any {\r\n const query = parseQueryParams(url);\r\n const path = url.split('?')[0];\r\n\r\n // 查找匹配的端点以提取路径参数\r\n const endpoint = this.matchEndpoint(path, req.method);\r\n const pathParams = endpoint\r\n ? matchPathParams(endpoint.path, path.split('?')[0])\r\n : null;\r\n\r\n return {\r\n query,\r\n params: pathParams || {},\r\n body: req.body,\r\n headers: req.headers,\r\n };\r\n }\r\n\r\n /**\r\n * 获取 Mock 数据\r\n */\r\n private async getMockData(\r\n endpoint: EndpointConfig,\r\n params: any\r\n ): Promise<any> {\r\n // 从存储获取数据\r\n let data = this.storage.get(endpoint.path, endpoint.method);\r\n\r\n if (!data) {\r\n console.warn(\r\n `[Mock] No data found for ${endpoint.method} ${endpoint.path}`\r\n );\r\n return formatResponse([], false, 'No mock data available');\r\n }\r\n\r\n // 如果是数组,应用过滤、排序、分页\r\n if (Array.isArray(data)) {\r\n // 过滤\r\n if (params.query.filter) {\r\n data = applyFilters(data, JSON.parse(params.query.filter));\r\n }\r\n\r\n // 排序\r\n if (params.query.sort) {\r\n data = applySorting(data, params.query.sort);\r\n }\r\n\r\n // 分页\r\n if (params.query.page || params.query.pageSize) {\r\n const page = parseInt(params.query.page) || 1;\r\n const pageSize = parseInt(params.query.pageSize) || 20;\r\n const result = applyPagination(data, page, pageSize);\r\n\r\n return formatResponse({\r\n list: result.data,\r\n pagination: result.pagination,\r\n });\r\n }\r\n }\r\n\r\n // 应用自定义处理\r\n if (endpoint.custom) {\r\n data = await endpoint.custom(data, params);\r\n }\r\n\r\n // 格式化响应\r\n return formatResponse(data);\r\n }\r\n\r\n /**\r\n * 添加端点\r\n */\r\n addEndpoint(endpoint: EndpointConfig): void {\r\n this.endpoints.push(endpoint);\r\n }\r\n\r\n /**\r\n * 移除端点\r\n */\r\n removeEndpoint(path: string, method: HttpMethod): void {\r\n this.endpoints = this.endpoints.filter(\r\n (e) => !(e.path === path && e.method === method)\r\n );\r\n }\r\n\r\n /**\r\n * 获取所有端点\r\n */\r\n getEndpoints(): EndpointConfig[] {\r\n return this.endpoints;\r\n }\r\n}\r\n","/**\r\n * AI Mock Generator - Vite 插件入口\r\n */\r\n\r\nimport type { Plugin } from \"vite\";\r\nimport type { MockGeneratorOptions, TypeDefinition } from \"./types\";\r\nimport { MockStorage } from \"./storage\";\r\nimport { MockDataGenerator } from \"./generator\";\r\nimport { MockServer } from \"./server\";\r\n\r\nexport function vitePluginAIMockGenerator(\r\n options: MockGeneratorOptions = {},\r\n): Plugin {\r\n const {\r\n apiKey = process.env.OPENAI_API_KEY || \"\",\r\n apiUrl = process.env.OPENAI_API_URL || \"https://api.openai.com/v1\",\r\n model = process.env.OPENAI_MODEL || \"gpt-4\",\r\n enabled = true,\r\n autoGenerate = false,\r\n generation = {\r\n locale: \"zh-CN\",\r\n count: 20,\r\n quality: \"balanced\",\r\n },\r\n storage: storageOptions = {\r\n dir: \"mock-data\",\r\n persist: true,\r\n cache: true,\r\n },\r\n output = {\r\n console: true,\r\n logs: false,\r\n },\r\n } = options;\r\n\r\n // 如果未启用,返回空插件\r\n if (!enabled) {\r\n return {\r\n name: \"vite-plugin-ai-mock-generator\",\r\n };\r\n }\r\n\r\n // 初始化组件\r\n const storage = new MockStorage(storageOptions);\r\n const generator = new MockDataGenerator({ apiKey, apiUrl, model });\r\n const server = new MockServer(storage, options);\r\n\r\n return {\r\n name: \"vite-plugin-ai-mock-generator\",\r\n enforce: \"pre\",\r\n\r\n configResolved(config) {\r\n if (output.console) {\r\n console.log(\"\\n🤖 AI Mock Generator 已启动\");\r\n console.log(`📂 存储目录: ${storageOptions.dir}`);\r\n console.log(`🌍 数据语言: ${generation.locale}`);\r\n console.log(`📊 默认数量: ${generation.count}`);\r\n console.log(`🔑 API Key: ${apiKey ? \"已配置\" : \"未配置\"}`);\r\n console.log(`📍 端点数量: ${options.endpoints?.length || 0}`);\r\n }\r\n },\r\n\r\n async buildStart() {\r\n // 如果启用自动生成\r\n if (autoGenerate && options.endpoints) {\r\n if (output.console) {\r\n console.log(\"\\n🔄 开始自动生成 Mock 数据...\\n\");\r\n }\r\n\r\n for (const endpoint of options.endpoints) {\r\n // 检查是否已有数据\r\n const existingData = storage.get(endpoint.path, endpoint.method);\r\n if (existingData) {\r\n if (output.console) {\r\n console.log(\r\n `⏭️ 跳过 ${endpoint.method} ${endpoint.path} (已有数据)`,\r\n );\r\n }\r\n continue;\r\n }\r\n\r\n try {\r\n if (output.console) {\r\n console.log(`🎲 生成 ${endpoint.method} ${endpoint.path}...`);\r\n }\r\n\r\n // 解析类型定义\r\n const typeDefinition = parseTypeDefinition(endpoint.response);\r\n\r\n // 生成数据\r\n const count = endpoint.count || generation.count || 20;\r\n let data;\r\n\r\n // 根据质量设置选择生成方式\r\n if (generation.quality === \"fast\") {\r\n // 使用基础生成器(不需要 AI)\r\n data = generator.generateBasic(typeDefinition, count);\r\n } else {\r\n // 使用 AI 生成\r\n data = await generator.generate({\r\n type: typeDefinition,\r\n count,\r\n locale: generation.locale || \"zh-CN\",\r\n quality: generation.quality || \"balanced\",\r\n });\r\n }\r\n\r\n // 存储数据\r\n storage.set(endpoint.path, endpoint.method, data, {\r\n type: endpoint.response as string,\r\n });\r\n\r\n if (output.console) {\r\n console.log(\r\n `✅ 已生成 ${count} 条数据: ${endpoint.method} ${endpoint.path}`,\r\n );\r\n }\r\n } catch (error: any) {\r\n console.error(\r\n `❌ 生成失败 ${endpoint.method} ${endpoint.path}:`,\r\n error.message,\r\n );\r\n }\r\n }\r\n\r\n if (output.console) {\r\n console.log(\"\\n✨ Mock 数据生成完成\\n\");\r\n }\r\n }\r\n },\r\n\r\n configureServer(viteServer) {\r\n // 配置 Mock 服务器中间件\r\n server.configureServer(viteServer);\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * 解析类型定义\r\n * 简化版本,实际应该使用 TypeScript Compiler API\r\n */\r\nfunction parseTypeDefinition(typeStr: string | TypeDefinition): TypeDefinition {\r\n if (typeof typeStr === \"object\") {\r\n return typeStr;\r\n }\r\n\r\n // 简单解析(实际应该更复杂)\r\n const isArray = typeStr.endsWith(\"[]\");\r\n const typeName = isArray ? typeStr.slice(0, -2) : typeStr;\r\n\r\n // 返回基础类型定义\r\n return {\r\n name: typeName,\r\n properties: [],\r\n isArray,\r\n };\r\n}\r\n\r\n// 导出类型\r\nexport type { MockGeneratorOptions, EndpointConfig } from \"./types\";\r\nexport { MockStorage } from \"./storage\";\r\nexport { MockDataGenerator } from \"./generator\";\r\nexport { MockServer } from \"./server\";\r\n\r\n// 默认导出\r\nexport default vitePluginAIMockGenerator;\r\n"],"mappings":"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","names":["path","path"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vite-plugin-ai-mock-generator",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "description": "AI-powered Mock data generator for Vite - Generate realistic test data with AI or basic algorithms",
5
5
  "keywords": [
6
6
  "vite",
@@ -44,7 +44,9 @@
44
44
  },
45
45
  "dependencies": {
46
46
  "picocolors": "^1.1.1",
47
- "vite-plugin-ai-shared": "1.0.0"
47
+ "@langchain/core": "^0.3.0",
48
+ "@langchain/openai": "^0.3.0",
49
+ "vite-plugin-ai-shared": "1.0.1"
48
50
  },
49
51
  "devDependencies": {
50
52
  "@types/node": "^20.0.0",