mozaic-mcp-server 2.4.0 → 2.5.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/app.module.d.ts +3 -0
- package/dist/app.module.d.ts.map +1 -0
- package/dist/app.module.js +28 -0
- package/dist/app.module.js.map +1 -0
- package/dist/auth/auth.guard.d.ts +10 -0
- package/dist/auth/auth.guard.d.ts.map +1 -0
- package/dist/auth/auth.guard.js +53 -0
- package/dist/auth/auth.guard.js.map +1 -0
- package/dist/auth/auth.module.d.ts +3 -0
- package/dist/auth/auth.module.d.ts.map +1 -0
- package/dist/auth/auth.module.js +18 -0
- package/dist/auth/auth.module.js.map +1 -0
- package/dist/config/configuration.d.ts +18 -0
- package/dist/config/configuration.d.ts.map +1 -0
- package/dist/config/configuration.js +17 -0
- package/dist/config/configuration.js.map +1 -0
- package/dist/main.d.ts +2 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +55 -0
- package/dist/main.js.map +1 -0
- package/dist/mcp/mcp.controller.d.ts +27 -0
- package/dist/mcp/mcp.controller.d.ts.map +1 -0
- package/dist/mcp/mcp.controller.js +102 -0
- package/dist/mcp/mcp.controller.js.map +1 -0
- package/dist/mcp/mcp.module.d.ts +3 -0
- package/dist/mcp/mcp.module.d.ts.map +1 -0
- package/dist/mcp/mcp.module.js +20 -0
- package/dist/mcp/mcp.module.js.map +1 -0
- package/dist/mcp/mcp.service.d.ts +35 -0
- package/dist/mcp/mcp.service.d.ts.map +1 -0
- package/dist/mcp/mcp.service.js +229 -0
- package/dist/mcp/mcp.service.js.map +1 -0
- package/dist/tools/generate-freemarker.d.ts +6 -6
- package/dist/tools/get-freemarker-info.d.ts +2 -2
- package/dist/tools/list-css-utilities.d.ts +1 -1
- package/dist/tools/list-freemarker.d.ts +2 -2
- package/package.json +17 -3
- package/dist/__tests__/sanity-check.test.d.ts +0 -2
- package/dist/__tests__/sanity-check.test.d.ts.map +0 -1
- package/dist/__tests__/sanity-check.test.js +0 -167
- package/dist/__tests__/sanity-check.test.js.map +0 -1
- package/dist/__tests__/skills-scripts.test.d.ts +0 -2
- package/dist/__tests__/skills-scripts.test.d.ts.map +0 -1
- package/dist/__tests__/skills-scripts.test.js +0 -404
- package/dist/__tests__/skills-scripts.test.js.map +0 -1
- package/dist/__tests__/tools.integration.test.d.ts +0 -2
- package/dist/__tests__/tools.integration.test.d.ts.map +0 -1
- package/dist/__tests__/tools.integration.test.js +0 -305
- package/dist/__tests__/tools.integration.test.js.map +0 -1
- package/dist/parsers/__tests__/docs-parser.test.d.ts +0 -2
- package/dist/parsers/__tests__/docs-parser.test.d.ts.map +0 -1
- package/dist/parsers/__tests__/docs-parser.test.js +0 -251
- package/dist/parsers/__tests__/docs-parser.test.js.map +0 -1
- package/dist/parsers/__tests__/icons-parser.test.d.ts +0 -2
- package/dist/parsers/__tests__/icons-parser.test.d.ts.map +0 -1
- package/dist/parsers/__tests__/icons-parser.test.js +0 -169
- package/dist/parsers/__tests__/icons-parser.test.js.map +0 -1
- package/dist/parsers/__tests__/react-parser.test.d.ts +0 -2
- package/dist/parsers/__tests__/react-parser.test.d.ts.map +0 -1
- package/dist/parsers/__tests__/react-parser.test.js +0 -274
- package/dist/parsers/__tests__/react-parser.test.js.map +0 -1
- package/dist/parsers/__tests__/scss-parser.test.d.ts +0 -2
- package/dist/parsers/__tests__/scss-parser.test.d.ts.map +0 -1
- package/dist/parsers/__tests__/scss-parser.test.js +0 -364
- package/dist/parsers/__tests__/scss-parser.test.js.map +0 -1
- package/dist/parsers/__tests__/tokens-parser.test.d.ts +0 -2
- package/dist/parsers/__tests__/tokens-parser.test.d.ts.map +0 -1
- package/dist/parsers/__tests__/tokens-parser.test.js +0 -172
- package/dist/parsers/__tests__/tokens-parser.test.js.map +0 -1
- package/dist/parsers/__tests__/vue-parser.test.d.ts +0 -2
- package/dist/parsers/__tests__/vue-parser.test.d.ts.map +0 -1
- package/dist/parsers/__tests__/vue-parser.test.js +0 -207
- package/dist/parsers/__tests__/vue-parser.test.js.map +0 -1
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
var McpService_1;
|
|
11
|
+
import { Injectable, Logger } from "@nestjs/common";
|
|
12
|
+
import { ConfigService } from "@nestjs/config";
|
|
13
|
+
import { spawn } from "child_process";
|
|
14
|
+
import { EventEmitter } from "events";
|
|
15
|
+
let McpService = McpService_1 = class McpService {
|
|
16
|
+
configService;
|
|
17
|
+
logger = new Logger(McpService_1.name);
|
|
18
|
+
mcpProcess = null;
|
|
19
|
+
requestId = 0;
|
|
20
|
+
pendingRequests = new Map();
|
|
21
|
+
eventEmitter = new EventEmitter();
|
|
22
|
+
serverInfo = null;
|
|
23
|
+
tools = [];
|
|
24
|
+
constructor(configService) {
|
|
25
|
+
this.configService = configService;
|
|
26
|
+
}
|
|
27
|
+
async onModuleInit() {
|
|
28
|
+
await this.startMcpServer();
|
|
29
|
+
await this.initializeServerInfo();
|
|
30
|
+
}
|
|
31
|
+
async onModuleDestroy() {
|
|
32
|
+
this.stopMcpServer();
|
|
33
|
+
}
|
|
34
|
+
async startMcpServer() {
|
|
35
|
+
const serverPath = this.configService.get("mcp.serverPath", "/app/dist/index.js");
|
|
36
|
+
const databasePath = this.configService.get("database.path");
|
|
37
|
+
this.logger.log(`Starting MCP server from ${serverPath}`);
|
|
38
|
+
// Spawn the MCP server process
|
|
39
|
+
this.mcpProcess = spawn("node", [serverPath], {
|
|
40
|
+
env: {
|
|
41
|
+
...process.env,
|
|
42
|
+
DATABASE_PATH: databasePath,
|
|
43
|
+
MCP_MODE: "stdio",
|
|
44
|
+
},
|
|
45
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
46
|
+
});
|
|
47
|
+
// Handle stdout (MCP responses)
|
|
48
|
+
this.mcpProcess.stdout?.on("data", (data) => {
|
|
49
|
+
try {
|
|
50
|
+
const lines = data.toString().split("\n").filter(Boolean);
|
|
51
|
+
for (const line of lines) {
|
|
52
|
+
const message = JSON.parse(line);
|
|
53
|
+
this.handleMcpMessage(message);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
this.logger.error("Failed to parse MCP message:", error);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
// Handle stderr (logging)
|
|
61
|
+
this.mcpProcess.stderr?.on("data", (data) => {
|
|
62
|
+
if (this.configService.get("mcp.debug")) {
|
|
63
|
+
this.logger.debug(`MCP Server: ${data.toString()}`);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
// Handle process exit
|
|
67
|
+
this.mcpProcess.on("exit", (code) => {
|
|
68
|
+
this.logger.warn(`MCP server exited with code ${code}`);
|
|
69
|
+
this.mcpProcess = null;
|
|
70
|
+
// Reject all pending requests
|
|
71
|
+
for (const [, { reject }] of this.pendingRequests) {
|
|
72
|
+
reject(new Error("MCP server process exited"));
|
|
73
|
+
}
|
|
74
|
+
this.pendingRequests.clear();
|
|
75
|
+
});
|
|
76
|
+
// Wait for server to be ready
|
|
77
|
+
await new Promise((resolve) => {
|
|
78
|
+
const timeout = setTimeout(() => {
|
|
79
|
+
this.logger.error("MCP server startup timeout");
|
|
80
|
+
resolve();
|
|
81
|
+
}, 5000);
|
|
82
|
+
this.eventEmitter.once("ready", () => {
|
|
83
|
+
clearTimeout(timeout);
|
|
84
|
+
this.logger.log("MCP server is ready");
|
|
85
|
+
resolve();
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
stopMcpServer() {
|
|
90
|
+
if (this.mcpProcess) {
|
|
91
|
+
this.mcpProcess.kill();
|
|
92
|
+
this.mcpProcess = null;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
handleMcpMessage(message) {
|
|
96
|
+
// Check if this is a response to a pending request
|
|
97
|
+
if (message.id !== undefined && this.pendingRequests.has(message.id)) {
|
|
98
|
+
const pendingRequest = this.pendingRequests.get(message.id);
|
|
99
|
+
if (pendingRequest) {
|
|
100
|
+
const { resolve } = pendingRequest;
|
|
101
|
+
this.pendingRequests.delete(message.id);
|
|
102
|
+
resolve(message);
|
|
103
|
+
}
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
// Check if this is a notification
|
|
107
|
+
if (message.method && !message.id) {
|
|
108
|
+
this.handleNotification(message);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
// Handle other message types
|
|
112
|
+
if (message.method === "initialize" && message.result) {
|
|
113
|
+
this.eventEmitter.emit("ready");
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
handleNotification(message) {
|
|
117
|
+
this.logger.debug(`Received notification: ${message.method}`);
|
|
118
|
+
// Handle specific notifications if needed
|
|
119
|
+
}
|
|
120
|
+
async sendRequest(method, params) {
|
|
121
|
+
if (!this.mcpProcess || !this.mcpProcess.stdin) {
|
|
122
|
+
throw new Error("MCP server is not running");
|
|
123
|
+
}
|
|
124
|
+
const id = ++this.requestId;
|
|
125
|
+
const request = {
|
|
126
|
+
jsonrpc: "2.0",
|
|
127
|
+
id,
|
|
128
|
+
method,
|
|
129
|
+
params: params || {},
|
|
130
|
+
};
|
|
131
|
+
return new Promise((resolve, reject) => {
|
|
132
|
+
this.pendingRequests.set(id, { resolve, reject });
|
|
133
|
+
// Send request to MCP server
|
|
134
|
+
if (this.mcpProcess?.stdin) {
|
|
135
|
+
this.mcpProcess.stdin.write(JSON.stringify(request) + "\n");
|
|
136
|
+
}
|
|
137
|
+
// Set timeout
|
|
138
|
+
setTimeout(() => {
|
|
139
|
+
if (this.pendingRequests.has(id)) {
|
|
140
|
+
this.pendingRequests.delete(id);
|
|
141
|
+
reject(new Error(`Request timeout: ${method}`));
|
|
142
|
+
}
|
|
143
|
+
}, 30000); // 30 second timeout
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
async initializeServerInfo() {
|
|
147
|
+
try {
|
|
148
|
+
// Initialize connection
|
|
149
|
+
const initResponse = await this.sendRequest("initialize", {
|
|
150
|
+
protocolVersion: "2024-11-05",
|
|
151
|
+
capabilities: {},
|
|
152
|
+
clientInfo: {
|
|
153
|
+
name: "mozaic-mcp-nestjs",
|
|
154
|
+
version: "2.4.0",
|
|
155
|
+
},
|
|
156
|
+
});
|
|
157
|
+
this.serverInfo = initResponse.result;
|
|
158
|
+
// Get list of tools
|
|
159
|
+
const toolsResponse = await this.sendRequest("tools/list");
|
|
160
|
+
this.tools = toolsResponse.result?.tools || [];
|
|
161
|
+
this.logger.log(`Loaded ${this.tools.length} MCP tools`);
|
|
162
|
+
}
|
|
163
|
+
catch (error) {
|
|
164
|
+
this.logger.error("Failed to initialize MCP server info:", error);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
async handleJsonRpcRequest(request) {
|
|
168
|
+
try {
|
|
169
|
+
// Forward the request to the MCP server
|
|
170
|
+
const response = await this.sendRequest(request.method || "", request.params);
|
|
171
|
+
return {
|
|
172
|
+
jsonrpc: "2.0",
|
|
173
|
+
id: request.id,
|
|
174
|
+
result: response.result,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
catch (error) {
|
|
178
|
+
const errorMessage = error instanceof Error ? error.message : "Internal error";
|
|
179
|
+
return {
|
|
180
|
+
jsonrpc: "2.0",
|
|
181
|
+
id: request.id,
|
|
182
|
+
error: {
|
|
183
|
+
code: -32603,
|
|
184
|
+
message: errorMessage,
|
|
185
|
+
},
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
async handleMcpRequest(request) {
|
|
190
|
+
// Handle direct MCP protocol messages
|
|
191
|
+
return this.sendRequest(request.method || request.type || "", request.params || request);
|
|
192
|
+
}
|
|
193
|
+
async getServerInfo() {
|
|
194
|
+
return {
|
|
195
|
+
info: this.serverInfo,
|
|
196
|
+
tools: this.tools.map((tool) => ({
|
|
197
|
+
name: tool.name,
|
|
198
|
+
description: tool.description,
|
|
199
|
+
inputSchema: tool.inputSchema,
|
|
200
|
+
})),
|
|
201
|
+
capabilities: this.serverInfo?.capabilities || {},
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
async listTools() {
|
|
205
|
+
return {
|
|
206
|
+
tools: this.tools,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
async callTool(name, args) {
|
|
210
|
+
const tool = this.tools.find((t) => t.name === name);
|
|
211
|
+
if (!tool) {
|
|
212
|
+
throw new Error(`Tool not found: ${name}`);
|
|
213
|
+
}
|
|
214
|
+
const response = await this.sendRequest("tools/call", {
|
|
215
|
+
name,
|
|
216
|
+
arguments: args || {},
|
|
217
|
+
});
|
|
218
|
+
if (response.error) {
|
|
219
|
+
throw new Error(response.error.message || "Tool execution failed");
|
|
220
|
+
}
|
|
221
|
+
return response.result;
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
McpService = McpService_1 = __decorate([
|
|
225
|
+
Injectable(),
|
|
226
|
+
__metadata("design:paramtypes", [ConfigService])
|
|
227
|
+
], McpService);
|
|
228
|
+
export { McpService };
|
|
229
|
+
//# sourceMappingURL=mcp.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.service.js","sourceRoot":"","sources":["../../src/mcp/mcp.service.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAiC,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACnF,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAgB,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAmC/B,IAAM,UAAU,kBAAhB,MAAM,UAAU;IASD;IARH,MAAM,GAAG,IAAI,MAAM,CAAC,YAAU,CAAC,IAAI,CAAC,CAAC;IAC9C,UAAU,GAAwB,IAAI,CAAC;IACvC,SAAS,GAAG,CAAC,CAAC;IACd,eAAe,GAAG,IAAI,GAAG,EAAmC,CAAC;IAC7D,YAAY,GAAG,IAAI,YAAY,EAAE,CAAC;IAClC,UAAU,GAAyB,IAAI,CAAC;IACxC,KAAK,GAAc,EAAE,CAAC;IAE9B,YAAoB,aAA4B;QAA5B,kBAAa,GAAb,aAAa,CAAe;IAAG,CAAC;IAEpD,KAAK,CAAC,YAAY;QAChB,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;QAC5B,MAAM,IAAI,CAAC,oBAAoB,EAAE,CAAC;IACpC,CAAC;IAED,KAAK,CAAC,eAAe;QACnB,IAAI,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC;IAEO,KAAK,CAAC,cAAc;QAC1B,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAS,gBAAgB,EAAE,oBAAoB,CAAC,CAAC;QAC1F,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAS,eAAe,CAAC,CAAC;QAErE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,4BAA4B,UAAU,EAAE,CAAC,CAAC;QAE1D,+BAA+B;QAC/B,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,EAAE;YAC5C,GAAG,EAAE;gBACH,GAAG,OAAO,CAAC,GAAG;gBACd,aAAa,EAAE,YAAY;gBAC3B,QAAQ,EAAE,OAAO;aAClB;YACD,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;SAChC,CAAC,CAAC;QAEH,gCAAgC;QAChC,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YAC1C,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;gBAC1D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;oBACzB,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBACjC,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;gBACjC,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAC;YAC3D,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,0BAA0B;QAC1B,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YAC1C,IAAI,IAAI,CAAC,aAAa,CAAC,GAAG,CAAU,WAAW,CAAC,EAAE,CAAC;gBACjD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,eAAe,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YACtD,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,sBAAsB;QACtB,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YAClC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,+BAA+B,IAAI,EAAE,CAAC,CAAC;YACxD,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;YAEvB,8BAA8B;YAC9B,KAAK,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;gBAClD,MAAM,CAAC,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC,CAAC;YACjD,CAAC;YACD,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;QAC/B,CAAC,CAAC,CAAC;QAEH,8BAA8B;QAC9B,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YAClC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC9B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;gBAChD,OAAO,EAAE,CAAC;YACZ,CAAC,EAAE,IAAI,CAAC,CAAC;YAET,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE;gBACnC,YAAY,CAAC,OAAO,CAAC,CAAC;gBACtB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;gBACvC,OAAO,EAAE,CAAC;YACZ,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,aAAa;QACnB,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;YACvB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACzB,CAAC;IACH,CAAC;IAEO,gBAAgB,CAAC,OAAmB;QAC1C,mDAAmD;QACnD,IAAI,OAAO,CAAC,EAAE,KAAK,SAAS,IAAI,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;YACrE,MAAM,cAAc,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAC5D,IAAI,cAAc,EAAE,CAAC;gBACnB,MAAM,EAAE,OAAO,EAAE,GAAG,cAAc,CAAC;gBACnC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;gBACxC,OAAO,CAAC,OAAO,CAAC,CAAC;YACnB,CAAC;YACD,OAAO;QACT,CAAC;QAED,kCAAkC;QAClC,IAAI,OAAO,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;YAClC,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;YACjC,OAAO;QACT,CAAC;QAED,6BAA6B;QAC7B,IAAI,OAAO,CAAC,MAAM,KAAK,YAAY,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACtD,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAEO,kBAAkB,CAAC,OAAmB;QAC5C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,0BAA0B,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QAC9D,0CAA0C;IAC5C,CAAC;IAEO,KAAK,CAAC,WAAW,CAAC,MAAc,EAAE,MAAgB;QACxD,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;YAC/C,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAC/C,CAAC;QAED,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC;QAC5B,MAAM,OAAO,GAAG;YACd,OAAO,EAAE,KAAK;YACd,EAAE;YACF,MAAM;YACN,MAAM,EAAE,MAAM,IAAI,EAAE;SACrB,CAAC;QAEF,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;YAElD,6BAA6B;YAC7B,IAAI,IAAI,CAAC,UAAU,EAAE,KAAK,EAAE,CAAC;gBAC3B,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;YAC9D,CAAC;YAED,cAAc;YACd,UAAU,CAAC,GAAG,EAAE;gBACd,IAAI,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;oBACjC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;oBAChC,MAAM,CAAC,IAAI,KAAK,CAAC,oBAAoB,MAAM,EAAE,CAAC,CAAC,CAAC;gBAClD,CAAC;YACH,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,oBAAoB;QACjC,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,oBAAoB;QAChC,IAAI,CAAC;YACH,wBAAwB;YACxB,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,YAAY,EAAE;gBACxD,eAAe,EAAE,YAAY;gBAC7B,YAAY,EAAE,EAAE;gBAChB,UAAU,EAAE;oBACV,IAAI,EAAE,mBAAmB;oBACzB,OAAO,EAAE,OAAO;iBACjB;aACF,CAAC,CAAC;YAEH,IAAI,CAAC,UAAU,GAAG,YAAY,CAAC,MAAuB,CAAC;YAEvD,oBAAoB;YACpB,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;YAC3D,IAAI,CAAC,KAAK,GAAI,aAAa,CAAC,MAAgC,EAAE,KAAK,IAAI,EAAE,CAAC;YAE1E,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,IAAI,CAAC,KAAK,CAAC,MAAM,YAAY,CAAC,CAAC;QAC3D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,uCAAuC,EAAE,KAAK,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;IAED,KAAK,CAAC,oBAAoB,CAAC,OAAmB;QAC5C,IAAI,CAAC;YACH,wCAAwC;YACxC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;YAE9E,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,EAAE,EAAE,OAAO,CAAC,EAAE;gBACd,MAAM,EAAE,QAAQ,CAAC,MAAM;aACxB,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC;YAC/E,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,EAAE,EAAE,OAAO,CAAC,EAAE;gBACd,KAAK,EAAE;oBACL,IAAI,EAAE,CAAC,KAAK;oBACZ,OAAO,EAAE,YAAY;iBACtB;aACF,CAAC;QACJ,CAAC;IACH,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,OAAmB;QACxC,sCAAsC;QACtC,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,IAAI,IAAI,EAAE,EAAE,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,CAAC;IAC3F,CAAC;IAED,KAAK,CAAC,aAAa;QACjB,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,UAAU;YACrB,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBAC/B,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,WAAW,EAAE,IAAI,CAAC,WAAW;aAC9B,CAAC,CAAC;YACH,YAAY,EAAE,IAAI,CAAC,UAAU,EAAE,YAAY,IAAI,EAAE;SAClD,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,SAAS;QACb,OAAO;YACL,KAAK,EAAE,IAAI,CAAC,KAAK;SAClB,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,IAAY,EAAE,IAA8B;QACzD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;QACrD,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,mBAAmB,IAAI,EAAE,CAAC,CAAC;QAC7C,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,YAAY,EAAE;YACpD,IAAI;YACJ,SAAS,EAAE,IAAI,IAAI,EAAE;SACtB,CAAC,CAAC;QAEH,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,IAAI,uBAAuB,CAAC,CAAC;QACrE,CAAC;QAED,OAAO,QAAQ,CAAC,MAAM,CAAC;IACzB,CAAC;CACF,CAAA;AA7OY,UAAU;IADtB,UAAU,EAAE;qCAUwB,aAAa;GATrC,UAAU,CA6OtB"}
|
|
@@ -13,13 +13,13 @@ declare const _GenerateFreemarkerInputSchema: z.ZodObject<{
|
|
|
13
13
|
config: z.ZodOptional<z.ZodString>;
|
|
14
14
|
content: z.ZodOptional<z.ZodString>;
|
|
15
15
|
}, "strip", z.ZodTypeAny, {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
content?: string;
|
|
17
|
+
component?: string;
|
|
18
|
+
config?: string;
|
|
19
19
|
}, {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
content?: string;
|
|
21
|
+
component?: string;
|
|
22
|
+
config?: string;
|
|
23
23
|
}>;
|
|
24
24
|
export type GenerateFreemarkerInput = z.infer<typeof _GenerateFreemarkerInputSchema>;
|
|
25
25
|
export declare function handleGenerateFreemarker(db: Database.Database, input: GenerateFreemarkerInput): {
|
|
@@ -12,9 +12,9 @@ import { z } from "zod";
|
|
|
12
12
|
declare const _GetFreemarkerInfoInputSchema: z.ZodObject<{
|
|
13
13
|
component: z.ZodString;
|
|
14
14
|
}, "strip", z.ZodTypeAny, {
|
|
15
|
-
component
|
|
15
|
+
component?: string;
|
|
16
16
|
}, {
|
|
17
|
-
component
|
|
17
|
+
component?: string;
|
|
18
18
|
}>;
|
|
19
19
|
export type GetFreemarkerInfoInput = z.infer<typeof _GetFreemarkerInfoInputSchema>;
|
|
20
20
|
export declare function handleGetFreemarkerInfo(db: Database.Database, input: GetFreemarkerInfoInput): {
|
|
@@ -8,9 +8,9 @@ import { z } from "zod";
|
|
|
8
8
|
declare const _ListFreemarkerInputSchema: z.ZodObject<{
|
|
9
9
|
category: z.ZodDefault<z.ZodOptional<z.ZodEnum<["all", "action", "form", "feedback", "navigation", "layout", "data-display", "other"]>>>;
|
|
10
10
|
}, "strip", z.ZodTypeAny, {
|
|
11
|
-
category
|
|
11
|
+
category?: "all" | "form" | "navigation" | "feedback" | "layout" | "data-display" | "action" | "other";
|
|
12
12
|
}, {
|
|
13
|
-
category?: "all" | "form" | "navigation" | "feedback" | "layout" | "data-display" | "action" | "other"
|
|
13
|
+
category?: "all" | "form" | "navigation" | "feedback" | "layout" | "data-display" | "action" | "other";
|
|
14
14
|
}>;
|
|
15
15
|
export type ListFreemarkerInput = z.infer<typeof _ListFreemarkerInputSchema>;
|
|
16
16
|
export declare function handleListFreemarker(db: Database.Database, input: ListFreemarkerInput): {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mozaic-mcp-server",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.0",
|
|
4
4
|
"description": "Self-contained Claude Code skills for Mozaic Design System by ADEO",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"compile": "tsc",
|
|
24
24
|
"postcompile": "chmod +x dist/index.js",
|
|
25
25
|
"build": "tsc && tsx scripts/build-index.ts",
|
|
26
|
+
"build:nest": "tsc",
|
|
26
27
|
"build:docs": "tsx scripts/generate-docs.ts",
|
|
27
28
|
"prebuild": "rm -rf dist",
|
|
28
29
|
"postbuild": "chmod +x dist/index.js",
|
|
@@ -64,15 +65,27 @@
|
|
|
64
65
|
},
|
|
65
66
|
"dependencies": {
|
|
66
67
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
68
|
+
"@nestjs/common": "^10.4.15",
|
|
69
|
+
"@nestjs/config": "^3.3.0",
|
|
70
|
+
"@nestjs/core": "^10.4.15",
|
|
71
|
+
"@nestjs/platform-express": "^10.4.15",
|
|
72
|
+
"@nestjs/swagger": "^7.4.2",
|
|
67
73
|
"@types/prompts": "^2.4.9",
|
|
68
74
|
"better-sqlite3": "12.8.0",
|
|
75
|
+
"class-transformer": "^0.5.1",
|
|
76
|
+
"class-validator": "^0.14.1",
|
|
69
77
|
"commander": "^14.0.3",
|
|
70
78
|
"glob": "^13.0.6",
|
|
71
79
|
"prompts": "^2.4.2",
|
|
80
|
+
"reflect-metadata": "^0.2.2",
|
|
81
|
+
"rxjs": "^7.8.1",
|
|
72
82
|
"zod": "^3.23.0"
|
|
73
83
|
},
|
|
74
84
|
"devDependencies": {
|
|
75
85
|
"@eslint/js": "^9.17.0",
|
|
86
|
+
"@nestjs/cli": "^11.0.0",
|
|
87
|
+
"@nestjs/schematics": "^11.0.0",
|
|
88
|
+
"@nestjs/testing": "^10.4.15",
|
|
76
89
|
"@semantic-release/changelog": "^6.0.3",
|
|
77
90
|
"@semantic-release/commit-analyzer": "^11.1.0",
|
|
78
91
|
"@semantic-release/git": "^10.0.1",
|
|
@@ -80,7 +93,8 @@
|
|
|
80
93
|
"@semantic-release/npm": "^11.0.2",
|
|
81
94
|
"@semantic-release/release-notes-generator": "^12.1.0",
|
|
82
95
|
"@types/better-sqlite3": "^7.6.0",
|
|
83
|
-
"@types/
|
|
96
|
+
"@types/express": "^5.0.0",
|
|
97
|
+
"@types/node": "^22.0.0",
|
|
84
98
|
"@vitest/coverage-v8": "^4.0.15",
|
|
85
99
|
"conventional-changelog-conventionalcommits": "^7.0.2",
|
|
86
100
|
"eslint": "^9.17.0",
|
|
@@ -102,7 +116,7 @@
|
|
|
102
116
|
]
|
|
103
117
|
},
|
|
104
118
|
"engines": {
|
|
105
|
-
"node": ">=
|
|
119
|
+
"node": ">=22.0.0"
|
|
106
120
|
},
|
|
107
121
|
"pnpm": {
|
|
108
122
|
"onlyBuiltDependencies": [
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sanity-check.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/sanity-check.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
2
|
-
import Database from "better-sqlite3";
|
|
3
|
-
import { SCHEMA } from "../db/schema.js";
|
|
4
|
-
describe("Sanity Check - Database Integrity", () => {
|
|
5
|
-
let db;
|
|
6
|
-
beforeEach(() => {
|
|
7
|
-
// Create in-memory database for testing
|
|
8
|
-
db = new Database(":memory:");
|
|
9
|
-
db.exec(SCHEMA);
|
|
10
|
-
});
|
|
11
|
-
afterEach(() => {
|
|
12
|
-
db.close();
|
|
13
|
-
});
|
|
14
|
-
describe("Token checks", () => {
|
|
15
|
-
it("should detect missing token categories", () => {
|
|
16
|
-
// Insert tokens with only some categories
|
|
17
|
-
db.prepare("INSERT INTO tokens (category, name, path, value_raw, css_variable) VALUES (?, ?, ?, ?, ?)").run("color", "primary", "color.primary", "#000", "--color-primary");
|
|
18
|
-
const categories = db.prepare("SELECT DISTINCT category FROM tokens").all();
|
|
19
|
-
expect(categories).toHaveLength(1);
|
|
20
|
-
expect(categories[0].category).toBe("color");
|
|
21
|
-
});
|
|
22
|
-
it("should count tokens by category", () => {
|
|
23
|
-
// Insert multiple tokens
|
|
24
|
-
const insert = db.prepare("INSERT INTO tokens (category, name, path, value_raw, css_variable) VALUES (?, ?, ?, ?, ?)");
|
|
25
|
-
insert.run("color", "primary-100", "color.primary.100", "#fff", "--color-primary-100");
|
|
26
|
-
insert.run("color", "primary-200", "color.primary.200", "#eee", "--color-primary-200");
|
|
27
|
-
insert.run("spacing", "mu100", "spacing.mu100", "16px", "--spacing-mu100");
|
|
28
|
-
const counts = db
|
|
29
|
-
.prepare("SELECT category, COUNT(*) as count FROM tokens GROUP BY category")
|
|
30
|
-
.all();
|
|
31
|
-
expect(counts).toHaveLength(2);
|
|
32
|
-
const colorCount = counts.find((c) => c.category === "color");
|
|
33
|
-
const spacingCount = counts.find((c) => c.category === "spacing");
|
|
34
|
-
expect(colorCount?.count).toBe(2);
|
|
35
|
-
expect(spacingCount?.count).toBe(1);
|
|
36
|
-
});
|
|
37
|
-
it("should detect missing required fields", () => {
|
|
38
|
-
// Insert token with missing path
|
|
39
|
-
db.prepare("INSERT INTO tokens (category, name, path, value_raw) VALUES (?, ?, ?, ?)").run("color", "test", "", "value");
|
|
40
|
-
const emptyPath = db
|
|
41
|
-
.prepare("SELECT COUNT(*) as count FROM tokens WHERE path IS NULL OR path = ''")
|
|
42
|
-
.get();
|
|
43
|
-
expect(emptyPath.count).toBe(1);
|
|
44
|
-
});
|
|
45
|
-
});
|
|
46
|
-
describe("Component checks", () => {
|
|
47
|
-
it("should count components by framework", () => {
|
|
48
|
-
const insert = db.prepare("INSERT INTO components (name, slug, category, frameworks) VALUES (?, ?, ?, ?)");
|
|
49
|
-
insert.run("Button", "button", "action", '["vue"]');
|
|
50
|
-
insert.run("Input", "input", "form", '["vue"]');
|
|
51
|
-
insert.run("Card", "card", "layout", '["react"]');
|
|
52
|
-
insert.run("Modal", "modal", "feedback", '["vue", "react"]');
|
|
53
|
-
const vueCount = db
|
|
54
|
-
.prepare("SELECT COUNT(*) as count FROM components WHERE frameworks LIKE '%vue%'")
|
|
55
|
-
.get();
|
|
56
|
-
const reactCount = db
|
|
57
|
-
.prepare("SELECT COUNT(*) as count FROM components WHERE frameworks LIKE '%react%'")
|
|
58
|
-
.get();
|
|
59
|
-
expect(vueCount.count).toBe(3);
|
|
60
|
-
expect(reactCount.count).toBe(2);
|
|
61
|
-
});
|
|
62
|
-
it("should detect components without props", () => {
|
|
63
|
-
const insertComponent = db.prepare("INSERT INTO components (name, slug, frameworks) VALUES (?, ?, ?)");
|
|
64
|
-
const insertProp = db.prepare("INSERT INTO component_props (component_id, name, type) VALUES (?, ?, ?)");
|
|
65
|
-
const c1 = insertComponent.run("Button", "button", '["vue"]');
|
|
66
|
-
const c2 = insertComponent.run("Input", "input", '["vue"]');
|
|
67
|
-
insertComponent.run("Card", "card", '["react"]');
|
|
68
|
-
// Only add props to first two components
|
|
69
|
-
insertProp.run(c1.lastInsertRowid, "size", "string");
|
|
70
|
-
insertProp.run(c2.lastInsertRowid, "value", "string");
|
|
71
|
-
const total = db.prepare("SELECT COUNT(*) as count FROM components").get();
|
|
72
|
-
const withProps = db
|
|
73
|
-
.prepare("SELECT COUNT(DISTINCT component_id) as count FROM component_props")
|
|
74
|
-
.get();
|
|
75
|
-
expect(total.count).toBe(3);
|
|
76
|
-
expect(withProps.count).toBe(2);
|
|
77
|
-
expect(Math.round((withProps.count / total.count) * 100)).toBe(67);
|
|
78
|
-
});
|
|
79
|
-
});
|
|
80
|
-
describe("CSS Utility checks", () => {
|
|
81
|
-
it("should count CSS utility classes", () => {
|
|
82
|
-
const insertUtility = db.prepare("INSERT INTO css_utilities (name, slug, category) VALUES (?, ?, ?)");
|
|
83
|
-
const insertClass = db.prepare("INSERT INTO css_utility_classes (utility_id, class_name) VALUES (?, ?)");
|
|
84
|
-
const u1 = insertUtility.run("Flexy", "flexy", "layout");
|
|
85
|
-
const u2 = insertUtility.run("Margin", "margin", "utility");
|
|
86
|
-
insertClass.run(u1.lastInsertRowid, ".ml-flexy");
|
|
87
|
-
insertClass.run(u1.lastInsertRowid, ".ml-flexy__col");
|
|
88
|
-
insertClass.run(u1.lastInsertRowid, ".ml-flexy__col--6of12");
|
|
89
|
-
insertClass.run(u2.lastInsertRowid, ".mu100");
|
|
90
|
-
const counts = db
|
|
91
|
-
.prepare(`SELECT u.name, COUNT(c.id) as count
|
|
92
|
-
FROM css_utilities u
|
|
93
|
-
LEFT JOIN css_utility_classes c ON c.utility_id = u.id
|
|
94
|
-
GROUP BY u.id`)
|
|
95
|
-
.all();
|
|
96
|
-
expect(counts.find((c) => c.name === "Flexy")?.count).toBe(3);
|
|
97
|
-
expect(counts.find((c) => c.name === "Margin")?.count).toBe(1);
|
|
98
|
-
});
|
|
99
|
-
it("should detect utilities without examples", () => {
|
|
100
|
-
const insertUtility = db.prepare("INSERT INTO css_utilities (name, slug, category) VALUES (?, ?, ?)");
|
|
101
|
-
const insertExample = db.prepare("INSERT INTO css_utility_examples (utility_id, title, code) VALUES (?, ?, ?)");
|
|
102
|
-
const u1 = insertUtility.run("Flexy", "flexy", "layout");
|
|
103
|
-
insertUtility.run("Container", "container", "layout");
|
|
104
|
-
insertExample.run(u1.lastInsertRowid, "Basic", '<div class="ml-flexy"></div>');
|
|
105
|
-
const total = db.prepare("SELECT COUNT(*) as count FROM css_utilities").get();
|
|
106
|
-
const withExamples = db
|
|
107
|
-
.prepare("SELECT COUNT(DISTINCT utility_id) as count FROM css_utility_examples")
|
|
108
|
-
.get();
|
|
109
|
-
expect(total.count).toBe(2);
|
|
110
|
-
expect(withExamples.count).toBe(1);
|
|
111
|
-
});
|
|
112
|
-
});
|
|
113
|
-
describe("Foreign Key Integrity", () => {
|
|
114
|
-
it("should detect orphaned component_props", () => {
|
|
115
|
-
// Disable FK constraints to test orphan detection logic
|
|
116
|
-
db.pragma("foreign_keys = OFF");
|
|
117
|
-
// Insert component
|
|
118
|
-
const insertComponent = db.prepare("INSERT INTO components (name, slug, frameworks) VALUES (?, ?, ?)");
|
|
119
|
-
const c1 = insertComponent.run("Button", "button", '["vue"]');
|
|
120
|
-
// Insert valid prop
|
|
121
|
-
db.prepare("INSERT INTO component_props (component_id, name, type) VALUES (?, ?, ?)").run(c1.lastInsertRowid, "size", "string");
|
|
122
|
-
// Insert orphaned prop (referencing non-existent component)
|
|
123
|
-
db.prepare("INSERT INTO component_props (component_id, name, type) VALUES (?, ?, ?)").run(9999, "orphan", "string");
|
|
124
|
-
const orphans = db
|
|
125
|
-
.prepare(`SELECT COUNT(*) as count FROM component_props cp
|
|
126
|
-
WHERE NOT EXISTS (SELECT 1 FROM components c WHERE c.id = cp.component_id)`)
|
|
127
|
-
.get();
|
|
128
|
-
expect(orphans.count).toBe(1);
|
|
129
|
-
// Re-enable FK constraints
|
|
130
|
-
db.pragma("foreign_keys = ON");
|
|
131
|
-
});
|
|
132
|
-
it("should detect orphaned css_utility_classes", () => {
|
|
133
|
-
// Disable FK constraints to test orphan detection logic
|
|
134
|
-
db.pragma("foreign_keys = OFF");
|
|
135
|
-
const insertUtility = db.prepare("INSERT INTO css_utilities (name, slug, category) VALUES (?, ?, ?)");
|
|
136
|
-
const u1 = insertUtility.run("Flexy", "flexy", "layout");
|
|
137
|
-
db.prepare("INSERT INTO css_utility_classes (utility_id, class_name) VALUES (?, ?)").run(u1.lastInsertRowid, ".ml-flexy");
|
|
138
|
-
db.prepare("INSERT INTO css_utility_classes (utility_id, class_name) VALUES (?, ?)").run(9999, ".orphan");
|
|
139
|
-
const orphans = db
|
|
140
|
-
.prepare(`SELECT COUNT(*) as count FROM css_utility_classes cuc
|
|
141
|
-
WHERE NOT EXISTS (SELECT 1 FROM css_utilities cu WHERE cu.id = cuc.utility_id)`)
|
|
142
|
-
.get();
|
|
143
|
-
expect(orphans.count).toBe(1);
|
|
144
|
-
// Re-enable FK constraints
|
|
145
|
-
db.pragma("foreign_keys = ON");
|
|
146
|
-
});
|
|
147
|
-
});
|
|
148
|
-
describe("Full-Text Search", () => {
|
|
149
|
-
it("should index tokens for FTS", () => {
|
|
150
|
-
db.prepare("INSERT INTO tokens (category, name, path, value_raw, css_variable) VALUES (?, ?, ?, ?, ?)").run("color", "primary-100", "color.primary.100", "#1a73e8", "--color-primary-100");
|
|
151
|
-
db.prepare("INSERT INTO tokens (category, name, path, value_raw, css_variable) VALUES (?, ?, ?, ?, ?)").run("color", "secondary-100", "color.secondary.100", "#666", "--color-secondary-100");
|
|
152
|
-
const results = db
|
|
153
|
-
.prepare("SELECT COUNT(*) as count FROM tokens_fts WHERE tokens_fts MATCH 'primary'")
|
|
154
|
-
.get();
|
|
155
|
-
expect(results.count).toBe(1);
|
|
156
|
-
});
|
|
157
|
-
it("should index documentation for FTS", () => {
|
|
158
|
-
db.prepare("INSERT INTO documentation (title, path, content, category, keywords) VALUES (?, ?, ?, ?, ?)").run("Button", "/components/button", "Button component documentation", "components", "button,action");
|
|
159
|
-
db.prepare("INSERT INTO documentation (title, path, content, category, keywords) VALUES (?, ?, ?, ?, ?)").run("Input", "/components/input", "Input field documentation", "components", "input,form");
|
|
160
|
-
const results = db
|
|
161
|
-
.prepare("SELECT COUNT(*) as count FROM docs_fts WHERE docs_fts MATCH 'button'")
|
|
162
|
-
.get();
|
|
163
|
-
expect(results.count).toBe(1);
|
|
164
|
-
});
|
|
165
|
-
});
|
|
166
|
-
});
|
|
167
|
-
//# sourceMappingURL=sanity-check.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sanity-check.test.js","sourceRoot":"","sources":["../../src/__tests__/sanity-check.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"skills-scripts.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/skills-scripts.test.ts"],"names":[],"mappings":""}
|