snapfail 0.0.17 → 0.0.19
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 +65 -3
- package/package.json +1 -1
- package/src/index.ts +2 -2
package/dist/index.js
CHANGED
|
@@ -164,6 +164,14 @@ async function fetchIncident(config, id) {
|
|
|
164
164
|
});
|
|
165
165
|
return data;
|
|
166
166
|
}
|
|
167
|
+
async function deleteGroup(config, id) {
|
|
168
|
+
const url = `${config.endpoint}/api/incidents/${id}`;
|
|
169
|
+
const data = await apiFetch(url, {
|
|
170
|
+
method: "DELETE",
|
|
171
|
+
headers: { "X-Project-Key": config.projectKey }
|
|
172
|
+
});
|
|
173
|
+
return data !== null;
|
|
174
|
+
}
|
|
167
175
|
async function fetchSample(config, groupId, sampleIndex) {
|
|
168
176
|
const url = `${config.endpoint}/api/incidents/${groupId}/samples/${sampleIndex}`;
|
|
169
177
|
const data = await apiFetch(url, {
|
|
@@ -237,6 +245,13 @@ function formatIncidentDetail(group, sample) {
|
|
|
237
245
|
for (const f of sample.stackFrames.slice(0, 6)) {
|
|
238
246
|
const fn = f.fn ? `${cyan(f.fn)} ` : "";
|
|
239
247
|
lines.push(` ${fn}${dim(f.file + ":" + f.line)}`);
|
|
248
|
+
if (f.codeSnippet) {
|
|
249
|
+
for (const snippetLine of f.codeSnippet.split(`
|
|
250
|
+
`)) {
|
|
251
|
+
const isError = snippetLine.startsWith("\u25BA");
|
|
252
|
+
lines.push(isError ? ` ${bold(snippetLine)}` : ` ${dim(snippetLine)}`);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
240
255
|
}
|
|
241
256
|
}
|
|
242
257
|
if (sample.consoleEntries.length > 0) {
|
|
@@ -287,6 +302,20 @@ async function runIncidents(opts) {
|
|
|
287
302
|
// src/commands/incident.ts
|
|
288
303
|
async function runIncident(opts) {
|
|
289
304
|
const config = loadConfig();
|
|
305
|
+
if (opts.delete) {
|
|
306
|
+
const ok = await deleteGroup(config, opts.id);
|
|
307
|
+
if (!ok) {
|
|
308
|
+
console.error(`Incident group ${opts.id} not found.`);
|
|
309
|
+
process.exit(1);
|
|
310
|
+
}
|
|
311
|
+
if (opts.json) {
|
|
312
|
+
process.stdout.write(JSON.stringify({ ok: true, deleted: opts.id }) + `
|
|
313
|
+
`);
|
|
314
|
+
} else {
|
|
315
|
+
console.log(`Deleted incident group ${opts.id} and all related data.`);
|
|
316
|
+
}
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
290
319
|
if (opts.sample != null) {
|
|
291
320
|
const s = await fetchSample(config, opts.id, opts.sample);
|
|
292
321
|
if (!s) {
|
|
@@ -2056,6 +2085,34 @@ function injectAstroAdapter(configPath) {
|
|
|
2056
2085
|
}
|
|
2057
2086
|
writeFileSync3(configPath, src, "utf-8");
|
|
2058
2087
|
}
|
|
2088
|
+
function injectNextConfig(cwd) {
|
|
2089
|
+
const candidates = ["next.config.ts", "next.config.mjs", "next.config.js"];
|
|
2090
|
+
const cfgFile = candidates.find((n2) => existsSync3(resolve2(cwd, n2)));
|
|
2091
|
+
if (!cfgFile)
|
|
2092
|
+
return;
|
|
2093
|
+
const cfgPath = resolve2(cwd, cfgFile);
|
|
2094
|
+
let src = readFileSync3(cfgPath, "utf-8");
|
|
2095
|
+
if (src.includes("withSnapfail"))
|
|
2096
|
+
return;
|
|
2097
|
+
const isEsm = cfgFile.endsWith(".mjs") || cfgFile.endsWith(".ts");
|
|
2098
|
+
const projectKeyExpr = isEsm ? `import.meta.env?.NEXT_PUBLIC_SNAPFAIL_PROJECT_KEY ?? process.env.NEXT_PUBLIC_SNAPFAIL_PROJECT_KEY ?? ""` : `process.env.NEXT_PUBLIC_SNAPFAIL_PROJECT_KEY ?? ""`;
|
|
2099
|
+
if (isEsm) {
|
|
2100
|
+
src = `import { withSnapfail } from "@snapfail/next";
|
|
2101
|
+
` + src;
|
|
2102
|
+
src = src.replace(/export\s+default\s+(\w+);/, `export default withSnapfail(${projectKeyExpr})($1);`);
|
|
2103
|
+
if (!src.includes("withSnapfail(")) {
|
|
2104
|
+
src = src.replace(/export\s+default\s+(\{)/, `export default withSnapfail(${projectKeyExpr})($1`);
|
|
2105
|
+
}
|
|
2106
|
+
} else {
|
|
2107
|
+
src = `const { withSnapfail } = require("@snapfail/next");
|
|
2108
|
+
` + src;
|
|
2109
|
+
src = src.replace(/module\.exports\s*=\s*(\w+);/, `module.exports = withSnapfail(${projectKeyExpr})($1);`);
|
|
2110
|
+
if (!src.includes("withSnapfail(")) {
|
|
2111
|
+
src = src.replace(/module\.exports\s*=\s*(\{)/, `module.exports = withSnapfail(${projectKeyExpr})($1`);
|
|
2112
|
+
}
|
|
2113
|
+
}
|
|
2114
|
+
writeFileSync3(cfgPath, src, "utf-8");
|
|
2115
|
+
}
|
|
2059
2116
|
function injectNextProvider(cwd) {
|
|
2060
2117
|
const providerSrc = `"use client";
|
|
2061
2118
|
import { useEffect } from "react";
|
|
@@ -2065,7 +2122,9 @@ export function SnapfailProvider() {
|
|
|
2065
2122
|
useEffect(() => {
|
|
2066
2123
|
initSnapfail({
|
|
2067
2124
|
projectKey: process.env.NEXT_PUBLIC_SNAPFAIL_PROJECT_KEY ?? "",
|
|
2125
|
+
endpoint: process.env.NEXT_PUBLIC_SNAPFAIL_ENDPOINT ?? "https://app.snapfail.com",
|
|
2068
2126
|
environment: process.env.NODE_ENV === "production" ? "prod" : "dev",
|
|
2127
|
+
buildId: process.env.NEXT_PUBLIC_SNAPFAIL_BUILD_ID,
|
|
2069
2128
|
});
|
|
2070
2129
|
}, []);
|
|
2071
2130
|
return null;
|
|
@@ -2210,6 +2269,8 @@ async function runInit(cwd = process.cwd()) {
|
|
|
2210
2269
|
} catch {
|
|
2211
2270
|
spinner2.stop("Skipping install (not yet on npm).");
|
|
2212
2271
|
}
|
|
2272
|
+
injectNextConfig(cwd);
|
|
2273
|
+
log.success("Injected withSnapfail into next.config");
|
|
2213
2274
|
injectNextProvider(cwd);
|
|
2214
2275
|
log.success("Created snapfail-provider.tsx");
|
|
2215
2276
|
log.warn("Add <SnapfailProvider /> to your root layout.");
|
|
@@ -2242,7 +2303,8 @@ async function fetchDiagnosis(config, id, force) {
|
|
|
2242
2303
|
try {
|
|
2243
2304
|
res = await fetch(url.toString(), {
|
|
2244
2305
|
method: "POST",
|
|
2245
|
-
headers: { "X-Project-Key": config.projectKey }
|
|
2306
|
+
headers: { "X-Project-Key": config.projectKey, "Content-Type": "application/json" },
|
|
2307
|
+
body: "{}"
|
|
2246
2308
|
});
|
|
2247
2309
|
} catch (err) {
|
|
2248
2310
|
throw new Error(`Network error: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -2318,7 +2380,7 @@ function parseArgs(argv) {
|
|
|
2318
2380
|
}
|
|
2319
2381
|
return { command, args, flags };
|
|
2320
2382
|
}
|
|
2321
|
-
var VERSION = "0.0.
|
|
2383
|
+
var VERSION = "0.0.18";
|
|
2322
2384
|
async function main() {
|
|
2323
2385
|
const { command, args, flags } = parseArgs(process.argv);
|
|
2324
2386
|
const json = flags["json"] === true;
|
|
@@ -2348,7 +2410,7 @@ async function main() {
|
|
|
2348
2410
|
}
|
|
2349
2411
|
const sampleFlag = flags["sample"];
|
|
2350
2412
|
const sample = typeof sampleFlag === "string" ? parseInt(sampleFlag) : undefined;
|
|
2351
|
-
await runIncident({ id, sample, json });
|
|
2413
|
+
await runIncident({ id, sample, json, delete: flags["delete"] === true });
|
|
2352
2414
|
return;
|
|
2353
2415
|
}
|
|
2354
2416
|
if (command === "explain") {
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -30,7 +30,7 @@ function parseArgs(argv: string[]): {
|
|
|
30
30
|
return { command, args, flags };
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
const VERSION = "0.0.
|
|
33
|
+
const VERSION = "0.0.18";
|
|
34
34
|
|
|
35
35
|
async function main(): Promise<void> {
|
|
36
36
|
const { command, args, flags } = parseArgs(process.argv);
|
|
@@ -66,7 +66,7 @@ async function main(): Promise<void> {
|
|
|
66
66
|
const sampleFlag = flags["sample"];
|
|
67
67
|
const sample =
|
|
68
68
|
typeof sampleFlag === "string" ? parseInt(sampleFlag) : undefined;
|
|
69
|
-
await runIncident({ id, sample, json });
|
|
69
|
+
await runIncident({ id, sample, json, delete: flags["delete"] === true });
|
|
70
70
|
return;
|
|
71
71
|
}
|
|
72
72
|
|