mock-data-mcp 1.0.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.
Files changed (40) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +164 -0
  3. package/data/mock.db +0 -0
  4. package/dist/db.d.ts +17 -0
  5. package/dist/db.d.ts.map +1 -0
  6. package/dist/db.js +127 -0
  7. package/dist/db.js.map +1 -0
  8. package/dist/generators/address.d.ts +14 -0
  9. package/dist/generators/address.d.ts.map +1 -0
  10. package/dist/generators/address.js +44 -0
  11. package/dist/generators/address.js.map +1 -0
  12. package/dist/generators/gemini.d.ts +7 -0
  13. package/dist/generators/gemini.d.ts.map +1 -0
  14. package/dist/generators/gemini.js +121 -0
  15. package/dist/generators/gemini.js.map +1 -0
  16. package/dist/generators/identity.d.ts +3 -0
  17. package/dist/generators/identity.d.ts.map +1 -0
  18. package/dist/generators/identity.js +56 -0
  19. package/dist/generators/identity.js.map +1 -0
  20. package/dist/generators/index.d.ts +7 -0
  21. package/dist/generators/index.d.ts.map +1 -0
  22. package/dist/generators/index.js +160 -0
  23. package/dist/generators/index.js.map +1 -0
  24. package/dist/generators/name.d.ts +4 -0
  25. package/dist/generators/name.d.ts.map +1 -0
  26. package/dist/generators/name.js +30 -0
  27. package/dist/generators/name.js.map +1 -0
  28. package/dist/generators/phone.d.ts +3 -0
  29. package/dist/generators/phone.d.ts.map +1 -0
  30. package/dist/generators/phone.js +25 -0
  31. package/dist/generators/phone.js.map +1 -0
  32. package/dist/index.d.ts +3 -0
  33. package/dist/index.d.ts.map +1 -0
  34. package/dist/index.js +242 -0
  35. package/dist/index.js.map +1 -0
  36. package/dist/types.d.ts +36 -0
  37. package/dist/types.d.ts.map +1 -0
  38. package/dist/types.js +3 -0
  39. package/dist/types.js.map +1 -0
  40. package/package.json +66 -0
@@ -0,0 +1,160 @@
1
+ // src/generators/index.ts - 產生器主控制器 (優化版:批次預載)
2
+ import { getDb } from '../db.js';
3
+ import { generateIdNumber } from './identity.js';
4
+ import { generatePhone } from './phone.js';
5
+ import { generateBatchWithAI } from './gemini.js';
6
+ let _cache = null;
7
+ function loadCache() {
8
+ if (_cache)
9
+ return _cache;
10
+ const db = getDb();
11
+ const names = db.prepare('SELECT surname, given_name FROM names').all();
12
+ const regions = db.prepare('SELECT county, district, zip_code FROM regions').all();
13
+ const streets = db.prepare('SELECT name, type FROM streets').all();
14
+ const companies = db.prepare('SELECT name FROM companies').all().map(r => r.name);
15
+ const jobTitles = db.prepare('SELECT title FROM job_titles').all().map(r => r.title);
16
+ // 建立 county → districts 索引
17
+ const regionsByCounty = new Map();
18
+ for (const r of regions) {
19
+ let arr = regionsByCounty.get(r.county);
20
+ if (!arr) {
21
+ arr = [];
22
+ regionsByCounty.set(r.county, arr);
23
+ }
24
+ arr.push({ district: r.district, zip_code: r.zip_code });
25
+ }
26
+ const counties = [...regionsByCounty.keys()];
27
+ _cache = { names, regions, regionsByCounty, streets, companies, jobTitles, counties };
28
+ return _cache;
29
+ }
30
+ // 快取取樣工具
31
+ function pick(arr) {
32
+ return arr[Math.floor(Math.random() * arr.length)];
33
+ }
34
+ // ── 解析欄位設定 ──
35
+ function parseFieldConfig(field) {
36
+ if (typeof field === 'string') {
37
+ return { type: field };
38
+ }
39
+ return field;
40
+ }
41
+ // ── 產生單一欄位值 (使用快取) ──
42
+ function generateFieldValue(config, cache, rowContext = {}) {
43
+ switch (config.type) {
44
+ case 'name': {
45
+ const n = pick(cache.names);
46
+ return `${n.surname}${n.given_name}`;
47
+ }
48
+ case 'phone':
49
+ return generatePhone();
50
+ case 'id_number':
51
+ return generateIdNumber();
52
+ case 'county':
53
+ return pick(cache.counties);
54
+ case 'district': {
55
+ const county = typeof rowContext.county === 'string' ? rowContext.county : undefined;
56
+ if (county && cache.regionsByCounty.has(county)) {
57
+ return pick(cache.regionsByCounty.get(county)).district;
58
+ }
59
+ return pick(cache.regions).district;
60
+ }
61
+ case 'address': {
62
+ const region = pick(cache.regions);
63
+ const street = pick(cache.streets);
64
+ const streetName = `${street.name}${street.type}`;
65
+ const lane = Math.floor(Math.random() * 50) + 1;
66
+ const num = Math.floor(Math.random() * 200) + 1;
67
+ const formats = [
68
+ `${streetName}${lane}巷${num}號`,
69
+ `${streetName}${lane}巷${Math.floor(Math.random() * 30) + 1}弄${num}號`,
70
+ `${streetName}${lane}巷${num}號${Math.floor(Math.random() * 15) + 1}樓`,
71
+ `${streetName}${num}號`,
72
+ `${streetName}${lane}巷${num}之${Math.floor(Math.random() * 20) + 1}號`,
73
+ ];
74
+ const streetPart = pick(formats);
75
+ return `${region.zip_code} ${region.county}${region.district}${streetPart}`;
76
+ }
77
+ case 'email': {
78
+ const n = pick(cache.names);
79
+ const domains = ['gmail.com', 'yahoo.com.tw', 'hotmail.com', 'outlook.com', 'mail.com.tw', 'pchome.com.tw'];
80
+ const domain = pick(domains);
81
+ const pinyin = n.surname.charCodeAt(0).toString(36);
82
+ const num = Math.floor(Math.random() * 9999);
83
+ return `${pinyin}${n.given_name.charCodeAt(0).toString(36)}${num}@${domain}`;
84
+ }
85
+ case 'company':
86
+ return pick(cache.companies);
87
+ case 'job_title':
88
+ return pick(cache.jobTitles);
89
+ case 'boolean':
90
+ return Math.random() > 0.5;
91
+ case 'uuid':
92
+ return crypto.randomUUID();
93
+ case 'number': {
94
+ const min = Number(config.min ?? 0);
95
+ const max = Number(config.max ?? 100);
96
+ return Math.floor(Math.random() * (max - min + 1)) + min;
97
+ }
98
+ case 'string': {
99
+ const len = config.length ?? 10;
100
+ const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
101
+ let result = '';
102
+ for (let i = 0; i < len; i++) {
103
+ result += chars[Math.floor(Math.random() * chars.length)];
104
+ }
105
+ return config.prefix ? config.prefix + result : result;
106
+ }
107
+ case 'date': {
108
+ const minDate = config.min ? new Date(String(config.min)).getTime() : new Date('1960-01-01').getTime();
109
+ const maxDate = config.max ? new Date(String(config.max)).getTime() : Date.now();
110
+ const ts = minDate + Math.random() * (maxDate - minDate);
111
+ return new Date(ts).toISOString().split('T')[0];
112
+ }
113
+ default:
114
+ return null;
115
+ }
116
+ }
117
+ // ── 產生完整資料陣列 (優化:一次預載,多次取用) ──
118
+ export function generateLocal(schema, count) {
119
+ const cache = loadCache();
120
+ const results = [];
121
+ const entries = Object.entries(schema);
122
+ const configs = entries.map(([key, field]) => [key, parseFieldConfig(field)]);
123
+ for (let i = 0; i < count; i++) {
124
+ const row = {};
125
+ for (const [fieldName, config] of configs) {
126
+ row[fieldName] = generateFieldValue(config, cache, row);
127
+ }
128
+ results.push(row);
129
+ }
130
+ return results;
131
+ }
132
+ // ── 產生完整資料陣列 (含 AI 增強) ──
133
+ export async function generateWithAIEnhanced(schema, count) {
134
+ const localFields = {};
135
+ const aiFields = [];
136
+ for (const [key, field] of Object.entries(schema)) {
137
+ const config = parseFieldConfig(field);
138
+ if (config.type === 'ai' && config.prompt) {
139
+ aiFields.push({ fieldName: key, prompt: config.prompt });
140
+ }
141
+ else {
142
+ localFields[key] = field;
143
+ }
144
+ }
145
+ const localData = generateLocal(localFields, count);
146
+ if (aiFields.length === 0) {
147
+ return { data: localData, aiUsed: false };
148
+ }
149
+ const aiData = await generateBatchWithAI(aiFields, count);
150
+ const results = [];
151
+ for (let i = 0; i < count; i++) {
152
+ const row = { ...localData[i] };
153
+ for (const { fieldName } of aiFields) {
154
+ row[fieldName] = aiData[fieldName]?.[i] ?? null;
155
+ }
156
+ results.push(row);
157
+ }
158
+ return { data: results, aiUsed: true };
159
+ }
160
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/generators/index.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAclD,IAAI,MAAM,GAAqB,IAAI,CAAC;AAEpC,SAAS,SAAS;IAChB,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAE1B,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;IAEnB,MAAM,KAAK,GAAG,EAAE,CAAC,OAAO,CAAC,uCAAuC,CAAC,CAAC,GAAG,EAAoD,CAAC;IAC1H,MAAM,OAAO,GAAG,EAAE,CAAC,OAAO,CAAC,gDAAgD,CAAC,CAAC,GAAG,EAAmE,CAAC;IACpJ,MAAM,OAAO,GAAG,EAAE,CAAC,OAAO,CAAC,gCAAgC,CAAC,CAAC,GAAG,EAA2C,CAAC;IAC5G,MAAM,SAAS,GAAI,EAAE,CAAC,OAAO,CAAC,4BAA4B,CAAC,CAAC,GAAG,EAA8B,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAC/G,MAAM,SAAS,GAAI,EAAE,CAAC,OAAO,CAAC,8BAA8B,CAAC,CAAC,GAAG,EAA+B,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAEnH,2BAA2B;IAC3B,MAAM,eAAe,GAAG,IAAI,GAAG,EAAyD,CAAC;IACzF,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,IAAI,GAAG,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACxC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,GAAG,GAAG,EAAE,CAAC;YACT,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACrC,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED,MAAM,QAAQ,GAAG,CAAC,GAAG,eAAe,CAAC,IAAI,EAAE,CAAC,CAAC;IAE7C,MAAM,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtF,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS;AACT,SAAS,IAAI,CAAI,GAAQ;IACvB,OAAO,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;AACrD,CAAC;AAED,eAAe;AACf,SAAS,gBAAgB,CAAC,KAAkB;IAC1C,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,EAAE,IAAI,EAAE,KAA4B,EAAE,CAAC;IAChD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,uBAAuB;AACvB,SAAS,kBAAkB,CAAC,MAAmB,EAAE,KAAgB,EAAE,aAAsC,EAAE;IACzG,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC5B,OAAO,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,UAAU,EAAE,CAAC;QACvC,CAAC;QACD,KAAK,OAAO;YACV,OAAO,aAAa,EAAE,CAAC;QACzB,KAAK,WAAW;YACd,OAAO,gBAAgB,EAAE,CAAC;QAC5B,KAAK,QAAQ;YACX,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC9B,KAAK,UAAU,CAAC,CAAC,CAAC;YAChB,MAAM,MAAM,GAAG,OAAO,UAAU,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;YACrF,IAAI,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;gBAChD,OAAO,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAE,CAAC,CAAC,QAAQ,CAAC;YAC3D,CAAC;YACD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC;QACtC,CAAC;QACD,KAAK,SAAS,CAAC,CAAC,CAAC;YACf,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACnC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACnC,MAAM,UAAU,GAAG,GAAG,MAAM,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;YAClD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;YAChD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;YAChD,MAAM,OAAO,GAAG;gBACd,GAAG,UAAU,GAAG,IAAI,IAAI,GAAG,GAAG;gBAC9B,GAAG,UAAU,GAAG,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG;gBACpE,GAAG,UAAU,GAAG,IAAI,IAAI,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG;gBACpE,GAAG,UAAU,GAAG,GAAG,GAAG;gBACtB,GAAG,UAAU,GAAG,IAAI,IAAI,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG;aACrE,CAAC;YACF,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;YACjC,OAAO,GAAG,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,QAAQ,GAAG,UAAU,EAAE,CAAC;QAC9E,CAAC;QACD,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC5B,MAAM,OAAO,GAAG,CAAC,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,eAAe,CAAC,CAAC;YAC5G,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;YAC7B,MAAM,MAAM,GAAG,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;YACpD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC;YAC7C,OAAO,GAAG,MAAM,GAAG,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,GAAG,IAAI,MAAM,EAAE,CAAC;QAC/E,CAAC;QACD,KAAK,SAAS;YACZ,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAC/B,KAAK,WAAW;YACd,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAC/B,KAAK,SAAS;YACZ,OAAO,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC;QAC7B,KAAK,MAAM;YACT,OAAO,MAAM,CAAC,UAAU,EAAE,CAAC;QAC7B,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;YACpC,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC;YACtC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;QAC3D,CAAC;QACD,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC;YAChC,MAAM,KAAK,GAAG,gEAAgE,CAAC;YAC/E,IAAI,MAAM,GAAG,EAAE,CAAC;YAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC7B,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;YAC5D,CAAC;YACD,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;QACzD,CAAC;QACD,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE,CAAC;YACvG,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;YACjF,MAAM,EAAE,GAAG,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,OAAO,GAAG,OAAO,CAAC,CAAC;YACzD,OAAO,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAClD,CAAC;QACD;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC;AAED,gCAAgC;AAChC,MAAM,UAAU,aAAa,CAAC,MAAmC,EAAE,KAAa;IAC9E,MAAM,KAAK,GAAG,SAAS,EAAE,CAAC;IAC1B,MAAM,OAAO,GAA8B,EAAE,CAAC;IAC9C,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACvC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,gBAAgB,CAAC,KAAK,CAAC,CAAU,CAAC,CAAC;IAEvF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/B,MAAM,GAAG,GAA4B,EAAE,CAAC;QACxC,KAAK,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YAC1C,GAAG,CAAC,SAAS,CAAC,GAAG,kBAAkB,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;QAC1D,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACpB,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,2BAA2B;AAC3B,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,MAAmC,EACnC,KAAa;IAEb,MAAM,WAAW,GAAgC,EAAE,CAAC;IACpD,MAAM,QAAQ,GAAiD,EAAE,CAAC;IAElE,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,MAAM,MAAM,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;QACvC,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAC1C,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QAC3D,CAAC;aAAM,CAAC;YACN,WAAW,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,MAAM,SAAS,GAAG,aAAa,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IAEpD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAC5C,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAE1D,MAAM,OAAO,GAA8B,EAAE,CAAC;IAC9C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/B,MAAM,GAAG,GAAG,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;QAChC,KAAK,MAAM,EAAE,SAAS,EAAE,IAAI,QAAQ,EAAE,CAAC;YACrC,GAAG,CAAC,SAAS,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;QAClD,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACpB,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AACzC,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare function generateName(gender?: 'M' | 'F' | 'N'): string;
2
+ export declare function generateSurname(): string;
3
+ export declare function generateGivenName(gender?: 'M' | 'F'): string;
4
+ //# sourceMappingURL=name.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"name.d.ts","sourceRoot":"","sources":["../../src/generators/name.ts"],"names":[],"mappings":"AAIA,wBAAgB,YAAY,CAAC,MAAM,CAAC,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,MAAM,CAc7D;AAED,wBAAgB,eAAe,IAAI,MAAM,CAIxC;AAED,wBAAgB,iBAAiB,CAAC,MAAM,CAAC,EAAE,GAAG,GAAG,GAAG,GAAG,MAAM,CAQ5D"}
@@ -0,0 +1,30 @@
1
+ // src/generators/name.ts - 台灣姓名產生器
2
+ import { getDb } from '../db.js';
3
+ export function generateName(gender) {
4
+ const db = getDb();
5
+ let query = 'SELECT * FROM names ORDER BY RANDOM() LIMIT 1';
6
+ const params = [];
7
+ if (gender && gender !== 'N') {
8
+ query = 'SELECT * FROM names WHERE gender = ? ORDER BY RANDOM() LIMIT 1';
9
+ params.push(gender);
10
+ }
11
+ const row = db.prepare(query).get(...params);
12
+ if (!row)
13
+ return '王小明';
14
+ return `${row.surname}${row.given_name}`;
15
+ }
16
+ export function generateSurname() {
17
+ const db = getDb();
18
+ const row = db.prepare('SELECT DISTINCT surname FROM names ORDER BY RANDOM() LIMIT 1').get();
19
+ return row?.surname || '王';
20
+ }
21
+ export function generateGivenName(gender) {
22
+ const db = getDb();
23
+ let query = 'SELECT given_name FROM names ORDER BY RANDOM() LIMIT 1';
24
+ if (gender) {
25
+ query = 'SELECT given_name FROM names WHERE gender = ? ORDER BY RANDOM() LIMIT 1';
26
+ }
27
+ const row = db.prepare(query).get(...(gender ? [gender] : []));
28
+ return row?.given_name || '小明';
29
+ }
30
+ //# sourceMappingURL=name.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"name.js","sourceRoot":"","sources":["../../src/generators/name.ts"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAGjC,MAAM,UAAU,YAAY,CAAC,MAAwB;IACnD,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;IAEnB,IAAI,KAAK,GAAG,+CAA+C,CAAC;IAC5D,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,IAAI,MAAM,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;QAC7B,KAAK,GAAG,gEAAgE,CAAC;QACzE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACtB,CAAC;IAED,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,MAAM,CAAwB,CAAC;IACpE,IAAI,CAAC,GAAG;QAAE,OAAO,KAAK,CAAC;IACvB,OAAO,GAAG,GAAG,CAAC,OAAO,GAAG,GAAG,CAAC,UAAU,EAAE,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;IACnB,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,8DAA8D,CAAC,CAAC,GAAG,EAAqC,CAAC;IAChI,OAAO,GAAG,EAAE,OAAO,IAAI,GAAG,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,MAAkB;IAClD,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;IACnB,IAAI,KAAK,GAAG,wDAAwD,CAAC;IACrE,IAAI,MAAM,EAAE,CAAC;QACX,KAAK,GAAG,yEAAyE,CAAC;IACpF,CAAC;IACD,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAuC,CAAC;IACrG,OAAO,GAAG,EAAE,UAAU,IAAI,IAAI,CAAC;AACjC,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare function generatePhone(): string;
2
+ export declare function generatePhoneFormatted(separator?: string): string;
3
+ //# sourceMappingURL=phone.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"phone.d.ts","sourceRoot":"","sources":["../../src/generators/phone.ts"],"names":[],"mappings":"AAcA,wBAAgB,aAAa,IAAI,MAAM,CAOtC;AAED,wBAAgB,sBAAsB,CAAC,SAAS,GAAE,MAAY,GAAG,MAAM,CAGtE"}
@@ -0,0 +1,25 @@
1
+ // src/generators/phone.ts - 台灣手機號碼產生器
2
+ // 格式: 09XX-XXXXXX (10 碼)
3
+ // 常見電信前綴
4
+ const MOBILE_PREFIXES = [
5
+ '0910', '0911', '0912', '0913', '0914', '0915', '0916', '0917', '0918', '0919',
6
+ '0920', '0921', '0922', '0923', '0924', '0925', '0926', '0927', '0928', '0929',
7
+ '0930', '0931', '0932', '0933', '0934', '0935', '0936', '0937', '0938', '0939',
8
+ '0952', '0953', '0954', '0955', '0956', '0958',
9
+ '0960', '0961', '0962', '0963', '0965', '0966', '0967', '0968',
10
+ '0970', '0971', '0972', '0973', '0974', '0975', '0976', '0977', '0978', '0979',
11
+ '0980', '0981', '0982', '0983', '0984', '0985', '0986', '0987', '0988', '0989',
12
+ ];
13
+ export function generatePhone() {
14
+ const prefix = MOBILE_PREFIXES[Math.floor(Math.random() * MOBILE_PREFIXES.length)];
15
+ let suffix = '';
16
+ for (let i = 0; i < 6; i++) {
17
+ suffix += Math.floor(Math.random() * 10).toString();
18
+ }
19
+ return `${prefix}${suffix}`;
20
+ }
21
+ export function generatePhoneFormatted(separator = '-') {
22
+ const phone = generatePhone();
23
+ return `${phone.slice(0, 4)}${separator}${phone.slice(4)}`;
24
+ }
25
+ //# sourceMappingURL=phone.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"phone.js","sourceRoot":"","sources":["../../src/generators/phone.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,yBAAyB;AAEzB,SAAS;AACT,MAAM,eAAe,GAAG;IACtB,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9E,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9E,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9E,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9C,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9E,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAC/E,CAAC;AAEF,MAAM,UAAU,aAAa;IAC3B,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC;IACnF,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;IACtD,CAAC;IACD,OAAO,GAAG,MAAM,GAAG,MAAM,EAAE,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,YAAoB,GAAG;IAC5D,MAAM,KAAK,GAAG,aAAa,EAAE,CAAC;IAC9B,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AAC7D,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ import 'dotenv/config';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAYA,OAAO,eAAe,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,242 @@
1
+ #!/usr/bin/env node
2
+ // src/index.ts - MCP 假資料產生器伺服器
3
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
4
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
5
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
6
+ import { z } from 'zod';
7
+ import { generateLocal, generateWithAIEnhanced } from './generators/index.js';
8
+ import { getDb } from './db.js';
9
+ import 'dotenv/config';
10
+ // ── Zod Schema 驗證 ──
11
+ const FieldSchema = z.union([
12
+ z.enum([
13
+ 'name', 'phone', 'id_number', 'county', 'district', 'address',
14
+ 'email', 'company', 'job_title', 'boolean', 'uuid',
15
+ ]),
16
+ z.object({
17
+ type: z.enum([
18
+ 'name', 'phone', 'id_number', 'county', 'district', 'address',
19
+ 'email', 'company', 'job_title', 'boolean', 'uuid',
20
+ 'date', 'number', 'string', 'ai',
21
+ ]),
22
+ min: z.union([z.number(), z.string()]).optional(),
23
+ max: z.union([z.number(), z.string()]).optional(),
24
+ length: z.number().optional(),
25
+ format: z.string().optional(),
26
+ prompt: z.string().optional(),
27
+ options: z.array(z.string()).optional(),
28
+ prefix: z.string().optional(),
29
+ }),
30
+ ]);
31
+ const GenerateRequestSchema = z.object({
32
+ schema: z.record(z.string(), FieldSchema),
33
+ count: z.number().int().min(1).max(10000),
34
+ });
35
+ // ── 工具定義 ──
36
+ const TOOLS = [
37
+ {
38
+ name: 'generate_mock_data',
39
+ description: `超高效率假資料產生器。輸入 JSON schema 和數量,輸出陣列 JSON。
40
+ 支援欄位類型:
41
+ - name: 台灣姓名 (含姓氏+名字)
42
+ - phone: 台灣手機號碼 (09XXXXXXXX)
43
+ - id_number: 台灣身份證字號 (含驗證碼)
44
+ - county: 縣市
45
+ - district: 鄉鎮市區
46
+ - address: 完整地址 (含郵遞區號)
47
+ - email: Email 地址
48
+ - company: 公司名稱
49
+ - job_title: 職稱
50
+ - boolean: 布林值
51
+ - uuid: UUID
52
+ - number: 數字 (需指定 min/max)
53
+ - date: 日期 (需指定 min/max,格式 YYYY-MM-DD)
54
+ - string: 隨機字串 (可指定 length/prefix)
55
+ - ai: 用 Gemini AI 產生 (需指定 prompt,適合複雜資料如商品分類)
56
+
57
+ 範例輸入:
58
+ {
59
+ "schema": {
60
+ "name": "name",
61
+ "phone": "phone",
62
+ "id_number": "id_number",
63
+ "county": "county",
64
+ "address": "address",
65
+ "age": { "type": "number", "min": 18, "max": 65 },
66
+ "salary": { "type": "number", "min": 30000, "max": 120000 },
67
+ "birth_date": { "type": "date", "min": "1960-01-01", "max": "2005-12-31" },
68
+ "active": "boolean",
69
+ "user_id": { "type": "string", "prefix": "USR_", "length": 8 },
70
+ "product_category": { "type": "ai", "prompt": "台灣常見電商商品分類" }
71
+ },
72
+ "count": 10
73
+ }`,
74
+ inputSchema: {
75
+ type: 'object',
76
+ properties: {
77
+ schema: {
78
+ type: 'object',
79
+ description: '欄位定義物件。key 為欄位名稱,value 為欄位類型字串或設定物件',
80
+ additionalProperties: {
81
+ oneOf: [
82
+ { type: 'string', description: '欄位類型名稱' },
83
+ {
84
+ type: 'object',
85
+ properties: {
86
+ type: { type: 'string', description: '欄位類型' },
87
+ min: { oneOf: [{ type: 'number' }, { type: 'string' }], description: '最小值 (number/date)' },
88
+ max: { oneOf: [{ type: 'number' }, { type: 'string' }], description: '最大值 (number/date)' },
89
+ length: { type: 'number', description: '長度 (string)' },
90
+ prompt: { type: 'string', description: 'AI 產生的提示詞' },
91
+ prefix: { type: 'string', description: '前綴字串' },
92
+ format: { type: 'string', description: '格式' },
93
+ options: { type: 'array', items: { type: 'string' }, description: '選項列表' },
94
+ },
95
+ required: ['type'],
96
+ },
97
+ ],
98
+ },
99
+ },
100
+ count: {
101
+ type: 'number',
102
+ description: '要產生的資料筆數 (1-10000)',
103
+ minimum: 1,
104
+ maximum: 10000,
105
+ },
106
+ },
107
+ required: ['schema', 'count'],
108
+ },
109
+ },
110
+ {
111
+ name: 'get_field_types',
112
+ description: '取得所有支援的欄位類型說明',
113
+ inputSchema: {
114
+ type: 'object',
115
+ properties: {},
116
+ },
117
+ },
118
+ {
119
+ name: 'get_db_stats',
120
+ description: '取得 SQLite 資料庫統計資訊 (縣市數量、姓名數量等)',
121
+ inputSchema: {
122
+ type: 'object',
123
+ properties: {},
124
+ },
125
+ },
126
+ ];
127
+ // ── MCP Server ──
128
+ const server = new Server({ name: 'mockcraft-mcp', version: '1.0.0' }, { capabilities: { tools: {} } });
129
+ // List tools
130
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
131
+ tools: TOOLS,
132
+ }));
133
+ // Call tool
134
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
135
+ const { name, arguments: args } = request.params;
136
+ switch (name) {
137
+ case 'generate_mock_data': {
138
+ const parsed = GenerateRequestSchema.safeParse(args);
139
+ if (!parsed.success) {
140
+ return {
141
+ content: [{
142
+ type: 'text',
143
+ text: `Invalid input: ${parsed.error.message}`,
144
+ }],
145
+ isError: true,
146
+ };
147
+ }
148
+ const { schema, count } = parsed.data;
149
+ const startTime = performance.now();
150
+ // 檢查是否有 AI 欄位
151
+ const hasAI = Object.values(schema).some((f) => {
152
+ const type = typeof f === 'string' ? f : f.type;
153
+ return type === 'ai';
154
+ });
155
+ let data;
156
+ let aiUsed = false;
157
+ if (hasAI) {
158
+ const result = await generateWithAIEnhanced(schema, count);
159
+ data = result.data;
160
+ aiUsed = result.aiUsed;
161
+ }
162
+ else {
163
+ data = generateLocal(schema, count);
164
+ }
165
+ const elapsed = (performance.now() - startTime).toFixed(1);
166
+ return {
167
+ content: [{
168
+ type: 'text',
169
+ text: JSON.stringify(data, null, 2),
170
+ }],
171
+ _meta: {
172
+ count: data.length,
173
+ elapsed_ms: parseFloat(elapsed),
174
+ ai_used: aiUsed,
175
+ },
176
+ };
177
+ }
178
+ case 'get_field_types': {
179
+ const types = {
180
+ name: '台灣姓名 (含姓氏+名字)',
181
+ phone: '台灣手機號碼 (09XXXXXXXX)',
182
+ id_number: '台灣身份證字號 (含驗證碼)',
183
+ county: '縣市 (台灣 22 縣市)',
184
+ district: '鄉鎮市區 (隨機)',
185
+ address: '完整地址 (含郵遞區號、縣市、鄉鎮、街道、巷弄、號、樓)',
186
+ email: 'Email 地址',
187
+ company: '公司名稱 (台灣常見)',
188
+ job_title: '職稱',
189
+ boolean: '布林值 (true/false)',
190
+ uuid: 'UUID v4',
191
+ number: '數字 (需指定 min/max)',
192
+ date: '日期 YYYY-MM-DD (需指定 min/max)',
193
+ string: '隨機英數字串 (可指定 length/prefix)',
194
+ ai: 'Gemini AI 產生 (需指定 prompt)',
195
+ };
196
+ return {
197
+ content: [{
198
+ type: 'text',
199
+ text: JSON.stringify(types, null, 2),
200
+ }],
201
+ };
202
+ }
203
+ case 'get_db_stats': {
204
+ const db = getDb();
205
+ const stats = {
206
+ regions: db.prepare('SELECT COUNT(*) as c FROM regions').get().c,
207
+ names: db.prepare('SELECT COUNT(*) as c FROM names').get().c,
208
+ streets: db.prepare('SELECT COUNT(*) as c FROM streets').get().c,
209
+ companies: db.prepare('SELECT COUNT(*) as c FROM companies').get().c,
210
+ job_titles: db.prepare('SELECT COUNT(*) as c FROM job_titles').get().c,
211
+ counties: db.prepare('SELECT COUNT(DISTINCT county) as c FROM regions').get().c,
212
+ };
213
+ return {
214
+ content: [{
215
+ type: 'text',
216
+ text: JSON.stringify(stats, null, 2),
217
+ }],
218
+ };
219
+ }
220
+ default:
221
+ return {
222
+ content: [{
223
+ type: 'text',
224
+ text: `Unknown tool: ${name}`,
225
+ }],
226
+ isError: true,
227
+ };
228
+ }
229
+ });
230
+ // ── 啟動 ──
231
+ async function main() {
232
+ // 確保 DB 已初始化
233
+ getDb();
234
+ const transport = new StdioServerTransport();
235
+ await server.connect(transport);
236
+ console.error('[MockCraft MCP] Server started on stdio');
237
+ }
238
+ main().catch((err) => {
239
+ console.error('[MockCraft MCP] Fatal:', err);
240
+ process.exit(1);
241
+ });
242
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ export interface FieldConfig {
2
+ type: 'name' | 'phone' | 'id_number' | 'county' | 'district' | 'address' | 'email' | 'company' | 'job_title' | 'boolean' | 'uuid' | 'date' | 'number' | 'string' | 'ai';
3
+ min?: number | string;
4
+ max?: number | string;
5
+ length?: number;
6
+ format?: string;
7
+ prompt?: string;
8
+ options?: string[];
9
+ prefix?: string;
10
+ }
11
+ export type SchemaField = string | FieldConfig;
12
+ export interface GenerateRequest {
13
+ schema: Record<string, SchemaField>;
14
+ count: number;
15
+ }
16
+ export interface GenerateResult {
17
+ data: Record<string, unknown>[];
18
+ meta: {
19
+ count: number;
20
+ generated_at: string;
21
+ ai_used: boolean;
22
+ };
23
+ }
24
+ export interface RegionRow {
25
+ id: number;
26
+ county: string;
27
+ district: string;
28
+ zip_code: string;
29
+ }
30
+ export interface NameRow {
31
+ id: number;
32
+ surname: string;
33
+ given_name: string;
34
+ gender: 'M' | 'F' | 'N';
35
+ }
36
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,WAAW,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,IAAI,CAAC;IACxK,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,WAAW,CAAC;AAE/C,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACpC,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IAChC,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAC;QACd,YAAY,EAAE,MAAM,CAAC;QACrB,OAAO,EAAE,OAAO,CAAC;KAClB,CAAC;CACH;AAED,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;CACzB"}
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ // src/types.ts - 型別定義
2
+ export {};
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,sBAAsB"}
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "mock-data-mcp",
3
+ "version": "1.0.0",
4
+ "description": "Ultra-fast mock data generator MCP server — Taiwan locale, schema-driven, SQLite cache, Gemini AI fallback",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "bin": {
9
+ "mock-data-mcp": "./dist/index.js"
10
+ },
11
+ "files": [
12
+ "dist",
13
+ "data/mock.db",
14
+ "README.md",
15
+ "LICENSE"
16
+ ],
17
+ "scripts": {
18
+ "build": "tsc",
19
+ "typecheck": "tsc --noEmit",
20
+ "dev": "bun src/index.ts",
21
+ "seed": "bun src/seed.ts",
22
+ "bench": "bun src/bench.ts",
23
+ "test": "bun src/test-client.ts",
24
+ "prepublishOnly": "bun run typecheck && bun run build && bun run seed"
25
+ },
26
+ "keywords": [
27
+ "mcp",
28
+ "model-context-protocol",
29
+ "mock-data",
30
+ "fake-data",
31
+ "test-data",
32
+ "taiwan",
33
+ "gemini",
34
+ "sqlite",
35
+ "bun"
36
+ ],
37
+ "author": "",
38
+ "license": "MIT",
39
+ "repository": {
40
+ "type": "git",
41
+ "url": ""
42
+ },
43
+ "engines": {
44
+ "node": ">=18.0.0",
45
+ "bun": ">=1.0.0"
46
+ },
47
+ "peerDependencies": {
48
+ "@modelcontextprotocol/sdk": "^1.12.0",
49
+ "zod": "^3.24.0"
50
+ },
51
+ "peerDependenciesMeta": {
52
+ "@modelcontextprotocol/sdk": { "optional": false },
53
+ "zod": { "optional": false }
54
+ },
55
+ "dependencies": {
56
+ "@modelcontextprotocol/sdk": "^1.28.0",
57
+ "better-sqlite3": "^12.0.0",
58
+ "dotenv": "^16.4.5",
59
+ "zod": "^3.25.0"
60
+ },
61
+ "devDependencies": {
62
+ "@types/better-sqlite3": "^7.6.12",
63
+ "@types/bun": "^1.2.0",
64
+ "typescript": "^5.7.2"
65
+ }
66
+ }