@superblocksteam/sdk 2.0.114 → 2.0.115-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/dev.d.mts.map +1 -1
- package/dist/cli-replacement/dev.mjs +93 -1
- package/dist/cli-replacement/dev.mjs.map +1 -1
- package/dist/dev-utils/dev-server.d.mts.map +1 -1
- package/dist/dev-utils/dev-server.mjs +10 -2
- package/dist/dev-utils/dev-server.mjs.map +1 -1
- package/dist/dev-utils/vite-dev-server-diagnostics.d.mts +61 -0
- package/dist/dev-utils/vite-dev-server-diagnostics.d.mts.map +1 -0
- package/dist/dev-utils/vite-dev-server-diagnostics.mjs +133 -0
- package/dist/dev-utils/vite-dev-server-diagnostics.mjs.map +1 -0
- package/dist/telemetry/logging.d.ts.map +1 -1
- package/dist/telemetry/logging.js +22 -10
- package/dist/telemetry/logging.js.map +1 -1
- package/dist/telemetry/logging.test.d.ts +2 -0
- package/dist/telemetry/logging.test.d.ts.map +1 -0
- package/dist/telemetry/logging.test.js +104 -0
- package/dist/telemetry/logging.test.js.map +1 -0
- package/package.json +7 -7
- package/src/cli-replacement/dev.mts +111 -4
- package/src/dev-utils/dev-server.mts +15 -2
- package/src/dev-utils/vite-dev-server-diagnostics.mts +213 -0
- package/src/telemetry/logging.test.ts +142 -0
- package/src/telemetry/logging.ts +30 -10
- package/test/vite-dev-server-diagnostics.test.mts +336 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/turbo.json +1 -0
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
buildViteBuildErrorLog,
|
|
5
|
+
diagnoseViteBuildLogMessage,
|
|
6
|
+
formatViteBuildErrorLogSummary,
|
|
7
|
+
formatViteDevServerStartedLog,
|
|
8
|
+
logViteBuildError,
|
|
9
|
+
truncateViteRawLog,
|
|
10
|
+
VITE_ERROR_RAW_LOG_MAX_CHARS,
|
|
11
|
+
viteErrorKindForDiagnostic,
|
|
12
|
+
} from "../src/dev-utils/vite-dev-server-diagnostics.mjs";
|
|
13
|
+
|
|
14
|
+
describe("diagnoseViteBuildLogMessage", () => {
|
|
15
|
+
it("detects esbuild could not resolve with double quotes", () => {
|
|
16
|
+
const msg = String.raw`✘ [ERROR] Could not resolve "@opentelemetry/api"
|
|
17
|
+
|
|
18
|
+
node_modules/foo/MetricStorageRegistry.js:28:21:`;
|
|
19
|
+
expect(diagnoseViteBuildLogMessage(msg)).toEqual({
|
|
20
|
+
category: "module_resolve",
|
|
21
|
+
unresolvedSpecifier: "@opentelemetry/api",
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it("detects could not resolve with single quotes", () => {
|
|
26
|
+
expect(
|
|
27
|
+
diagnoseViteBuildLogMessage("Could not resolve 'lodash/missing'"),
|
|
28
|
+
).toEqual({
|
|
29
|
+
category: "module_resolve",
|
|
30
|
+
unresolvedSpecifier: "lodash/missing",
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it("detects optimizeDeps-related output without resolve line", () => {
|
|
35
|
+
expect(
|
|
36
|
+
diagnoseViteBuildLogMessage(
|
|
37
|
+
"Error: optimizeDeps failed during pre-bundling",
|
|
38
|
+
),
|
|
39
|
+
).toEqual({ category: "optimize_deps" });
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it("returns unknown when no pattern matches", () => {
|
|
43
|
+
expect(diagnoseViteBuildLogMessage("Something else broke")).toEqual({
|
|
44
|
+
category: "unknown",
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
describe("formatViteBuildErrorLogSummary", () => {
|
|
50
|
+
it("includes stable tokens and unresolved_specifier when present", () => {
|
|
51
|
+
const summary = formatViteBuildErrorLogSummary({
|
|
52
|
+
diagnostic: {
|
|
53
|
+
category: "module_resolve",
|
|
54
|
+
unresolvedSpecifier: "@opentelemetry/api",
|
|
55
|
+
},
|
|
56
|
+
sdkVersion: "2.0.1",
|
|
57
|
+
viteRootBasename: "my-app",
|
|
58
|
+
});
|
|
59
|
+
expect(summary).toBe(
|
|
60
|
+
"sdk_dev_server_vite_error sdk_version=2.0.1 vite_root=my-app category=module_resolve unresolved_specifier=@opentelemetry/api",
|
|
61
|
+
);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it("quotes values with spaces so log facets stay parseable", () => {
|
|
65
|
+
const summary = formatViteBuildErrorLogSummary({
|
|
66
|
+
diagnostic: {
|
|
67
|
+
category: "module_resolve",
|
|
68
|
+
unresolvedSpecifier: "@scope/pkg with spaces",
|
|
69
|
+
},
|
|
70
|
+
sdkVersion: "2.0.1",
|
|
71
|
+
viteRootBasename: "my app",
|
|
72
|
+
});
|
|
73
|
+
expect(summary).toBe(
|
|
74
|
+
'sdk_dev_server_vite_error sdk_version=2.0.1 vite_root="my app" category=module_resolve unresolved_specifier="@scope/pkg with spaces"',
|
|
75
|
+
);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it("omits unresolved_specifier for optimize_deps diagnostics", () => {
|
|
79
|
+
const summary = formatViteBuildErrorLogSummary({
|
|
80
|
+
diagnostic: {
|
|
81
|
+
category: "optimize_deps",
|
|
82
|
+
},
|
|
83
|
+
sdkVersion: "2.0.1",
|
|
84
|
+
viteRootBasename: "my-app",
|
|
85
|
+
});
|
|
86
|
+
expect(summary).toBe(
|
|
87
|
+
"sdk_dev_server_vite_error sdk_version=2.0.1 vite_root=my-app category=optimize_deps",
|
|
88
|
+
);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it("omits unresolved_specifier for unknown diagnostics", () => {
|
|
92
|
+
const summary = formatViteBuildErrorLogSummary({
|
|
93
|
+
diagnostic: {
|
|
94
|
+
category: "unknown",
|
|
95
|
+
},
|
|
96
|
+
sdkVersion: "2.0.1",
|
|
97
|
+
viteRootBasename: "my-app",
|
|
98
|
+
});
|
|
99
|
+
expect(summary).toBe(
|
|
100
|
+
"sdk_dev_server_vite_error sdk_version=2.0.1 vite_root=my-app category=unknown",
|
|
101
|
+
);
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
describe("viteErrorKindForDiagnostic", () => {
|
|
106
|
+
it("maps categories to stable error kinds", () => {
|
|
107
|
+
expect(
|
|
108
|
+
viteErrorKindForDiagnostic({
|
|
109
|
+
category: "module_resolve",
|
|
110
|
+
unresolvedSpecifier: "x",
|
|
111
|
+
}),
|
|
112
|
+
).toBe("ViteModuleResolveError");
|
|
113
|
+
expect(viteErrorKindForDiagnostic({ category: "optimize_deps" })).toBe(
|
|
114
|
+
"ViteOptimizeDepsError",
|
|
115
|
+
);
|
|
116
|
+
expect(viteErrorKindForDiagnostic({ category: "unknown" })).toBe(
|
|
117
|
+
"ViteBuildError",
|
|
118
|
+
);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it("throws for an unexpected runtime category", () => {
|
|
122
|
+
expect(() =>
|
|
123
|
+
viteErrorKindForDiagnostic({
|
|
124
|
+
category: "unexpected",
|
|
125
|
+
} as unknown as Parameters<typeof viteErrorKindForDiagnostic>[0]),
|
|
126
|
+
).toThrow("Unhandled Vite build diagnostic category: unexpected");
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
describe("formatViteDevServerStartedLog", () => {
|
|
131
|
+
it("emits a single-line ready line for log facets", () => {
|
|
132
|
+
expect(
|
|
133
|
+
formatViteDevServerStartedLog({
|
|
134
|
+
sdkVersion: "2.0.1",
|
|
135
|
+
viteRootBasename: "my-app",
|
|
136
|
+
}),
|
|
137
|
+
).toBe("sdk_dev_server_vite_ready sdk_version=2.0.1 vite_root=my-app");
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it("quotes vite_root when it contains spaces", () => {
|
|
141
|
+
expect(
|
|
142
|
+
formatViteDevServerStartedLog({
|
|
143
|
+
sdkVersion: "2.0.1",
|
|
144
|
+
viteRootBasename: "my app",
|
|
145
|
+
}),
|
|
146
|
+
).toBe('sdk_dev_server_vite_ready sdk_version=2.0.1 vite_root="my app"');
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
describe("buildViteBuildErrorLog", () => {
|
|
151
|
+
it("builds a structured module_resolve payload on the happy path", () => {
|
|
152
|
+
expect(
|
|
153
|
+
buildViteBuildErrorLog({
|
|
154
|
+
rawMessage: 'Could not resolve "@opentelemetry/api"',
|
|
155
|
+
sdkVersion: "2.0.1",
|
|
156
|
+
viteRootBasename: "my-app",
|
|
157
|
+
}),
|
|
158
|
+
).toEqual({
|
|
159
|
+
error: {
|
|
160
|
+
kind: "ViteModuleResolveError",
|
|
161
|
+
message: "Could not resolve: @opentelemetry/api",
|
|
162
|
+
stack: 'Could not resolve "@opentelemetry/api"',
|
|
163
|
+
},
|
|
164
|
+
message:
|
|
165
|
+
"sdk_dev_server_vite_error sdk_version=2.0.1 vite_root=my-app category=module_resolve unresolved_specifier=@opentelemetry/api",
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
it("falls back to a raw error payload if summary formatting fails", () => {
|
|
170
|
+
const result = buildViteBuildErrorLog(
|
|
171
|
+
{
|
|
172
|
+
rawMessage: 'Could not resolve "@opentelemetry/api"',
|
|
173
|
+
sdkVersion: "2.0.1",
|
|
174
|
+
viteRootBasename: "my-app",
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
formatSummary: () => {
|
|
178
|
+
throw new Error("boom");
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
expect(result).toEqual({
|
|
184
|
+
error: {
|
|
185
|
+
kind: "ViteBuildError",
|
|
186
|
+
message: "Vite or esbuild reported an error",
|
|
187
|
+
stack: 'Could not resolve "@opentelemetry/api"',
|
|
188
|
+
},
|
|
189
|
+
message:
|
|
190
|
+
"sdk_dev_server_vite_error sdk_version=2.0.1 vite_root=my-app category=unknown",
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
describe("logViteBuildError", () => {
|
|
196
|
+
it("logs structured message and error metadata on the happy path", () => {
|
|
197
|
+
const calls: Array<{ message: string; meta?: unknown }> = [];
|
|
198
|
+
const logger = {
|
|
199
|
+
error: (message: string, meta?: unknown) => {
|
|
200
|
+
calls.push({ message, meta });
|
|
201
|
+
},
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
logViteBuildError(logger, {
|
|
205
|
+
rawMessage: 'Could not resolve "@opentelemetry/api"',
|
|
206
|
+
sdkVersion: "2.0.1",
|
|
207
|
+
viteRootBasename: "my-app",
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
expect(calls).toEqual([
|
|
211
|
+
{
|
|
212
|
+
message:
|
|
213
|
+
"sdk_dev_server_vite_error sdk_version=2.0.1 vite_root=my-app category=module_resolve unresolved_specifier=@opentelemetry/api",
|
|
214
|
+
meta: {
|
|
215
|
+
error: {
|
|
216
|
+
kind: "ViteModuleResolveError",
|
|
217
|
+
message: "Could not resolve: @opentelemetry/api",
|
|
218
|
+
stack: 'Could not resolve "@opentelemetry/api"',
|
|
219
|
+
},
|
|
220
|
+
},
|
|
221
|
+
},
|
|
222
|
+
]);
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
it("logs the raw vite message if building the structured payload throws", () => {
|
|
226
|
+
const calls: Array<{ message: string; meta?: unknown }> = [];
|
|
227
|
+
const logger = {
|
|
228
|
+
error: (message: string, meta?: unknown) => {
|
|
229
|
+
void meta;
|
|
230
|
+
calls.push({ message, meta });
|
|
231
|
+
},
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
expect(() =>
|
|
235
|
+
logViteBuildError(
|
|
236
|
+
logger,
|
|
237
|
+
{
|
|
238
|
+
rawMessage: 'Could not resolve "@opentelemetry/api"',
|
|
239
|
+
sdkVersion: "2.0.1",
|
|
240
|
+
viteRootBasename: "my-app",
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
build: () => {
|
|
244
|
+
throw new Error("boom");
|
|
245
|
+
},
|
|
246
|
+
},
|
|
247
|
+
),
|
|
248
|
+
).not.toThrow();
|
|
249
|
+
|
|
250
|
+
expect(calls).toEqual([
|
|
251
|
+
{
|
|
252
|
+
message: 'Could not resolve "@opentelemetry/api"',
|
|
253
|
+
meta: {
|
|
254
|
+
error: {
|
|
255
|
+
kind: "ViteDiagnosticsError",
|
|
256
|
+
message: "boom",
|
|
257
|
+
stack: 'Could not resolve "@opentelemetry/api"',
|
|
258
|
+
},
|
|
259
|
+
},
|
|
260
|
+
},
|
|
261
|
+
]);
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
it("falls back with diagnostics context if the structured emit throws", () => {
|
|
265
|
+
const calls: Array<{ message: string; meta?: unknown }> = [];
|
|
266
|
+
let firstCall = true;
|
|
267
|
+
const logger = {
|
|
268
|
+
error: (message: string, meta?: unknown) => {
|
|
269
|
+
if (firstCall) {
|
|
270
|
+
firstCall = false;
|
|
271
|
+
throw new Error("transport failed");
|
|
272
|
+
}
|
|
273
|
+
calls.push({ message, meta });
|
|
274
|
+
},
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
expect(() =>
|
|
278
|
+
logViteBuildError(logger, {
|
|
279
|
+
rawMessage: 'Could not resolve "@opentelemetry/api"',
|
|
280
|
+
sdkVersion: "2.0.1",
|
|
281
|
+
viteRootBasename: "my-app",
|
|
282
|
+
}),
|
|
283
|
+
).not.toThrow();
|
|
284
|
+
|
|
285
|
+
expect(calls).toEqual([
|
|
286
|
+
{
|
|
287
|
+
message: 'Could not resolve "@opentelemetry/api"',
|
|
288
|
+
meta: {
|
|
289
|
+
error: {
|
|
290
|
+
kind: "ViteDiagnosticsError",
|
|
291
|
+
message: "transport failed",
|
|
292
|
+
stack: 'Could not resolve "@opentelemetry/api"',
|
|
293
|
+
},
|
|
294
|
+
},
|
|
295
|
+
},
|
|
296
|
+
]);
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
it("never throws even if the fallback logger throws too", () => {
|
|
300
|
+
let callCount = 0;
|
|
301
|
+
const logger = {
|
|
302
|
+
error: () => {
|
|
303
|
+
callCount += 1;
|
|
304
|
+
throw new Error("logger failed");
|
|
305
|
+
},
|
|
306
|
+
};
|
|
307
|
+
|
|
308
|
+
expect(() =>
|
|
309
|
+
logViteBuildError(logger, {
|
|
310
|
+
rawMessage: 'Could not resolve "@opentelemetry/api"',
|
|
311
|
+
sdkVersion: "2.0.1",
|
|
312
|
+
viteRootBasename: "my-app",
|
|
313
|
+
}),
|
|
314
|
+
).not.toThrow();
|
|
315
|
+
|
|
316
|
+
expect(callCount).toBe(2);
|
|
317
|
+
});
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
describe("truncateViteRawLog", () => {
|
|
321
|
+
it("returns shorter logs unchanged", () => {
|
|
322
|
+
expect(truncateViteRawLog("short")).toBe("short");
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
it("returns exact-boundary logs unchanged", () => {
|
|
326
|
+
const exact = "a".repeat(VITE_ERROR_RAW_LOG_MAX_CHARS);
|
|
327
|
+
expect(truncateViteRawLog(exact)).toBe(exact);
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
it("truncates very long esbuild output", () => {
|
|
331
|
+
const long = "a".repeat(VITE_ERROR_RAW_LOG_MAX_CHARS + 100);
|
|
332
|
+
const out = truncateViteRawLog(long);
|
|
333
|
+
expect(out.length).toBeLessThanOrEqual(VITE_ERROR_RAW_LOG_MAX_CHARS + 30);
|
|
334
|
+
expect(out).toContain("...(truncated)");
|
|
335
|
+
});
|
|
336
|
+
});
|