@spotlightjs/sidecar
Advanced tools
Comparing version 1.11.1 to 1.11.2
@@ -30,6 +30,7 @@ import { type SidecarLogger } from './logger.js'; | ||
incomingPayload?: IncomingPayloadCallback; | ||
isStandalone?: boolean; | ||
}; | ||
export declare function setupSidecar({ port, logger: customLogger, basePath, filesToServe, debug, incomingPayload, }?: SideCarOptions): void; | ||
export declare function setupSidecar({ port, logger: customLogger, basePath, filesToServe, debug, incomingPayload, isStandalone, }?: SideCarOptions): void; | ||
export declare function clearBuffer(): void; | ||
export declare const shutdown: () => void; | ||
export {}; |
230
dist/main.js
var z = Object.defineProperty; | ||
var V = (e, t, n) => t in e ? z(e, t, { enumerable: !0, configurable: !0, writable: !0, value: n }) : e[t] = n; | ||
var p = (e, t, n) => V(e, typeof t != "symbol" ? t + "" : t, n); | ||
import { startSpan as _, getTraceData as J, captureException as W } from "@sentry/node"; | ||
import X from "launch-editor"; | ||
import { readFileSync as v, createWriteStream as K } from "node:fs"; | ||
import { createServer as Y, get as Q } from "node:http"; | ||
import * as $ from "node:path"; | ||
import { join as P, resolve as Z, extname as q } from "node:path"; | ||
import { createGunzip as ee, createInflate as te } from "node:zlib"; | ||
import { CONTEXT_LINES_ENDPOINT as ne, DEFAULT_PORT as oe, SERVER_IDENTIFIER as ie } from "./constants.js"; | ||
import * as re from "node:os"; | ||
import { addEventProcessor as W, startSpan as _, getTraceData as J, captureException as X } from "@sentry/node"; | ||
import K from "launch-editor"; | ||
import { readFileSync as R, createWriteStream as Y } from "node:fs"; | ||
import { get as Q, createServer as Z } from "node:http"; | ||
import * as v from "node:path"; | ||
import { join as O, resolve as q, extname as ee } from "node:path"; | ||
import { createGunzip as te, createInflate as ne } from "node:zlib"; | ||
import { DEFAULT_PORT as oe, CONTEXT_LINES_ENDPOINT as ie, SERVER_IDENTIFIER as re } from "./constants.js"; | ||
import * as se from "node:os"; | ||
import * as I from "source-map"; | ||
async function se(e) { | ||
async function ae(e) { | ||
try { | ||
@@ -21,3 +21,3 @@ return (await fetch(e)).text(); | ||
} | ||
function ae(e) { | ||
function ce(e) { | ||
try { | ||
@@ -29,3 +29,3 @@ return JSON.parse(e); | ||
} | ||
async function ce(e, t) { | ||
async function le(e, t) { | ||
const n = await new I.SourceMapConsumer(e), o = n.originalPositionFor({ | ||
@@ -39,5 +39,5 @@ line: t.lineno, | ||
const i = new URL(t.filename).pathname.slice(1); | ||
t.filename = $.resolve($.join($.dirname(i), o.source)); | ||
const r = n.sourceContentFor(o.source), s = (r == null ? void 0 : r.split(re.EOL)) ?? []; | ||
N(s, t); | ||
t.filename = v.resolve(v.join(v.dirname(i), o.source)); | ||
const r = n.sourceContentFor(o.source), a = (r == null ? void 0 : r.split(se.EOL)) ?? []; | ||
N(a, t); | ||
} | ||
@@ -48,5 +48,5 @@ return o; | ||
const o = e.length, i = Math.max(Math.min(o - 1, t.lineno - 1), 0); | ||
t.pre_context = e.slice(Math.max(0, i - n), i).map((r) => R(r, 0)), t.context_line = R(e[Math.min(o - 1, i)], t.colno || 0), t.post_context = e.slice(Math.min(i + 1, o), i + 1 + n).map((r) => R(r, 0)); | ||
t.pre_context = e.slice(Math.max(0, i - n), i).map((r) => $(r, 0)), t.context_line = $(e[Math.min(o - 1, i)], t.colno || 0), t.post_context = e.slice(Math.min(i + 1, o), i + 1 + n).map((r) => $(r, 0)); | ||
} | ||
function R(e, t) { | ||
function $(e, t) { | ||
let n = e; | ||
@@ -62,6 +62,6 @@ const o = n.length; | ||
} | ||
function le(e) { | ||
function de(e) { | ||
return !!e.filename && !!e.lineno && !!e.colno; | ||
} | ||
function de(e, t) { | ||
function ue(e, t) { | ||
if (e.method !== "PUT") { | ||
@@ -75,3 +75,3 @@ t.writeHead(405), t.end(); | ||
}), e.on("end", async () => { | ||
const o = ae(n); | ||
const o = ce(n); | ||
if (!o) { | ||
@@ -82,22 +82,22 @@ t.writeHead(500), t.end(); | ||
for (const r of o.frames ?? []) { | ||
if (!le(r) || // let's ignore dependencies for now with this naive check | ||
if (!de(r) || // let's ignore dependencies for now with this naive check | ||
r.filename.includes("/node_modules/")) | ||
continue; | ||
const { filename: s } = r; | ||
if (s.includes("://")) { | ||
const a = await se(r.filename); | ||
if (!a) | ||
const { filename: a } = r; | ||
if (a.includes("://")) { | ||
const s = await ae(r.filename); | ||
if (!s) | ||
continue; | ||
const h = a.match(/\/\/# sourceMappingURL=data:application\/json;base64,(.*)/); | ||
if (h && h[1]) { | ||
const c = h[1], l = Buffer.from(c, "base64").toString("utf-8"); | ||
await ce(l, r); | ||
const u = s.match(/\/\/# sourceMappingURL=data:application\/json;base64,(.*)/); | ||
if (u && u[1]) { | ||
const c = u[1], l = Buffer.from(c, "base64").toString("utf-8"); | ||
await le(l, r); | ||
} | ||
} else if (!s.includes(":")) | ||
} else if (!a.includes(":")) | ||
try { | ||
const a = v(s, { encoding: "utf-8" }).split(/\r?\n/); | ||
N(a, r); | ||
} catch (a) { | ||
if (a.code !== "ENOENT") | ||
throw a; | ||
const s = R(a, { encoding: "utf-8" }).split(/\r?\n/); | ||
N(s, r); | ||
} catch (s) { | ||
if (s.code !== "ENOENT") | ||
throw s; | ||
} | ||
@@ -116,9 +116,9 @@ } | ||
let S, A = !1; | ||
function ue(e) { | ||
function he(e) { | ||
S = e; | ||
} | ||
function he(e) { | ||
function fe(e) { | ||
A = e; | ||
} | ||
const u = { | ||
const h = { | ||
info: (e) => (S || y).info(e), | ||
@@ -129,3 +129,3 @@ warn: (e) => (S || y).warn(e), | ||
}; | ||
class fe { | ||
class pe { | ||
constructor(t = 100) { | ||
@@ -149,3 +149,3 @@ p(this, "size"); | ||
subscribe(t) { | ||
const n = pe(); | ||
const n = me(); | ||
return this.readers.set(n, t), setTimeout(() => this.stream(n)), n; | ||
@@ -168,3 +168,3 @@ } | ||
} | ||
function pe() { | ||
function me() { | ||
let e = (/* @__PURE__ */ new Date()).getTime(); | ||
@@ -182,3 +182,3 @@ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(t) { | ||
}, D = { | ||
"X-Powered-by": ie | ||
"X-Powered-by": re | ||
}, x = (e) => C( | ||
@@ -190,4 +190,4 @@ (t, n, o, i) => { | ||
}; | ||
for (const [s, a] of Object.entries(r)) | ||
n.setHeader(s, a); | ||
for (const [a, s] of Object.entries(r)) | ||
n.setHeader(a, s); | ||
if (t.method === "OPTIONS") { | ||
@@ -202,3 +202,3 @@ n.writeHead(204, { | ||
{ name: "enableCORS", op: "sidecar.http.middleware.cors" } | ||
), me = (e, t) => function(o, i, r, s) { | ||
), ge = (e, t) => function(o, i, r, a) { | ||
if (o.method === "GET" && o.headers.accept && o.headers.accept === "text/event-stream" && r === "/stream") { | ||
@@ -211,3 +211,3 @@ i.writeHead(200, { | ||
`); | ||
const a = (s == null ? void 0 : s.get("base64")) != null, h = a ? ";base64" : "", c = a ? (d) => i.write(`data:${d.toString("base64")} | ||
const s = (a == null ? void 0 : a.get("base64")) != null, u = s ? ";base64" : "", c = s ? (d) => i.write(`data:${d.toString("base64")} | ||
`) : (d) => { | ||
@@ -219,3 +219,3 @@ for (const f of d.toString("utf-8").split(` | ||
}, l = e.subscribe(([d, f]) => { | ||
u.debug("🕊️ sending to Spotlight"), i.write(`event:${d}${h} | ||
h.debug("🕊️ sending to Spotlight"), i.write(`event:${d}${u} | ||
`), c(f), i.write(` | ||
@@ -228,18 +228,18 @@ `); | ||
} else if (o.method === "POST") { | ||
u.debug("📩 Received event"); | ||
let a = o; | ||
const h = o.headers["content-encoding"]; | ||
h === "gzip" ? a = o.pipe(ee()) : h === "deflate" && (a = o.pipe(te())); | ||
h.debug("📩 Received event"); | ||
let s = o; | ||
const u = o.headers["content-encoding"]; | ||
u === "gzip" ? s = o.pipe(te()) : u === "deflate" && (s = o.pipe(ne())); | ||
const c = []; | ||
a.on("readable", () => { | ||
s.on("readable", () => { | ||
let l; | ||
for (; (l = a.read()) !== null; ) | ||
for (; (l = s.read()) !== null; ) | ||
c.push(l); | ||
}), a.on("end", () => { | ||
}), s.on("end", () => { | ||
var f, g; | ||
const l = Buffer.concat(c); | ||
let d = (f = o.headers["content-type"]) == null ? void 0 : f.split(";")[0].toLocaleLowerCase(); | ||
if ((g = s == null ? void 0 : s.get("sentry_client")) != null && g.startsWith("sentry.javascript.browser") && o.headers.origin && (d = "application/x-sentry-envelope"), d ? e.put([d, l]) : u.warn("No content type, skipping payload..."), process.env.SPOTLIGHT_CAPTURE || t) { | ||
if ((g = a == null ? void 0 : a.get("sentry_client")) != null && g.startsWith("sentry.javascript.browser") && o.headers.origin && (d = "application/x-sentry-envelope"), d ? e.put([d, l]) : h.warn("No content type, skipping payload..."), process.env.SPOTLIGHT_CAPTURE || t) { | ||
const T = (/* @__PURE__ */ new Date()).getTime(), w = `${(d == null ? void 0 : d.replace(/[^a-z0-9]/gi, "_")) || "no_content_type"}-${T}.txt`; | ||
t ? t(l.toString("binary")) : (K(w).write(l), u.info(`🗃️ Saved data to ${w}`)); | ||
t ? t(l.toString("binary")) : (Y(w).write(l), h.info(`🗃️ Saved data to ${w}`)); | ||
} | ||
@@ -255,21 +255,21 @@ i.writeHead(200, { | ||
} | ||
}, ge = (e) => function(n, o, i) { | ||
}, we = (e) => function(n, o, i) { | ||
let r = `${i || n.url}`; | ||
r === "/" && (r = "/src/index.html"), r = r.slice(1); | ||
const s = q(r); | ||
let a = "text/html"; | ||
switch (s) { | ||
const a = ee(r); | ||
let s = "text/html"; | ||
switch (a) { | ||
case ".js": | ||
a = "text/javascript"; | ||
s = "text/javascript"; | ||
break; | ||
case ".css": | ||
a = "text/css"; | ||
s = "text/css"; | ||
break; | ||
case ".json": | ||
a = "application/json"; | ||
s = "application/json"; | ||
break; | ||
} | ||
Object.hasOwn(e, r) ? (o.writeHead(200, { "Content-Type": a }), o.end(e[r])) : b(n, o); | ||
Object.hasOwn(e, r) ? (o.writeHead(200, { "Content-Type": s }), o.end(e[r])) : b(n, o); | ||
}; | ||
function we(e, t) { | ||
function xe(e, t) { | ||
t.writeHead(200, { | ||
@@ -281,8 +281,8 @@ "Content-Type": "text/plain", | ||
} | ||
function xe(e, t) { | ||
function Se(e, t) { | ||
e.method === "DELETE" ? (t.writeHead(200, { | ||
"Content-Type": "text/plain" | ||
}), Ce(), t.end("Cleared")) : U(e, t); | ||
}), Ee(), t.end("Cleared")) : U(e, t); | ||
} | ||
function Se(e = process.cwd()) { | ||
function Te(e = process.cwd()) { | ||
return (t, n) => { | ||
@@ -297,4 +297,4 @@ if (t.method !== "POST") { | ||
}), t.on("end", () => { | ||
const i = Z(e, o); | ||
u.debug(`Launching editor for ${i}`), X( | ||
const i = q(e, o); | ||
h.debug(`Launching editor for ${i}`), K( | ||
// filename:line:column | ||
@@ -304,4 +304,4 @@ // both line and column are optional | ||
// callback if failed to launch (optional) | ||
(r, s) => { | ||
u.error(`Failed to launch editor for ${r}: ${s}`); | ||
(r, a) => { | ||
h.error(`Failed to launch editor for ${r}: ${a}`); | ||
} | ||
@@ -321,15 +321,15 @@ ), n.writeHead(204), n.end(); | ||
const b = j(404), U = j(405); | ||
function Te(e, t, n, o, i) { | ||
function ye(e, t, n, o, i) { | ||
n && !o && (o = { | ||
"/src/index.html": v(P(n, "src/index.html")), | ||
"/assets/main.js": v(P(n, "assets/main.js")) | ||
"/src/index.html": R(O(n, "src/index.html")), | ||
"/assets/main.js": R(O(n, "assets/main.js")) | ||
}); | ||
const r = [ | ||
[/^\/health$/, we], | ||
[/^\/clear$/, x(xe)], | ||
[/^\/stream$|^\/api\/\d+\/envelope\/?$/, x(me(e, i))], | ||
[/^\/open$/, x(Se(n))], | ||
[RegExp(`^${ne}$`), x(de)], | ||
[/^.+$/, o != null ? x(ge(o)) : b] | ||
], s = Y((c, l) => { | ||
[/^\/health$/, xe], | ||
[/^\/clear$/, x(Se)], | ||
[/^\/stream$|^\/api\/\d+\/envelope\/?$/, x(ge(e, i))], | ||
[/^\/open$/, x(Te(n))], | ||
[RegExp(`^${ie}$`), x(ue)], | ||
[/^.+$/, o != null ? x(we(o)) : b] | ||
], a = Z((c, l) => { | ||
var L; | ||
@@ -354,8 +354,8 @@ const d = c.url; | ||
(E) => { | ||
const O = J(); | ||
const P = J(); | ||
l.appendHeader( | ||
"server-timing", | ||
[ | ||
`sentryTrace;desc="${O["sentry-trace"]}"`, | ||
`baggage;desc="${O.baggage}"`, | ||
`sentryTrace;desc="${P["sentry-trace"]}"`, | ||
`baggage;desc="${P.baggage}"`, | ||
`sentrySpotlightPort;desc=${t}` | ||
@@ -369,16 +369,16 @@ ].join(", ") | ||
}); | ||
return s.on("error", a), s.listen(t, () => { | ||
h(t, n); | ||
}), s; | ||
function a(c) { | ||
"code" in c && c.code === "EADDRINUSE" ? (u.info(`Port ${t} in use, retrying...`), s.close(), H = setTimeout(() => { | ||
s.listen(t); | ||
}, 5e3)) : W(c); | ||
return a.on("error", s), a.listen(t, () => { | ||
u(t, n); | ||
}), a; | ||
function s(c) { | ||
"code" in c && c.code === "EADDRINUSE" ? (h.info(`Port ${t} in use, retrying...`), a.close(), H = setTimeout(() => { | ||
a.listen(t); | ||
}, 5e3)) : X(c); | ||
} | ||
function h(c, l) { | ||
u.info(`Sidecar listening on ${c}`), l && u.info(`You can open: http://localhost:${c} to see the Spotlight overlay directly`); | ||
function u(c, l) { | ||
h.info(`Sidecar listening on ${c}`), l && h.info(`You can open: http://localhost:${c} to see the Spotlight overlay directly`); | ||
} | ||
} | ||
let m, H = null; | ||
const G = new fe(), ye = C( | ||
const G = new pe(), be = C( | ||
(e) => { | ||
@@ -392,5 +392,5 @@ if (typeof e == "string") { | ||
{ name: "isValidPort", op: "sidecar.server.portCheck" } | ||
), be = C( | ||
), Ce = C( | ||
(e) => new Promise((t) => { | ||
u.info(`Checking if we are already running on port ${e}`); | ||
h.info(`Checking if we are already running on port ${e}`); | ||
const n = { | ||
@@ -407,11 +407,11 @@ hostname: "localhost", | ||
let o; | ||
const i = Q(n, (a) => { | ||
const h = a.headers["x-powered-by"]; | ||
s(h === "spotlight-by-sentry"); | ||
const i = Q(n, (s) => { | ||
const u = s.headers["x-powered-by"]; | ||
a(u === "spotlight-by-sentry"); | ||
}), r = () => !i.destroyed && i.destroy(new Error("Request timed out.")); | ||
function s(a) { | ||
process.off("SIGINT", r), clearTimeout(o), t(a); | ||
function a(s) { | ||
process.off("SIGINT", r), clearTimeout(o), t(s); | ||
} | ||
process.on("SIGINT", r), o = setTimeout(r, 2e3), i.on("error", () => { | ||
s(!1); | ||
a(!1); | ||
}), i.end(); | ||
@@ -421,3 +421,3 @@ }), | ||
); | ||
function Ie({ | ||
function Me({ | ||
port: e, | ||
@@ -428,10 +428,18 @@ logger: t, | ||
debug: i, | ||
incomingPayload: r | ||
incomingPayload: r, | ||
isStandalone: a | ||
} = {}) { | ||
a || W((u) => { | ||
var c; | ||
return (c = u.spans) != null && c.some((l) => { | ||
var d; | ||
return (d = l.op) == null ? void 0 : d.startsWith("sidecar."); | ||
}) ? null : u; | ||
}); | ||
let s = oe; | ||
t && ue(t), (i || process.env.SPOTLIGHT_DEBUG) && he(!0), e && !ye(e) ? (u.info("Please provide a valid port."), process.exit(1)) : e && (s = typeof e == "string" ? Number(e) : e), be(s).then((a) => { | ||
a ? u.info(`Sidecar is already running on port ${s}`) : m || (m = Te(G, s, n, o, r)); | ||
t && he(t), (i || process.env.SPOTLIGHT_DEBUG) && fe(!0), e && !be(e) ? (h.info("Please provide a valid port."), process.exit(1)) : e && (s = typeof e == "string" ? Number(e) : e), Ce(s).then((u) => { | ||
u ? h.info(`Sidecar is already running on port ${s}`) : m || (m = ye(G, s, n, o, r)); | ||
}); | ||
} | ||
function Ce() { | ||
function Ee() { | ||
G.clear(); | ||
@@ -441,3 +449,3 @@ } | ||
const B = () => { | ||
H && clearTimeout(H), (M || !m) && (u.info("Bye."), process.exit(0)), m && (M = !0, u.info("Shutting down server gracefully..."), m.close(), m.closeAllConnections(), m.unref()); | ||
H && clearTimeout(H), (M || !m) && (h.info("Bye."), process.exit(0)), m && (M = !0, h.info("Shutting down server gracefully..."), m.close(), m.closeAllConnections(), m.unref()); | ||
}; | ||
@@ -447,6 +455,6 @@ process.on("SIGINT", B); | ||
export { | ||
Ce as clearBuffer, | ||
Ie as setupSidecar, | ||
Ee as clearBuffer, | ||
Me as setupSidecar, | ||
B as shutdown | ||
}; | ||
//# sourceMappingURL=main.js.map |
#!/usr/bin/env node | ||
import { setupSidecar as e } from "./main.js"; | ||
const r = process.argv.length >= 3 ? Number(process.argv[2]) : void 0; | ||
e({ port: r }); | ||
import { setupSidecar as r } from "./main.js"; | ||
const e = process.argv.length >= 3 ? Number(process.argv[2]) : void 0; | ||
r({ port: e, isStandalone: !0 }); | ||
//# sourceMappingURL=server.js.map |
{ | ||
"name": "@spotlightjs/sidecar", | ||
"description": "A small proxy server to capture and forward data from backend services to Spotlight.", | ||
"version": "1.11.1", | ||
"version": "1.11.2", | ||
"license": "Apache-2.0", | ||
@@ -31,3 +31,3 @@ "type": "module", | ||
"dependencies": { | ||
"@sentry/node": "^8.42.0", | ||
"@sentry/node": "^8.49.0", | ||
"kleur": "^4.1.5", | ||
@@ -40,4 +40,4 @@ "launch-editor": "^2.9.1", | ||
"typescript": "^5.6.2", | ||
"vite": "^5.4.12", | ||
"@spotlightjs/tsconfig": "1.0.1" | ||
"vite": "^5.4.14", | ||
"@spotlightjs/tsconfig": "2.0.0" | ||
}, | ||
@@ -44,0 +44,0 @@ "volta": { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
60860
527
Updated@sentry/node@^8.49.0