vite-plugin-ai-mock-generator 1.0.2 → 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;
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;
package/dist/index.js CHANGED
@@ -1,23 +1,53 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
- var fs = require('fs');
6
- var path = require('path');
7
-
8
- 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);
9
29
 
10
- var fs__default = /*#__PURE__*/_interopDefault(fs);
11
- 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);
12
40
 
13
41
  // src/storage.ts
42
+ var import_fs = __toESM(require("fs"));
43
+ var import_path = __toESM(require("path"));
14
44
  var MockStorage = class {
15
45
  constructor(options = {}) {
16
46
  this.storageDir = options.dir || "mock-data";
17
47
  this.persist = options.persist !== false;
18
48
  this.cache = /* @__PURE__ */ new Map();
19
- if (this.persist && !fs__default.default.existsSync(this.storageDir)) {
20
- 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 });
21
51
  }
22
52
  this.load();
23
53
  }
@@ -72,9 +102,9 @@ var MockStorage = class {
72
102
  this.cache.delete(key);
73
103
  if (this.persist) {
74
104
  const fileName = this.getFileName(endpoint, method);
75
- const filePath = path__default.default.join(this.storageDir, fileName);
76
- if (fs__default.default.existsSync(filePath)) {
77
- 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);
78
108
  }
79
109
  }
80
110
  }
@@ -83,10 +113,10 @@ var MockStorage = class {
83
113
  */
84
114
  clear() {
85
115
  this.cache.clear();
86
- if (this.persist && fs__default.default.existsSync(this.storageDir)) {
87
- 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);
88
118
  for (const file of files) {
89
- fs__default.default.unlinkSync(path__default.default.join(this.storageDir, file));
119
+ import_fs.default.unlinkSync(import_path.default.join(this.storageDir, file));
90
120
  }
91
121
  }
92
122
  }
@@ -101,22 +131,22 @@ var MockStorage = class {
101
131
  */
102
132
  save(endpoint, method, store) {
103
133
  const fileName = this.getFileName(endpoint, method);
104
- const filePath = path__default.default.join(this.storageDir, fileName);
105
- 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");
106
136
  }
107
137
  /**
108
138
  * 从文件加载
109
139
  */
110
140
  load() {
111
- if (!this.persist || !fs__default.default.existsSync(this.storageDir)) {
141
+ if (!this.persist || !import_fs.default.existsSync(this.storageDir)) {
112
142
  return;
113
143
  }
114
- const files = fs__default.default.readdirSync(this.storageDir);
144
+ const files = import_fs.default.readdirSync(this.storageDir);
115
145
  for (const file of files) {
116
146
  if (!file.endsWith(".json")) continue;
117
147
  try {
118
- const filePath = path__default.default.join(this.storageDir, file);
119
- 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");
120
150
  const store = JSON.parse(content);
121
151
  const key = this.getKey(store.endpoint, store.method);
122
152
  this.cache.set(key, store);
@@ -130,13 +160,13 @@ var MockStorage = class {
130
160
  */
131
161
  export(outputPath) {
132
162
  const allData = this.getAll();
133
- 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");
134
164
  }
135
165
  /**
136
166
  * 导入数据
137
167
  */
138
168
  import(inputPath) {
139
- const content = fs__default.default.readFileSync(inputPath, "utf-8");
169
+ const content = import_fs.default.readFileSync(inputPath, "utf-8");
140
170
  const allData = JSON.parse(content);
141
171
  for (const store of allData) {
142
172
  const key = this.getKey(store.endpoint, store.method);
@@ -149,11 +179,19 @@ var MockStorage = class {
149
179
  };
150
180
 
151
181
  // src/generator.ts
182
+ var import_openai = require("@langchain/openai");
183
+ var import_messages = require("@langchain/core/messages");
152
184
  var MockDataGenerator = class {
153
185
  constructor(options) {
154
- this.apiKey = options.apiKey;
155
- this.apiUrl = options.apiUrl;
156
- 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
+ });
157
195
  }
158
196
  /**
159
197
  * 生成 Mock 数据
@@ -170,34 +208,34 @@ var MockDataGenerator = class {
170
208
  buildPrompt(type, count, locale, quality) {
171
209
  const properties = type.properties.map((p) => this.formatProperty(p)).join("\n");
172
210
  return `
173
- \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 数据生成器。请根据以下类型定义生成真实、合理的测试数据。
174
212
 
175
- \u7C7B\u578B\u540D\u79F0: ${type.name}
176
- \u6570\u636E\u8BED\u8A00: ${locale === "zh-CN" ? "\u4E2D\u6587" : "\u82F1\u6587"}
177
- \u6570\u636E\u6570\u91CF: ${count}
178
- \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" ? "快速生成" : "平衡质量和速度"}
179
217
 
180
- \u7C7B\u578B\u5B9A\u4E49:
218
+ 类型定义:
181
219
  ${properties}
182
220
 
183
- \u8981\u6C42:
184
- 1. \u751F\u6210 ${count} \u6761\u6570\u636E
185
- 2. \u6570\u636E\u8981\u7B26\u5408\u4E1A\u52A1\u903B\u8F91\u548C\u771F\u5B9E\u573A\u666F
186
- 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
187
- 4. \u65E5\u671F\u683C\u5F0F\u4F7F\u7528 ISO 8601
188
- 5. \u8FD4\u56DE JSON \u6570\u7EC4\u683C\u5F0F\uFF0C\u4E0D\u8981\u5305\u542B\u4EFB\u4F55\u5176\u4ED6\u6587\u5B57
189
- 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 生成真实姓名)
190
228
 
191
- \u793A\u4F8B\u683C\u5F0F:
229
+ 示例格式:
192
230
  [
193
231
  {
194
232
  "id": 1,
195
- "name": "\u5F20\u4E09",
233
+ "name": "张三",
196
234
  ...
197
235
  }
198
236
  ]
199
237
 
200
- \u8BF7\u751F\u6210\u6570\u636E:
238
+ 请生成数据:
201
239
  `.trim();
202
240
  }
203
241
  /**
@@ -233,30 +271,16 @@ ${properties}
233
271
  */
234
272
  async callAI(prompt) {
235
273
  try {
236
- const response = await fetch(`${this.apiUrl}/chat/completions`, {
237
- method: "POST",
238
- headers: {
239
- "Content-Type": "application/json",
240
- Authorization: `Bearer ${this.apiKey}`
241
- },
242
- body: JSON.stringify({
243
- model: this.model,
244
- messages: [
245
- {
246
- role: "user",
247
- content: prompt
248
- }
249
- ],
250
- temperature: 0.7
251
- })
252
- });
253
- if (!response.ok) {
254
- throw new Error(`AI API error: ${response.statusText}`);
255
- }
256
- const data = await response.json();
257
- 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;
258
282
  } catch (error) {
259
- console.error("Failed to call AI API:", error);
283
+ console.error(" AI API 调用失败:", error.message);
260
284
  throw error;
261
285
  }
262
286
  }
@@ -276,8 +300,8 @@ ${properties}
276
300
  const data = JSON.parse(jsonMatch[0]);
277
301
  return isArray ? data : data[0];
278
302
  } catch (error) {
279
- console.error("Failed to parse AI response:", error);
280
- console.error("Response:", response);
303
+ console.error(" 解析 AI 响应失败:", error.message);
304
+ console.error("响应内容:", response);
281
305
  throw error;
282
306
  }
283
307
  }
@@ -435,7 +459,7 @@ var MockServer = class {
435
459
  res.statusCode = 200;
436
460
  res.end(JSON.stringify(data));
437
461
  if (this.options.output?.logs) {
438
- console.log(`[Mock] ${method} ${url} \u2192 ${data ? "OK" : "Empty"}`);
462
+ console.log(`[Mock] ${method} ${url} ${data ? "OK" : "Empty"}`);
439
463
  }
440
464
  } catch (error) {
441
465
  console.error(`[Mock] Error handling ${method} ${url}:`, error);
@@ -448,8 +472,8 @@ var MockServer = class {
448
472
  );
449
473
  }
450
474
  });
451
- console.log("\n\u{1F3AD} Mock \u670D\u52A1\u5668\u5DF2\u542F\u52A8");
452
- console.log(`\u{1F4CD} \u5DF2\u6CE8\u518C ${this.endpoints.length} \u4E2A\u7AEF\u70B9
475
+ console.log("\n🎭 Mock 服务器已启动");
476
+ console.log(`📍 已注册 ${this.endpoints.length} 个端点
453
477
  `);
454
478
  }
455
479
  /**
@@ -577,32 +601,32 @@ function vitePluginAIMockGenerator(options = {}) {
577
601
  enforce: "pre",
578
602
  configResolved(config) {
579
603
  if (output.console) {
580
- console.log("\n\u{1F916} AI Mock Generator \u5DF2\u542F\u52A8");
581
- console.log(`\u{1F4C2} \u5B58\u50A8\u76EE\u5F55: ${storageOptions.dir}`);
582
- console.log(`\u{1F30D} \u6570\u636E\u8BED\u8A00: ${generation.locale}`);
583
- console.log(`\u{1F4CA} \u9ED8\u8BA4\u6570\u91CF: ${generation.count}`);
584
- console.log(`\u{1F511} API Key: ${apiKey ? "\u5DF2\u914D\u7F6E" : "\u672A\u914D\u7F6E"}`);
585
- console.log(`\u{1F4CD} \u7AEF\u70B9\u6570\u91CF: ${options.endpoints?.length || 0}`);
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
  },
@@ -655,11 +679,11 @@ function parseTypeDefinition(typeStr) {
655
679
  };
656
680
  }
657
681
  var index_default = vitePluginAIMockGenerator;
658
-
659
- exports.MockDataGenerator = MockDataGenerator;
660
- exports.MockServer = MockServer;
661
- exports.MockStorage = MockStorage;
662
- exports.default = index_default;
663
- exports.vitePluginAIMockGenerator = vitePluginAIMockGenerator;
664
- //# sourceMappingURL=index.js.map
682
+ // Annotate the CommonJS export names for ESM import in node:
683
+ 0 && (module.exports = {
684
+ MockDataGenerator,
685
+ MockServer,
686
+ MockStorage,
687
+ vitePluginAIMockGenerator
688
+ });
665
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(`📍 端点数量: ${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"]}
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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACIA,gBAAe;AACf,kBAAiB;AAGV,IAAM,cAAN,MAAkB;AAAA,EAKvB,YAAY,UAA+C,CAAC,GAAG;AAC7D,SAAK,aAAa,QAAQ,OAAO;AACjC,SAAK,UAAU,QAAQ,YAAY;AACnC,SAAK,QAAQ,oBAAI,IAAI;AAGrB,QAAI,KAAK,WAAW,CAAC,UAAAA,QAAG,WAAW,KAAK,UAAU,GAAG;AACnD,gBAAAA,QAAG,UAAU,KAAK,YAAY,EAAE,WAAW,KAAK,CAAC;AAAA,IACnD;AAGA,SAAK,KAAK;AAAA,EACZ;AAAA;AAAA;AAAA;AAAA,EAKQ,OAAO,UAAkB,QAA4B;AAC3D,WAAO,GAAG,MAAM,IAAI,QAAQ;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA,EAKQ,YAAY,UAAkB,QAA4B;AAChE,UAAM,YAAY,SACf,QAAQ,OAAO,EAAE,EACjB,QAAQ,OAAO,GAAG,EAClB,QAAQ,MAAM,GAAG;AACpB,WAAO,GAAG,MAAM,IAAI,SAAS;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,UAAkB,SAAqB,OAAY;AACrD,UAAM,MAAM,KAAK,OAAO,UAAU,MAAM;AACxC,UAAM,QAAQ,KAAK,MAAM,IAAI,GAAG;AAChC,WAAO,OAAO;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA,EAKA,IACE,UACA,QACA,MACA,UACM;AACN,UAAM,MAAM,KAAK,OAAO,UAAU,MAAM;AAExC,UAAM,QAAuB;AAAA,MAC3B;AAAA,MACA;AAAA,MACA;AAAA,MACA,UAAU;AAAA,QACR,OAAO,MAAM,QAAQ,IAAI,IAAI,KAAK,SAAS;AAAA,QAC3C,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,QACpC,SAAS;AAAA,QACT,MAAM,OAAO;AAAA,QACb,GAAG;AAAA,MACL;AAAA,IACF;AAEA,SAAK,MAAM,IAAI,KAAK,KAAK;AAGzB,QAAI,KAAK,SAAS;AAChB,WAAK,KAAK,UAAU,QAAQ,KAAK;AAAA,IACnC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,UAAkB,SAAqB,OAAa;AACzD,UAAM,MAAM,KAAK,OAAO,UAAU,MAAM;AACxC,SAAK,MAAM,OAAO,GAAG;AAGrB,QAAI,KAAK,SAAS;AAChB,YAAM,WAAW,KAAK,YAAY,UAAU,MAAM;AAClD,YAAM,WAAW,YAAAC,QAAK,KAAK,KAAK,YAAY,QAAQ;AACpD,UAAI,UAAAD,QAAG,WAAW,QAAQ,GAAG;AAC3B,kBAAAA,QAAG,WAAW,QAAQ;AAAA,MACxB;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,QAAc;AACZ,SAAK,MAAM,MAAM;AAGjB,QAAI,KAAK,WAAW,UAAAA,QAAG,WAAW,KAAK,UAAU,GAAG;AAClD,YAAM,QAAQ,UAAAA,QAAG,YAAY,KAAK,UAAU;AAC5C,iBAAW,QAAQ,OAAO;AACxB,kBAAAA,QAAG,WAAW,YAAAC,QAAK,KAAK,KAAK,YAAY,IAAI,CAAC;AAAA,MAChD;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,SAA0B;AACxB,WAAO,MAAM,KAAK,KAAK,MAAM,OAAO,CAAC;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA,EAKQ,KACN,UACA,QACA,OACM;AACN,UAAM,WAAW,KAAK,YAAY,UAAU,MAAM;AAClD,UAAM,WAAW,YAAAA,QAAK,KAAK,KAAK,YAAY,QAAQ;AAEpD,cAAAD,QAAG,cAAc,UAAU,KAAK,UAAU,OAAO,MAAM,CAAC,GAAG,OAAO;AAAA,EACpE;AAAA;AAAA;AAAA;AAAA,EAKQ,OAAa;AACnB,QAAI,CAAC,KAAK,WAAW,CAAC,UAAAA,QAAG,WAAW,KAAK,UAAU,GAAG;AACpD;AAAA,IACF;AAEA,UAAM,QAAQ,UAAAA,QAAG,YAAY,KAAK,UAAU;AAE5C,eAAW,QAAQ,OAAO;AACxB,UAAI,CAAC,KAAK,SAAS,OAAO,EAAG;AAE7B,UAAI;AACF,cAAM,WAAW,YAAAC,QAAK,KAAK,KAAK,YAAY,IAAI;AAChD,cAAM,UAAU,UAAAD,QAAG,aAAa,UAAU,OAAO;AACjD,cAAM,QAAuB,KAAK,MAAM,OAAO;AAE/C,cAAM,MAAM,KAAK,OAAO,MAAM,UAAU,MAAM,MAAM;AACpD,aAAK,MAAM,IAAI,KAAK,KAAK;AAAA,MAC3B,SAAS,OAAO;AACd,gBAAQ,KAAK,iCAAiC,IAAI,KAAK,KAAK;AAAA,MAC9D;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,YAA0B;AAC/B,UAAM,UAAU,KAAK,OAAO;AAC5B,cAAAA,QAAG,cAAc,YAAY,KAAK,UAAU,SAAS,MAAM,CAAC,GAAG,OAAO;AAAA,EACxE;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,WAAyB;AAC9B,UAAM,UAAU,UAAAA,QAAG,aAAa,WAAW,OAAO;AAClD,UAAM,UAA2B,KAAK,MAAM,OAAO;AAEnD,eAAW,SAAS,SAAS;AAC3B,YAAM,MAAM,KAAK,OAAO,MAAM,UAAU,MAAM,MAAM;AACpD,WAAK,MAAM,IAAI,KAAK,KAAK;AAEzB,UAAI,KAAK,SAAS;AAChB,aAAK,KAAK,MAAM,UAAU,MAAM,QAAQ,KAAK;AAAA,MAC/C;AAAA,IACF;AAAA,EACF;AACF;;;ACzLA,oBAA2B;AAC3B,sBAA4C;AAOrC,IAAM,oBAAN,MAAwB;AAAA,EAG7B,YAAY,SAA4D;AACtE,SAAK,MAAM,IAAI,yBAAW;AAAA,MACxB,cAAc,QAAQ;AAAA,MACtB,eAAe;AAAA,QACb,SAAS,QAAQ;AAAA,MACnB;AAAA,MACA,WAAW,QAAQ;AAAA,MACnB,aAAa;AAAA,MACb,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAS,SAA0C;AACvD,UAAM,EAAE,MAAM,OAAO,QAAQ,QAAQ,IAAI;AAGzC,UAAM,SAAS,KAAK,YAAY,MAAM,OAAO,QAAQ,OAAO;AAG5D,UAAM,WAAW,MAAM,KAAK,OAAO,MAAM;AAGzC,WAAO,KAAK,cAAc,UAAU,KAAK,OAAO;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA,EAKQ,YACN,MACA,OACA,QACA,SACQ;AACR,UAAM,aAAa,KAAK,WACrB,IAAI,CAAC,MAAM,KAAK,eAAe,CAAC,CAAC,EACjC,KAAK,IAAI;AAEZ,WAAO;AAAA;AAAA;AAAA,QAGH,KAAK,IAAI;AAAA,QACT,WAAW,UAAU,OAAO,IAAI;AAAA,QAChC,KAAK;AAAA,QAEP,YAAY,SACR,gBACA,YAAY,SACZ,SACA,SACN;AAAA;AAAA;AAAA,EAGF,UAAU;AAAA;AAAA;AAAA,QAGJ,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBX,KAAK;AAAA,EACL;AAAA;AAAA;AAAA;AAAA,EAKQ,eAAe,MAAkC;AACvD,QAAI,OAAO,KAAK,KAAK,IAAI,KAAK,KAAK,IAAI;AAEvC,QAAI,KAAK,SAAS;AAChB,cAAQ,OAAO,KAAK,OAAO;AAAA,IAC7B;AAEA,QAAI,KAAK,aAAa;AACpB,YAAM,cAAc,CAAC;AACrB,UAAI,KAAK,YAAY,QAAQ,QAAW;AACtC,oBAAY,KAAK,QAAQ,KAAK,YAAY,GAAG,EAAE;AAAA,MACjD;AACA,UAAI,KAAK,YAAY,QAAQ,QAAW;AACtC,oBAAY,KAAK,QAAQ,KAAK,YAAY,GAAG,EAAE;AAAA,MACjD;AACA,UAAI,KAAK,YAAY,QAAQ;AAC3B,oBAAY,KAAK,QAAQ;AAAA,MAC3B;AACA,UAAI,KAAK,YAAY,MAAM;AACzB,oBAAY,KAAK,UAAU,KAAK,YAAY,KAAK,KAAK,IAAI,CAAC,GAAG;AAAA,MAChE;AACA,UAAI,YAAY,SAAS,GAAG;AAC1B,gBAAQ,KAAK,YAAY,KAAK,IAAI,CAAC;AAAA,MACrC;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,OAAO,QAAiC;AACpD,QAAI;AACF,YAAM,WAAW;AAAA,QACf,IAAI;AAAA,UACF;AAAA,QACF;AAAA,QACA,IAAI,6BAAa,MAAM;AAAA,MACzB;AAEA,YAAM,WAAW,MAAM,KAAK,IAAI,OAAO,QAAQ;AAC/C,aAAO,SAAS;AAAA,IAClB,SAAS,OAAY;AACnB,cAAQ,MAAM,kBAAkB,MAAM,OAAO;AAC7C,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,cAAc,UAAkB,UAAmB,MAAW;AACpE,QAAI;AAEF,UAAI,kBAAkB,SAAS,KAAK;AAGpC,wBAAkB,gBAAgB,QAAQ,gBAAgB,EAAE;AAC5D,wBAAkB,gBAAgB,QAAQ,WAAW,EAAE;AAGvD,wBAAkB,gBAAgB,QAAQ,WAAW,EAAE;AAGvD,YAAM,YAAY,gBAAgB,MAAM,2BAA2B;AACnE,UAAI,CAAC,WAAW;AACd,cAAM,IAAI,MAAM,2CAA2C;AAAA,MAC7D;AAEA,YAAM,OAAO,KAAK,MAAM,UAAU,CAAC,CAAC;AAEpC,aAAO,UAAU,OAAO,KAAK,CAAC;AAAA,IAChC,SAAS,OAAY;AACnB,cAAQ,MAAM,iBAAiB,MAAM,OAAO;AAC5C,cAAQ,MAAM,SAAS,QAAQ;AAC/B,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc,MAAsB,OAAsB;AACxD,UAAM,OAAO,CAAC;AAEd,aAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,YAAM,OAAY,CAAC;AAEnB,iBAAW,QAAQ,KAAK,YAAY;AAClC,aAAK,KAAK,IAAI,IAAI,KAAK,mBAAmB,MAAM,CAAC;AAAA,MACnD;AAEA,WAAK,KAAK,IAAI;AAAA,IAChB;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,mBAAmB,MAA0B,OAAoB;AACvE,UAAM,EAAE,MAAM,YAAY,IAAI;AAG9B,QAAI,aAAa,MAAM;AACrB,aAAO,YAAY,KAAK,QAAQ,YAAY,KAAK,MAAM;AAAA,IACzD;AAGA,YAAQ,MAAM;AAAA,MACZ,KAAK;AACH,cAAM,MAAM,aAAa,OAAO;AAChC,cAAM,MAAM,aAAa,OAAO;AAChC,eAAO,KAAK,MAAM,KAAK,OAAO,KAAK,MAAM,MAAM,EAAE,IAAI;AAAA,MAEvD,KAAK;AACH,eAAO,GAAG,KAAK,IAAI,IAAI,QAAQ,CAAC;AAAA,MAElC,KAAK;AACH,eAAO,KAAK,OAAO,IAAI;AAAA,MAEzB,KAAK;AACH,gBAAO,oBAAI,KAAK,GAAE,YAAY;AAAA,MAEhC;AACE,eAAO;AAAA,IACX;AAAA,EACF;AACF;;;AC1NO,SAAS,MAAM,IAA8C;AAClE,QAAM,YAAY,MAAM,QAAQ,EAAE,IAC9B,KAAK,OAAO,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,KAAK,GAAG,CAAC,IACtC;AAEJ,SAAO,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,SAAS,CAAC;AAChE;AAOO,SAAS,gBACd,SACAE,OAC+B;AAC/B,QAAM,eAAe,QAAQ,MAAM,GAAG;AACtC,QAAM,YAAYA,MAAK,MAAM,GAAG;AAEhC,MAAI,aAAa,WAAW,UAAU,QAAQ;AAC5C,WAAO;AAAA,EACT;AAEA,QAAM,SAAiC,CAAC;AAExC,WAAS,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;AAC5C,UAAM,cAAc,aAAa,CAAC;AAClC,UAAM,WAAW,UAAU,CAAC;AAE5B,QAAI,YAAY,WAAW,GAAG,GAAG;AAE/B,YAAM,YAAY,YAAY,MAAM,CAAC;AACrC,aAAO,SAAS,IAAI;AAAA,IACtB,WAAW,gBAAgB,UAAU;AAEnC,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;AAKO,SAAS,iBAAiB,KAAkC;AACjE,QAAM,cAAc,IAAI,MAAM,GAAG,EAAE,CAAC;AACpC,MAAI,CAAC,YAAa,QAAO,CAAC;AAE1B,QAAM,SAA8B,CAAC;AACrC,QAAM,QAAQ,YAAY,MAAM,GAAG;AAEnC,aAAW,QAAQ,OAAO;AACxB,UAAM,CAAC,KAAK,KAAK,IAAI,KAAK,MAAM,GAAG;AACnC,WAAO,mBAAmB,GAAG,CAAC,IAAI,mBAAmB,SAAS,EAAE;AAAA,EAClE;AAEA,SAAO;AACT;AAmBO,SAAS,aAAa,MAAa,SAAqC;AAC7E,MAAI,CAAC,WAAW,OAAO,KAAK,OAAO,EAAE,WAAW,GAAG;AACjD,WAAO;AAAA,EACT;AAEA,SAAO,KAAK,OAAO,CAAC,SAAS;AAC3B,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,OAAO,GAAG;AAClD,UAAI,KAAK,GAAG,MAAM,OAAO;AACvB,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO;AAAA,EACT,CAAC;AACH;AAKO,SAAS,aACd,MACA,MACO;AACP,MAAI,CAAC,KAAM,QAAO;AAElB,QAAM,aACJ,OAAO,SAAS,WACZ,EAAE,OAAO,MAAM,OAAO,MAAe,IACrC;AAEN,SAAO,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,MAAM;AAC9B,UAAM,SAAS,EAAE,WAAW,KAAK;AACjC,UAAM,SAAS,EAAE,WAAW,KAAK;AAEjC,QAAI,SAAS,OAAQ,QAAO,WAAW,UAAU,QAAQ,KAAK;AAC9D,QAAI,SAAS,OAAQ,QAAO,WAAW,UAAU,QAAQ,IAAI;AAC7D,WAAO;AAAA,EACT,CAAC;AACH;AAKO,SAAS,gBACd,MACA,OAAe,GACf,WAAmB,IASnB;AACA,QAAM,QAAQ,KAAK;AACnB,QAAM,aAAa,KAAK,KAAK,QAAQ,QAAQ;AAC7C,QAAM,SAAS,OAAO,KAAK;AAC3B,QAAM,MAAM,QAAQ;AAEpB,SAAO;AAAA,IACL,MAAM,KAAK,MAAM,OAAO,GAAG;AAAA,IAC3B,YAAY;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAKO,SAAS,eACd,MACA,UAAmB,MACnB,SACA;AACA,SAAO;AAAA,IACL,MAAM,UAAU,MAAM;AAAA,IACtB;AAAA,IACA,SAAS,YAAY,UAAU,YAAY;AAAA,EAC7C;AACF;;;ACtJO,IAAM,aAAN,MAAiB;AAAA,EAKtB,YAAY,SAAsB,SAA+B;AAC/D,SAAK,UAAU;AACf,SAAK,YAAY,QAAQ,aAAa,CAAC;AACvC,SAAK,UAAU;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB,QAA6B;AAC3C,WAAO,YAAY,IAAI,OAAO,KAAK,KAAK,SAAS;AAC/C,YAAM,MAAM,IAAI,OAAO;AACvB,YAAM,SAAS,IAAI;AAGnB,YAAM,WAAW,KAAK,cAAc,KAAK,MAAM;AAE/C,UAAI,CAAC,UAAU;AACb,eAAO,KAAK;AAAA,MACd;AAEA,UAAI;AAEF,cAAM,SAAS,KAAK,aAAa,KAAK,GAAG;AAGzC,cAAM,OAAO,MAAM,KAAK,YAAY,UAAU,MAAM;AAGpD,YAAI,KAAK,QAAQ,QAAQ,OAAO;AAC9B,gBAAM,MAAM,KAAK,QAAQ,OAAO,KAAK;AAAA,QACvC;AAGA,YAAI,UAAU,gBAAgB,kBAAkB;AAChD,YAAI,KAAK,QAAQ,QAAQ,MAAM;AAC7B,cAAI,UAAU,+BAA+B,GAAG;AAChD,cAAI,UAAU,gCAAgC,GAAG;AACjD,cAAI,UAAU,gCAAgC,GAAG;AAAA,QACnD;AAGA,YAAI,aAAa;AACjB,YAAI,IAAI,KAAK,UAAU,IAAI,CAAC;AAG5B,YAAI,KAAK,QAAQ,QAAQ,MAAM;AAC7B,kBAAQ,IAAI,UAAU,MAAM,IAAI,GAAG,MAAM,OAAO,OAAO,OAAO,EAAE;AAAA,QAClE;AAAA,MACF,SAAS,OAAY;AACnB,gBAAQ,MAAM,yBAAyB,MAAM,IAAI,GAAG,KAAK,KAAK;AAC9D,YAAI,aAAa;AACjB,YAAI;AAAA,UACF,KAAK,UAAU;AAAA,YACb,MAAM;AAAA,YACN,SAAS,MAAM;AAAA,UACjB,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF,CAAC;AAED,YAAQ,IAAI,kBAAkB;AAC9B,YAAQ,IAAI,UAAU,KAAK,UAAU,MAAM;AAAA,CAAQ;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA,EAKQ,cACN,KACA,QACuB;AAEvB,UAAMC,QAAO,IAAI,MAAM,GAAG,EAAE,CAAC;AAG7B,UAAM,SAAS,KAAK,QAAQ,QAAQ,UAAU;AAC9C,UAAM,YAAY,SAASA,MAAK,QAAQ,IAAI,OAAO,IAAI,MAAM,EAAE,GAAG,EAAE,IAAIA;AAExE,eAAW,YAAY,KAAK,WAAW;AAErC,UAAI,SAAS,YAAY,MAAO;AAGhC,UAAI,SAAS,WAAW,OAAQ;AAGhC,UAAI,SAAS,SAAS,WAAW;AAC/B,eAAO;AAAA,MACT;AAGA,UAAI,gBAAgB,SAAS,MAAM,SAAS,GAAG;AAC7C,eAAO;AAAA,MACT;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,aAAa,KAAU,KAAkB;AAC/C,UAAM,QAAQ,iBAAiB,GAAG;AAClC,UAAMA,QAAO,IAAI,MAAM,GAAG,EAAE,CAAC;AAG7B,UAAM,WAAW,KAAK,cAAcA,OAAM,IAAI,MAAM;AACpD,UAAM,aAAa,WACf,gBAAgB,SAAS,MAAMA,MAAK,MAAM,GAAG,EAAE,CAAC,CAAC,IACjD;AAEJ,WAAO;AAAA,MACL;AAAA,MACA,QAAQ,cAAc,CAAC;AAAA,MACvB,MAAM,IAAI;AAAA,MACV,SAAS,IAAI;AAAA,IACf;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,YACZ,UACA,QACc;AAEd,QAAI,OAAO,KAAK,QAAQ,IAAI,SAAS,MAAM,SAAS,MAAM;AAE1D,QAAI,CAAC,MAAM;AACT,cAAQ;AAAA,QACN,4BAA4B,SAAS,MAAM,IAAI,SAAS,IAAI;AAAA,MAC9D;AACA,aAAO,eAAe,CAAC,GAAG,OAAO,wBAAwB;AAAA,IAC3D;AAGA,QAAI,MAAM,QAAQ,IAAI,GAAG;AAEvB,UAAI,OAAO,MAAM,QAAQ;AACvB,eAAO,aAAa,MAAM,KAAK,MAAM,OAAO,MAAM,MAAM,CAAC;AAAA,MAC3D;AAGA,UAAI,OAAO,MAAM,MAAM;AACrB,eAAO,aAAa,MAAM,OAAO,MAAM,IAAI;AAAA,MAC7C;AAGA,UAAI,OAAO,MAAM,QAAQ,OAAO,MAAM,UAAU;AAC9C,cAAM,OAAO,SAAS,OAAO,MAAM,IAAI,KAAK;AAC5C,cAAM,WAAW,SAAS,OAAO,MAAM,QAAQ,KAAK;AACpD,cAAM,SAAS,gBAAgB,MAAM,MAAM,QAAQ;AAEnD,eAAO,eAAe;AAAA,UACpB,MAAM,OAAO;AAAA,UACb,YAAY,OAAO;AAAA,QACrB,CAAC;AAAA,MACH;AAAA,IACF;AAGA,QAAI,SAAS,QAAQ;AACnB,aAAO,MAAM,SAAS,OAAO,MAAM,MAAM;AAAA,IAC3C;AAGA,WAAO,eAAe,IAAI;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,UAAgC;AAC1C,SAAK,UAAU,KAAK,QAAQ;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA,EAKA,eAAeA,OAAc,QAA0B;AACrD,SAAK,YAAY,KAAK,UAAU;AAAA,MAC9B,CAAC,MAAM,EAAE,EAAE,SAASA,SAAQ,EAAE,WAAW;AAAA,IAC3C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,eAAiC;AAC/B,WAAO,KAAK;AAAA,EACd;AACF;;;AJlNO,SAAS,0BACd,UAAgC,CAAC,GACzB;AACR,QAAM;AAAA,IACJ,SAAS,QAAQ,IAAI,kBAAkB;AAAA,IACvC,SAAS,QAAQ,IAAI,kBAAkB;AAAA,IACvC,QAAQ,QAAQ,IAAI,gBAAgB;AAAA,IACpC,UAAU;AAAA,IACV,eAAe;AAAA,IACf,aAAa;AAAA,MACX,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,SAAS;AAAA,IACX;AAAA,IACA,SAAS,iBAAiB;AAAA,MACxB,KAAK;AAAA,MACL,SAAS;AAAA,MACT,OAAO;AAAA,IACT;AAAA,IACA,SAAS;AAAA,MACP,SAAS;AAAA,MACT,MAAM;AAAA,IACR;AAAA,EACF,IAAI;AAGJ,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,MACL,MAAM;AAAA,IACR;AAAA,EACF;AAGA,QAAM,UAAU,IAAI,YAAY,cAAc;AAC9C,QAAM,YAAY,IAAI,kBAAkB,EAAE,QAAQ,QAAQ,MAAM,CAAC;AACjE,QAAM,SAAS,IAAI,WAAW,SAAS,OAAO;AAE9C,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA,IAET,eAAe,QAAQ;AACrB,UAAI,OAAO,SAAS;AAClB,gBAAQ,IAAI,4BAA4B;AACxC,gBAAQ,IAAI,YAAY,eAAe,GAAG,EAAE;AAC5C,gBAAQ,IAAI,YAAY,WAAW,MAAM,EAAE;AAC3C,gBAAQ,IAAI,YAAY,WAAW,KAAK,EAAE;AAC1C,gBAAQ,IAAI,eAAe,SAAS,QAAQ,KAAK,EAAE;AACnD,gBAAQ,IAAI,YAAY,QAAQ,WAAW,UAAU,CAAC,EAAE;AAAA,MAC1D;AAAA,IACF;AAAA,IAEA,MAAM,aAAa;AAEjB,UAAI,gBAAgB,QAAQ,WAAW;AACrC,YAAI,OAAO,SAAS;AAClB,kBAAQ,IAAI,0BAA0B;AAAA,QACxC;AAEA,mBAAW,YAAY,QAAQ,WAAW;AAExC,gBAAM,eAAe,QAAQ,IAAI,SAAS,MAAM,SAAS,MAAM;AAC/D,cAAI,cAAc;AAChB,gBAAI,OAAO,SAAS;AAClB,sBAAQ;AAAA,gBACN,UAAU,SAAS,MAAM,IAAI,SAAS,IAAI;AAAA,cAC5C;AAAA,YACF;AACA;AAAA,UACF;AAEA,cAAI;AACF,gBAAI,OAAO,SAAS;AAClB,sBAAQ,IAAI,SAAS,SAAS,MAAM,IAAI,SAAS,IAAI,KAAK;AAAA,YAC5D;AAGA,kBAAM,iBAAiB,oBAAoB,SAAS,QAAQ;AAG5D,kBAAM,QAAQ,SAAS,SAAS,WAAW,SAAS;AACpD,gBAAI;AAGJ,gBAAI,WAAW,YAAY,QAAQ;AAEjC,qBAAO,UAAU,cAAc,gBAAgB,KAAK;AAAA,YACtD,OAAO;AAEL,qBAAO,MAAM,UAAU,SAAS;AAAA,gBAC9B,MAAM;AAAA,gBACN;AAAA,gBACA,QAAQ,WAAW,UAAU;AAAA,gBAC7B,SAAS,WAAW,WAAW;AAAA,cACjC,CAAC;AAAA,YACH;AAGA,oBAAQ,IAAI,SAAS,MAAM,SAAS,QAAQ,MAAM;AAAA,cAChD,MAAM,SAAS;AAAA,YACjB,CAAC;AAED,gBAAI,OAAO,SAAS;AAClB,sBAAQ;AAAA,gBACN,SAAS,KAAK,SAAS,SAAS,MAAM,IAAI,SAAS,IAAI;AAAA,cACzD;AAAA,YACF;AAAA,UACF,SAAS,OAAY;AACnB,oBAAQ;AAAA,cACN,UAAU,SAAS,MAAM,IAAI,SAAS,IAAI;AAAA,cAC1C,MAAM;AAAA,YACR;AAAA,UACF;AAAA,QACF;AAEA,YAAI,OAAO,SAAS;AAClB,kBAAQ,IAAI,mBAAmB;AAAA,QACjC;AAAA,MACF;AAAA,IACF;AAAA,IAEA,gBAAgB,YAAY;AAE1B,aAAO,gBAAgB,UAAU;AAAA,IACnC;AAAA,EACF;AACF;AAMA,SAAS,oBAAoB,SAAkD;AAC7E,MAAI,OAAO,YAAY,UAAU;AAC/B,WAAO;AAAA,EACT;AAGA,QAAM,UAAU,QAAQ,SAAS,IAAI;AACrC,QAAM,WAAW,UAAU,QAAQ,MAAM,GAAG,EAAE,IAAI;AAGlD,SAAO;AAAA,IACL,MAAM;AAAA,IACN,YAAY,CAAC;AAAA,IACb;AAAA,EACF;AACF;AASA,IAAO,gBAAQ;","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,32 +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(`\u{1F4CD} \u7AEF\u70B9\u6570\u91CF: ${options.endpoints?.length || 0}`);
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}`);
577
570
  }
578
571
  },
579
572
  async buildStart() {
580
573
  if (autoGenerate && options.endpoints) {
581
574
  if (output.console) {
582
- console.log("\n\u{1F504} \u5F00\u59CB\u81EA\u52A8\u751F\u6210 Mock \u6570\u636E...\n");
575
+ console.log("\n🔄 开始自动生成 Mock 数据...\n");
583
576
  }
584
577
  for (const endpoint of options.endpoints) {
585
578
  const existingData = storage.get(endpoint.path, endpoint.method);
586
579
  if (existingData) {
587
580
  if (output.console) {
588
581
  console.log(
589
- `\u23ED\uFE0F \u8DF3\u8FC7 ${endpoint.method} ${endpoint.path} (\u5DF2\u6709\u6570\u636E)`
582
+ `⏭️ 跳过 ${endpoint.method} ${endpoint.path} (已有数据)`
590
583
  );
591
584
  }
592
585
  continue;
593
586
  }
594
587
  try {
595
588
  if (output.console) {
596
- console.log(`\u{1F3B2} \u751F\u6210 ${endpoint.method} ${endpoint.path}...`);
589
+ console.log(`🎲 生成 ${endpoint.method} ${endpoint.path}...`);
597
590
  }
598
591
  const typeDefinition = parseTypeDefinition(endpoint.response);
599
592
  const count = endpoint.count || generation.count || 20;
@@ -613,18 +606,18 @@ function vitePluginAIMockGenerator(options = {}) {
613
606
  });
614
607
  if (output.console) {
615
608
  console.log(
616
- `\u2705 \u5DF2\u751F\u6210 ${count} \u6761\u6570\u636E: ${endpoint.method} ${endpoint.path}`
609
+ `✅ 已生成 ${count} 条数据: ${endpoint.method} ${endpoint.path}`
617
610
  );
618
611
  }
619
612
  } catch (error) {
620
613
  console.error(
621
- `\u274C \u751F\u6210\u5931\u8D25 ${endpoint.method} ${endpoint.path}:`,
614
+ `❌ 生成失败 ${endpoint.method} ${endpoint.path}:`,
622
615
  error.message
623
616
  );
624
617
  }
625
618
  }
626
619
  if (output.console) {
627
- console.log("\n\u2728 Mock \u6570\u636E\u751F\u6210\u5B8C\u6210\n");
620
+ console.log("\n Mock 数据生成完成\n");
628
621
  }
629
622
  }
630
623
  },
@@ -646,7 +639,11 @@ function parseTypeDefinition(typeStr) {
646
639
  };
647
640
  }
648
641
  var index_default = vitePluginAIMockGenerator;
649
-
650
- export { MockDataGenerator, MockServer, MockStorage, index_default as default, vitePluginAIMockGenerator };
651
- //# sourceMappingURL=index.mjs.map
642
+ export {
643
+ MockDataGenerator,
644
+ MockServer,
645
+ MockStorage,
646
+ index_default as default,
647
+ vitePluginAIMockGenerator
648
+ };
652
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(`📍 端点数量: ${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"]}
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":";AAIA,OAAO,QAAQ;AACf,OAAO,UAAU;AAGV,IAAM,cAAN,MAAkB;AAAA,EAKvB,YAAY,UAA+C,CAAC,GAAG;AAC7D,SAAK,aAAa,QAAQ,OAAO;AACjC,SAAK,UAAU,QAAQ,YAAY;AACnC,SAAK,QAAQ,oBAAI,IAAI;AAGrB,QAAI,KAAK,WAAW,CAAC,GAAG,WAAW,KAAK,UAAU,GAAG;AACnD,SAAG,UAAU,KAAK,YAAY,EAAE,WAAW,KAAK,CAAC;AAAA,IACnD;AAGA,SAAK,KAAK;AAAA,EACZ;AAAA;AAAA;AAAA;AAAA,EAKQ,OAAO,UAAkB,QAA4B;AAC3D,WAAO,GAAG,MAAM,IAAI,QAAQ;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA,EAKQ,YAAY,UAAkB,QAA4B;AAChE,UAAM,YAAY,SACf,QAAQ,OAAO,EAAE,EACjB,QAAQ,OAAO,GAAG,EAClB,QAAQ,MAAM,GAAG;AACpB,WAAO,GAAG,MAAM,IAAI,SAAS;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,UAAkB,SAAqB,OAAY;AACrD,UAAM,MAAM,KAAK,OAAO,UAAU,MAAM;AACxC,UAAM,QAAQ,KAAK,MAAM,IAAI,GAAG;AAChC,WAAO,OAAO;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA,EAKA,IACE,UACA,QACA,MACA,UACM;AACN,UAAM,MAAM,KAAK,OAAO,UAAU,MAAM;AAExC,UAAM,QAAuB;AAAA,MAC3B;AAAA,MACA;AAAA,MACA;AAAA,MACA,UAAU;AAAA,QACR,OAAO,MAAM,QAAQ,IAAI,IAAI,KAAK,SAAS;AAAA,QAC3C,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,QACpC,SAAS;AAAA,QACT,MAAM,OAAO;AAAA,QACb,GAAG;AAAA,MACL;AAAA,IACF;AAEA,SAAK,MAAM,IAAI,KAAK,KAAK;AAGzB,QAAI,KAAK,SAAS;AAChB,WAAK,KAAK,UAAU,QAAQ,KAAK;AAAA,IACnC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,UAAkB,SAAqB,OAAa;AACzD,UAAM,MAAM,KAAK,OAAO,UAAU,MAAM;AACxC,SAAK,MAAM,OAAO,GAAG;AAGrB,QAAI,KAAK,SAAS;AAChB,YAAM,WAAW,KAAK,YAAY,UAAU,MAAM;AAClD,YAAM,WAAW,KAAK,KAAK,KAAK,YAAY,QAAQ;AACpD,UAAI,GAAG,WAAW,QAAQ,GAAG;AAC3B,WAAG,WAAW,QAAQ;AAAA,MACxB;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,QAAc;AACZ,SAAK,MAAM,MAAM;AAGjB,QAAI,KAAK,WAAW,GAAG,WAAW,KAAK,UAAU,GAAG;AAClD,YAAM,QAAQ,GAAG,YAAY,KAAK,UAAU;AAC5C,iBAAW,QAAQ,OAAO;AACxB,WAAG,WAAW,KAAK,KAAK,KAAK,YAAY,IAAI,CAAC;AAAA,MAChD;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,SAA0B;AACxB,WAAO,MAAM,KAAK,KAAK,MAAM,OAAO,CAAC;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA,EAKQ,KACN,UACA,QACA,OACM;AACN,UAAM,WAAW,KAAK,YAAY,UAAU,MAAM;AAClD,UAAM,WAAW,KAAK,KAAK,KAAK,YAAY,QAAQ;AAEpD,OAAG,cAAc,UAAU,KAAK,UAAU,OAAO,MAAM,CAAC,GAAG,OAAO;AAAA,EACpE;AAAA;AAAA;AAAA;AAAA,EAKQ,OAAa;AACnB,QAAI,CAAC,KAAK,WAAW,CAAC,GAAG,WAAW,KAAK,UAAU,GAAG;AACpD;AAAA,IACF;AAEA,UAAM,QAAQ,GAAG,YAAY,KAAK,UAAU;AAE5C,eAAW,QAAQ,OAAO;AACxB,UAAI,CAAC,KAAK,SAAS,OAAO,EAAG;AAE7B,UAAI;AACF,cAAM,WAAW,KAAK,KAAK,KAAK,YAAY,IAAI;AAChD,cAAM,UAAU,GAAG,aAAa,UAAU,OAAO;AACjD,cAAM,QAAuB,KAAK,MAAM,OAAO;AAE/C,cAAM,MAAM,KAAK,OAAO,MAAM,UAAU,MAAM,MAAM;AACpD,aAAK,MAAM,IAAI,KAAK,KAAK;AAAA,MAC3B,SAAS,OAAO;AACd,gBAAQ,KAAK,iCAAiC,IAAI,KAAK,KAAK;AAAA,MAC9D;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,YAA0B;AAC/B,UAAM,UAAU,KAAK,OAAO;AAC5B,OAAG,cAAc,YAAY,KAAK,UAAU,SAAS,MAAM,CAAC,GAAG,OAAO;AAAA,EACxE;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,WAAyB;AAC9B,UAAM,UAAU,GAAG,aAAa,WAAW,OAAO;AAClD,UAAM,UAA2B,KAAK,MAAM,OAAO;AAEnD,eAAW,SAAS,SAAS;AAC3B,YAAM,MAAM,KAAK,OAAO,MAAM,UAAU,MAAM,MAAM;AACpD,WAAK,MAAM,IAAI,KAAK,KAAK;AAEzB,UAAI,KAAK,SAAS;AAChB,aAAK,KAAK,MAAM,UAAU,MAAM,QAAQ,KAAK;AAAA,MAC/C;AAAA,IACF;AAAA,EACF;AACF;;;ACzLA,SAAS,kBAAkB;AAC3B,SAAS,cAAc,qBAAqB;AAOrC,IAAM,oBAAN,MAAwB;AAAA,EAG7B,YAAY,SAA4D;AACtE,SAAK,MAAM,IAAI,WAAW;AAAA,MACxB,cAAc,QAAQ;AAAA,MACtB,eAAe;AAAA,QACb,SAAS,QAAQ;AAAA,MACnB;AAAA,MACA,WAAW,QAAQ;AAAA,MACnB,aAAa;AAAA,MACb,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAS,SAA0C;AACvD,UAAM,EAAE,MAAM,OAAO,QAAQ,QAAQ,IAAI;AAGzC,UAAM,SAAS,KAAK,YAAY,MAAM,OAAO,QAAQ,OAAO;AAG5D,UAAM,WAAW,MAAM,KAAK,OAAO,MAAM;AAGzC,WAAO,KAAK,cAAc,UAAU,KAAK,OAAO;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA,EAKQ,YACN,MACA,OACA,QACA,SACQ;AACR,UAAM,aAAa,KAAK,WACrB,IAAI,CAAC,MAAM,KAAK,eAAe,CAAC,CAAC,EACjC,KAAK,IAAI;AAEZ,WAAO;AAAA;AAAA;AAAA,QAGH,KAAK,IAAI;AAAA,QACT,WAAW,UAAU,OAAO,IAAI;AAAA,QAChC,KAAK;AAAA,QAEP,YAAY,SACR,gBACA,YAAY,SACZ,SACA,SACN;AAAA;AAAA;AAAA,EAGF,UAAU;AAAA;AAAA;AAAA,QAGJ,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBX,KAAK;AAAA,EACL;AAAA;AAAA;AAAA;AAAA,EAKQ,eAAe,MAAkC;AACvD,QAAI,OAAO,KAAK,KAAK,IAAI,KAAK,KAAK,IAAI;AAEvC,QAAI,KAAK,SAAS;AAChB,cAAQ,OAAO,KAAK,OAAO;AAAA,IAC7B;AAEA,QAAI,KAAK,aAAa;AACpB,YAAM,cAAc,CAAC;AACrB,UAAI,KAAK,YAAY,QAAQ,QAAW;AACtC,oBAAY,KAAK,QAAQ,KAAK,YAAY,GAAG,EAAE;AAAA,MACjD;AACA,UAAI,KAAK,YAAY,QAAQ,QAAW;AACtC,oBAAY,KAAK,QAAQ,KAAK,YAAY,GAAG,EAAE;AAAA,MACjD;AACA,UAAI,KAAK,YAAY,QAAQ;AAC3B,oBAAY,KAAK,QAAQ;AAAA,MAC3B;AACA,UAAI,KAAK,YAAY,MAAM;AACzB,oBAAY,KAAK,UAAU,KAAK,YAAY,KAAK,KAAK,IAAI,CAAC,GAAG;AAAA,MAChE;AACA,UAAI,YAAY,SAAS,GAAG;AAC1B,gBAAQ,KAAK,YAAY,KAAK,IAAI,CAAC;AAAA,MACrC;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,OAAO,QAAiC;AACpD,QAAI;AACF,YAAM,WAAW;AAAA,QACf,IAAI;AAAA,UACF;AAAA,QACF;AAAA,QACA,IAAI,aAAa,MAAM;AAAA,MACzB;AAEA,YAAM,WAAW,MAAM,KAAK,IAAI,OAAO,QAAQ;AAC/C,aAAO,SAAS;AAAA,IAClB,SAAS,OAAY;AACnB,cAAQ,MAAM,kBAAkB,MAAM,OAAO;AAC7C,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,cAAc,UAAkB,UAAmB,MAAW;AACpE,QAAI;AAEF,UAAI,kBAAkB,SAAS,KAAK;AAGpC,wBAAkB,gBAAgB,QAAQ,gBAAgB,EAAE;AAC5D,wBAAkB,gBAAgB,QAAQ,WAAW,EAAE;AAGvD,wBAAkB,gBAAgB,QAAQ,WAAW,EAAE;AAGvD,YAAM,YAAY,gBAAgB,MAAM,2BAA2B;AACnE,UAAI,CAAC,WAAW;AACd,cAAM,IAAI,MAAM,2CAA2C;AAAA,MAC7D;AAEA,YAAM,OAAO,KAAK,MAAM,UAAU,CAAC,CAAC;AAEpC,aAAO,UAAU,OAAO,KAAK,CAAC;AAAA,IAChC,SAAS,OAAY;AACnB,cAAQ,MAAM,iBAAiB,MAAM,OAAO;AAC5C,cAAQ,MAAM,SAAS,QAAQ;AAC/B,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc,MAAsB,OAAsB;AACxD,UAAM,OAAO,CAAC;AAEd,aAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,YAAM,OAAY,CAAC;AAEnB,iBAAW,QAAQ,KAAK,YAAY;AAClC,aAAK,KAAK,IAAI,IAAI,KAAK,mBAAmB,MAAM,CAAC;AAAA,MACnD;AAEA,WAAK,KAAK,IAAI;AAAA,IAChB;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,mBAAmB,MAA0B,OAAoB;AACvE,UAAM,EAAE,MAAM,YAAY,IAAI;AAG9B,QAAI,aAAa,MAAM;AACrB,aAAO,YAAY,KAAK,QAAQ,YAAY,KAAK,MAAM;AAAA,IACzD;AAGA,YAAQ,MAAM;AAAA,MACZ,KAAK;AACH,cAAM,MAAM,aAAa,OAAO;AAChC,cAAM,MAAM,aAAa,OAAO;AAChC,eAAO,KAAK,MAAM,KAAK,OAAO,KAAK,MAAM,MAAM,EAAE,IAAI;AAAA,MAEvD,KAAK;AACH,eAAO,GAAG,KAAK,IAAI,IAAI,QAAQ,CAAC;AAAA,MAElC,KAAK;AACH,eAAO,KAAK,OAAO,IAAI;AAAA,MAEzB,KAAK;AACH,gBAAO,oBAAI,KAAK,GAAE,YAAY;AAAA,MAEhC;AACE,eAAO;AAAA,IACX;AAAA,EACF;AACF;;;AC1NO,SAAS,MAAM,IAA8C;AAClE,QAAM,YAAY,MAAM,QAAQ,EAAE,IAC9B,KAAK,OAAO,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,KAAK,GAAG,CAAC,IACtC;AAEJ,SAAO,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,SAAS,CAAC;AAChE;AAOO,SAAS,gBACd,SACAA,OAC+B;AAC/B,QAAM,eAAe,QAAQ,MAAM,GAAG;AACtC,QAAM,YAAYA,MAAK,MAAM,GAAG;AAEhC,MAAI,aAAa,WAAW,UAAU,QAAQ;AAC5C,WAAO;AAAA,EACT;AAEA,QAAM,SAAiC,CAAC;AAExC,WAAS,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;AAC5C,UAAM,cAAc,aAAa,CAAC;AAClC,UAAM,WAAW,UAAU,CAAC;AAE5B,QAAI,YAAY,WAAW,GAAG,GAAG;AAE/B,YAAM,YAAY,YAAY,MAAM,CAAC;AACrC,aAAO,SAAS,IAAI;AAAA,IACtB,WAAW,gBAAgB,UAAU;AAEnC,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;AAKO,SAAS,iBAAiB,KAAkC;AACjE,QAAM,cAAc,IAAI,MAAM,GAAG,EAAE,CAAC;AACpC,MAAI,CAAC,YAAa,QAAO,CAAC;AAE1B,QAAM,SAA8B,CAAC;AACrC,QAAM,QAAQ,YAAY,MAAM,GAAG;AAEnC,aAAW,QAAQ,OAAO;AACxB,UAAM,CAAC,KAAK,KAAK,IAAI,KAAK,MAAM,GAAG;AACnC,WAAO,mBAAmB,GAAG,CAAC,IAAI,mBAAmB,SAAS,EAAE;AAAA,EAClE;AAEA,SAAO;AACT;AAmBO,SAAS,aAAa,MAAa,SAAqC;AAC7E,MAAI,CAAC,WAAW,OAAO,KAAK,OAAO,EAAE,WAAW,GAAG;AACjD,WAAO;AAAA,EACT;AAEA,SAAO,KAAK,OAAO,CAAC,SAAS;AAC3B,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,OAAO,GAAG;AAClD,UAAI,KAAK,GAAG,MAAM,OAAO;AACvB,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO;AAAA,EACT,CAAC;AACH;AAKO,SAAS,aACd,MACA,MACO;AACP,MAAI,CAAC,KAAM,QAAO;AAElB,QAAM,aACJ,OAAO,SAAS,WACZ,EAAE,OAAO,MAAM,OAAO,MAAe,IACrC;AAEN,SAAO,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,MAAM;AAC9B,UAAM,SAAS,EAAE,WAAW,KAAK;AACjC,UAAM,SAAS,EAAE,WAAW,KAAK;AAEjC,QAAI,SAAS,OAAQ,QAAO,WAAW,UAAU,QAAQ,KAAK;AAC9D,QAAI,SAAS,OAAQ,QAAO,WAAW,UAAU,QAAQ,IAAI;AAC7D,WAAO;AAAA,EACT,CAAC;AACH;AAKO,SAAS,gBACd,MACA,OAAe,GACf,WAAmB,IASnB;AACA,QAAM,QAAQ,KAAK;AACnB,QAAM,aAAa,KAAK,KAAK,QAAQ,QAAQ;AAC7C,QAAM,SAAS,OAAO,KAAK;AAC3B,QAAM,MAAM,QAAQ;AAEpB,SAAO;AAAA,IACL,MAAM,KAAK,MAAM,OAAO,GAAG;AAAA,IAC3B,YAAY;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAKO,SAAS,eACd,MACA,UAAmB,MACnB,SACA;AACA,SAAO;AAAA,IACL,MAAM,UAAU,MAAM;AAAA,IACtB;AAAA,IACA,SAAS,YAAY,UAAU,YAAY;AAAA,EAC7C;AACF;;;ACtJO,IAAM,aAAN,MAAiB;AAAA,EAKtB,YAAY,SAAsB,SAA+B;AAC/D,SAAK,UAAU;AACf,SAAK,YAAY,QAAQ,aAAa,CAAC;AACvC,SAAK,UAAU;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB,QAA6B;AAC3C,WAAO,YAAY,IAAI,OAAO,KAAK,KAAK,SAAS;AAC/C,YAAM,MAAM,IAAI,OAAO;AACvB,YAAM,SAAS,IAAI;AAGnB,YAAM,WAAW,KAAK,cAAc,KAAK,MAAM;AAE/C,UAAI,CAAC,UAAU;AACb,eAAO,KAAK;AAAA,MACd;AAEA,UAAI;AAEF,cAAM,SAAS,KAAK,aAAa,KAAK,GAAG;AAGzC,cAAM,OAAO,MAAM,KAAK,YAAY,UAAU,MAAM;AAGpD,YAAI,KAAK,QAAQ,QAAQ,OAAO;AAC9B,gBAAM,MAAM,KAAK,QAAQ,OAAO,KAAK;AAAA,QACvC;AAGA,YAAI,UAAU,gBAAgB,kBAAkB;AAChD,YAAI,KAAK,QAAQ,QAAQ,MAAM;AAC7B,cAAI,UAAU,+BAA+B,GAAG;AAChD,cAAI,UAAU,gCAAgC,GAAG;AACjD,cAAI,UAAU,gCAAgC,GAAG;AAAA,QACnD;AAGA,YAAI,aAAa;AACjB,YAAI,IAAI,KAAK,UAAU,IAAI,CAAC;AAG5B,YAAI,KAAK,QAAQ,QAAQ,MAAM;AAC7B,kBAAQ,IAAI,UAAU,MAAM,IAAI,GAAG,MAAM,OAAO,OAAO,OAAO,EAAE;AAAA,QAClE;AAAA,MACF,SAAS,OAAY;AACnB,gBAAQ,MAAM,yBAAyB,MAAM,IAAI,GAAG,KAAK,KAAK;AAC9D,YAAI,aAAa;AACjB,YAAI;AAAA,UACF,KAAK,UAAU;AAAA,YACb,MAAM;AAAA,YACN,SAAS,MAAM;AAAA,UACjB,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF,CAAC;AAED,YAAQ,IAAI,kBAAkB;AAC9B,YAAQ,IAAI,UAAU,KAAK,UAAU,MAAM;AAAA,CAAQ;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA,EAKQ,cACN,KACA,QACuB;AAEvB,UAAMC,QAAO,IAAI,MAAM,GAAG,EAAE,CAAC;AAG7B,UAAM,SAAS,KAAK,QAAQ,QAAQ,UAAU;AAC9C,UAAM,YAAY,SAASA,MAAK,QAAQ,IAAI,OAAO,IAAI,MAAM,EAAE,GAAG,EAAE,IAAIA;AAExE,eAAW,YAAY,KAAK,WAAW;AAErC,UAAI,SAAS,YAAY,MAAO;AAGhC,UAAI,SAAS,WAAW,OAAQ;AAGhC,UAAI,SAAS,SAAS,WAAW;AAC/B,eAAO;AAAA,MACT;AAGA,UAAI,gBAAgB,SAAS,MAAM,SAAS,GAAG;AAC7C,eAAO;AAAA,MACT;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,aAAa,KAAU,KAAkB;AAC/C,UAAM,QAAQ,iBAAiB,GAAG;AAClC,UAAMA,QAAO,IAAI,MAAM,GAAG,EAAE,CAAC;AAG7B,UAAM,WAAW,KAAK,cAAcA,OAAM,IAAI,MAAM;AACpD,UAAM,aAAa,WACf,gBAAgB,SAAS,MAAMA,MAAK,MAAM,GAAG,EAAE,CAAC,CAAC,IACjD;AAEJ,WAAO;AAAA,MACL;AAAA,MACA,QAAQ,cAAc,CAAC;AAAA,MACvB,MAAM,IAAI;AAAA,MACV,SAAS,IAAI;AAAA,IACf;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,YACZ,UACA,QACc;AAEd,QAAI,OAAO,KAAK,QAAQ,IAAI,SAAS,MAAM,SAAS,MAAM;AAE1D,QAAI,CAAC,MAAM;AACT,cAAQ;AAAA,QACN,4BAA4B,SAAS,MAAM,IAAI,SAAS,IAAI;AAAA,MAC9D;AACA,aAAO,eAAe,CAAC,GAAG,OAAO,wBAAwB;AAAA,IAC3D;AAGA,QAAI,MAAM,QAAQ,IAAI,GAAG;AAEvB,UAAI,OAAO,MAAM,QAAQ;AACvB,eAAO,aAAa,MAAM,KAAK,MAAM,OAAO,MAAM,MAAM,CAAC;AAAA,MAC3D;AAGA,UAAI,OAAO,MAAM,MAAM;AACrB,eAAO,aAAa,MAAM,OAAO,MAAM,IAAI;AAAA,MAC7C;AAGA,UAAI,OAAO,MAAM,QAAQ,OAAO,MAAM,UAAU;AAC9C,cAAM,OAAO,SAAS,OAAO,MAAM,IAAI,KAAK;AAC5C,cAAM,WAAW,SAAS,OAAO,MAAM,QAAQ,KAAK;AACpD,cAAM,SAAS,gBAAgB,MAAM,MAAM,QAAQ;AAEnD,eAAO,eAAe;AAAA,UACpB,MAAM,OAAO;AAAA,UACb,YAAY,OAAO;AAAA,QACrB,CAAC;AAAA,MACH;AAAA,IACF;AAGA,QAAI,SAAS,QAAQ;AACnB,aAAO,MAAM,SAAS,OAAO,MAAM,MAAM;AAAA,IAC3C;AAGA,WAAO,eAAe,IAAI;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,UAAgC;AAC1C,SAAK,UAAU,KAAK,QAAQ;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA,EAKA,eAAeA,OAAc,QAA0B;AACrD,SAAK,YAAY,KAAK,UAAU;AAAA,MAC9B,CAAC,MAAM,EAAE,EAAE,SAASA,SAAQ,EAAE,WAAW;AAAA,IAC3C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,eAAiC;AAC/B,WAAO,KAAK;AAAA,EACd;AACF;;;AClNO,SAAS,0BACd,UAAgC,CAAC,GACzB;AACR,QAAM;AAAA,IACJ,SAAS,QAAQ,IAAI,kBAAkB;AAAA,IACvC,SAAS,QAAQ,IAAI,kBAAkB;AAAA,IACvC,QAAQ,QAAQ,IAAI,gBAAgB;AAAA,IACpC,UAAU;AAAA,IACV,eAAe;AAAA,IACf,aAAa;AAAA,MACX,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,SAAS;AAAA,IACX;AAAA,IACA,SAAS,iBAAiB;AAAA,MACxB,KAAK;AAAA,MACL,SAAS;AAAA,MACT,OAAO;AAAA,IACT;AAAA,IACA,SAAS;AAAA,MACP,SAAS;AAAA,MACT,MAAM;AAAA,IACR;AAAA,EACF,IAAI;AAGJ,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,MACL,MAAM;AAAA,IACR;AAAA,EACF;AAGA,QAAM,UAAU,IAAI,YAAY,cAAc;AAC9C,QAAM,YAAY,IAAI,kBAAkB,EAAE,QAAQ,QAAQ,MAAM,CAAC;AACjE,QAAM,SAAS,IAAI,WAAW,SAAS,OAAO;AAE9C,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA,IAET,eAAe,QAAQ;AACrB,UAAI,OAAO,SAAS;AAClB,gBAAQ,IAAI,4BAA4B;AACxC,gBAAQ,IAAI,YAAY,eAAe,GAAG,EAAE;AAC5C,gBAAQ,IAAI,YAAY,WAAW,MAAM,EAAE;AAC3C,gBAAQ,IAAI,YAAY,WAAW,KAAK,EAAE;AAC1C,gBAAQ,IAAI,eAAe,SAAS,QAAQ,KAAK,EAAE;AACnD,gBAAQ,IAAI,YAAY,QAAQ,WAAW,UAAU,CAAC,EAAE;AAAA,MAC1D;AAAA,IACF;AAAA,IAEA,MAAM,aAAa;AAEjB,UAAI,gBAAgB,QAAQ,WAAW;AACrC,YAAI,OAAO,SAAS;AAClB,kBAAQ,IAAI,0BAA0B;AAAA,QACxC;AAEA,mBAAW,YAAY,QAAQ,WAAW;AAExC,gBAAM,eAAe,QAAQ,IAAI,SAAS,MAAM,SAAS,MAAM;AAC/D,cAAI,cAAc;AAChB,gBAAI,OAAO,SAAS;AAClB,sBAAQ;AAAA,gBACN,UAAU,SAAS,MAAM,IAAI,SAAS,IAAI;AAAA,cAC5C;AAAA,YACF;AACA;AAAA,UACF;AAEA,cAAI;AACF,gBAAI,OAAO,SAAS;AAClB,sBAAQ,IAAI,SAAS,SAAS,MAAM,IAAI,SAAS,IAAI,KAAK;AAAA,YAC5D;AAGA,kBAAM,iBAAiB,oBAAoB,SAAS,QAAQ;AAG5D,kBAAM,QAAQ,SAAS,SAAS,WAAW,SAAS;AACpD,gBAAI;AAGJ,gBAAI,WAAW,YAAY,QAAQ;AAEjC,qBAAO,UAAU,cAAc,gBAAgB,KAAK;AAAA,YACtD,OAAO;AAEL,qBAAO,MAAM,UAAU,SAAS;AAAA,gBAC9B,MAAM;AAAA,gBACN;AAAA,gBACA,QAAQ,WAAW,UAAU;AAAA,gBAC7B,SAAS,WAAW,WAAW;AAAA,cACjC,CAAC;AAAA,YACH;AAGA,oBAAQ,IAAI,SAAS,MAAM,SAAS,QAAQ,MAAM;AAAA,cAChD,MAAM,SAAS;AAAA,YACjB,CAAC;AAED,gBAAI,OAAO,SAAS;AAClB,sBAAQ;AAAA,gBACN,SAAS,KAAK,SAAS,SAAS,MAAM,IAAI,SAAS,IAAI;AAAA,cACzD;AAAA,YACF;AAAA,UACF,SAAS,OAAY;AACnB,oBAAQ;AAAA,cACN,UAAU,SAAS,MAAM,IAAI,SAAS,IAAI;AAAA,cAC1C,MAAM;AAAA,YACR;AAAA,UACF;AAAA,QACF;AAEA,YAAI,OAAO,SAAS;AAClB,kBAAQ,IAAI,mBAAmB;AAAA,QACjC;AAAA,MACF;AAAA,IACF;AAAA,IAEA,gBAAgB,YAAY;AAE1B,aAAO,gBAAgB,UAAU;AAAA,IACnC;AAAA,EACF;AACF;AAMA,SAAS,oBAAoB,SAAkD;AAC7E,MAAI,OAAO,YAAY,UAAU;AAC/B,WAAO;AAAA,EACT;AAGA,QAAM,UAAU,QAAQ,SAAS,IAAI;AACrC,QAAM,WAAW,UAAU,QAAQ,MAAM,GAAG,EAAE,IAAI;AAGlD,SAAO;AAAA,IACL,MAAM;AAAA,IACN,YAAY,CAAC;AAAA,IACb;AAAA,EACF;AACF;AASA,IAAO,gBAAQ;","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.2",
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",