UNPKG

@safaricom-mxl/nextjs

Version:

MXL Javascript RUM agent for nextjs

133 lines (128 loc) 4.63 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/server.ts var server_exports = {}; __export(server_exports, { createRouteHandler: () => createRouteHandler }); module.exports = __toCommonJS(server_exports); // src/create-next-route-handler.ts var import_node_crypto = require("crypto"); var import_server = require("next/server.js"); // src/constants.ts var SCRIPT_URL = "https://mxl-scripts.apps.ocpthikadev01.safaricom.net/v1"; var DEFAULT_API_URL = "https://mxl-server.apps.ocpthikadev01.safaricom.net"; var SCRIPT_PATH = "/mxl.js"; // src/create-next-route-handler.ts function getClientHeaders(req) { const headers = new Headers(); const ip = req.headers.get("cf-connecting-ip") ?? req.headers.get("x-forwarded-for")?.split(",")[0] ?? req.headers.get("x-vercel-forwarded-for"); headers.set("Content-Type", "application/json"); headers.set("mxl-client-id", req.headers.get("mxl-client-id") ?? ""); const origin = req.headers.get("origin") ?? (() => { const url = new URL(req.url); return `${url.protocol}//${url.host}`; })(); headers.set("origin", origin); headers.set("User-Agent", req.headers.get("user-agent") ?? ""); if (ip) { headers.set("mxl-client-ip", ip); } return headers; } async function handleApiRoute(req, apiUrl, apiPath) { const headers = getClientHeaders(req); try { const res = await fetch(`${apiUrl}${apiPath}`, { method: req.method, headers, body: req.method === "POST" ? JSON.stringify(await req.json()) : void 0 }); if (res.headers.get("content-type")?.includes("application/json")) { return import_server.NextResponse.json(await res.json(), { status: res.status }); } return import_server.NextResponse.json(await res.text(), { status: res.status }); } catch (e) { return import_server.NextResponse.json( { error: "Failed to proxy request", message: e instanceof Error ? e.message : String(e) }, { status: 500 } ); } } async function handleScriptProxyRoute(req) { const url = new URL(req.url); const pathname = url.pathname; if (!pathname.endsWith(SCRIPT_PATH)) { return import_server.NextResponse.json({ error: "Not found" }, { status: 404 }); } let scriptUrl = `${SCRIPT_URL}${SCRIPT_PATH}`; if (url.searchParams.size > 0) { scriptUrl += `?${url.searchParams.toString()}`; } try { const res = await fetch(scriptUrl, { // @ts-expect-error next: { revalidate: 86400 } }); const text = await res.text(); const etag = `"${(0, import_node_crypto.createHash)("md5").update(scriptUrl + text).digest("hex")}"`; return new import_server.NextResponse(text, { headers: { "Content-Type": "text/javascript", "Cache-Control": "public, max-age=86400, stale-while-revalidate=86400", ETag: etag } }); } catch (e) { return import_server.NextResponse.json( { error: "Failed to fetch script", message: e instanceof Error ? e.message : String(e) }, { status: 500 } ); } } function createRouteHandler(options) { const apiUrl = options?.apiUrl ?? DEFAULT_API_URL; const handler = async function handler2(req) { const url = new URL(req.url); const pathname = url.pathname; const method = req.method; if (method === "GET" && pathname.endsWith(SCRIPT_PATH)) { return handleScriptProxyRoute(req); } const apiPathMatch = pathname.indexOf("/track"); if (apiPathMatch === -1) { return import_server.NextResponse.json({ error: "Not found" }, { status: 404 }); } const apiPath = pathname.substring(apiPathMatch); return handleApiRoute(req, apiUrl, apiPath); }; handler.GET = handler; handler.POST = handler; return handler; } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { createRouteHandler });