@stephenov/feedbackwidget 0.6.0 → 0.7.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/cli.js +67 -42
- package/dist/cli.mjs +67 -42
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -89,45 +89,70 @@ async function initProject() {
|
|
|
89
89
|
}, 5 * 60 * 1e3);
|
|
90
90
|
});
|
|
91
91
|
const framework = detectFramework();
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
console.log("\u2705 Authenticated!\n");
|
|
100
|
-
console.log("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n");
|
|
92
|
+
const cwd = process.cwd();
|
|
93
|
+
const fullPath = framework.fullPath ? import_path.default.join(cwd, framework.fullPath) : null;
|
|
94
|
+
const targetFile = fullPath || framework.file;
|
|
95
|
+
const isAstro = framework.name === "Astro";
|
|
96
|
+
const importLine = 'import { FeedbackWidget } from "@stephenov/feedbackwidget";';
|
|
97
|
+
const componentSnippet = isAstro ? `<FeedbackWidget client:load apiKey="${apiKey}" />` : `<FeedbackWidget apiKey="${apiKey}" />`;
|
|
98
|
+
console.log("\n\u2705 Authenticated!\n");
|
|
101
99
|
if (framework.name) {
|
|
102
|
-
console.log(`
|
|
100
|
+
console.log(`Detected: ${framework.name}
|
|
103
101
|
`);
|
|
104
102
|
}
|
|
105
|
-
console.log("
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
console.log(" ---\n");
|
|
110
|
-
} else {
|
|
111
|
-
console.log(' import { FeedbackWidget } from "@stephenov/feedbackwidget"\n');
|
|
112
|
-
}
|
|
113
|
-
console.log(" Step 2: Add the component " + (framework.note || "inside <body>") + "\n");
|
|
114
|
-
if (framework.name === "Astro") {
|
|
115
|
-
console.log(` <FeedbackWidget client:load apiKey="${apiKey}" />
|
|
103
|
+
console.log("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n");
|
|
104
|
+
console.log("STEP 1: Add the import\n");
|
|
105
|
+
console.log("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n");
|
|
106
|
+
console.log(`Open: ${targetFile}
|
|
116
107
|
`);
|
|
108
|
+
if (isAstro) {
|
|
109
|
+
console.log("Add this inside the --- frontmatter block:\n");
|
|
117
110
|
} else {
|
|
118
|
-
console.log(
|
|
119
|
-
`);
|
|
111
|
+
console.log("Add this with your other imports:\n");
|
|
120
112
|
}
|
|
121
|
-
console.log(
|
|
122
|
-
console.log(` ${framework.devCommand || "npm run dev"}
|
|
113
|
+
console.log(` ${importLine}
|
|
123
114
|
`);
|
|
124
|
-
|
|
115
|
+
await waitForEnter("Press ENTER when you've added the import...");
|
|
116
|
+
console.log("\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n");
|
|
117
|
+
console.log("STEP 2: Add the component\n");
|
|
125
118
|
console.log("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n");
|
|
126
|
-
console.log(
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
119
|
+
console.log(`In the same file, add this ${framework.note || "inside <body>"}:
|
|
120
|
+
`);
|
|
121
|
+
console.log(` ${componentSnippet}
|
|
122
|
+
`);
|
|
123
|
+
try {
|
|
124
|
+
await copyToClipboard(componentSnippet);
|
|
125
|
+
console.log(" \u{1F4CB} Copied to clipboard!\n");
|
|
126
|
+
} catch {
|
|
127
|
+
}
|
|
128
|
+
await waitForEnter("Press ENTER when you've added the component...");
|
|
129
|
+
let verified = false;
|
|
130
|
+
if (fullPath && import_fs.default.existsSync(fullPath)) {
|
|
131
|
+
const content = import_fs.default.readFileSync(fullPath, "utf-8");
|
|
132
|
+
if (content.includes("FeedbackWidget")) {
|
|
133
|
+
verified = true;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
if (verified) {
|
|
137
|
+
console.log("\n\u2705 Found FeedbackWidget in your file!\n");
|
|
130
138
|
}
|
|
139
|
+
console.log("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n");
|
|
140
|
+
console.log("\u{1F389} SETUP COMPLETE!\n");
|
|
141
|
+
console.log("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n");
|
|
142
|
+
console.log(`Run: ${framework.devCommand || "npm run dev"}
|
|
143
|
+
`);
|
|
144
|
+
console.log("Refresh your browser - the widget will appear in the bottom-right.\n");
|
|
145
|
+
console.log("View feedback at: https://feedbackwidget-api.vercel.app/dashboard\n");
|
|
146
|
+
}
|
|
147
|
+
function waitForEnter(prompt) {
|
|
148
|
+
return new Promise((resolve) => {
|
|
149
|
+
process.stdout.write(prompt);
|
|
150
|
+
process.stdin.setRawMode?.(false);
|
|
151
|
+
process.stdin.resume();
|
|
152
|
+
process.stdin.once("data", () => {
|
|
153
|
+
resolve();
|
|
154
|
+
});
|
|
155
|
+
});
|
|
131
156
|
}
|
|
132
157
|
async function whoami() {
|
|
133
158
|
console.log("\nRun 'npx feedbackwidget init' to get your API key.\n");
|
|
@@ -200,49 +225,49 @@ function detectFramework() {
|
|
|
200
225
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
201
226
|
if (deps.astro) {
|
|
202
227
|
if (import_fs.default.existsSync(import_path.default.join(cwd, "src", "layouts", "Layout.astro"))) {
|
|
203
|
-
return { name: "Astro", file: "src/layouts/Layout.astro", note: "inside <body>", devCommand: "npm run dev" };
|
|
228
|
+
return { name: "Astro", file: "src/layouts/Layout.astro", fullPath: "src/layouts/Layout.astro", note: "inside <body>", devCommand: "npm run dev" };
|
|
204
229
|
}
|
|
205
230
|
if (import_fs.default.existsSync(import_path.default.join(cwd, "src", "layouts", "BaseLayout.astro"))) {
|
|
206
|
-
return { name: "Astro", file: "src/layouts/BaseLayout.astro", note: "inside <body>", devCommand: "npm run dev" };
|
|
231
|
+
return { name: "Astro", file: "src/layouts/BaseLayout.astro", fullPath: "src/layouts/BaseLayout.astro", note: "inside <body>", devCommand: "npm run dev" };
|
|
207
232
|
}
|
|
208
233
|
return { name: "Astro", file: "your main layout .astro file", note: "inside <body>", devCommand: "npm run dev" };
|
|
209
234
|
}
|
|
210
235
|
if (deps.next) {
|
|
211
236
|
if (import_fs.default.existsSync(import_path.default.join(cwd, "app", "layout.tsx"))) {
|
|
212
|
-
return { name: "Next.js (App Router)", file: "app/layout.tsx", note: "inside <body>, before {children}", devCommand: "npm run dev" };
|
|
237
|
+
return { name: "Next.js (App Router)", file: "app/layout.tsx", fullPath: "app/layout.tsx", note: "inside <body>, before {children}", devCommand: "npm run dev" };
|
|
213
238
|
}
|
|
214
239
|
if (import_fs.default.existsSync(import_path.default.join(cwd, "app", "layout.js"))) {
|
|
215
|
-
return { name: "Next.js (App Router)", file: "app/layout.js", note: "inside <body>, before {children}", devCommand: "npm run dev" };
|
|
240
|
+
return { name: "Next.js (App Router)", file: "app/layout.js", fullPath: "app/layout.js", note: "inside <body>, before {children}", devCommand: "npm run dev" };
|
|
216
241
|
}
|
|
217
242
|
if (import_fs.default.existsSync(import_path.default.join(cwd, "src", "app", "layout.tsx"))) {
|
|
218
|
-
return { name: "Next.js (App Router)", file: "src/app/layout.tsx", note: "inside <body>, before {children}", devCommand: "npm run dev" };
|
|
243
|
+
return { name: "Next.js (App Router)", file: "src/app/layout.tsx", fullPath: "src/app/layout.tsx", note: "inside <body>, before {children}", devCommand: "npm run dev" };
|
|
219
244
|
}
|
|
220
245
|
if (import_fs.default.existsSync(import_path.default.join(cwd, "pages", "_app.tsx"))) {
|
|
221
|
-
return { name: "Next.js (Pages Router)", file: "pages/_app.tsx", note: "after <Component {...pageProps} />", devCommand: "npm run dev" };
|
|
246
|
+
return { name: "Next.js (Pages Router)", file: "pages/_app.tsx", fullPath: "pages/_app.tsx", note: "after <Component {...pageProps} />", devCommand: "npm run dev" };
|
|
222
247
|
}
|
|
223
248
|
if (import_fs.default.existsSync(import_path.default.join(cwd, "pages", "_app.js"))) {
|
|
224
|
-
return { name: "Next.js (Pages Router)", file: "pages/_app.js", note: "after <Component {...pageProps} />", devCommand: "npm run dev" };
|
|
249
|
+
return { name: "Next.js (Pages Router)", file: "pages/_app.js", fullPath: "pages/_app.js", note: "after <Component {...pageProps} />", devCommand: "npm run dev" };
|
|
225
250
|
}
|
|
226
251
|
}
|
|
227
252
|
if (deps["@remix-run/react"]) {
|
|
228
253
|
if (import_fs.default.existsSync(import_path.default.join(cwd, "app", "root.tsx"))) {
|
|
229
|
-
return { name: "Remix", file: "app/root.tsx", note: "inside <body>", devCommand: "npm run dev" };
|
|
254
|
+
return { name: "Remix", file: "app/root.tsx", fullPath: "app/root.tsx", note: "inside <body>", devCommand: "npm run dev" };
|
|
230
255
|
}
|
|
231
256
|
}
|
|
232
257
|
if (deps.vite && (deps.react || deps["@vitejs/plugin-react"])) {
|
|
233
258
|
if (import_fs.default.existsSync(import_path.default.join(cwd, "src", "App.tsx"))) {
|
|
234
|
-
return { name: "Vite + React", file: "src/App.tsx", note: "at the end of your App component", devCommand: "npm run dev" };
|
|
259
|
+
return { name: "Vite + React", file: "src/App.tsx", fullPath: "src/App.tsx", note: "at the end of your App component", devCommand: "npm run dev" };
|
|
235
260
|
}
|
|
236
261
|
if (import_fs.default.existsSync(import_path.default.join(cwd, "src", "App.jsx"))) {
|
|
237
|
-
return { name: "Vite + React", file: "src/App.jsx", note: "at the end of your App component", devCommand: "npm run dev" };
|
|
262
|
+
return { name: "Vite + React", file: "src/App.jsx", fullPath: "src/App.jsx", note: "at the end of your App component", devCommand: "npm run dev" };
|
|
238
263
|
}
|
|
239
264
|
}
|
|
240
265
|
if (deps["react-scripts"]) {
|
|
241
266
|
if (import_fs.default.existsSync(import_path.default.join(cwd, "src", "App.tsx"))) {
|
|
242
|
-
return { name: "Create React App", file: "src/App.tsx", note: "at the end of your App component", devCommand: "npm start" };
|
|
267
|
+
return { name: "Create React App", file: "src/App.tsx", fullPath: "src/App.tsx", note: "at the end of your App component", devCommand: "npm start" };
|
|
243
268
|
}
|
|
244
269
|
if (import_fs.default.existsSync(import_path.default.join(cwd, "src", "App.js"))) {
|
|
245
|
-
return { name: "Create React App", file: "src/App.js", note: "at the end of your App component", devCommand: "npm start" };
|
|
270
|
+
return { name: "Create React App", file: "src/App.js", fullPath: "src/App.js", note: "at the end of your App component", devCommand: "npm start" };
|
|
246
271
|
}
|
|
247
272
|
}
|
|
248
273
|
if (deps.react) {
|
package/dist/cli.mjs
CHANGED
|
@@ -66,45 +66,70 @@ async function initProject() {
|
|
|
66
66
|
}, 5 * 60 * 1e3);
|
|
67
67
|
});
|
|
68
68
|
const framework = detectFramework();
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
console.log("\u2705 Authenticated!\n");
|
|
77
|
-
console.log("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n");
|
|
69
|
+
const cwd = process.cwd();
|
|
70
|
+
const fullPath = framework.fullPath ? path.join(cwd, framework.fullPath) : null;
|
|
71
|
+
const targetFile = fullPath || framework.file;
|
|
72
|
+
const isAstro = framework.name === "Astro";
|
|
73
|
+
const importLine = 'import { FeedbackWidget } from "@stephenov/feedbackwidget";';
|
|
74
|
+
const componentSnippet = isAstro ? `<FeedbackWidget client:load apiKey="${apiKey}" />` : `<FeedbackWidget apiKey="${apiKey}" />`;
|
|
75
|
+
console.log("\n\u2705 Authenticated!\n");
|
|
78
76
|
if (framework.name) {
|
|
79
|
-
console.log(`
|
|
77
|
+
console.log(`Detected: ${framework.name}
|
|
80
78
|
`);
|
|
81
79
|
}
|
|
82
|
-
console.log("
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
console.log(" ---\n");
|
|
87
|
-
} else {
|
|
88
|
-
console.log(' import { FeedbackWidget } from "@stephenov/feedbackwidget"\n');
|
|
89
|
-
}
|
|
90
|
-
console.log(" Step 2: Add the component " + (framework.note || "inside <body>") + "\n");
|
|
91
|
-
if (framework.name === "Astro") {
|
|
92
|
-
console.log(` <FeedbackWidget client:load apiKey="${apiKey}" />
|
|
80
|
+
console.log("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n");
|
|
81
|
+
console.log("STEP 1: Add the import\n");
|
|
82
|
+
console.log("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n");
|
|
83
|
+
console.log(`Open: ${targetFile}
|
|
93
84
|
`);
|
|
85
|
+
if (isAstro) {
|
|
86
|
+
console.log("Add this inside the --- frontmatter block:\n");
|
|
94
87
|
} else {
|
|
95
|
-
console.log(
|
|
96
|
-
`);
|
|
88
|
+
console.log("Add this with your other imports:\n");
|
|
97
89
|
}
|
|
98
|
-
console.log(
|
|
99
|
-
console.log(` ${framework.devCommand || "npm run dev"}
|
|
90
|
+
console.log(` ${importLine}
|
|
100
91
|
`);
|
|
101
|
-
|
|
92
|
+
await waitForEnter("Press ENTER when you've added the import...");
|
|
93
|
+
console.log("\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n");
|
|
94
|
+
console.log("STEP 2: Add the component\n");
|
|
102
95
|
console.log("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n");
|
|
103
|
-
console.log(
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
96
|
+
console.log(`In the same file, add this ${framework.note || "inside <body>"}:
|
|
97
|
+
`);
|
|
98
|
+
console.log(` ${componentSnippet}
|
|
99
|
+
`);
|
|
100
|
+
try {
|
|
101
|
+
await copyToClipboard(componentSnippet);
|
|
102
|
+
console.log(" \u{1F4CB} Copied to clipboard!\n");
|
|
103
|
+
} catch {
|
|
104
|
+
}
|
|
105
|
+
await waitForEnter("Press ENTER when you've added the component...");
|
|
106
|
+
let verified = false;
|
|
107
|
+
if (fullPath && fs.existsSync(fullPath)) {
|
|
108
|
+
const content = fs.readFileSync(fullPath, "utf-8");
|
|
109
|
+
if (content.includes("FeedbackWidget")) {
|
|
110
|
+
verified = true;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (verified) {
|
|
114
|
+
console.log("\n\u2705 Found FeedbackWidget in your file!\n");
|
|
107
115
|
}
|
|
116
|
+
console.log("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n");
|
|
117
|
+
console.log("\u{1F389} SETUP COMPLETE!\n");
|
|
118
|
+
console.log("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n");
|
|
119
|
+
console.log(`Run: ${framework.devCommand || "npm run dev"}
|
|
120
|
+
`);
|
|
121
|
+
console.log("Refresh your browser - the widget will appear in the bottom-right.\n");
|
|
122
|
+
console.log("View feedback at: https://feedbackwidget-api.vercel.app/dashboard\n");
|
|
123
|
+
}
|
|
124
|
+
function waitForEnter(prompt) {
|
|
125
|
+
return new Promise((resolve) => {
|
|
126
|
+
process.stdout.write(prompt);
|
|
127
|
+
process.stdin.setRawMode?.(false);
|
|
128
|
+
process.stdin.resume();
|
|
129
|
+
process.stdin.once("data", () => {
|
|
130
|
+
resolve();
|
|
131
|
+
});
|
|
132
|
+
});
|
|
108
133
|
}
|
|
109
134
|
async function whoami() {
|
|
110
135
|
console.log("\nRun 'npx feedbackwidget init' to get your API key.\n");
|
|
@@ -177,49 +202,49 @@ function detectFramework() {
|
|
|
177
202
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
178
203
|
if (deps.astro) {
|
|
179
204
|
if (fs.existsSync(path.join(cwd, "src", "layouts", "Layout.astro"))) {
|
|
180
|
-
return { name: "Astro", file: "src/layouts/Layout.astro", note: "inside <body>", devCommand: "npm run dev" };
|
|
205
|
+
return { name: "Astro", file: "src/layouts/Layout.astro", fullPath: "src/layouts/Layout.astro", note: "inside <body>", devCommand: "npm run dev" };
|
|
181
206
|
}
|
|
182
207
|
if (fs.existsSync(path.join(cwd, "src", "layouts", "BaseLayout.astro"))) {
|
|
183
|
-
return { name: "Astro", file: "src/layouts/BaseLayout.astro", note: "inside <body>", devCommand: "npm run dev" };
|
|
208
|
+
return { name: "Astro", file: "src/layouts/BaseLayout.astro", fullPath: "src/layouts/BaseLayout.astro", note: "inside <body>", devCommand: "npm run dev" };
|
|
184
209
|
}
|
|
185
210
|
return { name: "Astro", file: "your main layout .astro file", note: "inside <body>", devCommand: "npm run dev" };
|
|
186
211
|
}
|
|
187
212
|
if (deps.next) {
|
|
188
213
|
if (fs.existsSync(path.join(cwd, "app", "layout.tsx"))) {
|
|
189
|
-
return { name: "Next.js (App Router)", file: "app/layout.tsx", note: "inside <body>, before {children}", devCommand: "npm run dev" };
|
|
214
|
+
return { name: "Next.js (App Router)", file: "app/layout.tsx", fullPath: "app/layout.tsx", note: "inside <body>, before {children}", devCommand: "npm run dev" };
|
|
190
215
|
}
|
|
191
216
|
if (fs.existsSync(path.join(cwd, "app", "layout.js"))) {
|
|
192
|
-
return { name: "Next.js (App Router)", file: "app/layout.js", note: "inside <body>, before {children}", devCommand: "npm run dev" };
|
|
217
|
+
return { name: "Next.js (App Router)", file: "app/layout.js", fullPath: "app/layout.js", note: "inside <body>, before {children}", devCommand: "npm run dev" };
|
|
193
218
|
}
|
|
194
219
|
if (fs.existsSync(path.join(cwd, "src", "app", "layout.tsx"))) {
|
|
195
|
-
return { name: "Next.js (App Router)", file: "src/app/layout.tsx", note: "inside <body>, before {children}", devCommand: "npm run dev" };
|
|
220
|
+
return { name: "Next.js (App Router)", file: "src/app/layout.tsx", fullPath: "src/app/layout.tsx", note: "inside <body>, before {children}", devCommand: "npm run dev" };
|
|
196
221
|
}
|
|
197
222
|
if (fs.existsSync(path.join(cwd, "pages", "_app.tsx"))) {
|
|
198
|
-
return { name: "Next.js (Pages Router)", file: "pages/_app.tsx", note: "after <Component {...pageProps} />", devCommand: "npm run dev" };
|
|
223
|
+
return { name: "Next.js (Pages Router)", file: "pages/_app.tsx", fullPath: "pages/_app.tsx", note: "after <Component {...pageProps} />", devCommand: "npm run dev" };
|
|
199
224
|
}
|
|
200
225
|
if (fs.existsSync(path.join(cwd, "pages", "_app.js"))) {
|
|
201
|
-
return { name: "Next.js (Pages Router)", file: "pages/_app.js", note: "after <Component {...pageProps} />", devCommand: "npm run dev" };
|
|
226
|
+
return { name: "Next.js (Pages Router)", file: "pages/_app.js", fullPath: "pages/_app.js", note: "after <Component {...pageProps} />", devCommand: "npm run dev" };
|
|
202
227
|
}
|
|
203
228
|
}
|
|
204
229
|
if (deps["@remix-run/react"]) {
|
|
205
230
|
if (fs.existsSync(path.join(cwd, "app", "root.tsx"))) {
|
|
206
|
-
return { name: "Remix", file: "app/root.tsx", note: "inside <body>", devCommand: "npm run dev" };
|
|
231
|
+
return { name: "Remix", file: "app/root.tsx", fullPath: "app/root.tsx", note: "inside <body>", devCommand: "npm run dev" };
|
|
207
232
|
}
|
|
208
233
|
}
|
|
209
234
|
if (deps.vite && (deps.react || deps["@vitejs/plugin-react"])) {
|
|
210
235
|
if (fs.existsSync(path.join(cwd, "src", "App.tsx"))) {
|
|
211
|
-
return { name: "Vite + React", file: "src/App.tsx", note: "at the end of your App component", devCommand: "npm run dev" };
|
|
236
|
+
return { name: "Vite + React", file: "src/App.tsx", fullPath: "src/App.tsx", note: "at the end of your App component", devCommand: "npm run dev" };
|
|
212
237
|
}
|
|
213
238
|
if (fs.existsSync(path.join(cwd, "src", "App.jsx"))) {
|
|
214
|
-
return { name: "Vite + React", file: "src/App.jsx", note: "at the end of your App component", devCommand: "npm run dev" };
|
|
239
|
+
return { name: "Vite + React", file: "src/App.jsx", fullPath: "src/App.jsx", note: "at the end of your App component", devCommand: "npm run dev" };
|
|
215
240
|
}
|
|
216
241
|
}
|
|
217
242
|
if (deps["react-scripts"]) {
|
|
218
243
|
if (fs.existsSync(path.join(cwd, "src", "App.tsx"))) {
|
|
219
|
-
return { name: "Create React App", file: "src/App.tsx", note: "at the end of your App component", devCommand: "npm start" };
|
|
244
|
+
return { name: "Create React App", file: "src/App.tsx", fullPath: "src/App.tsx", note: "at the end of your App component", devCommand: "npm start" };
|
|
220
245
|
}
|
|
221
246
|
if (fs.existsSync(path.join(cwd, "src", "App.js"))) {
|
|
222
|
-
return { name: "Create React App", file: "src/App.js", note: "at the end of your App component", devCommand: "npm start" };
|
|
247
|
+
return { name: "Create React App", file: "src/App.js", fullPath: "src/App.js", note: "at the end of your App component", devCommand: "npm start" };
|
|
223
248
|
}
|
|
224
249
|
}
|
|
225
250
|
if (deps.react) {
|