@easyfunnel/mcp 0.1.8 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +61 -46
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -211,25 +211,25 @@ var frameworkConfigs = {
|
|
|
211
211
|
nextjs: {
|
|
212
212
|
envFile: ".env.local",
|
|
213
213
|
envVarName: "NEXT_PUBLIC_EASYFUNNEL_KEY",
|
|
214
|
-
envAccessor:
|
|
214
|
+
envAccessor: (apiKey2) => `process.env.NEXT_PUBLIC_EASYFUNNEL_KEY || "${apiKey2}"`,
|
|
215
215
|
layoutPaths: ["app/layout.tsx", "app/layout.jsx", "src/app/layout.tsx", "src/app/layout.jsx"]
|
|
216
216
|
},
|
|
217
217
|
vite: {
|
|
218
218
|
envFile: ".env",
|
|
219
219
|
envVarName: "VITE_EASYFUNNEL_KEY",
|
|
220
|
-
envAccessor:
|
|
220
|
+
envAccessor: (apiKey2) => `import.meta.env.VITE_EASYFUNNEL_KEY || "${apiKey2}"`,
|
|
221
221
|
layoutPaths: ["src/App.tsx", "src/App.jsx", "src/main.tsx", "src/main.jsx"]
|
|
222
222
|
},
|
|
223
223
|
cra: {
|
|
224
224
|
envFile: ".env",
|
|
225
225
|
envVarName: "REACT_APP_EASYFUNNEL_KEY",
|
|
226
|
-
envAccessor:
|
|
226
|
+
envAccessor: (apiKey2) => `process.env.REACT_APP_EASYFUNNEL_KEY || "${apiKey2}"`,
|
|
227
227
|
layoutPaths: ["src/App.tsx", "src/App.jsx", "src/index.tsx", "src/index.jsx"]
|
|
228
228
|
},
|
|
229
229
|
sveltekit: {
|
|
230
230
|
envFile: ".env",
|
|
231
231
|
envVarName: "PUBLIC_EASYFUNNEL_KEY",
|
|
232
|
-
envAccessor:
|
|
232
|
+
envAccessor: (apiKey2) => `import.meta.env.PUBLIC_EASYFUNNEL_KEY || "${apiKey2}"`,
|
|
233
233
|
layoutPaths: ["src/routes/+layout.svelte"]
|
|
234
234
|
}
|
|
235
235
|
};
|
|
@@ -374,7 +374,7 @@ Next: After adding the script, I'll verify everything works with a test event.`
|
|
|
374
374
|
if (content.includes("{children}")) {
|
|
375
375
|
content = content.replace(
|
|
376
376
|
/(\{children\})/,
|
|
377
|
-
`<EasyFunnelProvider apiKey={${config.envAccessor}}>
|
|
377
|
+
`<EasyFunnelProvider apiKey={${config.envAccessor(project_api_key)}}>
|
|
378
378
|
$1
|
|
379
379
|
</EasyFunnelProvider>`
|
|
380
380
|
);
|
|
@@ -416,10 +416,12 @@ Project API Key: ${project_api_key}
|
|
|
416
416
|
output += `(This is the PROJECT key for the SDK \u2014 not the account key used by the MCP server.)
|
|
417
417
|
`;
|
|
418
418
|
output += `
|
|
419
|
-
|
|
419
|
+
The API key is hardcoded in your layout file \u2014 no env var configuration needed.
|
|
420
|
+
`;
|
|
421
|
+
output += `If you prefer, you can override it via ${config.envVarName} in ${config.envFile}.
|
|
420
422
|
`;
|
|
421
423
|
output += `
|
|
422
|
-
Next:
|
|
424
|
+
Next: I'll verify everything works with a test event.`;
|
|
423
425
|
return {
|
|
424
426
|
content: [{ type: "text", text: output }]
|
|
425
427
|
};
|
|
@@ -1636,18 +1638,18 @@ function readEnvFile(projectRoot) {
|
|
|
1636
1638
|
}
|
|
1637
1639
|
return null;
|
|
1638
1640
|
}
|
|
1641
|
+
var layoutCandidates = [
|
|
1642
|
+
"app/layout.tsx",
|
|
1643
|
+
"app/layout.jsx",
|
|
1644
|
+
"src/app/layout.tsx",
|
|
1645
|
+
"src/app/layout.jsx",
|
|
1646
|
+
"src/App.tsx",
|
|
1647
|
+
"src/App.jsx",
|
|
1648
|
+
"src/main.tsx",
|
|
1649
|
+
"src/main.jsx"
|
|
1650
|
+
];
|
|
1639
1651
|
function findProviderFile(projectRoot) {
|
|
1640
|
-
const
|
|
1641
|
-
"app/layout.tsx",
|
|
1642
|
-
"app/layout.jsx",
|
|
1643
|
-
"src/app/layout.tsx",
|
|
1644
|
-
"src/app/layout.jsx",
|
|
1645
|
-
"src/App.tsx",
|
|
1646
|
-
"src/App.jsx",
|
|
1647
|
-
"src/main.tsx",
|
|
1648
|
-
"src/main.jsx"
|
|
1649
|
-
];
|
|
1650
|
-
for (const relPath of candidates) {
|
|
1652
|
+
for (const relPath of layoutCandidates) {
|
|
1651
1653
|
const fullPath = (0, import_path4.join)(projectRoot, relPath);
|
|
1652
1654
|
if ((0, import_fs6.existsSync)(fullPath)) {
|
|
1653
1655
|
const content = (0, import_fs6.readFileSync)(fullPath, "utf-8");
|
|
@@ -1658,37 +1660,50 @@ function findProviderFile(projectRoot) {
|
|
|
1658
1660
|
}
|
|
1659
1661
|
return null;
|
|
1660
1662
|
}
|
|
1663
|
+
function findHardcodedKey(projectRoot) {
|
|
1664
|
+
for (const relPath of layoutCandidates) {
|
|
1665
|
+
const fullPath = (0, import_path4.join)(projectRoot, relPath);
|
|
1666
|
+
if (!(0, import_fs6.existsSync)(fullPath)) continue;
|
|
1667
|
+
const content = (0, import_fs6.readFileSync)(fullPath, "utf-8");
|
|
1668
|
+
if (!content.includes("EasyFunnelProvider")) continue;
|
|
1669
|
+
const match = content.match(/apiKey[=:].*?(ef_[a-f0-9]+)/);
|
|
1670
|
+
if (match) {
|
|
1671
|
+
return { file: relPath, key: match[1] };
|
|
1672
|
+
}
|
|
1673
|
+
}
|
|
1674
|
+
return null;
|
|
1675
|
+
}
|
|
1661
1676
|
async function validateSetup(client2, args) {
|
|
1662
1677
|
const { project_root, project_id } = args;
|
|
1663
1678
|
const checks = [];
|
|
1664
1679
|
const envResult = readEnvFile(project_root);
|
|
1680
|
+
const hardcodedResult = findHardcodedKey(project_root);
|
|
1665
1681
|
let apiKey2 = args.project_api_key || "";
|
|
1666
|
-
if (envResult) {
|
|
1682
|
+
if (envResult && envResult.value && envResult.value.startsWith("ef_")) {
|
|
1667
1683
|
apiKey2 = apiKey2 || envResult.value;
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
}
|
|
1684
|
+
checks.push({
|
|
1685
|
+
name: `${envResult.file} contains ${envResult.varName}`,
|
|
1686
|
+
passed: true,
|
|
1687
|
+
detail: `${envResult.varName}=${envResult.value.slice(0, 8)}...`
|
|
1688
|
+
});
|
|
1689
|
+
} else if (hardcodedResult) {
|
|
1690
|
+
apiKey2 = apiKey2 || hardcodedResult.key;
|
|
1691
|
+
checks.push({
|
|
1692
|
+
name: `API key found in ${hardcodedResult.file}`,
|
|
1693
|
+
passed: true,
|
|
1694
|
+
detail: `Hardcoded key: ${hardcodedResult.key.slice(0, 8)}... (recommended for static deployments)`
|
|
1695
|
+
});
|
|
1696
|
+
} else if (envResult && envResult.value) {
|
|
1697
|
+
checks.push({
|
|
1698
|
+
name: `${envResult.file} contains ${envResult.varName}`,
|
|
1699
|
+
passed: false,
|
|
1700
|
+
detail: `Value doesn't start with "ef_". Got: ${envResult.value.slice(0, 20)}`
|
|
1701
|
+
});
|
|
1687
1702
|
} else {
|
|
1688
1703
|
checks.push({
|
|
1689
|
-
name: "
|
|
1704
|
+
name: "API key configured",
|
|
1690
1705
|
passed: false,
|
|
1691
|
-
detail: "No EasyFunnel API key found in
|
|
1706
|
+
detail: "No EasyFunnel API key found in env file or hardcoded in layout. Run setup_sdk to add it."
|
|
1692
1707
|
});
|
|
1693
1708
|
}
|
|
1694
1709
|
const providerFile = findProviderFile(project_root);
|
|
@@ -1789,14 +1804,14 @@ Next: Let me suggest conversion funnels based on what I found in your codebase.`
|
|
|
1789
1804
|
output += `
|
|
1790
1805
|
`;
|
|
1791
1806
|
for (const check of failedChecks) {
|
|
1792
|
-
if (check.name.includes("
|
|
1793
|
-
|
|
1794
|
-
const envFile = envResult?.file || ".env.local";
|
|
1795
|
-
output += `To fix: Add your project API key to ${envFile}:
|
|
1807
|
+
if (check.name.includes("API key") || check.name.includes("Env file")) {
|
|
1808
|
+
output += `To fix: Run setup_sdk to hardcode the API key in your layout file.
|
|
1796
1809
|
`;
|
|
1797
|
-
output += `
|
|
1810
|
+
output += `Alternatively, add it to an env file:
|
|
1798
1811
|
`;
|
|
1799
|
-
|
|
1812
|
+
const varName = envResult?.varName || "NEXT_PUBLIC_EASYFUNNEL_KEY";
|
|
1813
|
+
const envFile = envResult?.file || ".env.local";
|
|
1814
|
+
output += ` ${varName}=ef_your_key_here (in ${envFile})
|
|
1800
1815
|
|
|
1801
1816
|
`;
|
|
1802
1817
|
} else if (check.name.includes("Provider")) {
|