@bowlly/mcp-server 0.1.9 → 0.1.10
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/README.md +6 -1
- package/dist/cli/configure.d.ts +1 -1
- package/dist/cli/configure.d.ts.map +1 -1
- package/dist/cli/configure.js +15 -2
- package/dist/cli/configure.js.map +1 -1
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +2 -1
- package/dist/cli/setup.js.map +1 -1
- package/dist/config.js +1 -1
- package/dist/config.js.map +1 -1
- package/dist/index.js +0 -0
- package/package.json +1 -1
- package/scripts/smoke-prod.ts +3 -3
- package/dist/__tests__/curation-tool.test.d.ts +0 -2
- package/dist/__tests__/curation-tool.test.d.ts.map +0 -1
- package/dist/__tests__/curation-tool.test.js +0 -329
- package/dist/__tests__/curation-tool.test.js.map +0 -1
- package/dist/__tests__/nutrition-tool.test.d.ts +0 -2
- package/dist/__tests__/nutrition-tool.test.d.ts.map +0 -1
- package/dist/__tests__/nutrition-tool.test.js +0 -286
- package/dist/__tests__/nutrition-tool.test.js.map +0 -1
- package/dist/__tests__/rate-limit.test.d.ts +0 -2
- package/dist/__tests__/rate-limit.test.d.ts.map +0 -1
- package/dist/__tests__/rate-limit.test.js +0 -154
- package/dist/__tests__/rate-limit.test.js.map +0 -1
- package/dist/__tests__/safeguard.test.d.ts +0 -2
- package/dist/__tests__/safeguard.test.d.ts.map +0 -1
- package/dist/__tests__/safeguard.test.js +0 -146
- package/dist/__tests__/safeguard.test.js.map +0 -1
- package/dist/__tests__/search-tool.test.d.ts +0 -2
- package/dist/__tests__/search-tool.test.d.ts.map +0 -1
- package/dist/__tests__/search-tool.test.js +0 -260
- package/dist/__tests__/search-tool.test.js.map +0 -1
package/README.md
CHANGED
|
@@ -9,6 +9,7 @@ Enables Claude Desktop to search, analyze, and compare cat food products.
|
|
|
9
9
|
|
|
10
10
|
- **Node.js 22+** - Required for running the MCP server
|
|
11
11
|
- **Claude Desktop** - [Download here](https://claude.ai/download) if not installed
|
|
12
|
+
- **Bowlly API key** - Required for Agent API access (currently private/beta; no self-serve issuance yet)
|
|
12
13
|
|
|
13
14
|
## Quick Start
|
|
14
15
|
|
|
@@ -18,6 +19,7 @@ Enables Claude Desktop to search, analyze, and compare cat food products.
|
|
|
18
19
|
npx @bowlly/mcp-server --setup
|
|
19
20
|
```
|
|
20
21
|
|
|
22
|
+
The setup wizard can optionally save your `BOWLLY_API_KEY` into your Claude Desktop config.
|
|
21
23
|
After running, restart Claude Desktop and you're ready to go!
|
|
22
24
|
|
|
23
25
|
### Option 2: Manual Configuration
|
|
@@ -34,7 +36,10 @@ After running, restart Claude Desktop and you're ready to go!
|
|
|
34
36
|
"mcpServers": {
|
|
35
37
|
"bowlly": {
|
|
36
38
|
"command": "npx",
|
|
37
|
-
"args": ["-y", "@bowlly/mcp-server"]
|
|
39
|
+
"args": ["-y", "@bowlly/mcp-server"],
|
|
40
|
+
"env": {
|
|
41
|
+
"BOWLLY_API_KEY": "your-api-key-here"
|
|
42
|
+
}
|
|
38
43
|
}
|
|
39
44
|
}
|
|
40
45
|
}
|
package/dist/cli/configure.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configure.d.ts","sourceRoot":"","sources":["../../src/cli/configure.ts"],"names":[],"mappings":"AA8BA,wBAAsB,sBAAsB,
|
|
1
|
+
{"version":3,"file":"configure.d.ts","sourceRoot":"","sources":["../../src/cli/configure.ts"],"names":[],"mappings":"AA8BA,wBAAsB,sBAAsB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAoE3E;AAED,wBAAgB,sBAAsB,IAAI,MAAM,CAsB/C"}
|
package/dist/cli/configure.js
CHANGED
|
@@ -15,7 +15,7 @@ function getClaudeConfigPath() {
|
|
|
15
15
|
return path.join(home, ".config", "Claude", "claude_desktop_config.json");
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
|
-
export async function configureClaudeDesktop() {
|
|
18
|
+
export async function configureClaudeDesktop(apiKey) {
|
|
19
19
|
const configPath = getClaudeConfigPath();
|
|
20
20
|
try {
|
|
21
21
|
// Read existing config or create new
|
|
@@ -37,6 +37,13 @@ export async function configureClaudeDesktop() {
|
|
|
37
37
|
command: "npx",
|
|
38
38
|
args: ["-y", "@bowlly/mcp-server"],
|
|
39
39
|
};
|
|
40
|
+
// Optional API key (private/beta). Only write if explicitly provided.
|
|
41
|
+
if (apiKey && apiKey.trim()) {
|
|
42
|
+
config.mcpServers.bowlly.env = {
|
|
43
|
+
...(config.mcpServers.bowlly.env || {}),
|
|
44
|
+
BOWLLY_API_KEY: apiKey.trim(),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
40
47
|
// Ensure directory exists
|
|
41
48
|
await fs.mkdir(path.dirname(configPath), { recursive: true });
|
|
42
49
|
// Write config
|
|
@@ -58,6 +65,9 @@ export async function configureClaudeDesktop() {
|
|
|
58
65
|
bowlly: {
|
|
59
66
|
command: "npx",
|
|
60
67
|
args: ["-y", "@bowlly/mcp-server"],
|
|
68
|
+
env: {
|
|
69
|
+
BOWLLY_API_KEY: "your-api-key-here",
|
|
70
|
+
},
|
|
61
71
|
},
|
|
62
72
|
}, null, 2));
|
|
63
73
|
}
|
|
@@ -74,7 +84,10 @@ Manual Claude Desktop configuration:
|
|
|
74
84
|
"mcpServers": {
|
|
75
85
|
"bowlly": {
|
|
76
86
|
"command": "npx",
|
|
77
|
-
"args": ["-y", "@bowlly/mcp-server"]
|
|
87
|
+
"args": ["-y", "@bowlly/mcp-server"],
|
|
88
|
+
"env": {
|
|
89
|
+
"BOWLLY_API_KEY": "your-api-key-here"
|
|
90
|
+
}
|
|
78
91
|
}
|
|
79
92
|
}
|
|
80
93
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configure.js","sourceRoot":"","sources":["../../src/cli/configure.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAaxB,SAAS,mBAAmB;IAC1B,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC;IAC1B,QAAQ,OAAO,CAAC,QAAQ,EAAE,CAAC;QACzB,KAAK,QAAQ;YACX,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,qBAAqB,EAAE,QAAQ,EAAE,4BAA4B,CAAC,CAAC;QACnG,KAAK,OAAO;YACV,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,4BAA4B,CAAC,CAAC;QACvF;YACE,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,4BAA4B,CAAC,CAAC;IAC9E,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB;
|
|
1
|
+
{"version":3,"file":"configure.js","sourceRoot":"","sources":["../../src/cli/configure.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/setup.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/cli/setup.ts"],"names":[],"mappings":"AAQA,wBAAsB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/cli/setup.ts"],"names":[],"mappings":"AAQA,wBAAsB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAgC9C"}
|
package/dist/cli/setup.js
CHANGED
|
@@ -12,11 +12,12 @@ export async function runSetup() {
|
|
|
12
12
|
});
|
|
13
13
|
const ask = (question) => new Promise((resolve) => rl.question(question, resolve));
|
|
14
14
|
try {
|
|
15
|
+
const apiKey = (await ask("Enter BOWLLY_API_KEY (leave blank to skip): ")).trim();
|
|
15
16
|
// Configure Claude Desktop
|
|
16
17
|
console.log("🤖 Claude Desktop Configuration");
|
|
17
18
|
const shouldConfigure = await ask("Configure Claude Desktop automatically? (Y/n): ");
|
|
18
19
|
if (shouldConfigure.toLowerCase() !== "n") {
|
|
19
|
-
await configureClaudeDesktop();
|
|
20
|
+
await configureClaudeDesktop(apiKey || undefined);
|
|
20
21
|
}
|
|
21
22
|
else {
|
|
22
23
|
console.log("\nSkipping Claude Desktop configuration.");
|
package/dist/cli/setup.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/cli/setup.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,QAAQ,MAAM,UAAU,CAAC;AAEhC,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAExD,MAAM,CAAC,KAAK,UAAU,QAAQ;IAC5B,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;IAE5C,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC;QAClC,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,MAAM,EAAE,OAAO,CAAC,MAAM;KACvB,CAAC,CAAC;IAEH,MAAM,GAAG,GAAG,CAAC,QAAgB,EAAmB,EAAE,CAAC,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;IAE5G,IAAI,CAAC;QACH,2BAA2B;QAC3B,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;QAC/C,MAAM,eAAe,GAAG,MAAM,GAAG,CAAC,iDAAiD,CAAC,CAAC;QAErF,IAAI,eAAe,CAAC,WAAW,EAAE,KAAK,GAAG,EAAE,CAAC;YAC1C,MAAM,sBAAsB,
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/cli/setup.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,QAAQ,MAAM,UAAU,CAAC;AAEhC,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAExD,MAAM,CAAC,KAAK,UAAU,QAAQ;IAC5B,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;IAE5C,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC;QAClC,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,MAAM,EAAE,OAAO,CAAC,MAAM;KACvB,CAAC,CAAC;IAEH,MAAM,GAAG,GAAG,CAAC,QAAgB,EAAmB,EAAE,CAAC,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;IAE5G,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,CAAC,MAAM,GAAG,CAAC,8CAA8C,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAElF,2BAA2B;QAC3B,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;QAC/C,MAAM,eAAe,GAAG,MAAM,GAAG,CAAC,iDAAiD,CAAC,CAAC;QAErF,IAAI,eAAe,CAAC,WAAW,EAAE,KAAK,GAAG,EAAE,CAAC;YAC1C,MAAM,sBAAsB,CAAC,MAAM,IAAI,SAAS,CAAC,CAAC;QACpD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;YACxD,OAAO,CAAC,GAAG,CAAC,sDAAsD,CAAC,CAAC;QACtE,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;QACnC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;QACzD,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC;QAC3D,OAAO,CAAC,GAAG,CAAC,sDAAsD,CAAC,CAAC;IACtE,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;AACH,CAAC"}
|
package/dist/config.js
CHANGED
|
@@ -34,7 +34,7 @@ function parsePositiveInt(value, defaultValue) {
|
|
|
34
34
|
export const config = Object.freeze({
|
|
35
35
|
// API Configuration
|
|
36
36
|
apiBaseUrl: process.env.FITPICK_API_BASE_URL ?? process.env.FITPICK_API_URL ?? "https://api.bowlly.net",
|
|
37
|
-
apiKey: process.env.FITPICK_API_KEY,
|
|
37
|
+
apiKey: process.env.BOWLLY_API_KEY ?? process.env.FITPICK_API_KEY,
|
|
38
38
|
// Agent Identification
|
|
39
39
|
agentName: process.env.FITPICK_AGENT_NAME ?? "mcp",
|
|
40
40
|
// Rate Limiting
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,+CAA+C;AAC/C,+BAA+B;AAC/B,+CAA+C;AAE/C;;;;;;;GAOG;AACH,SAAS,gBAAgB,CAAC,KAAyB,EAAE,YAAoB;IACvE,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACnC,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;QACjC,OAAO,CAAC,IAAI,CAAC,mCAAmC,KAAK,qBAAqB,YAAY,EAAE,CAAC,CAAC;QAC1F,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAClC,oBAAoB;IACpB,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,wBAAwB;IACvG,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,+CAA+C;AAC/C,+BAA+B;AAC/B,+CAA+C;AAE/C;;;;;;;GAOG;AACH,SAAS,gBAAgB,CAAC,KAAyB,EAAE,YAAoB;IACvE,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACnC,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;QACjC,OAAO,CAAC,IAAI,CAAC,mCAAmC,KAAK,qBAAqB,YAAY,EAAE,CAAC,CAAC;QAC1F,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAClC,oBAAoB;IACpB,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,wBAAwB;IACvG,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe;IAEjE,uBAAuB;IACvB,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,KAAK;IAElD,gBAAgB;IAChB,eAAe,EAAE,gBAAgB,CAAC,OAAO,CAAC,GAAG,CAAC,0BAA0B,EAAE,GAAG,CAAC;IAE9E,0EAA0E;IAC1E,SAAS,EAAE,UAAU,EAAE;IAEvB,kBAAkB;IAClB,UAAU,EAAE,QAAQ;IACpB,aAAa,EAAE,OAAO;IAEtB,WAAW;IACX,YAAY,EAAE,KAAK,EAAE,wCAAwC;IAE7D,uBAAuB;IACvB,oBAAoB,EAAE,gBAAgB,CACpC,OAAO,CAAC,GAAG,CAAC,+BAA+B,EAC3C,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC,eAAe;KACjC;CACF,CAAC,CAAC"}
|
package/dist/index.js
CHANGED
|
File without changes
|
package/package.json
CHANGED
package/scripts/smoke-prod.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Smoke test for the deployed Agent API (used by the MCP server).
|
|
3
3
|
*
|
|
4
4
|
* Usage:
|
|
5
|
-
*
|
|
5
|
+
* BOWLLY_API_KEY=... pnpm tsx packages/mcp-server/scripts/smoke-prod.ts
|
|
6
6
|
*
|
|
7
7
|
* Optional:
|
|
8
8
|
* FITPICK_API_BASE_URL=https://api.bowlly.net pnpm tsx packages/mcp-server/scripts/smoke-prod.ts --verbose
|
|
@@ -42,8 +42,8 @@ async function main() {
|
|
|
42
42
|
const args = parseArgs(process.argv.slice(2));
|
|
43
43
|
|
|
44
44
|
// API key is optional - some endpoints may be public or already have auth via other means
|
|
45
|
-
if (!process.env.FITPICK_API_KEY) {
|
|
46
|
-
console.log("Note:
|
|
45
|
+
if (!process.env.BOWLLY_API_KEY && !process.env.FITPICK_API_KEY) {
|
|
46
|
+
console.log("Note: BOWLLY_API_KEY not set. Running without authentication...");
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
const { AgentApiClient } = await import("../src/client.js");
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"curation-tool.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/curation-tool.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,329 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
|
2
|
-
import { AgentApiClient } from "../client.js";
|
|
3
|
-
import { TokenBucketManager } from "../rate-limit.js";
|
|
4
|
-
// Mock the @fitpick/core/data module - factory is hoisted, so define everything inside
|
|
5
|
-
vi.mock("@fitpick/core/data", () => {
|
|
6
|
-
const mockPage = {
|
|
7
|
-
slug: "low-carb-cat-food",
|
|
8
|
-
title: "Best Low Carb Cat Food (2026)",
|
|
9
|
-
description: "Top rated low carbohydrate cat foods for diabetic cats",
|
|
10
|
-
tldr: ["Low carb diets are essential for diabetic cats", "Wet food is generally lower in carbs"],
|
|
11
|
-
criteria: ["Carbohydrates < 10%", "High quality animal protein"],
|
|
12
|
-
recommendedProductIds: ["prod-123", "prod-456", "prod-789"],
|
|
13
|
-
updatedAt: "2026-01-15",
|
|
14
|
-
sections: [
|
|
15
|
-
{
|
|
16
|
-
heading: "Why Low Carb Matters",
|
|
17
|
-
capsule: "Low carbohydrate cat food contains less than 10% carbs",
|
|
18
|
-
content: "Cats evolved as obligate carnivores...",
|
|
19
|
-
},
|
|
20
|
-
],
|
|
21
|
-
faq: [
|
|
22
|
-
{ question: "Why low carb?", answer: "Cats are obligate carnivores" },
|
|
23
|
-
],
|
|
24
|
-
};
|
|
25
|
-
return {
|
|
26
|
-
bestPages: [mockPage],
|
|
27
|
-
findBestPageBySlug: vi.fn((slug) => {
|
|
28
|
-
if (slug === "low-carb-cat-food")
|
|
29
|
-
return mockPage;
|
|
30
|
-
return undefined;
|
|
31
|
-
}),
|
|
32
|
-
};
|
|
33
|
-
});
|
|
34
|
-
// Import after mocking
|
|
35
|
-
import { registerCurationTool, clearProductCache } from "../tools/get-curation-list.js";
|
|
36
|
-
import { findBestPageBySlug } from "@fitpick/core/data";
|
|
37
|
-
describe("get_curation_list tool", () => {
|
|
38
|
-
let client;
|
|
39
|
-
let bucketManager;
|
|
40
|
-
const getClientId = () => "test-client";
|
|
41
|
-
let capturedHandler = null;
|
|
42
|
-
// Mock server that captures the registered tool handler
|
|
43
|
-
// McpServer.tool(name, description, paramsSchema, handler)
|
|
44
|
-
const createMockServer = () => {
|
|
45
|
-
return {
|
|
46
|
-
tool: (name, _description, _schema, handler) => {
|
|
47
|
-
if (name === "get_curation_list") {
|
|
48
|
-
capturedHandler = handler;
|
|
49
|
-
}
|
|
50
|
-
},
|
|
51
|
-
};
|
|
52
|
-
};
|
|
53
|
-
beforeEach(() => {
|
|
54
|
-
client = new AgentApiClient();
|
|
55
|
-
bucketManager = new TokenBucketManager(100, 60000);
|
|
56
|
-
capturedHandler = null;
|
|
57
|
-
vi.clearAllMocks();
|
|
58
|
-
clearProductCache();
|
|
59
|
-
});
|
|
60
|
-
afterEach(() => {
|
|
61
|
-
vi.restoreAllMocks();
|
|
62
|
-
});
|
|
63
|
-
it("returns curation data for valid slug", async () => {
|
|
64
|
-
// Mock client.getProductDetail to return wrapped product response
|
|
65
|
-
vi.spyOn(client, "getProductDetail").mockResolvedValue({
|
|
66
|
-
product: {
|
|
67
|
-
id: "prod-123",
|
|
68
|
-
name: "Premium Low Carb Cat Food",
|
|
69
|
-
brand: "Test Brand",
|
|
70
|
-
detailUrl: "https://fitpick.example.com/products/prod-123",
|
|
71
|
-
form: "wet",
|
|
72
|
-
nutrition: { protein: 45 },
|
|
73
|
-
},
|
|
74
|
-
});
|
|
75
|
-
const mockServer = createMockServer();
|
|
76
|
-
registerCurationTool(mockServer, client, bucketManager, getClientId);
|
|
77
|
-
expect(capturedHandler).not.toBeNull();
|
|
78
|
-
const result = await capturedHandler({ slug: "low-carb-cat-food" });
|
|
79
|
-
const content = JSON.parse(result.content[0].text);
|
|
80
|
-
// Verify response structure
|
|
81
|
-
expect(content.data).toBeDefined();
|
|
82
|
-
expect(content.data.title).toBe("Best Low Carb Cat Food (2026)");
|
|
83
|
-
expect(content.data.description).toBe("Top rated low carbohydrate cat foods for diabetic cats");
|
|
84
|
-
expect(content.data.tldr).toHaveLength(2);
|
|
85
|
-
expect(content.data.criteria).toContain("Carbohydrates < 10%");
|
|
86
|
-
expect(content.data.methodology).toContain("selection process");
|
|
87
|
-
expect(content.data.recommendedProductIds).toEqual(["prod-123", "prod-456", "prod-789"]);
|
|
88
|
-
expect(content.data.updatedAt).toBe("2026-01-15");
|
|
89
|
-
// Verify recommended products are enriched
|
|
90
|
-
expect(content.data.recommendedProducts).toBeDefined();
|
|
91
|
-
expect(content.data.recommendedProducts.length).toBeGreaterThan(0);
|
|
92
|
-
});
|
|
93
|
-
it("returns 404-like error for invalid slug", async () => {
|
|
94
|
-
// Override the mock for this test
|
|
95
|
-
vi.mocked(findBestPageBySlug).mockReturnValueOnce(undefined);
|
|
96
|
-
const mockServer = createMockServer();
|
|
97
|
-
registerCurationTool(mockServer, client, bucketManager, getClientId);
|
|
98
|
-
expect(capturedHandler).not.toBeNull();
|
|
99
|
-
const result = await capturedHandler({ slug: "non-existent-slug" });
|
|
100
|
-
const content = JSON.parse(result.content[0].text);
|
|
101
|
-
expect(content.error).toBeDefined();
|
|
102
|
-
expect(content.error.type).toBe('NOT_FOUND');
|
|
103
|
-
expect(content.error.message).toContain("not found");
|
|
104
|
-
});
|
|
105
|
-
it("handles missing products gracefully", async () => {
|
|
106
|
-
// Mock to return wrapped product for first call, throw for second, return for third
|
|
107
|
-
vi.spyOn(client, "getProductDetail")
|
|
108
|
-
.mockResolvedValueOnce({
|
|
109
|
-
product: {
|
|
110
|
-
id: "prod-123",
|
|
111
|
-
name: "Product 1",
|
|
112
|
-
brand: "Brand A",
|
|
113
|
-
detailUrl: "https://fitpick.example.com/products/prod-123",
|
|
114
|
-
form: "dry",
|
|
115
|
-
nutrition: { protein: 40 },
|
|
116
|
-
},
|
|
117
|
-
})
|
|
118
|
-
.mockRejectedValueOnce(new Error("Product not found"))
|
|
119
|
-
.mockResolvedValueOnce({
|
|
120
|
-
product: {
|
|
121
|
-
id: "prod-789",
|
|
122
|
-
name: "Product 3",
|
|
123
|
-
brand: "Brand C",
|
|
124
|
-
detailUrl: "https://fitpick.example.com/products/prod-789",
|
|
125
|
-
form: "wet",
|
|
126
|
-
nutrition: { protein: 42 },
|
|
127
|
-
},
|
|
128
|
-
});
|
|
129
|
-
const mockServer = createMockServer();
|
|
130
|
-
registerCurationTool(mockServer, client, bucketManager, getClientId);
|
|
131
|
-
expect(capturedHandler).not.toBeNull();
|
|
132
|
-
const result = await capturedHandler({ slug: "low-carb-cat-food" });
|
|
133
|
-
const content = JSON.parse(result.content[0].text);
|
|
134
|
-
// Verify we have products array with mixed results
|
|
135
|
-
expect(content.data.recommendedProducts).toBeDefined();
|
|
136
|
-
const products = content.data.recommendedProducts;
|
|
137
|
-
// Should have 3 products (top 3 from the list)
|
|
138
|
-
expect(products.length).toBe(3);
|
|
139
|
-
// First product should be successful
|
|
140
|
-
expect(products[0]).toHaveProperty("name");
|
|
141
|
-
// Second product should have error
|
|
142
|
-
expect(products[1]).toHaveProperty("error");
|
|
143
|
-
expect(products[1].id).toBe("prod-456");
|
|
144
|
-
// Third product should be successful
|
|
145
|
-
expect(products[2]).toHaveProperty("name");
|
|
146
|
-
});
|
|
147
|
-
it("includes extended content when requested", async () => {
|
|
148
|
-
vi.spyOn(client, "getProductDetail").mockResolvedValue({
|
|
149
|
-
product: {
|
|
150
|
-
id: "prod-123",
|
|
151
|
-
name: "Test Product",
|
|
152
|
-
brand: "Test Brand",
|
|
153
|
-
detailUrl: "https://fitpick.example.com/products/prod-123",
|
|
154
|
-
},
|
|
155
|
-
});
|
|
156
|
-
const mockServer = createMockServer();
|
|
157
|
-
registerCurationTool(mockServer, client, bucketManager, getClientId);
|
|
158
|
-
expect(capturedHandler).not.toBeNull();
|
|
159
|
-
const result = await capturedHandler({
|
|
160
|
-
slug: "low-carb-cat-food",
|
|
161
|
-
includeSections: true,
|
|
162
|
-
includeFaq: true,
|
|
163
|
-
});
|
|
164
|
-
const content = JSON.parse(result.content[0].text);
|
|
165
|
-
// Verify sections are included
|
|
166
|
-
expect(content.data.sections).toBeDefined();
|
|
167
|
-
expect(content.data.sections.length).toBeGreaterThan(0);
|
|
168
|
-
expect(content.data.sections[0]).toHaveProperty("heading");
|
|
169
|
-
expect(content.data.sections[0]).toHaveProperty("capsule");
|
|
170
|
-
expect(content.data.sections[0]).toHaveProperty("content");
|
|
171
|
-
// Verify FAQ is included
|
|
172
|
-
expect(content.data.faq).toBeDefined();
|
|
173
|
-
expect(content.data.faq.length).toBeGreaterThan(0);
|
|
174
|
-
expect(content.data.faq[0]).toHaveProperty("question");
|
|
175
|
-
expect(content.data.faq[0]).toHaveProperty("answer");
|
|
176
|
-
});
|
|
177
|
-
it("excludes extended content by default", async () => {
|
|
178
|
-
vi.spyOn(client, "getProductDetail").mockResolvedValue({
|
|
179
|
-
product: {
|
|
180
|
-
id: "prod-123",
|
|
181
|
-
name: "Test Product",
|
|
182
|
-
brand: "Test Brand",
|
|
183
|
-
detailUrl: "https://fitpick.example.com/products/prod-123",
|
|
184
|
-
},
|
|
185
|
-
});
|
|
186
|
-
const mockServer = createMockServer();
|
|
187
|
-
registerCurationTool(mockServer, client, bucketManager, getClientId);
|
|
188
|
-
expect(capturedHandler).not.toBeNull();
|
|
189
|
-
const result = await capturedHandler({
|
|
190
|
-
slug: "low-carb-cat-food",
|
|
191
|
-
});
|
|
192
|
-
const content = JSON.parse(result.content[0].text);
|
|
193
|
-
// Verify sections and FAQ are NOT included by default
|
|
194
|
-
expect(content.data.sections).toBeUndefined();
|
|
195
|
-
expect(content.data.faq).toBeUndefined();
|
|
196
|
-
});
|
|
197
|
-
it("includes rate limit info in response", async () => {
|
|
198
|
-
vi.spyOn(client, "getProductDetail").mockResolvedValue({
|
|
199
|
-
product: {
|
|
200
|
-
id: "prod-123",
|
|
201
|
-
name: "Test Product",
|
|
202
|
-
brand: "Test Brand",
|
|
203
|
-
detailUrl: "https://fitpick.example.com/products/prod-123",
|
|
204
|
-
},
|
|
205
|
-
});
|
|
206
|
-
const mockServer = createMockServer();
|
|
207
|
-
registerCurationTool(mockServer, client, bucketManager, getClientId);
|
|
208
|
-
expect(capturedHandler).not.toBeNull();
|
|
209
|
-
const result = await capturedHandler({ slug: "low-carb-cat-food" });
|
|
210
|
-
const content = JSON.parse(result.content[0].text);
|
|
211
|
-
// Verify rate limit info is present
|
|
212
|
-
expect(content.rateLimit).toBeDefined();
|
|
213
|
-
expect(content.rateLimit.limit).toBe(100);
|
|
214
|
-
expect(typeof content.rateLimit.remaining).toBe("number");
|
|
215
|
-
expect(typeof content.rateLimit.resetEpochMs).toBe("number");
|
|
216
|
-
});
|
|
217
|
-
it("should extract products from wrapped { product } responses in enrichTopProducts", async () => {
|
|
218
|
-
// Mock API returning wrapped format { product: {...} }
|
|
219
|
-
vi.spyOn(client, "getProductDetail").mockResolvedValue({
|
|
220
|
-
product: {
|
|
221
|
-
id: "prod-wrapped-123",
|
|
222
|
-
name: "Wrapped Product",
|
|
223
|
-
brand: "Test Brand",
|
|
224
|
-
form: "dry",
|
|
225
|
-
nutrition: { protein: 40 },
|
|
226
|
-
derivedMetrics: { carbEstimated: 15 },
|
|
227
|
-
},
|
|
228
|
-
});
|
|
229
|
-
const mockServer = createMockServer();
|
|
230
|
-
registerCurationTool(mockServer, client, bucketManager, getClientId);
|
|
231
|
-
expect(capturedHandler).not.toBeNull();
|
|
232
|
-
const result = await capturedHandler({ slug: "low-carb-cat-food" });
|
|
233
|
-
const content = JSON.parse(result.content[0].text);
|
|
234
|
-
// Verify enriched products contain correct data from wrapped responses
|
|
235
|
-
expect(content.data.recommendedProducts).toBeDefined();
|
|
236
|
-
expect(content.data.recommendedProducts.length).toBeGreaterThan(0);
|
|
237
|
-
const firstProduct = content.data.recommendedProducts[0];
|
|
238
|
-
expect(firstProduct.name).toBe("Wrapped Product");
|
|
239
|
-
expect(firstProduct.brand).toBe("Test Brand");
|
|
240
|
-
expect(firstProduct.form).toBe("dry");
|
|
241
|
-
expect(firstProduct.keyNutrition.protein).toBe(40);
|
|
242
|
-
expect(firstProduct.keyNutrition.carbEstimated).toBe(15);
|
|
243
|
-
});
|
|
244
|
-
it("should handle API responses with Zod validation", async () => {
|
|
245
|
-
// Mock API returning wrapped format (validated by Zod in client.ts)
|
|
246
|
-
vi.spyOn(client, "getProductDetail").mockResolvedValue({
|
|
247
|
-
product: {
|
|
248
|
-
id: "prod-validated-123",
|
|
249
|
-
name: "Validated Product",
|
|
250
|
-
brand: "Test Brand",
|
|
251
|
-
detailUrl: "https://fitpick.example.com/products/prod-validated-123",
|
|
252
|
-
form: "wet",
|
|
253
|
-
nutrition: { protein: 35 },
|
|
254
|
-
derivedMetrics: { carbEstimated: 8 },
|
|
255
|
-
},
|
|
256
|
-
});
|
|
257
|
-
const mockServer = createMockServer();
|
|
258
|
-
registerCurationTool(mockServer, client, bucketManager, getClientId);
|
|
259
|
-
expect(capturedHandler).not.toBeNull();
|
|
260
|
-
const result = await capturedHandler({ slug: "low-carb-cat-food" });
|
|
261
|
-
const content = JSON.parse(result.content[0].text);
|
|
262
|
-
// Verify enriched products work with Zod-validated responses
|
|
263
|
-
expect(content.data.recommendedProducts).toBeDefined();
|
|
264
|
-
expect(content.data.recommendedProducts.length).toBeGreaterThan(0);
|
|
265
|
-
const firstProduct = content.data.recommendedProducts[0];
|
|
266
|
-
expect(firstProduct.name).toBe("Validated Product");
|
|
267
|
-
expect(firstProduct.brand).toBe("Test Brand");
|
|
268
|
-
expect(firstProduct.form).toBe("wet");
|
|
269
|
-
});
|
|
270
|
-
it("should handle multiple wrapped responses", async () => {
|
|
271
|
-
// Mock multiple wrapped responses (all validated by Zod in client.ts)
|
|
272
|
-
vi.spyOn(client, "getProductDetail")
|
|
273
|
-
.mockResolvedValueOnce({
|
|
274
|
-
product: {
|
|
275
|
-
id: "prod-multi-1",
|
|
276
|
-
name: "Product 1",
|
|
277
|
-
brand: "Brand A",
|
|
278
|
-
detailUrl: "https://fitpick.example.com/products/prod-multi-1",
|
|
279
|
-
nutrition: { protein: 42 },
|
|
280
|
-
},
|
|
281
|
-
})
|
|
282
|
-
.mockResolvedValueOnce({
|
|
283
|
-
product: {
|
|
284
|
-
id: "prod-multi-2",
|
|
285
|
-
name: "Product 2",
|
|
286
|
-
brand: "Brand B",
|
|
287
|
-
detailUrl: "https://fitpick.example.com/products/prod-multi-2",
|
|
288
|
-
nutrition: { protein: 38 },
|
|
289
|
-
},
|
|
290
|
-
})
|
|
291
|
-
.mockResolvedValueOnce({
|
|
292
|
-
product: {
|
|
293
|
-
id: "prod-multi-3",
|
|
294
|
-
name: "Product 3",
|
|
295
|
-
brand: "Brand C",
|
|
296
|
-
detailUrl: "https://fitpick.example.com/products/prod-multi-3",
|
|
297
|
-
nutrition: { protein: 45 },
|
|
298
|
-
},
|
|
299
|
-
});
|
|
300
|
-
const mockServer = createMockServer();
|
|
301
|
-
registerCurationTool(mockServer, client, bucketManager, getClientId);
|
|
302
|
-
expect(capturedHandler).not.toBeNull();
|
|
303
|
-
const result = await capturedHandler({ slug: "low-carb-cat-food" });
|
|
304
|
-
const content = JSON.parse(result.content[0].text);
|
|
305
|
-
// Verify all products are enriched correctly with Zod-validated responses
|
|
306
|
-
expect(content.data.recommendedProducts).toBeDefined();
|
|
307
|
-
expect(content.data.recommendedProducts.length).toBe(3);
|
|
308
|
-
expect(content.data.recommendedProducts[0].name).toBe("Product 1");
|
|
309
|
-
expect(content.data.recommendedProducts[1].name).toBe("Product 2");
|
|
310
|
-
expect(content.data.recommendedProducts[2].name).toBe("Product 3");
|
|
311
|
-
});
|
|
312
|
-
it("should handle null product in wrapped response", async () => {
|
|
313
|
-
// Mock wrapped response with null product
|
|
314
|
-
vi.spyOn(client, "getProductDetail").mockResolvedValue({
|
|
315
|
-
product: null,
|
|
316
|
-
});
|
|
317
|
-
const mockServer = createMockServer();
|
|
318
|
-
registerCurationTool(mockServer, client, bucketManager, getClientId);
|
|
319
|
-
expect(capturedHandler).not.toBeNull();
|
|
320
|
-
const result = await capturedHandler({ slug: "low-carb-cat-food" });
|
|
321
|
-
const content = JSON.parse(result.content[0].text);
|
|
322
|
-
// Verify products with null data show error
|
|
323
|
-
expect(content.data.recommendedProducts).toBeDefined();
|
|
324
|
-
expect(content.data.recommendedProducts.length).toBeGreaterThan(0);
|
|
325
|
-
const firstProduct = content.data.recommendedProducts[0];
|
|
326
|
-
expect(firstProduct.error).toBe("Product not found");
|
|
327
|
-
});
|
|
328
|
-
});
|
|
329
|
-
//# sourceMappingURL=curation-tool.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"curation-tool.test.js","sourceRoot":"","sources":["../../src/__tests__/curation-tool.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEtD,uFAAuF;AACvF,EAAE,CAAC,IAAI,CAAC,oBAAoB,EAAE,GAAG,EAAE;IACjC,MAAM,QAAQ,GAAG;QACf,IAAI,EAAE,mBAAmB;QACzB,KAAK,EAAE,+BAA+B;QACtC,WAAW,EAAE,wDAAwD;QACrE,IAAI,EAAE,CAAC,gDAAgD,EAAE,sCAAsC,CAAC;QAChG,QAAQ,EAAE,CAAC,qBAAqB,EAAE,6BAA6B,CAAC;QAChE,qBAAqB,EAAE,CAAC,UAAU,EAAE,UAAU,EAAE,UAAU,CAAC;QAC3D,SAAS,EAAE,YAAY;QACvB,QAAQ,EAAE;YACR;gBACE,OAAO,EAAE,sBAAsB;gBAC/B,OAAO,EAAE,wDAAwD;gBACjE,OAAO,EAAE,wCAAwC;aAClD;SACF;QACD,GAAG,EAAE;YACH,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,EAAE,8BAA8B,EAAE;SACtE;KACF,CAAC;IAEF,OAAO;QACL,SAAS,EAAE,CAAC,QAAQ,CAAC;QACrB,kBAAkB,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,IAAY,EAAE,EAAE;YACzC,IAAI,IAAI,KAAK,mBAAmB;gBAAE,OAAO,QAAQ,CAAC;YAClD,OAAO,SAAS,CAAC;QACnB,CAAC,CAAC;KACH,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,uBAAuB;AACvB,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AACxF,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;IACtC,IAAI,MAAsB,CAAC;IAC3B,IAAI,aAAiC,CAAC;IACtC,MAAM,WAAW,GAAG,GAAG,EAAE,CAAC,aAAa,CAAC;IACxC,IAAI,eAAe,GAA4F,IAAI,CAAC;IAEpH,wDAAwD;IACxD,2DAA2D;IAC3D,MAAM,gBAAgB,GAAG,GAAG,EAAE;QAC5B,OAAO;YACL,IAAI,EAAE,CACJ,IAAY,EACZ,YAAoB,EACpB,OAAgB,EAChB,OAAuF,EACvF,EAAE;gBACF,IAAI,IAAI,KAAK,mBAAmB,EAAE,CAAC;oBACjC,eAAe,GAAG,OAAO,CAAC;gBAC5B,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC,CAAC;IAEF,UAAU,CAAC,GAAG,EAAE;QACd,MAAM,GAAG,IAAI,cAAc,EAAE,CAAC;QAC9B,aAAa,GAAG,IAAI,kBAAkB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACnD,eAAe,GAAG,IAAI,CAAC;QACvB,EAAE,CAAC,aAAa,EAAE,CAAC;QACnB,iBAAiB,EAAE,CAAC;IACtB,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,EAAE,CAAC,eAAe,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;QACpD,kEAAkE;QAClE,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,iBAAiB,CAAC;YACrD,OAAO,EAAE;gBACP,EAAE,EAAE,UAAU;gBACd,IAAI,EAAE,2BAA2B;gBACjC,KAAK,EAAE,YAAY;gBACnB,SAAS,EAAE,+CAA+C;gBAC1D,IAAI,EAAE,KAAK;gBACX,SAAS,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;aAC3B;SACF,CAAC,CAAC;QAEH,MAAM,UAAU,GAAG,gBAAgB,EAAE,CAAC;QACtC,oBAAoB,CAAC,UAAwD,EAAE,MAAM,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC;QAEnH,MAAM,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QACvC,MAAM,MAAM,GAAG,MAAM,eAAgB,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC,CAAC;QAErE,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAEnD,4BAA4B;QAC5B,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;QACnC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;QACjE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,wDAAwD,CAAC,CAAC;QAChG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC;QAC/D,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;QAChE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC;QACzF,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAElD,2CAA2C;QAC3C,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,WAAW,EAAE,CAAC;QACvD,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;QACvD,kCAAkC;QAClC,EAAE,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC;QAE7D,MAAM,UAAU,GAAG,gBAAgB,EAAE,CAAC;QACtC,oBAAoB,CAAC,UAAwD,EAAE,MAAM,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC;QAEnH,MAAM,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QACvC,MAAM,MAAM,GAAG,MAAM,eAAgB,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC,CAAC;QAErE,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAEnD,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;QACpC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC7C,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;QACnD,oFAAoF;QACpF,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,kBAAkB,CAAC;aACjC,qBAAqB,CAAC;YACrB,OAAO,EAAE;gBACP,EAAE,EAAE,UAAU;gBACd,IAAI,EAAE,WAAW;gBACjB,KAAK,EAAE,SAAS;gBAChB,SAAS,EAAE,+CAA+C;gBAC1D,IAAI,EAAE,KAAK;gBACX,SAAS,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;aAC3B;SACF,CAAC;aACD,qBAAqB,CAAC,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;aACrD,qBAAqB,CAAC;YACrB,OAAO,EAAE;gBACP,EAAE,EAAE,UAAU;gBACd,IAAI,EAAE,WAAW;gBACjB,KAAK,EAAE,SAAS;gBAChB,SAAS,EAAE,+CAA+C;gBAC1D,IAAI,EAAE,KAAK;gBACX,SAAS,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;aAC3B;SACF,CAAC,CAAC;QAEL,MAAM,UAAU,GAAG,gBAAgB,EAAE,CAAC;QACtC,oBAAoB,CAAC,UAAwD,EAAE,MAAM,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC;QAEnH,MAAM,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QACvC,MAAM,MAAM,GAAG,MAAM,eAAgB,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC,CAAC;QAErE,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAEnD,mDAAmD;QACnD,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,WAAW,EAAE,CAAC;QACvD,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC;QAElD,+CAA+C;QAC/C,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAEhC,qCAAqC;QACrC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;QAE3C,mCAAmC;QACnC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QAC5C,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAExC,qCAAqC;QACrC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;QACxD,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,iBAAiB,CAAC;YACrD,OAAO,EAAE;gBACP,EAAE,EAAE,UAAU;gBACd,IAAI,EAAE,cAAc;gBACpB,KAAK,EAAE,YAAY;gBACnB,SAAS,EAAE,+CAA+C;aAC3D;SACF,CAAC,CAAC;QAEH,MAAM,UAAU,GAAG,gBAAgB,EAAE,CAAC;QACtC,oBAAoB,CAAC,UAAwD,EAAE,MAAM,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC;QAEnH,MAAM,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QACvC,MAAM,MAAM,GAAG,MAAM,eAAgB,CAAC;YACpC,IAAI,EAAE,mBAAmB;YACzB,eAAe,EAAE,IAAI;YACrB,UAAU,EAAE,IAAI;SACjB,CAAC,CAAC;QAEH,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAEnD,+BAA+B;QAC/B,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;QAC5C,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QACxD,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;QAC3D,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;QAC3D,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;QAE3D,yBAAyB;QACzB,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;QACvC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QACnD,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;QACvD,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;QACpD,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,iBAAiB,CAAC;YACrD,OAAO,EAAE;gBACP,EAAE,EAAE,UAAU;gBACd,IAAI,EAAE,cAAc;gBACpB,KAAK,EAAE,YAAY;gBACnB,SAAS,EAAE,+CAA+C;aAC3D;SACF,CAAC,CAAC;QAEH,MAAM,UAAU,GAAG,gBAAgB,EAAE,CAAC;QACtC,oBAAoB,CAAC,UAAwD,EAAE,MAAM,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC;QAEnH,MAAM,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QACvC,MAAM,MAAM,GAAG,MAAM,eAAgB,CAAC;YACpC,IAAI,EAAE,mBAAmB;SAC1B,CAAC,CAAC;QAEH,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAEnD,sDAAsD;QACtD,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,aAAa,EAAE,CAAC;QAC9C,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,aAAa,EAAE,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;QACpD,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,iBAAiB,CAAC;YACrD,OAAO,EAAE;gBACP,EAAE,EAAE,UAAU;gBACd,IAAI,EAAE,cAAc;gBACpB,KAAK,EAAE,YAAY;gBACnB,SAAS,EAAE,+CAA+C;aAC3D;SACF,CAAC,CAAC;QAEH,MAAM,UAAU,GAAG,gBAAgB,EAAE,CAAC;QACtC,oBAAoB,CAAC,UAAwD,EAAE,MAAM,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC;QAEnH,MAAM,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QACvC,MAAM,MAAM,GAAG,MAAM,eAAgB,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC,CAAC;QAErE,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAEnD,oCAAoC;QACpC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC;QACxC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC1C,MAAM,CAAC,OAAO,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC1D,MAAM,CAAC,OAAO,OAAO,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iFAAiF,EAAE,KAAK,IAAI,EAAE;QAC/F,uDAAuD;QACvD,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,iBAAiB,CAAC;YACrD,OAAO,EAAE;gBACP,EAAE,EAAE,kBAAkB;gBACtB,IAAI,EAAE,iBAAiB;gBACvB,KAAK,EAAE,YAAY;gBACnB,IAAI,EAAE,KAAc;gBACpB,SAAS,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;gBAC1B,cAAc,EAAE,EAAE,aAAa,EAAE,EAAE,EAAE;aACtC;SACF,CAAC,CAAC;QAEH,MAAM,UAAU,GAAG,gBAAgB,EAAE,CAAC;QACtC,oBAAoB,CAAC,UAAwD,EAAE,MAAM,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC;QAEnH,MAAM,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QACvC,MAAM,MAAM,GAAG,MAAM,eAAgB,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC,CAAC;QAErE,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAEnD,uEAAuE;QACvE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,WAAW,EAAE,CAAC;QACvD,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAEnE,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;QACzD,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAClD,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC9C,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACtC,MAAM,CAAC,YAAY,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACnD,MAAM,CAAC,YAAY,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;QAC/D,oEAAoE;QACpE,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,iBAAiB,CAAC;YACrD,OAAO,EAAE;gBACP,EAAE,EAAE,oBAAoB;gBACxB,IAAI,EAAE,mBAAmB;gBACzB,KAAK,EAAE,YAAY;gBACnB,SAAS,EAAE,yDAAyD;gBACpE,IAAI,EAAE,KAAK;gBACX,SAAS,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;gBAC1B,cAAc,EAAE,EAAE,aAAa,EAAE,CAAC,EAAE;aACrC;SACF,CAAC,CAAC;QAEH,MAAM,UAAU,GAAG,gBAAgB,EAAE,CAAC;QACtC,oBAAoB,CAAC,UAAwD,EAAE,MAAM,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC;QAEnH,MAAM,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QACvC,MAAM,MAAM,GAAG,MAAM,eAAgB,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC,CAAC;QAErE,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAEnD,6DAA6D;QAC7D,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,WAAW,EAAE,CAAC;QACvD,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAEnE,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;QACzD,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QACpD,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC9C,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;QACxD,sEAAsE;QACtE,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,kBAAkB,CAAC;aACjC,qBAAqB,CAAC;YACrB,OAAO,EAAE;gBACP,EAAE,EAAE,cAAc;gBAClB,IAAI,EAAE,WAAW;gBACjB,KAAK,EAAE,SAAS;gBAChB,SAAS,EAAE,mDAAmD;gBAC9D,SAAS,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;aAC3B;SACF,CAAC;aACD,qBAAqB,CAAC;YACrB,OAAO,EAAE;gBACP,EAAE,EAAE,cAAc;gBAClB,IAAI,EAAE,WAAW;gBACjB,KAAK,EAAE,SAAS;gBAChB,SAAS,EAAE,mDAAmD;gBAC9D,SAAS,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;aAC3B;SACF,CAAC;aACD,qBAAqB,CAAC;YACrB,OAAO,EAAE;gBACP,EAAE,EAAE,cAAc;gBAClB,IAAI,EAAE,WAAW;gBACjB,KAAK,EAAE,SAAS;gBAChB,SAAS,EAAE,mDAAmD;gBAC9D,SAAS,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;aAC3B;SACF,CAAC,CAAC;QAEL,MAAM,UAAU,GAAG,gBAAgB,EAAE,CAAC;QACtC,oBAAoB,CAAC,UAAwD,EAAE,MAAM,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC;QAEnH,MAAM,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QACvC,MAAM,MAAM,GAAG,MAAM,eAAgB,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC,CAAC;QAErE,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAEnD,0EAA0E;QAC1E,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,WAAW,EAAE,CAAC;QACvD,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAExD,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACnE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACnE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;QAC9D,0CAA0C;QAC1C,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,iBAAiB,CAAC;YACrD,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;QAEH,MAAM,UAAU,GAAG,gBAAgB,EAAE,CAAC;QACtC,oBAAoB,CAAC,UAAwD,EAAE,MAAM,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC;QAEnH,MAAM,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QACvC,MAAM,MAAM,GAAG,MAAM,eAAgB,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC,CAAC;QAErE,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAEnD,4CAA4C;QAC5C,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,WAAW,EAAE,CAAC;QACvD,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAEnE,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;QACzD,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"nutrition-tool.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/nutrition-tool.test.ts"],"names":[],"mappings":""}
|