usetraceforge-cli 0.1.0 → 0.1.3
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 +6 -1
- package/dist/installers/nextjs.js +36 -15
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -29,6 +29,11 @@ async function main() {
|
|
|
29
29
|
outro(chalk.red("Installation cancelled."));
|
|
30
30
|
process.exit(1);
|
|
31
31
|
}
|
|
32
|
+
const endpoint = await text({
|
|
33
|
+
message: "What is your TraceForge Ingest Endpoint URL?",
|
|
34
|
+
placeholder: "http://localhost:80/ingest",
|
|
35
|
+
defaultValue: "http://localhost:80/ingest",
|
|
36
|
+
});
|
|
32
37
|
const s = spinner();
|
|
33
38
|
s.start("Installing usetraceforge SDK...");
|
|
34
39
|
try {
|
|
@@ -39,7 +44,7 @@ async function main() {
|
|
|
39
44
|
s.stop(chalk.red("Failed to install SDK. Please run 'npm install usetraceforge' manually."));
|
|
40
45
|
}
|
|
41
46
|
if (framework === "nextjs") {
|
|
42
|
-
await installNextJs(apiKey);
|
|
47
|
+
await installNextJs(apiKey, endpoint);
|
|
43
48
|
}
|
|
44
49
|
else if (framework === "express") {
|
|
45
50
|
// await installExpress(apiKey);
|
|
@@ -2,13 +2,13 @@ import fs from "fs";
|
|
|
2
2
|
import path from "path";
|
|
3
3
|
import { spinner } from "@clack/prompts";
|
|
4
4
|
import chalk from "chalk";
|
|
5
|
-
export async function installNextJs(apiKey) {
|
|
5
|
+
export async function installNextJs(apiKey, endpoint) {
|
|
6
6
|
const s = spinner();
|
|
7
7
|
s.start("Configuring Next.js...");
|
|
8
8
|
try {
|
|
9
|
-
// 1. Add API key to .env.local
|
|
9
|
+
// 1. Add API key and endpoint to .env.local
|
|
10
10
|
const envPath = path.resolve(process.cwd(), ".env.local");
|
|
11
|
-
const envVar = `\nNEXT_PUBLIC_TRACEFORGE_API_KEY="${apiKey}"\n`;
|
|
11
|
+
const envVar = `\nNEXT_PUBLIC_TRACEFORGE_API_KEY="${apiKey}"\nNEXT_PUBLIC_TRACEFORGE_INGEST_URL="${endpoint}"\n`;
|
|
12
12
|
if (fs.existsSync(envPath)) {
|
|
13
13
|
const content = fs.readFileSync(envPath, "utf-8");
|
|
14
14
|
if (!content.includes("NEXT_PUBLIC_TRACEFORGE_API_KEY")) {
|
|
@@ -18,12 +18,37 @@ export async function installNextJs(apiKey) {
|
|
|
18
18
|
else {
|
|
19
19
|
fs.writeFileSync(envPath, envVar);
|
|
20
20
|
}
|
|
21
|
-
// 2.
|
|
21
|
+
// 2. Generate TraceForgeProvider.tsx
|
|
22
|
+
const componentsDir = path.resolve(process.cwd(), "components");
|
|
23
|
+
if (!fs.existsSync(componentsDir)) {
|
|
24
|
+
fs.mkdirSync(componentsDir);
|
|
25
|
+
}
|
|
26
|
+
const providerCode = `"use client";
|
|
27
|
+
import { useEffect } from "react";
|
|
28
|
+
import TraceForge from "usetraceforge";
|
|
29
|
+
import { TraceForgeErrorBoundary } from "usetraceforge/react";
|
|
30
|
+
|
|
31
|
+
let initialized = false;
|
|
32
|
+
|
|
33
|
+
export function TraceForgeProvider({ children }: { children: React.ReactNode }) {
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
if (initialized) return;
|
|
36
|
+
TraceForge.init({
|
|
37
|
+
apiKey: process.env.NEXT_PUBLIC_TRACEFORGE_API_KEY!,
|
|
38
|
+
endpoint: process.env.NEXT_PUBLIC_TRACEFORGE_INGEST_URL,
|
|
39
|
+
autoCapture: true,
|
|
40
|
+
});
|
|
41
|
+
initialized = true;
|
|
42
|
+
}, []);
|
|
43
|
+
|
|
44
|
+
return <TraceForgeErrorBoundary>{children}</TraceForgeErrorBoundary>;
|
|
45
|
+
}
|
|
46
|
+
`;
|
|
47
|
+
fs.writeFileSync(path.join(componentsDir, "TraceForgeProvider.tsx"), providerCode);
|
|
48
|
+
// 3. Find layout.tsx
|
|
22
49
|
const layoutPaths = [
|
|
23
50
|
path.resolve(process.cwd(), "app/layout.tsx"),
|
|
24
51
|
path.resolve(process.cwd(), "src/app/layout.tsx"),
|
|
25
|
-
path.resolve(process.cwd(), "app/layout.jsx"),
|
|
26
|
-
path.resolve(process.cwd(), "src/app/layout.jsx"),
|
|
27
52
|
];
|
|
28
53
|
let targetLayout = null;
|
|
29
54
|
for (const p of layoutPaths) {
|
|
@@ -36,20 +61,16 @@ export async function installNextJs(apiKey) {
|
|
|
36
61
|
s.stop(chalk.yellow("Could not find app/layout.tsx. Please configure TraceForge manually."));
|
|
37
62
|
return;
|
|
38
63
|
}
|
|
39
|
-
//
|
|
64
|
+
// 4. Inject code into layout.tsx
|
|
40
65
|
let layoutCode = fs.readFileSync(targetLayout, "utf-8");
|
|
41
|
-
|
|
42
|
-
if (layoutCode.includes("TraceForgeErrorBoundary")) {
|
|
66
|
+
if (layoutCode.includes("TraceForgeProvider")) {
|
|
43
67
|
s.stop(chalk.green("TraceForge is already configured in layout.tsx!"));
|
|
44
68
|
return;
|
|
45
69
|
}
|
|
46
|
-
|
|
47
|
-
const importStatement = `import { TraceForgeErrorBoundary } from "usetraceforge/react";\n`;
|
|
70
|
+
const importStatement = `import { TraceForgeProvider } from "@/components/TraceForgeProvider";\n`;
|
|
48
71
|
layoutCode = importStatement + layoutCode;
|
|
49
|
-
|
|
50
|
-
layoutCode = layoutCode.replace(
|
|
51
|
-
// Replace </body> with </TraceForgeErrorBoundary></body>
|
|
52
|
-
layoutCode = layoutCode.replace(/<\/body>/g, ` </TraceForgeErrorBoundary>\n </body>`);
|
|
72
|
+
layoutCode = layoutCode.replace(/(<body[^>]*>)/g, `$1\n <TraceForgeProvider>`);
|
|
73
|
+
layoutCode = layoutCode.replace(/<\/body>/g, ` </TraceForgeProvider>\n </body>`);
|
|
53
74
|
fs.writeFileSync(targetLayout, layoutCode);
|
|
54
75
|
s.stop(chalk.green("Next.js configuration complete!"));
|
|
55
76
|
}
|