@superblocksteam/sdk 2.0.149 → 2.0.150-next.1
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/.turbo/turbo-build.log +1 -1
- package/dist/cli-replacement/dependency-install-classifier.d.mts +3 -1
- package/dist/cli-replacement/dependency-install-classifier.d.mts.map +1 -1
- package/dist/cli-replacement/dependency-install-classifier.mjs +16 -5
- package/dist/cli-replacement/dependency-install-classifier.mjs.map +1 -1
- package/dist/cli-replacement/dev-s3-restore.test.mjs +73 -14
- package/dist/cli-replacement/dev-s3-restore.test.mjs.map +1 -1
- package/dist/cli-replacement/dev-startup-git-before-dbfs-order.test.mjs +4 -0
- package/dist/cli-replacement/dev-startup-git-before-dbfs-order.test.mjs.map +1 -1
- package/dist/cli-replacement/dev.d.mts.map +1 -1
- package/dist/cli-replacement/dev.mjs +130 -12
- package/dist/cli-replacement/dev.mjs.map +1 -1
- package/dist/cli-replacement/install-packages.npm-registry.test.mjs +153 -0
- package/dist/cli-replacement/install-packages.npm-registry.test.mjs.map +1 -1
- package/dist/cli-replacement/npm-install-summary.d.mts +30 -0
- package/dist/cli-replacement/npm-install-summary.d.mts.map +1 -0
- package/dist/cli-replacement/npm-install-summary.mjs +67 -0
- package/dist/cli-replacement/npm-install-summary.mjs.map +1 -0
- package/dist/cli-replacement/npm-install-summary.test.d.mts +2 -0
- package/dist/cli-replacement/npm-install-summary.test.d.mts.map +1 -0
- package/dist/cli-replacement/npm-install-summary.test.mjs +70 -0
- package/dist/cli-replacement/npm-install-summary.test.mjs.map +1 -0
- package/dist/cli-replacement/npm-install-timing.d.mts +16 -0
- package/dist/cli-replacement/npm-install-timing.d.mts.map +1 -0
- package/dist/cli-replacement/npm-install-timing.mjs +104 -0
- package/dist/cli-replacement/npm-install-timing.mjs.map +1 -0
- package/dist/cli-replacement/npm-install-timing.test.d.mts +2 -0
- package/dist/cli-replacement/npm-install-timing.test.d.mts.map +1 -0
- package/dist/cli-replacement/npm-install-timing.test.mjs +151 -0
- package/dist/cli-replacement/npm-install-timing.test.mjs.map +1 -0
- package/dist/telemetry/logging.d.ts +7 -0
- package/dist/telemetry/logging.d.ts.map +1 -1
- package/dist/telemetry/logging.js +13 -0
- package/dist/telemetry/logging.js.map +1 -1
- package/dist/telemetry/logging.test.js +40 -0
- package/dist/telemetry/logging.test.js.map +1 -1
- package/package.json +6 -6
- package/src/cli-replacement/dependency-install-classifier.mts +38 -6
- package/src/cli-replacement/dev-s3-restore.test.mts +98 -14
- package/src/cli-replacement/dev-startup-git-before-dbfs-order.test.mts +4 -0
- package/src/cli-replacement/dev.mts +155 -11
- package/src/cli-replacement/install-packages.npm-registry.test.mts +235 -0
- package/src/cli-replacement/npm-install-summary.mts +82 -0
- package/src/cli-replacement/npm-install-summary.test.mts +94 -0
- package/src/cli-replacement/npm-install-timing.mts +121 -0
- package/src/cli-replacement/npm-install-timing.test.mts +199 -0
- package/src/telemetry/logging.test.ts +55 -0
- package/src/telemetry/logging.ts +21 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import nodeFs from "node:fs/promises";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
5
|
+
import { consumeNpmInstallTimingAttributes } from "./npm-install-timing.mjs";
|
|
6
|
+
let logsDir;
|
|
7
|
+
beforeEach(async () => {
|
|
8
|
+
logsDir = await nodeFs.mkdtemp(path.join(os.tmpdir(), "npm-timing-"));
|
|
9
|
+
});
|
|
10
|
+
afterEach(async () => {
|
|
11
|
+
await nodeFs.rm(logsDir, { force: true, recursive: true });
|
|
12
|
+
});
|
|
13
|
+
/** Write a timing file using npm's own naming (`<log id>-timing.json`). */
|
|
14
|
+
async function writeTimingFile(logId, contents) {
|
|
15
|
+
const file = path.join(logsDir, `${logId}-timing.json`);
|
|
16
|
+
await nodeFs.writeFile(file, typeof contents === "string" ? contents : JSON.stringify(contents));
|
|
17
|
+
return file;
|
|
18
|
+
}
|
|
19
|
+
async function listTimingFiles() {
|
|
20
|
+
const entries = await nodeFs.readdir(logsDir);
|
|
21
|
+
return entries.filter((name) => name.endsWith("-timing.json"));
|
|
22
|
+
}
|
|
23
|
+
describe("consumeNpmInstallTimingAttributes", () => {
|
|
24
|
+
it("converts the whitelisted timers from milliseconds to seconds", async () => {
|
|
25
|
+
await writeTimingFile("2026-08-07T12_00_00_000Z", {
|
|
26
|
+
metadata: { version: "11.16.0" },
|
|
27
|
+
timers: {
|
|
28
|
+
idealTree: 230,
|
|
29
|
+
reify: 24500,
|
|
30
|
+
"reify:build": 90,
|
|
31
|
+
"reify:loadTrees": 400,
|
|
32
|
+
"reify:unpack": 23200,
|
|
33
|
+
},
|
|
34
|
+
unfinishedTimers: {},
|
|
35
|
+
});
|
|
36
|
+
expect(await consumeNpmInstallTimingAttributes(logsDir)).toEqual({
|
|
37
|
+
"superblocks.npm.install.build_seconds": 0.09,
|
|
38
|
+
"superblocks.npm.install.ideal_tree_seconds": 0.23,
|
|
39
|
+
"superblocks.npm.install.load_trees_seconds": 0.4,
|
|
40
|
+
"superblocks.npm.install.reify_seconds": 24.5,
|
|
41
|
+
"superblocks.npm.install.unpack_seconds": 23.2,
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
// npm records one `reifyNode:node_modules/<package>` timer per package it
|
|
45
|
+
// touched. Emitting those would be unbounded attribute cardinality and would
|
|
46
|
+
// put dependency names into telemetry, so only the fixed whitelist is ever
|
|
47
|
+
// emitted.
|
|
48
|
+
it("never emits a per-package reifyNode timer", async () => {
|
|
49
|
+
await writeTimingFile("2026-08-07T12_00_00_000Z", {
|
|
50
|
+
timers: {
|
|
51
|
+
idealTree: 100,
|
|
52
|
+
"reifyNode:node_modules/@dnd-kit/core": 12,
|
|
53
|
+
"reifyNode:node_modules/lodash": 34,
|
|
54
|
+
"reifyNode:node_modules/react": 56,
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
const attributes = await consumeNpmInstallTimingAttributes(logsDir);
|
|
58
|
+
expect(attributes).toEqual({
|
|
59
|
+
"superblocks.npm.install.ideal_tree_seconds": 0.1,
|
|
60
|
+
});
|
|
61
|
+
expect(Object.keys(attributes ?? {}).some((key) => key.includes("reifyNode"))).toBe(false);
|
|
62
|
+
});
|
|
63
|
+
// Which phases npm records depends on what the install did, so a missing
|
|
64
|
+
// timer is normal rather than an error.
|
|
65
|
+
it("omits timers npm did not record", async () => {
|
|
66
|
+
await writeTimingFile("2026-08-07T12_00_00_000Z", {
|
|
67
|
+
timers: { reify: 500 },
|
|
68
|
+
});
|
|
69
|
+
expect(await consumeNpmInstallTimingAttributes(logsDir)).toEqual({
|
|
70
|
+
"superblocks.npm.install.reify_seconds": 0.5,
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
// "npm unpacked nothing" is the signal that separates a metadata-only
|
|
74
|
+
// install from one that wrote tens of thousands of files, so a recorded zero
|
|
75
|
+
// is real data and must not be dropped as if it were missing.
|
|
76
|
+
it("emits a recorded zero rather than dropping it", async () => {
|
|
77
|
+
await writeTimingFile("2026-08-07T12_00_00_000Z", {
|
|
78
|
+
timers: { "reify:unpack": 0 },
|
|
79
|
+
});
|
|
80
|
+
expect(await consumeNpmInstallTimingAttributes(logsDir)).toEqual({
|
|
81
|
+
"superblocks.npm.install.unpack_seconds": 0,
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
// npm's log ids are fixed-width ISO timestamps, so the newest file is the
|
|
85
|
+
// last one alphabetically.
|
|
86
|
+
it("reads the newest file when older installs left files behind", async () => {
|
|
87
|
+
await writeTimingFile("2026-08-07T11_00_00_000Z", {
|
|
88
|
+
timers: { reify: 1000 },
|
|
89
|
+
});
|
|
90
|
+
await writeTimingFile("2026-08-07T12_00_00_000Z", {
|
|
91
|
+
timers: { reify: 2000 },
|
|
92
|
+
});
|
|
93
|
+
expect(await consumeNpmInstallTimingAttributes(logsDir)).toEqual({
|
|
94
|
+
"superblocks.npm.install.reify_seconds": 2,
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
// npm's `logs-max` pruning only covers its debug logs, so timing files would
|
|
98
|
+
// pile up on the app volume forever if nothing removed them.
|
|
99
|
+
it("removes the timing files it read so they cannot accumulate", async () => {
|
|
100
|
+
await writeTimingFile("2026-08-07T11_00_00_000Z", {
|
|
101
|
+
timers: { reify: 1000 },
|
|
102
|
+
});
|
|
103
|
+
await writeTimingFile("2026-08-07T12_00_00_000Z", {
|
|
104
|
+
timers: { reify: 2000 },
|
|
105
|
+
});
|
|
106
|
+
const debugLog = path.join(logsDir, "2026-08-07T12_00_00_000Z-debug-0.log");
|
|
107
|
+
await nodeFs.writeFile(debugLog, "npm debug output");
|
|
108
|
+
await consumeNpmInstallTimingAttributes(logsDir);
|
|
109
|
+
expect(await listTimingFiles()).toEqual([]);
|
|
110
|
+
// npm's debug log is a separate diagnostic that must survive.
|
|
111
|
+
await expect(nodeFs.readFile(debugLog, "utf8")).resolves.toBe("npm debug output");
|
|
112
|
+
});
|
|
113
|
+
it("returns null when the logs dir has no timing file", async () => {
|
|
114
|
+
await nodeFs.writeFile(path.join(logsDir, "2026-08-07T12_00_00_000Z-debug-0.log"), "npm debug output");
|
|
115
|
+
expect(await consumeNpmInstallTimingAttributes(logsDir)).toBeNull();
|
|
116
|
+
});
|
|
117
|
+
it("returns null when the logs dir does not exist", async () => {
|
|
118
|
+
expect(await consumeNpmInstallTimingAttributes(path.join(logsDir, "missing"))).toBeNull();
|
|
119
|
+
});
|
|
120
|
+
it("returns null for a file that is not JSON rather than throwing", async () => {
|
|
121
|
+
await writeTimingFile("2026-08-07T12_00_00_000Z", "not json at all");
|
|
122
|
+
expect(await consumeNpmInstallTimingAttributes(logsDir)).toBeNull();
|
|
123
|
+
});
|
|
124
|
+
it("returns null when the file carries no timers object", async () => {
|
|
125
|
+
await writeTimingFile("2026-08-07T12_00_00_000Z", { metadata: {} });
|
|
126
|
+
expect(await consumeNpmInstallTimingAttributes(logsDir)).toBeNull();
|
|
127
|
+
});
|
|
128
|
+
it("returns null when none of the whitelisted timers are present", async () => {
|
|
129
|
+
await writeTimingFile("2026-08-07T12_00_00_000Z", {
|
|
130
|
+
timers: { "npm:load": 12, "reifyNode:node_modules/lodash": 34 },
|
|
131
|
+
});
|
|
132
|
+
expect(await consumeNpmInstallTimingAttributes(logsDir)).toBeNull();
|
|
133
|
+
});
|
|
134
|
+
it("ignores timer values that are not finite numbers", async () => {
|
|
135
|
+
await writeTimingFile("2026-08-07T12_00_00_000Z", {
|
|
136
|
+
timers: { idealTree: "230", reify: null, "reify:unpack": 23200 },
|
|
137
|
+
});
|
|
138
|
+
expect(await consumeNpmInstallTimingAttributes(logsDir)).toEqual({
|
|
139
|
+
"superblocks.npm.install.unpack_seconds": 23.2,
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
it("clamps a negative duration so dashboards cannot be skewed", async () => {
|
|
143
|
+
await writeTimingFile("2026-08-07T12_00_00_000Z", {
|
|
144
|
+
timers: { reify: -500 },
|
|
145
|
+
});
|
|
146
|
+
expect(await consumeNpmInstallTimingAttributes(logsDir)).toEqual({
|
|
147
|
+
"superblocks.npm.install.reify_seconds": 0,
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
//# sourceMappingURL=npm-install-timing.test.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"npm-install-timing.test.mjs","sourceRoot":"","sources":["../../src/cli-replacement/npm-install-timing.test.mts"],"names":[],"mappings":"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"}
|
|
@@ -15,6 +15,13 @@ export interface Logger {
|
|
|
15
15
|
debug: (...messages: unknown[]) => void;
|
|
16
16
|
info: (...messages: unknown[]) => void;
|
|
17
17
|
warn: (...messages: unknown[]) => void;
|
|
18
|
+
/**
|
|
19
|
+
* Emit an INFO-level log whose structured attributes are exported as OTel
|
|
20
|
+
* log attributes (Datadog facets) instead of being flattened into the
|
|
21
|
+
* message body. Plain `info()` joins every argument into one body string, so
|
|
22
|
+
* attributes passed to it are never queryable.
|
|
23
|
+
*/
|
|
24
|
+
infoStructured?: (message: string, attributes: LogAttributes) => void;
|
|
18
25
|
/**
|
|
19
26
|
* Emit a WARN-level log whose structured attributes are exported as OTel log
|
|
20
27
|
* attributes (Datadog facets) instead of being flattened into the message
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logging.d.ts","sourceRoot":"","sources":["../../src/telemetry/logging.ts"],"names":[],"mappings":"AA8DA,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAED;;;;GAIG;AACH,KAAK,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;AAE/D,MAAM,WAAW,MAAM;IACrB,KAAK,EAAE,CAAC,GAAG,QAAQ,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACxC,IAAI,EAAE,CAAC,GAAG,QAAQ,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACvC,IAAI,EAAE,CAAC,GAAG,QAAQ,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACvC;;;;OAIG;IACH,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,KAAK,IAAI,CAAC;IACtE,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,SAAS,KAAK,IAAI,CAAC;CACpD;
|
|
1
|
+
{"version":3,"file":"logging.d.ts","sourceRoot":"","sources":["../../src/telemetry/logging.ts"],"names":[],"mappings":"AA8DA,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAED;;;;GAIG;AACH,KAAK,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;AAE/D,MAAM,WAAW,MAAM;IACrB,KAAK,EAAE,CAAC,GAAG,QAAQ,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACxC,IAAI,EAAE,CAAC,GAAG,QAAQ,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACvC,IAAI,EAAE,CAAC,GAAG,QAAQ,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACvC;;;;;OAKG;IACH,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,KAAK,IAAI,CAAC;IACtE;;;;OAIG;IACH,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,KAAK,IAAI,CAAC;IACtE,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,SAAS,KAAK,IAAI,CAAC;CACpD;AAqFD,wBAAgB,SAAS,CACvB,cAAc,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,OAAO,EAAE,KAAK,IAAI,GAChD,MAAM,CAmBR;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,CAgBtD"}
|
|
@@ -70,6 +70,18 @@ const logger = Object.freeze({
|
|
|
70
70
|
});
|
|
71
71
|
winstonLogger.warn(body);
|
|
72
72
|
},
|
|
73
|
+
infoStructured: (message, attributes) => {
|
|
74
|
+
const body = sanitizeLogMessage(message);
|
|
75
|
+
// Same sanitize-then-emit contract as warnStructured below.
|
|
76
|
+
const safeAttributes = sanitizeLogObject(attributes);
|
|
77
|
+
getTracedLogger().emit({
|
|
78
|
+
severityNumber: SeverityNumber.INFO,
|
|
79
|
+
severityText: "INFO",
|
|
80
|
+
body,
|
|
81
|
+
attributes: safeAttributes,
|
|
82
|
+
});
|
|
83
|
+
winstonLogger.info(body);
|
|
84
|
+
},
|
|
73
85
|
warnStructured: (message, attributes) => {
|
|
74
86
|
const body = sanitizeLogMessage(message);
|
|
75
87
|
// sanitizeLogObject strips secret-named keys and redacts secret values,
|
|
@@ -119,6 +131,7 @@ export function getLogger(loggerOverride) {
|
|
|
119
131
|
// above, it forwards raw args to the supplied function and does NOT
|
|
120
132
|
// sanitize or emit OTel attributes. Production callers use the default
|
|
121
133
|
// logger (and the vite-plugin wrapLogger) which sanitize before emitting.
|
|
134
|
+
infoStructured: (message, attributes) => loggerOverride(message, attributes),
|
|
122
135
|
warnStructured: (message, attributes) => loggerOverride(message, attributes),
|
|
123
136
|
error: loggerOverride,
|
|
124
137
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logging.js","sourceRoot":"","sources":["../../src/telemetry/logging.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAEzD,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAG3D,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAE,SAAS,IAAI,eAAe,EAAE,MAAM,YAAY,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,MAAM,gBAAgB,GAAwB,EAAE,CAAC;AAEjD,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,MAAM,EAAE,CAAC;IAC9C,0DAA0D;IAC1D,uDAAuD;IACvD,gBAAgB,CAAC,IAAI,CACnB,IAAI,UAAU,CAAC,IAAI,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;QACzD,QAAQ,EAAE,qBAAqB;QAC/B,KAAK,EAAE,OAAO;KACf,CAAC,CACH,CAAC;IACF,gBAAgB,CAAC,IAAI,CACnB,IAAI,UAAU,CAAC,OAAO,CAAC;QACrB,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;QACzD,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,yBAAyB,IAAI,MAAM;KACvD,CAAC,CACH,CAAC;AACJ,CAAC;KAAM,CAAC;IACN,6CAA6C;IAC7C,gBAAgB,CAAC,IAAI,CACnB,IAAI,UAAU,CAAC,OAAO,CAAC;QACrB,MAAM,EAAE,MAAM,CAAC,OAAO,CACpB,MAAM,CAAC,SAAS,CAAC;YACf,MAAM,EAAE,cAAc;SACvB,CAAC,EACF,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACtB,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;YACnD,MAAM,IAAI,GAAG,GAAG,SAAS,KAAK,OAAO,CAAC,GAAG,KAAK,OAAO,EAAE,CAAC;YACxD,IAAI,KAAK,KAAK,OAAO,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBAC7C,OAAO,GAAG,IAAI,IAAK,KAA4B,CAAC,OAAO,IAAK,KAA4B,CAAC,KAAK,EAAE,CAAC;YACnG,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,EACF,MAAM,CAAC,QAAQ,EAAE,CAClB;KACF,CAAC,CACH,CAAC;AACJ,CAAC;AAED,MAAM,aAAa,GAAG,YAAY,CAAC;IACjC,KAAK,EAAE,OAAO;IACd,WAAW,EAAE,KAAK;IAClB,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE;IACrB,WAAW,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE;IACjC,UAAU,EAAE,gBAAgB;CAC7B,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"logging.js","sourceRoot":"","sources":["../../src/telemetry/logging.ts"],"names":[],"mappings":"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"}
|
|
@@ -115,6 +115,46 @@ describe("telemetry logger error sanitization", () => {
|
|
|
115
115
|
expect(winstonErrorMock).toHaveBeenCalledWith("sanitized-message:plain failure");
|
|
116
116
|
});
|
|
117
117
|
});
|
|
118
|
+
describe("telemetry logger infoStructured", () => {
|
|
119
|
+
beforeEach(() => {
|
|
120
|
+
vi.clearAllMocks();
|
|
121
|
+
});
|
|
122
|
+
it("emits an INFO record carrying structured attributes (not flattened into the body)", () => {
|
|
123
|
+
const logger = getLogger();
|
|
124
|
+
logger.infoStructured?.("Package installation completed successfully", {
|
|
125
|
+
"superblocks.npm.install.added": 8,
|
|
126
|
+
"superblocks.npm.install.duration_seconds": 32.5,
|
|
127
|
+
"superblocks.npm.install.outcome": "success",
|
|
128
|
+
});
|
|
129
|
+
expect(emitMock).toHaveBeenCalledWith(expect.objectContaining({
|
|
130
|
+
severityText: "INFO",
|
|
131
|
+
body: "sanitized-message:Package installation completed successfully",
|
|
132
|
+
attributes: {
|
|
133
|
+
"superblocks.npm.install.added": 8,
|
|
134
|
+
"superblocks.npm.install.duration_seconds": 32.5,
|
|
135
|
+
"superblocks.npm.install.outcome": "sanitized-object:success",
|
|
136
|
+
},
|
|
137
|
+
}));
|
|
138
|
+
// Winston gets the body only (structured attributes go to OTel, not also
|
|
139
|
+
// to stdout log shippers as a duplicate).
|
|
140
|
+
expect(winstonLoggerMock.info).toHaveBeenCalledWith("sanitized-message:Package installation completed successfully");
|
|
141
|
+
});
|
|
142
|
+
it("strips secret-named attribute keys before emitting", () => {
|
|
143
|
+
const logger = getLogger();
|
|
144
|
+
logger.infoStructured?.("install done", {
|
|
145
|
+
registry: "https://npm.example.com",
|
|
146
|
+
token: "[REDACTED:token]",
|
|
147
|
+
});
|
|
148
|
+
expect(emitMock).toHaveBeenCalledWith(expect.objectContaining({
|
|
149
|
+
attributes: expect.objectContaining({
|
|
150
|
+
registry: "sanitized-object:https://npm.example.com",
|
|
151
|
+
}),
|
|
152
|
+
}));
|
|
153
|
+
expect(emitMock).not.toHaveBeenCalledWith(expect.objectContaining({
|
|
154
|
+
attributes: expect.objectContaining({ token: expect.anything() }),
|
|
155
|
+
}));
|
|
156
|
+
});
|
|
157
|
+
});
|
|
118
158
|
describe("telemetry logger warnStructured", () => {
|
|
119
159
|
beforeEach(() => {
|
|
120
160
|
vi.clearAllMocks();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logging.test.js","sourceRoot":"","sources":["../../src/telemetry/logging.test.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"logging.test.js","sourceRoot":"","sources":["../../src/telemetry/logging.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@superblocksteam/sdk",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.150-next.1",
|
|
4
4
|
"description": "Superblocks JS SDK",
|
|
5
5
|
"homepage": "https://www.superblocks.com",
|
|
6
6
|
"license": "Superblocks Community Software License",
|
|
@@ -57,11 +57,11 @@
|
|
|
57
57
|
"vite-tsconfig-paths": "^6.0.4",
|
|
58
58
|
"winston": "^3.17.0",
|
|
59
59
|
"yaml": "^2.7.1",
|
|
60
|
-
"@superblocksteam/library-shared": "2.0.
|
|
61
|
-
"@superblocksteam/shared": "0.
|
|
62
|
-
"@superblocksteam/telemetry": "2.0.
|
|
63
|
-
"@superblocksteam/
|
|
64
|
-
"@superblocksteam/
|
|
60
|
+
"@superblocksteam/library-shared": "2.0.150-next.1",
|
|
61
|
+
"@superblocksteam/shared": "0.9604.1",
|
|
62
|
+
"@superblocksteam/telemetry": "2.0.150-next.1",
|
|
63
|
+
"@superblocksteam/util": "2.0.150-next.1",
|
|
64
|
+
"@superblocksteam/vite-plugin-file-sync": "2.0.150-next.1"
|
|
65
65
|
},
|
|
66
66
|
"devDependencies": {
|
|
67
67
|
"@eslint/js": "^9.39.2",
|
|
@@ -45,8 +45,21 @@ interface ExecFailure {
|
|
|
45
45
|
message?: string;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
/**
|
|
49
|
+
* `vulnerable_package` is produced only by Clark's install-time vulnerability
|
|
50
|
+
* gate, which runs in the ai-service AppShell — never by the parsers here,
|
|
51
|
+
* which read npm's own JSON/stderr. It is excluded rather than mapped so the
|
|
52
|
+
* registry/network reasons stay exhaustively checked, and folded to `unknown`
|
|
53
|
+
* at the boundary: the CLI has no distinct remediation for an index-blocked
|
|
54
|
+
* install, so a dedicated category would render the same generic guidance.
|
|
55
|
+
*/
|
|
56
|
+
type ParsedBlockedReason = Exclude<
|
|
49
57
|
NpmInstallBlockedReason,
|
|
58
|
+
"vulnerable_package"
|
|
59
|
+
>;
|
|
60
|
+
|
|
61
|
+
const REASON_TO_CATEGORY: Record<
|
|
62
|
+
ParsedBlockedReason,
|
|
50
63
|
DependencyInstallError["category"]
|
|
51
64
|
> = {
|
|
52
65
|
not_in_registry: "not_in_registry",
|
|
@@ -55,6 +68,12 @@ const REASON_TO_CATEGORY: Record<
|
|
|
55
68
|
tls_failed: "tls_failed",
|
|
56
69
|
};
|
|
57
70
|
|
|
71
|
+
function isParsedBlockedReason(
|
|
72
|
+
reason: NpmInstallBlockedReason,
|
|
73
|
+
): reason is ParsedBlockedReason {
|
|
74
|
+
return reason !== "vulnerable_package";
|
|
75
|
+
}
|
|
76
|
+
|
|
58
77
|
const DEP_CONFLICT_CODES = /\b(ERESOLVE|ETARGET|EPEERINVALID)\b/;
|
|
59
78
|
|
|
60
79
|
/** Best-effort: pull package specs out of an ERESOLVE/ETARGET `--json` detail. */
|
|
@@ -91,7 +110,9 @@ function fromBlocked(
|
|
|
91
110
|
return {
|
|
92
111
|
type: "dev-server/dependency-install",
|
|
93
112
|
timestamp: new Date().toISOString(),
|
|
94
|
-
category:
|
|
113
|
+
category: isParsedBlockedReason(b.reason)
|
|
114
|
+
? REASON_TO_CATEGORY[b.reason]
|
|
115
|
+
: "unknown",
|
|
95
116
|
subreason: b.subreason,
|
|
96
117
|
packages: b.packages.map((name) => ({ name })),
|
|
97
118
|
registryHost: b.registryHost,
|
|
@@ -101,6 +122,15 @@ function fromBlocked(
|
|
|
101
122
|
};
|
|
102
123
|
}
|
|
103
124
|
|
|
125
|
+
/** Map a gate/registry `NpmInstallBlocked` into the startup degrade marker. */
|
|
126
|
+
export function initialInstallFailedFromBlocked(
|
|
127
|
+
blocked: NpmInstallBlocked,
|
|
128
|
+
): InitialInstallFailed {
|
|
129
|
+
return new InitialInstallFailed(
|
|
130
|
+
fromBlocked(blocked, scrubSecrets(blocked.message)),
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
|
|
104
134
|
/** Always returns a DependencyInstallError (never null). */
|
|
105
135
|
export function classifyInitialInstallError(
|
|
106
136
|
failure: ExecFailure,
|
|
@@ -196,10 +226,12 @@ export function classifyUpgradeError(
|
|
|
196
226
|
if (blocked) {
|
|
197
227
|
return {
|
|
198
228
|
...base,
|
|
199
|
-
//
|
|
200
|
-
//
|
|
201
|
-
//
|
|
202
|
-
category: blocked.reason
|
|
229
|
+
// Each parsed registry/network reason is also a `DependencyUpgradeError`
|
|
230
|
+
// category, so the reason doubles as the category directly
|
|
231
|
+
// (REASON_TO_CATEGORY is identity here).
|
|
232
|
+
category: isParsedBlockedReason(blocked.reason)
|
|
233
|
+
? blocked.reason
|
|
234
|
+
: "unknown",
|
|
203
235
|
npmErrorCode: blocked.npmErrorCode,
|
|
204
236
|
hasAnyRegistryConfigured: blocked.hasAnyRegistryConfigured,
|
|
205
237
|
};
|
|
@@ -5,6 +5,8 @@ import * as path from "node:path";
|
|
|
5
5
|
|
|
6
6
|
import { beforeEach, describe, expect, it, vi, type Mock } from "vitest";
|
|
7
7
|
|
|
8
|
+
import type * as npmRegistry from "@superblocksteam/vite-plugin-file-sync/npm-registry";
|
|
9
|
+
|
|
8
10
|
import { packageJsonSnapshot } from "./package-json-snapshot.mjs";
|
|
9
11
|
|
|
10
12
|
const execMock = vi.fn();
|
|
@@ -62,6 +64,7 @@ const mockAiServiceState = vi.hoisted(() => ({
|
|
|
62
64
|
npmRegistryClient: undefined as
|
|
63
65
|
| { getConfig: () => Promise<Record<string, unknown>> }
|
|
64
66
|
| undefined,
|
|
67
|
+
remediateDeclaredDependencies: vi.fn(async () => undefined),
|
|
65
68
|
}));
|
|
66
69
|
|
|
67
70
|
vi.mock("../telemetry/logging.js", () => ({
|
|
@@ -81,6 +84,8 @@ vi.mock("../telemetry/index.js", () => ({
|
|
|
81
84
|
) => fn({ end: vi.fn(), setStatus: vi.fn() }),
|
|
82
85
|
),
|
|
83
86
|
}),
|
|
87
|
+
isCloudPrem: false,
|
|
88
|
+
shutdownTelemetry: vi.fn(async () => true),
|
|
84
89
|
}));
|
|
85
90
|
|
|
86
91
|
vi.mock("@opentelemetry/api", () => ({
|
|
@@ -117,6 +122,8 @@ vi.mock("@superblocksteam/vite-plugin-file-sync/ai-service", () => ({
|
|
|
117
122
|
initialize = vi.fn(async () => undefined);
|
|
118
123
|
notifyMigrationAppArtifactsReady = vi.fn();
|
|
119
124
|
removeIntegrationCache = vi.fn(async () => undefined);
|
|
125
|
+
remediateDeclaredDependencies =
|
|
126
|
+
mockAiServiceState.remediateDeclaredDependencies;
|
|
120
127
|
chatSessionStore = { invalidateCache: vi.fn() };
|
|
121
128
|
// `dev.mts` reads this at startup for two paths: `syncHomeNpmrc`
|
|
122
129
|
// (APPS-4231 home `~/.npmrc` writer) and the startup `installPackages`
|
|
@@ -131,24 +138,34 @@ vi.mock("@superblocksteam/vite-plugin-file-sync/ai-service", () => ({
|
|
|
131
138
|
SnapshotManager: class {
|
|
132
139
|
executePendingRestore = vi.fn(async () => false);
|
|
133
140
|
},
|
|
141
|
+
hasEditLifecycleCapability: vi.fn(() => false),
|
|
134
142
|
isSdkApiTemplate: vi.fn(() => false),
|
|
135
143
|
stripResolvedFromLockfile: vi.fn(async () => undefined),
|
|
136
144
|
}));
|
|
137
145
|
|
|
138
|
-
vi.mock("@superblocksteam/vite-plugin-file-sync/npm-registry", () =>
|
|
139
|
-
|
|
140
|
-
//
|
|
141
|
-
//
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
146
|
+
vi.mock("@superblocksteam/vite-plugin-file-sync/npm-registry", async () => {
|
|
147
|
+
// `NpmInstallBlocked` stays real: the startup remediation gate rejects with
|
|
148
|
+
// it and `dev.mts` routes it by `instanceof`, which only holds if the test
|
|
149
|
+
// and the module under test share one class.
|
|
150
|
+
const { NpmInstallBlocked } = await vi.importActual<typeof npmRegistry>(
|
|
151
|
+
"@superblocksteam/vite-plugin-file-sync/npm-registry",
|
|
152
|
+
);
|
|
153
|
+
return {
|
|
154
|
+
NpmInstallBlocked,
|
|
155
|
+
shouldIgnoreInstallScripts: vi.fn(() => false),
|
|
156
|
+
// Used by the dependency-install-classifier reachable from installPackages'
|
|
157
|
+
// catch path (APPS-4450). Previously the only test that hit this codepath
|
|
158
|
+
// (`logs a structured error when the background install fails`) didn't
|
|
159
|
+
// assert classification, so the missing exports surfaced silently as a
|
|
160
|
+
// ReferenceError instead of an InitialInstallFailed. The new
|
|
161
|
+
// restart-vs-degrade test depends on installPackages re-throwing an actual
|
|
162
|
+
// InitialInstallFailed marker, so stub all classifier-required exports.
|
|
163
|
+
scrubSecrets: vi.fn((value: string) => value),
|
|
164
|
+
parseNpmJsonDiagnostic: vi.fn(() => ""),
|
|
165
|
+
parseNpmJsonError: vi.fn(() => null),
|
|
166
|
+
classifyNpmExecStderr: vi.fn(() => null),
|
|
167
|
+
};
|
|
168
|
+
});
|
|
152
169
|
|
|
153
170
|
vi.mock("@superblocksteam/vite-plugin-file-sync/git-service", () => ({
|
|
154
171
|
createGitService: vi.fn(async () => undefined),
|
|
@@ -339,6 +356,10 @@ describe("dev startup after S3 workspace restore", () => {
|
|
|
339
356
|
beforeEach(async () => {
|
|
340
357
|
vi.clearAllMocks();
|
|
341
358
|
mockAiServiceState.npmRegistryClient = undefined;
|
|
359
|
+
mockAiServiceState.remediateDeclaredDependencies.mockReset();
|
|
360
|
+
mockAiServiceState.remediateDeclaredDependencies.mockResolvedValue(
|
|
361
|
+
undefined,
|
|
362
|
+
);
|
|
342
363
|
setupExecMock();
|
|
343
364
|
mockCheckVersions.mockResolvedValue({
|
|
344
365
|
cliUpdated: false,
|
|
@@ -346,6 +367,7 @@ describe("dev startup after S3 workspace restore", () => {
|
|
|
346
367
|
});
|
|
347
368
|
|
|
348
369
|
const { readPackage } = await import("read-pkg");
|
|
370
|
+
(readPackage as Mock).mockReset();
|
|
349
371
|
(readPackage as Mock).mockResolvedValue({
|
|
350
372
|
name: "test-app",
|
|
351
373
|
dependencies: { "@superblocksteam/library": "1.0.0" },
|
|
@@ -357,6 +379,9 @@ describe("dev startup after S3 workspace restore", () => {
|
|
|
357
379
|
|
|
358
380
|
await dev(buildDevOptions() as any);
|
|
359
381
|
|
|
382
|
+
expect(
|
|
383
|
+
mockAiServiceState.remediateDeclaredDependencies,
|
|
384
|
+
).toHaveBeenCalledOnce();
|
|
360
385
|
expect(execMock).not.toHaveBeenCalled();
|
|
361
386
|
expect(mockLogger.info).toHaveBeenCalledWith(
|
|
362
387
|
"Package install decision",
|
|
@@ -368,6 +393,65 @@ describe("dev startup after S3 workspace restore", () => {
|
|
|
368
393
|
);
|
|
369
394
|
});
|
|
370
395
|
|
|
396
|
+
it("installs packages when startup remediation changes package.json", async () => {
|
|
397
|
+
const { readPackage } = await import("read-pkg");
|
|
398
|
+
let packageJson = {
|
|
399
|
+
name: "test-app",
|
|
400
|
+
dependencies: { react: "18.2.0" },
|
|
401
|
+
};
|
|
402
|
+
(readPackage as Mock).mockImplementation(async () => packageJson);
|
|
403
|
+
mockAiServiceState.remediateDeclaredDependencies.mockImplementationOnce(
|
|
404
|
+
async () => {
|
|
405
|
+
packageJson = {
|
|
406
|
+
name: "test-app",
|
|
407
|
+
dependencies: { react: "18.3.1" },
|
|
408
|
+
};
|
|
409
|
+
},
|
|
410
|
+
);
|
|
411
|
+
const { dev } = await import("./dev.mjs");
|
|
412
|
+
|
|
413
|
+
await dev(buildDevOptions() as any);
|
|
414
|
+
|
|
415
|
+
expectInstallToHaveRun();
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
it("does not run the ungated install when startup remediation hard-blocks", async () => {
|
|
419
|
+
const { NpmInstallBlocked } =
|
|
420
|
+
await import("@superblocksteam/vite-plugin-file-sync/npm-registry");
|
|
421
|
+
mockAiServiceState.remediateDeclaredDependencies.mockRejectedValueOnce(
|
|
422
|
+
new NpmInstallBlocked({
|
|
423
|
+
findings: [
|
|
424
|
+
{
|
|
425
|
+
advisoryId: "MAL-2024-test",
|
|
426
|
+
kind: "malware",
|
|
427
|
+
package: "evil@1.0.0",
|
|
428
|
+
},
|
|
429
|
+
],
|
|
430
|
+
packages: ["evil@1.0.0"],
|
|
431
|
+
reason: "vulnerable_package",
|
|
432
|
+
}),
|
|
433
|
+
);
|
|
434
|
+
const { readPackage } = await import("read-pkg");
|
|
435
|
+
(readPackage as Mock).mockResolvedValue({
|
|
436
|
+
name: "test-app",
|
|
437
|
+
dependencies: { evil: "1.0.0" },
|
|
438
|
+
});
|
|
439
|
+
const { dev } = await import("./dev.mjs");
|
|
440
|
+
|
|
441
|
+
await dev(
|
|
442
|
+
buildDevOptions({
|
|
443
|
+
forcePackageInstall: true,
|
|
444
|
+
}) as any,
|
|
445
|
+
);
|
|
446
|
+
|
|
447
|
+
expect(execMock).not.toHaveBeenCalled();
|
|
448
|
+
expect(mockCreateDevServer).toHaveBeenCalled();
|
|
449
|
+
expect(mockLogger.error).toHaveBeenCalledWith(
|
|
450
|
+
"[dev-server] initial dependency install failed; keeping dev server up",
|
|
451
|
+
expect.anything(),
|
|
452
|
+
);
|
|
453
|
+
});
|
|
454
|
+
|
|
371
455
|
it("runs npm install when auto-upgrade only rewrites @superblocksteam/library", async () => {
|
|
372
456
|
const { readPackage } = await import("read-pkg");
|
|
373
457
|
(readPackage as Mock)
|
|
@@ -81,6 +81,8 @@ vi.mock("../telemetry/index.js", () => ({
|
|
|
81
81
|
) => fn({ end: vi.fn(), setStatus: vi.fn() }),
|
|
82
82
|
),
|
|
83
83
|
}),
|
|
84
|
+
isCloudPrem: false,
|
|
85
|
+
shutdownTelemetry: vi.fn(async () => true),
|
|
84
86
|
}));
|
|
85
87
|
|
|
86
88
|
vi.mock("@opentelemetry/api", () => ({
|
|
@@ -117,6 +119,7 @@ vi.mock("@superblocksteam/vite-plugin-file-sync/ai-service", () => ({
|
|
|
117
119
|
initialize = vi.fn(async () => undefined);
|
|
118
120
|
notifyMigrationAppArtifactsReady = vi.fn();
|
|
119
121
|
removeIntegrationCache = vi.fn(async () => undefined);
|
|
122
|
+
remediateDeclaredDependencies = vi.fn(async () => undefined);
|
|
120
123
|
chatSessionStore = { invalidateCache: vi.fn() };
|
|
121
124
|
getNpmRegistryClient = vi.fn(() => undefined);
|
|
122
125
|
},
|
|
@@ -126,6 +129,7 @@ vi.mock("@superblocksteam/vite-plugin-file-sync/ai-service", () => ({
|
|
|
126
129
|
SnapshotManager: class {
|
|
127
130
|
executePendingRestore = vi.fn(async () => false);
|
|
128
131
|
},
|
|
132
|
+
hasEditLifecycleCapability: vi.fn(() => false),
|
|
129
133
|
isSdkApiTemplate: vi.fn(() => false),
|
|
130
134
|
stripResolvedFromLockfile: vi.fn(async () => undefined),
|
|
131
135
|
}));
|