@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/cli.js +70 -5
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +274 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +56 -1
- package/dist/index.d.ts +56 -1
- package/dist/index.js +270 -6
- package/dist/index.js.map +1 -1
- package/package.json +4 -1
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
|
-
|
|
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
|
-
|
|
956
|
-
|
|
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}
|
|
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
|
|
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: [
|
|
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
|
-
|
|
2184
|
+
isInstallProbeFingerprint,
|
|
2185
|
+
reportPixel,
|
|
2186
|
+
verifyInstall
|
|
1920
2187
|
});
|
|
1921
2188
|
//# sourceMappingURL=index.cjs.map
|