@stephenov/feedbackwidget 0.2.2 → 0.3.1
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/auto.d.mts +5 -0
- package/dist/auto.d.ts +5 -0
- package/dist/auto.js +1529 -0
- package/dist/auto.mjs +46 -0
- package/dist/chunk-QQLLK6MC.mjs +1457 -0
- package/dist/cli.js +48 -55
- package/dist/cli.mjs +48 -55
- package/dist/index.mjs +21 -1459
- package/package.json +8 -3
package/dist/cli.js
CHANGED
|
@@ -27,7 +27,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
27
27
|
var import_http = __toESM(require("http"));
|
|
28
28
|
var import_open = __toESM(require("open"));
|
|
29
29
|
var import_crypto = require("crypto");
|
|
30
|
-
var import_child_process = require("child_process");
|
|
31
30
|
var import_fs = __toESM(require("fs"));
|
|
32
31
|
var import_path = __toESM(require("path"));
|
|
33
32
|
var API_BASE = "https://feedbackwidget-api.vercel.app";
|
|
@@ -95,25 +94,26 @@ async function initProject() {
|
|
|
95
94
|
reject(new Error("Authentication timed out"));
|
|
96
95
|
}, 5 * 60 * 1e3);
|
|
97
96
|
});
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
<FeedbackWidget apiKey="${apiKey}" />`;
|
|
102
|
-
try {
|
|
103
|
-
await copyToClipboard(snippet);
|
|
104
|
-
console.log("\u2705 Authenticated successfully!\n");
|
|
105
|
-
console.log(` API Key: ${apiKey.slice(0, 20)}...`);
|
|
106
|
-
console.log(" Saved to .feedbackwidgetrc\n");
|
|
107
|
-
console.log(" \u{1F4CB} Code snippet copied to clipboard! Just paste into your app.\n");
|
|
108
|
-
} catch {
|
|
109
|
-
console.log("\u2705 Authenticated successfully!\n");
|
|
110
|
-
console.log(` API Key: ${apiKey.slice(0, 20)}...`);
|
|
111
|
-
console.log(" Saved to .feedbackwidgetrc\n");
|
|
112
|
-
console.log(" Add to your app:\n");
|
|
113
|
-
console.log(' import { FeedbackWidget } from "@stephenov/feedbackwidget"');
|
|
114
|
-
console.log(` <FeedbackWidget apiKey="${apiKey}" />
|
|
97
|
+
const saved = saveApiKeyToEnv(apiKey);
|
|
98
|
+
console.log("\u2705 Authenticated successfully!\n");
|
|
99
|
+
console.log(` API Key: ${apiKey}
|
|
115
100
|
`);
|
|
101
|
+
if (saved) {
|
|
102
|
+
console.log(` \u2713 Saved to ${saved}
|
|
103
|
+
`);
|
|
104
|
+
console.log(" Add ONE line to your app's root layout:\n");
|
|
105
|
+
console.log(' import "@stephenov/feedbackwidget/auto"\n');
|
|
106
|
+
} else {
|
|
107
|
+
console.log(" Add to your .env.local (or .env):\n");
|
|
108
|
+
console.log(` NEXT_PUBLIC_FEEDBACKWIDGET_API_KEY=${apiKey}
|
|
109
|
+
`);
|
|
110
|
+
console.log(" Then add to your app's root layout:\n");
|
|
111
|
+
console.log(' import "@stephenov/feedbackwidget/auto"\n');
|
|
116
112
|
}
|
|
113
|
+
console.log(" Or use directly:\n");
|
|
114
|
+
console.log(' import { FeedbackWidget } from "@stephenov/feedbackwidget"');
|
|
115
|
+
console.log(` <FeedbackWidget apiKey="${apiKey}" />
|
|
116
|
+
`);
|
|
117
117
|
}
|
|
118
118
|
async function whoami() {
|
|
119
119
|
const apiKey = getStoredApiKey();
|
|
@@ -152,26 +152,45 @@ Usage:
|
|
|
152
152
|
`);
|
|
153
153
|
}
|
|
154
154
|
function getStoredApiKey() {
|
|
155
|
-
const
|
|
155
|
+
const envPath = import_path.default.join(process.cwd(), ".env.local");
|
|
156
156
|
try {
|
|
157
|
-
const content = import_fs.default.readFileSync(
|
|
158
|
-
const match = content.match(/
|
|
157
|
+
const content = import_fs.default.readFileSync(envPath, "utf-8");
|
|
158
|
+
const match = content.match(/NEXT_PUBLIC_FEEDBACKWIDGET_API_KEY=(.+)/);
|
|
159
159
|
return match ? match[1].trim() : null;
|
|
160
160
|
} catch {
|
|
161
161
|
return null;
|
|
162
162
|
}
|
|
163
163
|
}
|
|
164
|
-
function
|
|
165
|
-
const
|
|
166
|
-
|
|
164
|
+
function saveApiKeyToEnv(apiKey) {
|
|
165
|
+
const envVar = `NEXT_PUBLIC_FEEDBACKWIDGET_API_KEY=${apiKey}`;
|
|
166
|
+
const envFiles = [".env.local", ".env"];
|
|
167
|
+
for (const envFile of envFiles) {
|
|
168
|
+
const envPath = import_path.default.join(process.cwd(), envFile);
|
|
169
|
+
try {
|
|
170
|
+
const content = import_fs.default.readFileSync(envPath, "utf-8");
|
|
171
|
+
if (content.includes("NEXT_PUBLIC_FEEDBACKWIDGET_API_KEY=")) {
|
|
172
|
+
const updated = content.replace(
|
|
173
|
+
/NEXT_PUBLIC_FEEDBACKWIDGET_API_KEY=.*/,
|
|
174
|
+
envVar
|
|
175
|
+
);
|
|
176
|
+
import_fs.default.writeFileSync(envPath, updated);
|
|
177
|
+
} else {
|
|
178
|
+
import_fs.default.appendFileSync(envPath, `
|
|
179
|
+
${envVar}
|
|
167
180
|
`);
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
import_fs.default.appendFileSync(gitignorePath, "\n.feedbackwidgetrc\n");
|
|
181
|
+
}
|
|
182
|
+
return envFile;
|
|
183
|
+
} catch {
|
|
184
|
+
continue;
|
|
173
185
|
}
|
|
186
|
+
}
|
|
187
|
+
try {
|
|
188
|
+
const envPath = import_path.default.join(process.cwd(), ".env.local");
|
|
189
|
+
import_fs.default.writeFileSync(envPath, `${envVar}
|
|
190
|
+
`);
|
|
191
|
+
return ".env.local";
|
|
174
192
|
} catch {
|
|
193
|
+
return null;
|
|
175
194
|
}
|
|
176
195
|
}
|
|
177
196
|
function successPage() {
|
|
@@ -220,30 +239,4 @@ function errorPage(error) {
|
|
|
220
239
|
</body>
|
|
221
240
|
</html>`;
|
|
222
241
|
}
|
|
223
|
-
async function copyToClipboard(text) {
|
|
224
|
-
return new Promise((resolve, reject) => {
|
|
225
|
-
const platform = process.platform;
|
|
226
|
-
let cmd;
|
|
227
|
-
let args = [];
|
|
228
|
-
if (platform === "darwin") {
|
|
229
|
-
cmd = "pbcopy";
|
|
230
|
-
} else if (platform === "linux") {
|
|
231
|
-
cmd = "xclip";
|
|
232
|
-
args = ["-selection", "clipboard"];
|
|
233
|
-
} else if (platform === "win32") {
|
|
234
|
-
cmd = "clip";
|
|
235
|
-
} else {
|
|
236
|
-
reject(new Error("Unsupported platform"));
|
|
237
|
-
return;
|
|
238
|
-
}
|
|
239
|
-
const proc = (0, import_child_process.spawn)(cmd, args);
|
|
240
|
-
proc.stdin.write(text);
|
|
241
|
-
proc.stdin.end();
|
|
242
|
-
proc.on("close", (code) => {
|
|
243
|
-
if (code === 0) resolve();
|
|
244
|
-
else reject(new Error(`Clipboard failed with code ${code}`));
|
|
245
|
-
});
|
|
246
|
-
proc.on("error", reject);
|
|
247
|
-
});
|
|
248
|
-
}
|
|
249
242
|
main().catch(console.error);
|
package/dist/cli.mjs
CHANGED
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
import http from "http";
|
|
5
5
|
import open from "open";
|
|
6
6
|
import { randomBytes } from "crypto";
|
|
7
|
-
import { spawn } from "child_process";
|
|
8
7
|
import fs from "fs";
|
|
9
8
|
import path from "path";
|
|
10
9
|
var API_BASE = "https://feedbackwidget-api.vercel.app";
|
|
@@ -72,25 +71,26 @@ async function initProject() {
|
|
|
72
71
|
reject(new Error("Authentication timed out"));
|
|
73
72
|
}, 5 * 60 * 1e3);
|
|
74
73
|
});
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
<FeedbackWidget apiKey="${apiKey}" />`;
|
|
79
|
-
try {
|
|
80
|
-
await copyToClipboard(snippet);
|
|
81
|
-
console.log("\u2705 Authenticated successfully!\n");
|
|
82
|
-
console.log(` API Key: ${apiKey.slice(0, 20)}...`);
|
|
83
|
-
console.log(" Saved to .feedbackwidgetrc\n");
|
|
84
|
-
console.log(" \u{1F4CB} Code snippet copied to clipboard! Just paste into your app.\n");
|
|
85
|
-
} catch {
|
|
86
|
-
console.log("\u2705 Authenticated successfully!\n");
|
|
87
|
-
console.log(` API Key: ${apiKey.slice(0, 20)}...`);
|
|
88
|
-
console.log(" Saved to .feedbackwidgetrc\n");
|
|
89
|
-
console.log(" Add to your app:\n");
|
|
90
|
-
console.log(' import { FeedbackWidget } from "@stephenov/feedbackwidget"');
|
|
91
|
-
console.log(` <FeedbackWidget apiKey="${apiKey}" />
|
|
74
|
+
const saved = saveApiKeyToEnv(apiKey);
|
|
75
|
+
console.log("\u2705 Authenticated successfully!\n");
|
|
76
|
+
console.log(` API Key: ${apiKey}
|
|
92
77
|
`);
|
|
78
|
+
if (saved) {
|
|
79
|
+
console.log(` \u2713 Saved to ${saved}
|
|
80
|
+
`);
|
|
81
|
+
console.log(" Add ONE line to your app's root layout:\n");
|
|
82
|
+
console.log(' import "@stephenov/feedbackwidget/auto"\n');
|
|
83
|
+
} else {
|
|
84
|
+
console.log(" Add to your .env.local (or .env):\n");
|
|
85
|
+
console.log(` NEXT_PUBLIC_FEEDBACKWIDGET_API_KEY=${apiKey}
|
|
86
|
+
`);
|
|
87
|
+
console.log(" Then add to your app's root layout:\n");
|
|
88
|
+
console.log(' import "@stephenov/feedbackwidget/auto"\n');
|
|
93
89
|
}
|
|
90
|
+
console.log(" Or use directly:\n");
|
|
91
|
+
console.log(' import { FeedbackWidget } from "@stephenov/feedbackwidget"');
|
|
92
|
+
console.log(` <FeedbackWidget apiKey="${apiKey}" />
|
|
93
|
+
`);
|
|
94
94
|
}
|
|
95
95
|
async function whoami() {
|
|
96
96
|
const apiKey = getStoredApiKey();
|
|
@@ -129,26 +129,45 @@ Usage:
|
|
|
129
129
|
`);
|
|
130
130
|
}
|
|
131
131
|
function getStoredApiKey() {
|
|
132
|
-
const
|
|
132
|
+
const envPath = path.join(process.cwd(), ".env.local");
|
|
133
133
|
try {
|
|
134
|
-
const content = fs.readFileSync(
|
|
135
|
-
const match = content.match(/
|
|
134
|
+
const content = fs.readFileSync(envPath, "utf-8");
|
|
135
|
+
const match = content.match(/NEXT_PUBLIC_FEEDBACKWIDGET_API_KEY=(.+)/);
|
|
136
136
|
return match ? match[1].trim() : null;
|
|
137
137
|
} catch {
|
|
138
138
|
return null;
|
|
139
139
|
}
|
|
140
140
|
}
|
|
141
|
-
function
|
|
142
|
-
const
|
|
143
|
-
|
|
141
|
+
function saveApiKeyToEnv(apiKey) {
|
|
142
|
+
const envVar = `NEXT_PUBLIC_FEEDBACKWIDGET_API_KEY=${apiKey}`;
|
|
143
|
+
const envFiles = [".env.local", ".env"];
|
|
144
|
+
for (const envFile of envFiles) {
|
|
145
|
+
const envPath = path.join(process.cwd(), envFile);
|
|
146
|
+
try {
|
|
147
|
+
const content = fs.readFileSync(envPath, "utf-8");
|
|
148
|
+
if (content.includes("NEXT_PUBLIC_FEEDBACKWIDGET_API_KEY=")) {
|
|
149
|
+
const updated = content.replace(
|
|
150
|
+
/NEXT_PUBLIC_FEEDBACKWIDGET_API_KEY=.*/,
|
|
151
|
+
envVar
|
|
152
|
+
);
|
|
153
|
+
fs.writeFileSync(envPath, updated);
|
|
154
|
+
} else {
|
|
155
|
+
fs.appendFileSync(envPath, `
|
|
156
|
+
${envVar}
|
|
144
157
|
`);
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
fs.appendFileSync(gitignorePath, "\n.feedbackwidgetrc\n");
|
|
158
|
+
}
|
|
159
|
+
return envFile;
|
|
160
|
+
} catch {
|
|
161
|
+
continue;
|
|
150
162
|
}
|
|
163
|
+
}
|
|
164
|
+
try {
|
|
165
|
+
const envPath = path.join(process.cwd(), ".env.local");
|
|
166
|
+
fs.writeFileSync(envPath, `${envVar}
|
|
167
|
+
`);
|
|
168
|
+
return ".env.local";
|
|
151
169
|
} catch {
|
|
170
|
+
return null;
|
|
152
171
|
}
|
|
153
172
|
}
|
|
154
173
|
function successPage() {
|
|
@@ -197,30 +216,4 @@ function errorPage(error) {
|
|
|
197
216
|
</body>
|
|
198
217
|
</html>`;
|
|
199
218
|
}
|
|
200
|
-
async function copyToClipboard(text) {
|
|
201
|
-
return new Promise((resolve, reject) => {
|
|
202
|
-
const platform = process.platform;
|
|
203
|
-
let cmd;
|
|
204
|
-
let args = [];
|
|
205
|
-
if (platform === "darwin") {
|
|
206
|
-
cmd = "pbcopy";
|
|
207
|
-
} else if (platform === "linux") {
|
|
208
|
-
cmd = "xclip";
|
|
209
|
-
args = ["-selection", "clipboard"];
|
|
210
|
-
} else if (platform === "win32") {
|
|
211
|
-
cmd = "clip";
|
|
212
|
-
} else {
|
|
213
|
-
reject(new Error("Unsupported platform"));
|
|
214
|
-
return;
|
|
215
|
-
}
|
|
216
|
-
const proc = spawn(cmd, args);
|
|
217
|
-
proc.stdin.write(text);
|
|
218
|
-
proc.stdin.end();
|
|
219
|
-
proc.on("close", (code) => {
|
|
220
|
-
if (code === 0) resolve();
|
|
221
|
-
else reject(new Error(`Clipboard failed with code ${code}`));
|
|
222
|
-
});
|
|
223
|
-
proc.on("error", reject);
|
|
224
|
-
});
|
|
225
|
-
}
|
|
226
219
|
main().catch(console.error);
|