@kenkaiiii/gg-pixel 4.3.90 → 4.3.92

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.cjs CHANGED
@@ -25,7 +25,9 @@ __export(index_exports, {
25
25
  flushPixel: () => flushPixel,
26
26
  initPixel: () => initPixel,
27
27
  install: () => install,
28
- reportPixel: () => reportPixel
28
+ isInstallProbeFingerprint: () => isInstallProbeFingerprint,
29
+ reportPixel: () => reportPixel,
30
+ verifyInstall: () => verifyInstall
29
31
  });
30
32
  module.exports = __toCommonJS(index_exports);
31
33
 
@@ -454,9 +456,12 @@ var LocalSqliteSink = class {
454
456
 
455
457
  // src/install.ts
456
458
  var import_node_fs3 = require("fs");
459
+ var import_node_module2 = require("module");
457
460
  var import_node_os2 = require("os");
458
461
  var import_node_path2 = require("path");
459
462
  var import_node_child_process2 = require("child_process");
463
+ var import_meta2 = {};
464
+ var nodeRequire = (0, import_node_module2.createRequire)(import_meta2.url);
460
465
  var DEFAULT_INGEST_URL = "https://gg-pixel-server.buzzbeamaustralia.workers.dev";
461
466
  async function install(opts = {}) {
462
467
  const cwd = (0, import_node_path2.resolve)(opts.cwd ?? process.cwd());
@@ -520,6 +525,7 @@ async function install(opts = {}) {
520
525
  projectSecret: created.secret,
521
526
  projectName,
522
527
  projectKind: kind,
528
+ projectRoot: nodeRoot,
523
529
  initFilePath: wired.primaryInitPath,
524
530
  envFilePath,
525
531
  projectsJsonPath,
@@ -952,26 +958,85 @@ export default nextConfig;
952
958
  );
953
959
  return;
954
960
  }
955
- const content = (0, import_node_fs3.readFileSync)(configPath, "utf8");
956
- if (content.includes("@kenkaiiii/gg-pixel")) return;
961
+ patchNextConfigViaAst(configPath);
962
+ }
963
+ var PIXEL_PKG = "@kenkaiiii/gg-pixel";
964
+ function patchNextConfigViaAst(configPath) {
965
+ const original = (0, import_node_fs3.readFileSync)(configPath, "utf8");
966
+ if (original.includes(PIXEL_PKG)) return;
967
+ let parseModule;
968
+ let generateCode;
969
+ try {
970
+ const mod = nodeRequire("magicast");
971
+ parseModule = mod.parseModule;
972
+ generateCode = mod.generateCode;
973
+ } catch {
974
+ return patchNextConfigViaRegex(configPath, original);
975
+ }
976
+ let module_;
977
+ try {
978
+ module_ = parseModule(original);
979
+ } catch {
980
+ return patchNextConfigViaRegex(configPath, original);
981
+ }
982
+ const cfg = resolveNextConfigObject(module_);
983
+ if (!cfg) {
984
+ return patchNextConfigViaRegex(configPath, original);
985
+ }
986
+ const existing = cfg.serverExternalPackages;
987
+ const isArrayLike = Array.isArray(existing) || typeof existing === "object" && existing !== null && existing.$type === "array";
988
+ if (isArrayLike) {
989
+ const arr = existing;
990
+ if (arr.includes(PIXEL_PKG)) return;
991
+ arr.push(PIXEL_PKG);
992
+ } else {
993
+ cfg.serverExternalPackages = [PIXEL_PKG];
994
+ }
995
+ const out = generateCode(module_).code;
996
+ if (out !== original) (0, import_node_fs3.writeFileSync)(configPath, out, "utf8");
997
+ }
998
+ function resolveNextConfigObject(mod) {
999
+ const root = mod.exports.default ?? mod.exports;
1000
+ if (!root) return null;
1001
+ return unwrapWrappers(root);
1002
+ }
1003
+ function unwrapWrappers(node) {
1004
+ let cur = node;
1005
+ for (let i = 0; i < 6; i++) {
1006
+ if (cur.$type === "function-call") {
1007
+ const args = cur.$args ?? [];
1008
+ const objArg = args.find(
1009
+ (a) => typeof a === "object" && a !== null && a.$type !== "function-call"
1010
+ );
1011
+ if (!objArg) return null;
1012
+ cur = objArg;
1013
+ continue;
1014
+ }
1015
+ if (cur.$type === "object" || cur.$type === void 0) return cur;
1016
+ return null;
1017
+ }
1018
+ return null;
1019
+ }
1020
+ function patchNextConfigViaRegex(configPath, content) {
1021
+ if (content.includes(PIXEL_PKG)) return;
957
1022
  if (content.includes("serverExternalPackages")) {
958
1023
  const updated = content.replace(
959
1024
  /serverExternalPackages\s*:\s*\[([^\]]*)\]/,
960
1025
  (_match, inside) => {
961
1026
  const trimmed = inside.trim();
962
1027
  const sep2 = trimmed.length > 0 ? ", " : "";
963
- return `serverExternalPackages: [${trimmed}${sep2}"@kenkaiiii/gg-pixel"]`;
1028
+ return `serverExternalPackages: [${trimmed}${sep2}${JSON.stringify(PIXEL_PKG)}]`;
964
1029
  }
965
1030
  );
966
1031
  if (updated !== content) (0, import_node_fs3.writeFileSync)(configPath, updated, "utf8");
967
1032
  return;
968
1033
  }
969
- const objStart = /(const\s+\w+\s*:\s*NextConfig\s*=\s*\{|module\.exports\s*=\s*\{|export\s+default\s*\{)/;
1034
+ const objStart = /(const\s+\w+\s*(?::\s*\w+)?\s*=\s*\{|module\.exports\s*=\s*\{|export\s+default\s*\{)/;
970
1035
  const m = objStart.exec(content);
971
1036
  if (m) {
972
1037
  const insertAt = m.index + m[0].length;
973
1038
  const updated = content.slice(0, insertAt) + `
974
- serverExternalPackages: ["@kenkaiiii/gg-pixel"],` + content.slice(insertAt);
1039
+ serverExternalPackages: [${JSON.stringify(PIXEL_PKG)}],` + content.slice(insertAt);
975
1040
  (0, import_node_fs3.writeFileSync)(configPath, updated, "utf8");
976
1041
  }
977
1042
  }
@@ -1599,6 +1664,7 @@ func init() {
1599
1664
  projectSecret: created.secret,
1600
1665
  projectName,
1601
1666
  projectKind: "go",
1667
+ projectRoot,
1602
1668
  initFilePath,
1603
1669
  envFilePath,
1604
1670
  projectsJsonPath,
@@ -1664,6 +1730,7 @@ GGPixel.init(
1664
1730
  projectSecret: created.secret,
1665
1731
  projectName,
1666
1732
  projectKind: "ruby",
1733
+ projectRoot,
1667
1734
  initFilePath,
1668
1735
  envFilePath,
1669
1736
  projectsJsonPath,
@@ -1733,6 +1800,7 @@ async function installPython(ctx) {
1733
1800
  projectSecret: created.secret,
1734
1801
  projectName,
1735
1802
  projectKind: "python",
1803
+ projectRoot,
1736
1804
  initFilePath,
1737
1805
  envFilePath,
1738
1806
  projectsJsonPath,
@@ -1864,6 +1932,203 @@ function writeProjectsMapping(projectsJsonPath, projectId, name, path, secret) {
1864
1932
  `, "utf8");
1865
1933
  }
1866
1934
 
1935
+ // src/verify.ts
1936
+ var import_node_child_process3 = require("child_process");
1937
+ var import_node_fs4 = require("fs");
1938
+ var import_node_path3 = require("path");
1939
+ var import_node_crypto3 = require("crypto");
1940
+ var PROBE_FINGERPRINT_PREFIX = "__pixel_install_probe__";
1941
+ function isInstallProbeFingerprint(fingerprint2) {
1942
+ return typeof fingerprint2 === "string" && fingerprint2.startsWith(PROBE_FINGERPRINT_PREFIX);
1943
+ }
1944
+ async function verifyInstall(opts) {
1945
+ const fetchFn = opts.fetchFn ?? fetch;
1946
+ const spawnFn = opts.spawnFn ?? import_node_child_process3.spawn;
1947
+ const timeoutMs = opts.timeoutMs ?? 5e3;
1948
+ const ingest = opts.ingestUrl.replace(/\/+$/, "");
1949
+ const fingerprint2 = `${PROBE_FINGERPRINT_PREFIX}${(0, import_node_crypto3.randomBytes)(6).toString("hex")}`;
1950
+ const start = Date.now();
1951
+ let method;
1952
+ let probeError = null;
1953
+ if (opts.skipChildProbe) {
1954
+ try {
1955
+ await postDirectIngest({
1956
+ ingestUrl: ingest,
1957
+ projectKey: opts.projectKey,
1958
+ fingerprint: fingerprint2,
1959
+ fetchFn
1960
+ });
1961
+ method = "direct_ingest";
1962
+ } catch (err) {
1963
+ return {
1964
+ kind: "failed",
1965
+ reason: "Direct ingest failed",
1966
+ hint: err.message
1967
+ };
1968
+ }
1969
+ } else {
1970
+ try {
1971
+ await runChildProbe({
1972
+ projectRoot: opts.projectRoot,
1973
+ ingestUrl: ingest,
1974
+ projectKey: opts.projectKey,
1975
+ fingerprint: fingerprint2,
1976
+ spawnFn
1977
+ });
1978
+ method = "child_process";
1979
+ } catch (err) {
1980
+ probeError = err.message;
1981
+ try {
1982
+ await postDirectIngest({
1983
+ ingestUrl: ingest,
1984
+ projectKey: opts.projectKey,
1985
+ fingerprint: fingerprint2,
1986
+ fetchFn
1987
+ });
1988
+ method = "direct_ingest";
1989
+ } catch (err2) {
1990
+ return {
1991
+ kind: "failed",
1992
+ reason: "Could not deliver probe event",
1993
+ hint: `child-process: ${probeError}; direct ingest: ${err2.message}`
1994
+ };
1995
+ }
1996
+ }
1997
+ }
1998
+ const probeRow = await pollForFingerprint({
1999
+ ingestUrl: ingest,
2000
+ projectId: opts.projectId,
2001
+ projectSecret: opts.projectSecret,
2002
+ fingerprint: fingerprint2,
2003
+ timeoutMs,
2004
+ fetchFn
2005
+ });
2006
+ if (!probeRow) {
2007
+ return {
2008
+ kind: "failed",
2009
+ reason: `Probe sent (${method}) but didn't appear in /api/projects/${opts.projectId}/errors within ${timeoutMs}ms`,
2010
+ hint: probeError ?? void 0
2011
+ };
2012
+ }
2013
+ try {
2014
+ await fetchFn(`${ingest}/api/errors/${probeRow.id}`, {
2015
+ method: "DELETE",
2016
+ headers: { authorization: `Bearer ${opts.projectSecret}` }
2017
+ });
2018
+ } catch {
2019
+ }
2020
+ return {
2021
+ kind: "ok",
2022
+ method,
2023
+ latencyMs: Date.now() - start
2024
+ };
2025
+ }
2026
+ async function runChildProbe(args) {
2027
+ const ggDir = (0, import_node_path3.join)(args.projectRoot, ".gg");
2028
+ if (!(0, import_node_fs4.existsSync)(ggDir)) (0, import_node_fs4.mkdirSync)(ggDir, { recursive: true });
2029
+ const probePath = (0, import_node_path3.join)(ggDir, `pixel-probe-${(0, import_node_crypto3.randomBytes)(4).toString("hex")}.mjs`);
2030
+ const script = `import "@kenkaiiii/gg-pixel";
2031
+ const body = ${JSON.stringify({
2032
+ project_key: args.projectKey,
2033
+ fingerprint: args.fingerprint,
2034
+ type: "InstallProbe",
2035
+ message: "Install verification probe \u2014 auto-generated, safe to delete",
2036
+ stack: [],
2037
+ code_context: null,
2038
+ runtime: "",
2039
+ manual_report: true,
2040
+ level: "error"
2041
+ })};
2042
+ body.event_id = "evt_probe_" + crypto.randomUUID();
2043
+ body.runtime = "installer-node-" + process.versions.node;
2044
+ body.occurred_at = new Date().toISOString();
2045
+ const res = await fetch(${JSON.stringify(args.ingestUrl + "/ingest")}, {
2046
+ method: "POST",
2047
+ headers: { "content-type": "application/json" },
2048
+ body: JSON.stringify(body),
2049
+ });
2050
+ if (!res.ok) {
2051
+ const txt = await res.text().catch(() => "");
2052
+ console.error("probe ingest failed: status=" + res.status + " body=" + txt.slice(0, 200));
2053
+ process.exit(1);
2054
+ }
2055
+ `;
2056
+ (0, import_node_fs4.writeFileSync)(probePath, script, "utf8");
2057
+ try {
2058
+ await new Promise((resolve2, reject) => {
2059
+ const opts = { cwd: args.projectRoot, stdio: "pipe" };
2060
+ const child = args.spawnFn("node", [probePath], opts);
2061
+ let stderr = "";
2062
+ child.stderr?.on("data", (b) => {
2063
+ stderr += b.toString();
2064
+ });
2065
+ const timer = setTimeout(() => {
2066
+ child.kill("SIGKILL");
2067
+ reject(new Error("Probe child timed out after 10s"));
2068
+ }, 1e4);
2069
+ child.on("error", (err) => {
2070
+ clearTimeout(timer);
2071
+ reject(err);
2072
+ });
2073
+ child.on("exit", (code) => {
2074
+ clearTimeout(timer);
2075
+ if (code === 0) resolve2();
2076
+ else reject(new Error(`Probe exited code=${code}; stderr: ${stderr.trim().slice(0, 400)}`));
2077
+ });
2078
+ });
2079
+ } finally {
2080
+ try {
2081
+ (0, import_node_fs4.unlinkSync)(probePath);
2082
+ } catch {
2083
+ }
2084
+ }
2085
+ }
2086
+ async function postDirectIngest(args) {
2087
+ const res = await args.fetchFn(`${args.ingestUrl}/ingest`, {
2088
+ method: "POST",
2089
+ headers: { "content-type": "application/json" },
2090
+ body: JSON.stringify({
2091
+ event_id: `evt_probe_${(0, import_node_crypto3.randomBytes)(8).toString("hex")}`,
2092
+ project_key: args.projectKey,
2093
+ fingerprint: args.fingerprint,
2094
+ type: "InstallProbe",
2095
+ message: "Install verification probe",
2096
+ stack: [],
2097
+ code_context: null,
2098
+ runtime: `installer-node-${process.versions.node}`,
2099
+ manual_report: true,
2100
+ level: "error",
2101
+ occurred_at: (/* @__PURE__ */ new Date()).toISOString()
2102
+ })
2103
+ });
2104
+ if (!res.ok) {
2105
+ let body = "";
2106
+ try {
2107
+ body = await res.text();
2108
+ } catch {
2109
+ }
2110
+ throw new Error(`POST /ingest \u2192 ${res.status} ${body.slice(0, 200)}`);
2111
+ }
2112
+ }
2113
+ async function pollForFingerprint(args) {
2114
+ const deadline = Date.now() + args.timeoutMs;
2115
+ while (Date.now() < deadline) {
2116
+ try {
2117
+ const res = await args.fetchFn(`${args.ingestUrl}/api/projects/${args.projectId}/errors`, {
2118
+ headers: { authorization: `Bearer ${args.projectSecret}` }
2119
+ });
2120
+ if (res.ok) {
2121
+ const body = await res.json();
2122
+ const match = body.errors.find((e) => e.fingerprint === args.fingerprint);
2123
+ if (match) return { id: match.id };
2124
+ }
2125
+ } catch {
2126
+ }
2127
+ await new Promise((r) => setTimeout(r, 250));
2128
+ }
2129
+ return null;
2130
+ }
2131
+
1867
2132
  // src/index.ts
1868
2133
  var active = null;
1869
2134
  function initPixel(options) {
@@ -1916,6 +2181,8 @@ function defaultRuntime() {
1916
2181
  flushPixel,
1917
2182
  initPixel,
1918
2183
  install,
1919
- reportPixel
2184
+ isInstallProbeFingerprint,
2185
+ reportPixel,
2186
+ verifyInstall
1920
2187
  });
1921
2188
  //# sourceMappingURL=index.cjs.map