@kenkaiiii/gg-pixel 4.3.90 → 4.3.91
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 +4 -0
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +207 -2
- 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 +204 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -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
|
|
|
@@ -520,6 +522,7 @@ async function install(opts = {}) {
|
|
|
520
522
|
projectSecret: created.secret,
|
|
521
523
|
projectName,
|
|
522
524
|
projectKind: kind,
|
|
525
|
+
projectRoot: nodeRoot,
|
|
523
526
|
initFilePath: wired.primaryInitPath,
|
|
524
527
|
envFilePath,
|
|
525
528
|
projectsJsonPath,
|
|
@@ -1599,6 +1602,7 @@ func init() {
|
|
|
1599
1602
|
projectSecret: created.secret,
|
|
1600
1603
|
projectName,
|
|
1601
1604
|
projectKind: "go",
|
|
1605
|
+
projectRoot,
|
|
1602
1606
|
initFilePath,
|
|
1603
1607
|
envFilePath,
|
|
1604
1608
|
projectsJsonPath,
|
|
@@ -1664,6 +1668,7 @@ GGPixel.init(
|
|
|
1664
1668
|
projectSecret: created.secret,
|
|
1665
1669
|
projectName,
|
|
1666
1670
|
projectKind: "ruby",
|
|
1671
|
+
projectRoot,
|
|
1667
1672
|
initFilePath,
|
|
1668
1673
|
envFilePath,
|
|
1669
1674
|
projectsJsonPath,
|
|
@@ -1733,6 +1738,7 @@ async function installPython(ctx) {
|
|
|
1733
1738
|
projectSecret: created.secret,
|
|
1734
1739
|
projectName,
|
|
1735
1740
|
projectKind: "python",
|
|
1741
|
+
projectRoot,
|
|
1736
1742
|
initFilePath,
|
|
1737
1743
|
envFilePath,
|
|
1738
1744
|
projectsJsonPath,
|
|
@@ -1864,6 +1870,203 @@ function writeProjectsMapping(projectsJsonPath, projectId, name, path, secret) {
|
|
|
1864
1870
|
`, "utf8");
|
|
1865
1871
|
}
|
|
1866
1872
|
|
|
1873
|
+
// src/verify.ts
|
|
1874
|
+
var import_node_child_process3 = require("child_process");
|
|
1875
|
+
var import_node_fs4 = require("fs");
|
|
1876
|
+
var import_node_path3 = require("path");
|
|
1877
|
+
var import_node_crypto3 = require("crypto");
|
|
1878
|
+
var PROBE_FINGERPRINT_PREFIX = "__pixel_install_probe__";
|
|
1879
|
+
function isInstallProbeFingerprint(fingerprint2) {
|
|
1880
|
+
return typeof fingerprint2 === "string" && fingerprint2.startsWith(PROBE_FINGERPRINT_PREFIX);
|
|
1881
|
+
}
|
|
1882
|
+
async function verifyInstall(opts) {
|
|
1883
|
+
const fetchFn = opts.fetchFn ?? fetch;
|
|
1884
|
+
const spawnFn = opts.spawnFn ?? import_node_child_process3.spawn;
|
|
1885
|
+
const timeoutMs = opts.timeoutMs ?? 5e3;
|
|
1886
|
+
const ingest = opts.ingestUrl.replace(/\/+$/, "");
|
|
1887
|
+
const fingerprint2 = `${PROBE_FINGERPRINT_PREFIX}${(0, import_node_crypto3.randomBytes)(6).toString("hex")}`;
|
|
1888
|
+
const start = Date.now();
|
|
1889
|
+
let method;
|
|
1890
|
+
let probeError = null;
|
|
1891
|
+
if (opts.skipChildProbe) {
|
|
1892
|
+
try {
|
|
1893
|
+
await postDirectIngest({
|
|
1894
|
+
ingestUrl: ingest,
|
|
1895
|
+
projectKey: opts.projectKey,
|
|
1896
|
+
fingerprint: fingerprint2,
|
|
1897
|
+
fetchFn
|
|
1898
|
+
});
|
|
1899
|
+
method = "direct_ingest";
|
|
1900
|
+
} catch (err) {
|
|
1901
|
+
return {
|
|
1902
|
+
kind: "failed",
|
|
1903
|
+
reason: "Direct ingest failed",
|
|
1904
|
+
hint: err.message
|
|
1905
|
+
};
|
|
1906
|
+
}
|
|
1907
|
+
} else {
|
|
1908
|
+
try {
|
|
1909
|
+
await runChildProbe({
|
|
1910
|
+
projectRoot: opts.projectRoot,
|
|
1911
|
+
ingestUrl: ingest,
|
|
1912
|
+
projectKey: opts.projectKey,
|
|
1913
|
+
fingerprint: fingerprint2,
|
|
1914
|
+
spawnFn
|
|
1915
|
+
});
|
|
1916
|
+
method = "child_process";
|
|
1917
|
+
} catch (err) {
|
|
1918
|
+
probeError = err.message;
|
|
1919
|
+
try {
|
|
1920
|
+
await postDirectIngest({
|
|
1921
|
+
ingestUrl: ingest,
|
|
1922
|
+
projectKey: opts.projectKey,
|
|
1923
|
+
fingerprint: fingerprint2,
|
|
1924
|
+
fetchFn
|
|
1925
|
+
});
|
|
1926
|
+
method = "direct_ingest";
|
|
1927
|
+
} catch (err2) {
|
|
1928
|
+
return {
|
|
1929
|
+
kind: "failed",
|
|
1930
|
+
reason: "Could not deliver probe event",
|
|
1931
|
+
hint: `child-process: ${probeError}; direct ingest: ${err2.message}`
|
|
1932
|
+
};
|
|
1933
|
+
}
|
|
1934
|
+
}
|
|
1935
|
+
}
|
|
1936
|
+
const probeRow = await pollForFingerprint({
|
|
1937
|
+
ingestUrl: ingest,
|
|
1938
|
+
projectId: opts.projectId,
|
|
1939
|
+
projectSecret: opts.projectSecret,
|
|
1940
|
+
fingerprint: fingerprint2,
|
|
1941
|
+
timeoutMs,
|
|
1942
|
+
fetchFn
|
|
1943
|
+
});
|
|
1944
|
+
if (!probeRow) {
|
|
1945
|
+
return {
|
|
1946
|
+
kind: "failed",
|
|
1947
|
+
reason: `Probe sent (${method}) but didn't appear in /api/projects/${opts.projectId}/errors within ${timeoutMs}ms`,
|
|
1948
|
+
hint: probeError ?? void 0
|
|
1949
|
+
};
|
|
1950
|
+
}
|
|
1951
|
+
try {
|
|
1952
|
+
await fetchFn(`${ingest}/api/errors/${probeRow.id}`, {
|
|
1953
|
+
method: "DELETE",
|
|
1954
|
+
headers: { authorization: `Bearer ${opts.projectSecret}` }
|
|
1955
|
+
});
|
|
1956
|
+
} catch {
|
|
1957
|
+
}
|
|
1958
|
+
return {
|
|
1959
|
+
kind: "ok",
|
|
1960
|
+
method,
|
|
1961
|
+
latencyMs: Date.now() - start
|
|
1962
|
+
};
|
|
1963
|
+
}
|
|
1964
|
+
async function runChildProbe(args) {
|
|
1965
|
+
const ggDir = (0, import_node_path3.join)(args.projectRoot, ".gg");
|
|
1966
|
+
if (!(0, import_node_fs4.existsSync)(ggDir)) (0, import_node_fs4.mkdirSync)(ggDir, { recursive: true });
|
|
1967
|
+
const probePath = (0, import_node_path3.join)(ggDir, `pixel-probe-${(0, import_node_crypto3.randomBytes)(4).toString("hex")}.mjs`);
|
|
1968
|
+
const script = `import "@kenkaiiii/gg-pixel";
|
|
1969
|
+
const body = ${JSON.stringify({
|
|
1970
|
+
project_key: args.projectKey,
|
|
1971
|
+
fingerprint: args.fingerprint,
|
|
1972
|
+
type: "InstallProbe",
|
|
1973
|
+
message: "Install verification probe \u2014 auto-generated, safe to delete",
|
|
1974
|
+
stack: [],
|
|
1975
|
+
code_context: null,
|
|
1976
|
+
runtime: "",
|
|
1977
|
+
manual_report: true,
|
|
1978
|
+
level: "error"
|
|
1979
|
+
})};
|
|
1980
|
+
body.event_id = "evt_probe_" + crypto.randomUUID();
|
|
1981
|
+
body.runtime = "installer-node-" + process.versions.node;
|
|
1982
|
+
body.occurred_at = new Date().toISOString();
|
|
1983
|
+
const res = await fetch(${JSON.stringify(args.ingestUrl + "/ingest")}, {
|
|
1984
|
+
method: "POST",
|
|
1985
|
+
headers: { "content-type": "application/json" },
|
|
1986
|
+
body: JSON.stringify(body),
|
|
1987
|
+
});
|
|
1988
|
+
if (!res.ok) {
|
|
1989
|
+
const txt = await res.text().catch(() => "");
|
|
1990
|
+
console.error("probe ingest failed: status=" + res.status + " body=" + txt.slice(0, 200));
|
|
1991
|
+
process.exit(1);
|
|
1992
|
+
}
|
|
1993
|
+
`;
|
|
1994
|
+
(0, import_node_fs4.writeFileSync)(probePath, script, "utf8");
|
|
1995
|
+
try {
|
|
1996
|
+
await new Promise((resolve2, reject) => {
|
|
1997
|
+
const opts = { cwd: args.projectRoot, stdio: "pipe" };
|
|
1998
|
+
const child = args.spawnFn("node", [probePath], opts);
|
|
1999
|
+
let stderr = "";
|
|
2000
|
+
child.stderr?.on("data", (b) => {
|
|
2001
|
+
stderr += b.toString();
|
|
2002
|
+
});
|
|
2003
|
+
const timer = setTimeout(() => {
|
|
2004
|
+
child.kill("SIGKILL");
|
|
2005
|
+
reject(new Error("Probe child timed out after 10s"));
|
|
2006
|
+
}, 1e4);
|
|
2007
|
+
child.on("error", (err) => {
|
|
2008
|
+
clearTimeout(timer);
|
|
2009
|
+
reject(err);
|
|
2010
|
+
});
|
|
2011
|
+
child.on("exit", (code) => {
|
|
2012
|
+
clearTimeout(timer);
|
|
2013
|
+
if (code === 0) resolve2();
|
|
2014
|
+
else reject(new Error(`Probe exited code=${code}; stderr: ${stderr.trim().slice(0, 400)}`));
|
|
2015
|
+
});
|
|
2016
|
+
});
|
|
2017
|
+
} finally {
|
|
2018
|
+
try {
|
|
2019
|
+
(0, import_node_fs4.unlinkSync)(probePath);
|
|
2020
|
+
} catch {
|
|
2021
|
+
}
|
|
2022
|
+
}
|
|
2023
|
+
}
|
|
2024
|
+
async function postDirectIngest(args) {
|
|
2025
|
+
const res = await args.fetchFn(`${args.ingestUrl}/ingest`, {
|
|
2026
|
+
method: "POST",
|
|
2027
|
+
headers: { "content-type": "application/json" },
|
|
2028
|
+
body: JSON.stringify({
|
|
2029
|
+
event_id: `evt_probe_${(0, import_node_crypto3.randomBytes)(8).toString("hex")}`,
|
|
2030
|
+
project_key: args.projectKey,
|
|
2031
|
+
fingerprint: args.fingerprint,
|
|
2032
|
+
type: "InstallProbe",
|
|
2033
|
+
message: "Install verification probe",
|
|
2034
|
+
stack: [],
|
|
2035
|
+
code_context: null,
|
|
2036
|
+
runtime: `installer-node-${process.versions.node}`,
|
|
2037
|
+
manual_report: true,
|
|
2038
|
+
level: "error",
|
|
2039
|
+
occurred_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
2040
|
+
})
|
|
2041
|
+
});
|
|
2042
|
+
if (!res.ok) {
|
|
2043
|
+
let body = "";
|
|
2044
|
+
try {
|
|
2045
|
+
body = await res.text();
|
|
2046
|
+
} catch {
|
|
2047
|
+
}
|
|
2048
|
+
throw new Error(`POST /ingest \u2192 ${res.status} ${body.slice(0, 200)}`);
|
|
2049
|
+
}
|
|
2050
|
+
}
|
|
2051
|
+
async function pollForFingerprint(args) {
|
|
2052
|
+
const deadline = Date.now() + args.timeoutMs;
|
|
2053
|
+
while (Date.now() < deadline) {
|
|
2054
|
+
try {
|
|
2055
|
+
const res = await args.fetchFn(`${args.ingestUrl}/api/projects/${args.projectId}/errors`, {
|
|
2056
|
+
headers: { authorization: `Bearer ${args.projectSecret}` }
|
|
2057
|
+
});
|
|
2058
|
+
if (res.ok) {
|
|
2059
|
+
const body = await res.json();
|
|
2060
|
+
const match = body.errors.find((e) => e.fingerprint === args.fingerprint);
|
|
2061
|
+
if (match) return { id: match.id };
|
|
2062
|
+
}
|
|
2063
|
+
} catch {
|
|
2064
|
+
}
|
|
2065
|
+
await new Promise((r) => setTimeout(r, 250));
|
|
2066
|
+
}
|
|
2067
|
+
return null;
|
|
2068
|
+
}
|
|
2069
|
+
|
|
1867
2070
|
// src/index.ts
|
|
1868
2071
|
var active = null;
|
|
1869
2072
|
function initPixel(options) {
|
|
@@ -1916,6 +2119,8 @@ function defaultRuntime() {
|
|
|
1916
2119
|
flushPixel,
|
|
1917
2120
|
initPixel,
|
|
1918
2121
|
install,
|
|
1919
|
-
|
|
2122
|
+
isInstallProbeFingerprint,
|
|
2123
|
+
reportPixel,
|
|
2124
|
+
verifyInstall
|
|
1920
2125
|
});
|
|
1921
2126
|
//# sourceMappingURL=index.cjs.map
|