@superblocksteam/sdk 2.0.83-next.1 → 2.0.83
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/automatic-upgrades.d.ts +6 -0
- package/dist/cli-replacement/automatic-upgrades.d.ts.map +1 -1
- package/dist/cli-replacement/automatic-upgrades.js +27 -5
- package/dist/cli-replacement/automatic-upgrades.js.map +1 -1
- package/dist/cli-replacement/dev.d.mts.map +1 -1
- package/dist/cli-replacement/dev.mjs +217 -260
- package/dist/cli-replacement/dev.mjs.map +1 -1
- package/dist/dev-utils/dev-server.mjs +115 -133
- package/dist/dev-utils/dev-server.mjs.map +1 -1
- package/dist/telemetry/index.d.ts +4 -4
- package/dist/telemetry/index.d.ts.map +1 -1
- package/dist/telemetry/index.js +64 -92
- package/dist/telemetry/index.js.map +1 -1
- package/dist/telemetry/util.d.ts +2 -1
- package/dist/telemetry/util.d.ts.map +1 -1
- package/dist/telemetry/util.js +4 -26
- package/dist/telemetry/util.js.map +1 -1
- package/package.json +5 -6
- package/src/cli-replacement/automatic-upgrades.ts +42 -10
- package/src/cli-replacement/dev.mts +281 -336
- package/src/dev-utils/dev-server.mts +127 -149
- package/src/telemetry/index.ts +83 -105
- package/src/telemetry/util.ts +4 -27
- package/tsconfig.tsbuildinfo +1 -1
- package/turbo.json +2 -20
- package/dist/cli-replacement/version-detection.d.ts +0 -71
- package/dist/cli-replacement/version-detection.d.ts.map +0 -1
- package/dist/cli-replacement/version-detection.js +0 -186
- package/dist/cli-replacement/version-detection.js.map +0 -1
- package/dist/cli-replacement/version-detection.test.d.ts +0 -5
- package/dist/cli-replacement/version-detection.test.d.ts.map +0 -1
- package/dist/cli-replacement/version-detection.test.js +0 -257
- package/dist/cli-replacement/version-detection.test.js.map +0 -1
- package/dist/telemetry/index.test.d.ts +0 -2
- package/dist/telemetry/index.test.d.ts.map +0 -1
- package/dist/telemetry/index.test.js +0 -93
- package/dist/telemetry/index.test.js.map +0 -1
- package/dist/telemetry/local-obs.d.ts +0 -73
- package/dist/telemetry/local-obs.d.ts.map +0 -1
- package/dist/telemetry/local-obs.js +0 -107
- package/dist/telemetry/local-obs.js.map +0 -1
- package/src/cli-replacement/version-detection.test.ts +0 -336
- package/src/cli-replacement/version-detection.ts +0 -220
- package/src/telemetry/index.test.ts +0 -130
- package/src/telemetry/local-obs.ts +0 -138
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeAll, afterAll, beforeEach, } from "vitest";
|
|
2
|
-
// Set environment variables before any imports
|
|
3
|
-
process.env.OTEL_SDK_DISABLED = "true";
|
|
4
|
-
process.env.SUPERBLOCKS_DEPLOYMENT_TYPE = "";
|
|
5
|
-
// Mock dd-trace before importing the module under test
|
|
6
|
-
vi.mock("dd-trace", () => ({
|
|
7
|
-
default: {
|
|
8
|
-
init: vi.fn(),
|
|
9
|
-
llmobs: { enabled: false },
|
|
10
|
-
},
|
|
11
|
-
}));
|
|
12
|
-
// Mock getConfiguration to avoid needing real credentials
|
|
13
|
-
vi.mock("./util.js", () => ({
|
|
14
|
-
SERVICE_NAME: "sdk-dev-server",
|
|
15
|
-
getConfiguration: vi.fn().mockResolvedValue({
|
|
16
|
-
superblocksBaseUrl: new URL("https://app.superblocks.com"),
|
|
17
|
-
otlpBaseUrl: "https://app.superblocks.com/api",
|
|
18
|
-
superblocksHostname: "app.superblocks.com",
|
|
19
|
-
serviceName: "sdk-dev-server",
|
|
20
|
-
token: "test1234",
|
|
21
|
-
}),
|
|
22
|
-
}));
|
|
23
|
-
// Mock the logging module
|
|
24
|
-
vi.mock("./logging.js", () => ({
|
|
25
|
-
getLogger: vi.fn().mockReturnValue({
|
|
26
|
-
info: vi.fn(),
|
|
27
|
-
debug: vi.fn(),
|
|
28
|
-
warn: vi.fn(),
|
|
29
|
-
error: vi.fn(),
|
|
30
|
-
}),
|
|
31
|
-
}));
|
|
32
|
-
describe("CLI SDK Telemetry Integration", () => {
|
|
33
|
-
let telemetryModule;
|
|
34
|
-
beforeAll(async () => {
|
|
35
|
-
// Dynamic import after mocks are set up
|
|
36
|
-
telemetryModule = await import("./index.js");
|
|
37
|
-
});
|
|
38
|
-
afterAll(async () => {
|
|
39
|
-
// Clean up telemetry
|
|
40
|
-
const { resetTelemetry, isTelemetryInitialized, getTelemetryInstance } = await import("@superblocksteam/telemetry");
|
|
41
|
-
if (isTelemetryInitialized()) {
|
|
42
|
-
await getTelemetryInstance().shutdown();
|
|
43
|
-
resetTelemetry();
|
|
44
|
-
}
|
|
45
|
-
});
|
|
46
|
-
beforeEach(() => {
|
|
47
|
-
vi.clearAllMocks();
|
|
48
|
-
});
|
|
49
|
-
describe("configureTelemetry", () => {
|
|
50
|
-
it("successfully initializes telemetry", async () => {
|
|
51
|
-
const { isTelemetryInitialized } = await import("@superblocksteam/telemetry");
|
|
52
|
-
await telemetryModule.configureTelemetry();
|
|
53
|
-
expect(isTelemetryInitialized()).toBe(true);
|
|
54
|
-
});
|
|
55
|
-
it("initializes dd-trace for LLMObs", async () => {
|
|
56
|
-
const ddTrace = await import("dd-trace");
|
|
57
|
-
await telemetryModule.configureTelemetry();
|
|
58
|
-
expect(ddTrace.default.init).toHaveBeenCalled();
|
|
59
|
-
});
|
|
60
|
-
});
|
|
61
|
-
describe("getTracer", () => {
|
|
62
|
-
it("returns working tracer after initialization", async () => {
|
|
63
|
-
await telemetryModule.configureTelemetry();
|
|
64
|
-
const tracer = telemetryModule.getTracer();
|
|
65
|
-
expect(tracer).toBeDefined();
|
|
66
|
-
expect(typeof tracer.startSpan).toBe("function");
|
|
67
|
-
});
|
|
68
|
-
it("can create spans", async () => {
|
|
69
|
-
await telemetryModule.configureTelemetry();
|
|
70
|
-
const tracer = telemetryModule.getTracer();
|
|
71
|
-
const span = tracer.startSpan("test-span");
|
|
72
|
-
expect(span).toBeDefined();
|
|
73
|
-
span.end();
|
|
74
|
-
});
|
|
75
|
-
});
|
|
76
|
-
describe("getLogger", () => {
|
|
77
|
-
it("returns working logger after initialization", async () => {
|
|
78
|
-
await telemetryModule.configureTelemetry();
|
|
79
|
-
const logger = telemetryModule.getLogger();
|
|
80
|
-
expect(logger).toBeDefined();
|
|
81
|
-
expect(typeof logger.emit).toBe("function");
|
|
82
|
-
});
|
|
83
|
-
});
|
|
84
|
-
describe("deploymentType", () => {
|
|
85
|
-
it("exports deploymentType constant", () => {
|
|
86
|
-
expect(telemetryModule.deploymentType).toBeDefined();
|
|
87
|
-
});
|
|
88
|
-
it("exports isCloudPrem constant", () => {
|
|
89
|
-
expect(typeof telemetryModule.isCloudPrem).toBe("boolean");
|
|
90
|
-
});
|
|
91
|
-
});
|
|
92
|
-
});
|
|
93
|
-
//# sourceMappingURL=index.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.test.js","sourceRoot":"","sources":["../../src/telemetry/index.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Local Observability Configuration
|
|
3
|
-
*
|
|
4
|
-
* Provides a single toggle (SUPERBLOCKS_LOCAL_OBS=true) that auto-configures
|
|
5
|
-
* all environment variables needed for local observability testing with the
|
|
6
|
-
* LGTM stack (Loki, Grafana, Tempo, Mimir).
|
|
7
|
-
*
|
|
8
|
-
* This eliminates the need to manually set 9+ environment variables:
|
|
9
|
-
* - SUPERBLOCKS_DEPLOYMENT_TYPE
|
|
10
|
-
* - SUPERBLOCKS_LLMOBS_ENABLED
|
|
11
|
-
* - OTEL_EXPORTER_OTLP_ENDPOINT
|
|
12
|
-
* - SUPERBLOCKS_OTEL_COLLECTOR_URL
|
|
13
|
-
* - DD_LLMOBS_ENABLED
|
|
14
|
-
* - DD_LLMOBS_ML_APP
|
|
15
|
-
* - DD_LLMOBS_AGENTLESS_ENABLED
|
|
16
|
-
* - DD_SITE
|
|
17
|
-
* - DD_API_KEY
|
|
18
|
-
*
|
|
19
|
-
* Usage:
|
|
20
|
-
* SUPERBLOCKS_LOCAL_OBS=true pnpm start:all
|
|
21
|
-
*
|
|
22
|
-
* Or with custom OTEL endpoint:
|
|
23
|
-
* SUPERBLOCKS_LOCAL_OBS=true OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 pnpm start:all
|
|
24
|
-
*/
|
|
25
|
-
import { DeploymentTypeEnum } from "@superblocksteam/shared";
|
|
26
|
-
export interface LocalObsConfig {
|
|
27
|
-
/** Whether local observability mode is enabled */
|
|
28
|
-
enabled: boolean;
|
|
29
|
-
/** OTEL endpoint for traces, metrics, logs */
|
|
30
|
-
otelEndpoint: string;
|
|
31
|
-
/** Deployment type (cloud-prem for local obs) */
|
|
32
|
-
deploymentType: DeploymentTypeEnum.CLOUD_PREM;
|
|
33
|
-
/** LLMObs configuration */
|
|
34
|
-
llmobs: {
|
|
35
|
-
enabled: true;
|
|
36
|
-
mlApp: string;
|
|
37
|
-
agentlessEnabled: true;
|
|
38
|
-
};
|
|
39
|
-
/** Datadog configuration for dd-trace */
|
|
40
|
-
datadog: {
|
|
41
|
-
site: string;
|
|
42
|
-
apiKey: string;
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Checks if local observability mode is enabled.
|
|
47
|
-
*
|
|
48
|
-
* Returns true if:
|
|
49
|
-
* - SUPERBLOCKS_LOCAL_OBS=true (primary toggle)
|
|
50
|
-
* - OR all required env vars are manually configured (legacy mode)
|
|
51
|
-
*/
|
|
52
|
-
export declare function isLocalObsEnabled(): boolean;
|
|
53
|
-
/**
|
|
54
|
-
* Gets the local observability configuration.
|
|
55
|
-
*
|
|
56
|
-
* When SUPERBLOCKS_LOCAL_OBS=true, this returns a complete configuration
|
|
57
|
-
* with sensible defaults for local development. Individual values can still
|
|
58
|
-
* be overridden via environment variables.
|
|
59
|
-
*
|
|
60
|
-
* @returns LocalObsConfig if local obs is enabled, null otherwise
|
|
61
|
-
*/
|
|
62
|
-
export declare function getLocalObsConfig(): LocalObsConfig | null;
|
|
63
|
-
/**
|
|
64
|
-
* Applies local observability configuration to process.env.
|
|
65
|
-
*
|
|
66
|
-
* This ensures that all downstream code that reads env vars directly
|
|
67
|
-
* (like dd-trace auto-initialization) gets the correct values.
|
|
68
|
-
*
|
|
69
|
-
* Should be called early in the application lifecycle, before any
|
|
70
|
-
* telemetry initialization occurs.
|
|
71
|
-
*/
|
|
72
|
-
export declare function applyLocalObsEnvVars(): void;
|
|
73
|
-
//# sourceMappingURL=local-obs.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"local-obs.d.ts","sourceRoot":"","sources":["../../src/telemetry/local-obs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAK7D,MAAM,WAAW,cAAc;IAC7B,kDAAkD;IAClD,OAAO,EAAE,OAAO,CAAC;IACjB,8CAA8C;IAC9C,YAAY,EAAE,MAAM,CAAC;IACrB,iDAAiD;IACjD,cAAc,EAAE,kBAAkB,CAAC,UAAU,CAAC;IAC9C,2BAA2B;IAC3B,MAAM,EAAE;QACN,OAAO,EAAE,IAAI,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;QACd,gBAAgB,EAAE,IAAI,CAAC;KACxB,CAAC;IACF,yCAAyC;IACzC,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAa3C;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,IAAI,cAAc,GAAG,IAAI,CAqBzD;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAwB3C"}
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Local Observability Configuration
|
|
3
|
-
*
|
|
4
|
-
* Provides a single toggle (SUPERBLOCKS_LOCAL_OBS=true) that auto-configures
|
|
5
|
-
* all environment variables needed for local observability testing with the
|
|
6
|
-
* LGTM stack (Loki, Grafana, Tempo, Mimir).
|
|
7
|
-
*
|
|
8
|
-
* This eliminates the need to manually set 9+ environment variables:
|
|
9
|
-
* - SUPERBLOCKS_DEPLOYMENT_TYPE
|
|
10
|
-
* - SUPERBLOCKS_LLMOBS_ENABLED
|
|
11
|
-
* - OTEL_EXPORTER_OTLP_ENDPOINT
|
|
12
|
-
* - SUPERBLOCKS_OTEL_COLLECTOR_URL
|
|
13
|
-
* - DD_LLMOBS_ENABLED
|
|
14
|
-
* - DD_LLMOBS_ML_APP
|
|
15
|
-
* - DD_LLMOBS_AGENTLESS_ENABLED
|
|
16
|
-
* - DD_SITE
|
|
17
|
-
* - DD_API_KEY
|
|
18
|
-
*
|
|
19
|
-
* Usage:
|
|
20
|
-
* SUPERBLOCKS_LOCAL_OBS=true pnpm start:all
|
|
21
|
-
*
|
|
22
|
-
* Or with custom OTEL endpoint:
|
|
23
|
-
* SUPERBLOCKS_LOCAL_OBS=true OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 pnpm start:all
|
|
24
|
-
*/
|
|
25
|
-
import { DeploymentTypeEnum } from "@superblocksteam/shared";
|
|
26
|
-
const DEFAULT_LOCAL_OTEL_ENDPOINT = "http://localhost:24318";
|
|
27
|
-
const DEFAULT_ML_APP_NAME = "superblocks-ai-code-gen";
|
|
28
|
-
/**
|
|
29
|
-
* Checks if local observability mode is enabled.
|
|
30
|
-
*
|
|
31
|
-
* Returns true if:
|
|
32
|
-
* - SUPERBLOCKS_LOCAL_OBS=true (primary toggle)
|
|
33
|
-
* - OR all required env vars are manually configured (legacy mode)
|
|
34
|
-
*/
|
|
35
|
-
export function isLocalObsEnabled() {
|
|
36
|
-
// Primary toggle
|
|
37
|
-
if (process.env.SUPERBLOCKS_LOCAL_OBS === "true") {
|
|
38
|
-
return true;
|
|
39
|
-
}
|
|
40
|
-
// Legacy mode: all env vars manually configured
|
|
41
|
-
const hasLegacyConfig = process.env.SUPERBLOCKS_DEPLOYMENT_TYPE === DeploymentTypeEnum.CLOUD_PREM &&
|
|
42
|
-
process.env.SUPERBLOCKS_LLMOBS_ENABLED === "true" &&
|
|
43
|
-
!!process.env.OTEL_EXPORTER_OTLP_ENDPOINT;
|
|
44
|
-
return hasLegacyConfig;
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Gets the local observability configuration.
|
|
48
|
-
*
|
|
49
|
-
* When SUPERBLOCKS_LOCAL_OBS=true, this returns a complete configuration
|
|
50
|
-
* with sensible defaults for local development. Individual values can still
|
|
51
|
-
* be overridden via environment variables.
|
|
52
|
-
*
|
|
53
|
-
* @returns LocalObsConfig if local obs is enabled, null otherwise
|
|
54
|
-
*/
|
|
55
|
-
export function getLocalObsConfig() {
|
|
56
|
-
if (!isLocalObsEnabled()) {
|
|
57
|
-
return null;
|
|
58
|
-
}
|
|
59
|
-
return {
|
|
60
|
-
enabled: true,
|
|
61
|
-
otelEndpoint: process.env.OTEL_EXPORTER_OTLP_ENDPOINT || DEFAULT_LOCAL_OTEL_ENDPOINT,
|
|
62
|
-
deploymentType: DeploymentTypeEnum.CLOUD_PREM,
|
|
63
|
-
llmobs: {
|
|
64
|
-
enabled: true,
|
|
65
|
-
mlApp: process.env.DD_LLMOBS_ML_APP || DEFAULT_ML_APP_NAME,
|
|
66
|
-
agentlessEnabled: true,
|
|
67
|
-
},
|
|
68
|
-
datadog: {
|
|
69
|
-
site: process.env.DD_SITE || "datadoghq.com",
|
|
70
|
-
// Dummy key for agentless mode - not used when exporting to local OTEL
|
|
71
|
-
apiKey: process.env.DD_API_KEY || "local-dev-dummy-key",
|
|
72
|
-
},
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Applies local observability configuration to process.env.
|
|
77
|
-
*
|
|
78
|
-
* This ensures that all downstream code that reads env vars directly
|
|
79
|
-
* (like dd-trace auto-initialization) gets the correct values.
|
|
80
|
-
*
|
|
81
|
-
* Should be called early in the application lifecycle, before any
|
|
82
|
-
* telemetry initialization occurs.
|
|
83
|
-
*/
|
|
84
|
-
export function applyLocalObsEnvVars() {
|
|
85
|
-
const config = getLocalObsConfig();
|
|
86
|
-
if (!config) {
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
// Apply env vars if not already set (allow explicit overrides)
|
|
90
|
-
const envDefaults = {
|
|
91
|
-
SUPERBLOCKS_DEPLOYMENT_TYPE: config.deploymentType,
|
|
92
|
-
SUPERBLOCKS_LLMOBS_ENABLED: "true",
|
|
93
|
-
OTEL_EXPORTER_OTLP_ENDPOINT: config.otelEndpoint,
|
|
94
|
-
SUPERBLOCKS_OTEL_COLLECTOR_URL: config.otelEndpoint,
|
|
95
|
-
DD_LLMOBS_ENABLED: "1",
|
|
96
|
-
DD_LLMOBS_ML_APP: config.llmobs.mlApp,
|
|
97
|
-
DD_LLMOBS_AGENTLESS_ENABLED: "1",
|
|
98
|
-
DD_SITE: config.datadog.site,
|
|
99
|
-
DD_API_KEY: config.datadog.apiKey,
|
|
100
|
-
};
|
|
101
|
-
for (const [key, value] of Object.entries(envDefaults)) {
|
|
102
|
-
if (!process.env[key]) {
|
|
103
|
-
process.env[key] = value;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
//# sourceMappingURL=local-obs.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"local-obs.js","sourceRoot":"","sources":["../../src/telemetry/local-obs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAE7D,MAAM,2BAA2B,GAAG,wBAAwB,CAAC;AAC7D,MAAM,mBAAmB,GAAG,yBAAyB,CAAC;AAsBtD;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB;IAC/B,iBAAiB;IACjB,IAAI,OAAO,CAAC,GAAG,CAAC,qBAAqB,KAAK,MAAM,EAAE,CAAC;QACjD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,gDAAgD;IAChD,MAAM,eAAe,GACnB,OAAO,CAAC,GAAG,CAAC,2BAA2B,KAAK,kBAAkB,CAAC,UAAU;QACzE,OAAO,CAAC,GAAG,CAAC,0BAA0B,KAAK,MAAM;QACjD,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC;IAE5C,OAAO,eAAe,CAAC;AACzB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB;IAC/B,IAAI,CAAC,iBAAiB,EAAE,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO;QACL,OAAO,EAAE,IAAI;QACb,YAAY,EACV,OAAO,CAAC,GAAG,CAAC,2BAA2B,IAAI,2BAA2B;QACxE,cAAc,EAAE,kBAAkB,CAAC,UAAU;QAC7C,MAAM,EAAE;YACN,OAAO,EAAE,IAAI;YACb,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,mBAAmB;YAC1D,gBAAgB,EAAE,IAAI;SACvB;QACD,OAAO,EAAE;YACP,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,eAAe;YAC5C,uEAAuE;YACvE,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,qBAAqB;SACxD;KACF,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB;IAClC,MAAM,MAAM,GAAG,iBAAiB,EAAE,CAAC;IACnC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO;IACT,CAAC;IAED,+DAA+D;IAC/D,MAAM,WAAW,GAA2B;QAC1C,2BAA2B,EAAE,MAAM,CAAC,cAAc;QAClD,0BAA0B,EAAE,MAAM;QAClC,2BAA2B,EAAE,MAAM,CAAC,YAAY;QAChD,8BAA8B,EAAE,MAAM,CAAC,YAAY;QACnD,iBAAiB,EAAE,GAAG;QACtB,gBAAgB,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK;QACrC,2BAA2B,EAAE,GAAG;QAChC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI;QAC5B,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM;KAClC,CAAC;IAEF,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;QACvD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QAC3B,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -1,336 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for CLI version detection with caching.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import * as child_process from "node:child_process";
|
|
6
|
-
import { describe, it, expect, beforeEach, vi, afterEach } from "vitest";
|
|
7
|
-
import {
|
|
8
|
-
getCurrentCliVersion,
|
|
9
|
-
clearCliVersionCache,
|
|
10
|
-
} from "./version-detection.js";
|
|
11
|
-
|
|
12
|
-
// Mock child_process.exec and execFile
|
|
13
|
-
vi.mock("node:child_process", () => ({
|
|
14
|
-
exec: vi.fn(),
|
|
15
|
-
execFile: vi.fn(),
|
|
16
|
-
}));
|
|
17
|
-
|
|
18
|
-
// Mock logger to suppress console output during tests
|
|
19
|
-
vi.mock("../telemetry/logging.js", () => ({
|
|
20
|
-
getLogger: () => ({
|
|
21
|
-
debug: vi.fn(),
|
|
22
|
-
warn: vi.fn(),
|
|
23
|
-
error: vi.fn(),
|
|
24
|
-
}),
|
|
25
|
-
}));
|
|
26
|
-
|
|
27
|
-
describe("version-detection", () => {
|
|
28
|
-
const originalEnv = process.env;
|
|
29
|
-
|
|
30
|
-
beforeEach(() => {
|
|
31
|
-
// Reset environment and cache before each test
|
|
32
|
-
process.env = { ...originalEnv };
|
|
33
|
-
clearCliVersionCache(); // Clear cache
|
|
34
|
-
vi.clearAllMocks();
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
afterEach(() => {
|
|
38
|
-
// Restore original environment
|
|
39
|
-
process.env = originalEnv;
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
describe("Docker/CSB environment", () => {
|
|
43
|
-
it("should read version from SUPERBLOCKS_CLI_VERSION env var", async () => {
|
|
44
|
-
process.env.SUPERBLOCKS_IS_CSB = "true";
|
|
45
|
-
process.env.SUPERBLOCKS_CLI_VERSION = "2.0.0-next.1";
|
|
46
|
-
|
|
47
|
-
const result = await getCurrentCliVersion();
|
|
48
|
-
|
|
49
|
-
expect(result).toEqual({
|
|
50
|
-
version: "2.0.0-next.1",
|
|
51
|
-
alias: undefined,
|
|
52
|
-
});
|
|
53
|
-
// Should not call subprocess
|
|
54
|
-
expect(child_process.exec).not.toHaveBeenCalled();
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
it("should detect ephemeral builds from SNAPSHOT in version", async () => {
|
|
58
|
-
process.env.SUPERBLOCKS_IS_CSB = "true";
|
|
59
|
-
process.env.SUPERBLOCKS_CLI_VERSION = "2.0.0-SNAPSHOT.ebd2b86d643331f5";
|
|
60
|
-
|
|
61
|
-
const result = await getCurrentCliVersion();
|
|
62
|
-
|
|
63
|
-
expect(result).toEqual({
|
|
64
|
-
version: "2.0.0-SNAPSHOT.ebd2b86d643331f5",
|
|
65
|
-
alias: "@superblocksteam/cli-ephemeral",
|
|
66
|
-
});
|
|
67
|
-
expect(child_process.exec).not.toHaveBeenCalled();
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
it("should fall back to subprocess if env var not set", async () => {
|
|
71
|
-
process.env.SUPERBLOCKS_IS_CSB = "true";
|
|
72
|
-
// No SUPERBLOCKS_CLI_VERSION set
|
|
73
|
-
|
|
74
|
-
// Mock subprocess calls
|
|
75
|
-
const execMock = child_process.exec as unknown as ReturnType<
|
|
76
|
-
typeof vi.fn
|
|
77
|
-
>;
|
|
78
|
-
const execFileMock = child_process.execFile as unknown as ReturnType<
|
|
79
|
-
typeof vi.fn
|
|
80
|
-
>;
|
|
81
|
-
execMock.mockImplementationOnce((_cmd, callback: any) => {
|
|
82
|
-
// which/where command
|
|
83
|
-
callback(null, { stdout: "/usr/local/bin/superblocks\n" });
|
|
84
|
-
});
|
|
85
|
-
execFileMock.mockImplementationOnce((_path, _args, callback: any) => {
|
|
86
|
-
// version command
|
|
87
|
-
callback(null, {
|
|
88
|
-
stdout: JSON.stringify({
|
|
89
|
-
cliVersion: "@superblocksteam/cli/2.0.0-next.1",
|
|
90
|
-
}),
|
|
91
|
-
});
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
const result = await getCurrentCliVersion();
|
|
95
|
-
|
|
96
|
-
expect(result).toEqual({
|
|
97
|
-
version: "2.0.0-next.1",
|
|
98
|
-
});
|
|
99
|
-
expect(child_process.exec).toHaveBeenCalledTimes(1);
|
|
100
|
-
expect(child_process.execFile).toHaveBeenCalledTimes(1);
|
|
101
|
-
});
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
describe("Local environment", () => {
|
|
105
|
-
beforeEach(() => {
|
|
106
|
-
process.env.SUPERBLOCKS_IS_CSB = "false";
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
it("should detect version via subprocess", async () => {
|
|
110
|
-
const execMock = child_process.exec as unknown as ReturnType<
|
|
111
|
-
typeof vi.fn
|
|
112
|
-
>;
|
|
113
|
-
const execFileMock = child_process.execFile as unknown as ReturnType<
|
|
114
|
-
typeof vi.fn
|
|
115
|
-
>;
|
|
116
|
-
execMock.mockImplementationOnce((_cmd, callback: any) => {
|
|
117
|
-
// which/where command
|
|
118
|
-
callback(null, { stdout: "/usr/local/bin/superblocks\n" });
|
|
119
|
-
});
|
|
120
|
-
execFileMock.mockImplementationOnce((_path, _args, callback: any) => {
|
|
121
|
-
// version command
|
|
122
|
-
callback(null, {
|
|
123
|
-
stdout: JSON.stringify({
|
|
124
|
-
cliVersion: "@superblocksteam/cli/2.0.0-next.1",
|
|
125
|
-
}),
|
|
126
|
-
});
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
const result = await getCurrentCliVersion();
|
|
130
|
-
|
|
131
|
-
expect(result).toEqual({
|
|
132
|
-
version: "2.0.0-next.1",
|
|
133
|
-
});
|
|
134
|
-
expect(child_process.exec).toHaveBeenCalledTimes(1);
|
|
135
|
-
expect(child_process.execFile).toHaveBeenCalledTimes(1);
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
it("should detect ephemeral builds with alias", async () => {
|
|
139
|
-
const execMock = child_process.exec as unknown as ReturnType<
|
|
140
|
-
typeof vi.fn
|
|
141
|
-
>;
|
|
142
|
-
const execFileMock = child_process.execFile as unknown as ReturnType<
|
|
143
|
-
typeof vi.fn
|
|
144
|
-
>;
|
|
145
|
-
execMock.mockImplementationOnce((_cmd, callback: any) => {
|
|
146
|
-
callback(null, { stdout: "/usr/local/bin/superblocks\n" });
|
|
147
|
-
});
|
|
148
|
-
execFileMock.mockImplementationOnce((_path, _args, callback: any) => {
|
|
149
|
-
callback(null, {
|
|
150
|
-
stdout: JSON.stringify({
|
|
151
|
-
cliVersion:
|
|
152
|
-
"@superblocksteam/cli-ephemeral/2.0.0-SNAPSHOT.ebd2b86d643331f5",
|
|
153
|
-
}),
|
|
154
|
-
});
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
const result = await getCurrentCliVersion();
|
|
158
|
-
|
|
159
|
-
expect(result).toEqual({
|
|
160
|
-
version: "2.0.0-SNAPSHOT.ebd2b86d643331f5",
|
|
161
|
-
alias: "@superblocksteam/cli-ephemeral",
|
|
162
|
-
});
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
it("should use Windows 'where' command on win32", async () => {
|
|
166
|
-
const originalPlatform = process.platform;
|
|
167
|
-
Object.defineProperty(process, "platform", {
|
|
168
|
-
value: "win32",
|
|
169
|
-
configurable: true,
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
try {
|
|
173
|
-
const execMock = child_process.exec as unknown as ReturnType<
|
|
174
|
-
typeof vi.fn
|
|
175
|
-
>;
|
|
176
|
-
const execFileMock = child_process.execFile as unknown as ReturnType<
|
|
177
|
-
typeof vi.fn
|
|
178
|
-
>;
|
|
179
|
-
execMock.mockImplementationOnce((cmd, callback: any) => {
|
|
180
|
-
expect(cmd).toContain("where superblocks");
|
|
181
|
-
callback(null, { stdout: "C:\\Program Files\\superblocks.exe\n" });
|
|
182
|
-
});
|
|
183
|
-
execFileMock.mockImplementationOnce((_path, _args, callback: any) => {
|
|
184
|
-
callback(null, {
|
|
185
|
-
stdout: JSON.stringify({
|
|
186
|
-
cliVersion: "@superblocksteam/cli/2.0.0-next.1",
|
|
187
|
-
}),
|
|
188
|
-
});
|
|
189
|
-
});
|
|
190
|
-
|
|
191
|
-
await getCurrentCliVersion();
|
|
192
|
-
} finally {
|
|
193
|
-
// Restore platform
|
|
194
|
-
Object.defineProperty(process, "platform", {
|
|
195
|
-
value: originalPlatform,
|
|
196
|
-
configurable: true,
|
|
197
|
-
});
|
|
198
|
-
}
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
it("should return undefined if CLI not found", async () => {
|
|
202
|
-
const execMock = child_process.exec as unknown as ReturnType<
|
|
203
|
-
typeof vi.fn
|
|
204
|
-
>;
|
|
205
|
-
execMock.mockImplementationOnce((_cmd, callback: any) => {
|
|
206
|
-
callback(null, { stdout: "" }); // Empty output = not found
|
|
207
|
-
});
|
|
208
|
-
|
|
209
|
-
const result = await getCurrentCliVersion();
|
|
210
|
-
|
|
211
|
-
expect(result).toBeUndefined();
|
|
212
|
-
// Should only call which/where, not version command
|
|
213
|
-
expect(child_process.exec).toHaveBeenCalledTimes(1);
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
it("should return undefined on error", async () => {
|
|
217
|
-
const execMock = child_process.exec as unknown as ReturnType<
|
|
218
|
-
typeof vi.fn
|
|
219
|
-
>;
|
|
220
|
-
execMock.mockImplementationOnce((_cmd, callback: any) => {
|
|
221
|
-
callback(new Error("Command not found"));
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
const result = await getCurrentCliVersion();
|
|
225
|
-
|
|
226
|
-
expect(result).toBeUndefined();
|
|
227
|
-
});
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
describe("Caching behavior", () => {
|
|
231
|
-
beforeEach(() => {
|
|
232
|
-
process.env.SUPERBLOCKS_IS_CSB = "false";
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
it("should cache successful subprocess result", async () => {
|
|
236
|
-
const execMock = child_process.exec as unknown as ReturnType<
|
|
237
|
-
typeof vi.fn
|
|
238
|
-
>;
|
|
239
|
-
const execFileMock = child_process.execFile as unknown as ReturnType<
|
|
240
|
-
typeof vi.fn
|
|
241
|
-
>;
|
|
242
|
-
execMock.mockImplementationOnce((_cmd, callback: any) => {
|
|
243
|
-
callback(null, { stdout: "/usr/local/bin/superblocks\n" });
|
|
244
|
-
});
|
|
245
|
-
execFileMock.mockImplementationOnce((_path, _args, callback: any) => {
|
|
246
|
-
callback(null, {
|
|
247
|
-
stdout: JSON.stringify({
|
|
248
|
-
cliVersion: "@superblocksteam/cli/2.0.0-next.1",
|
|
249
|
-
}),
|
|
250
|
-
});
|
|
251
|
-
});
|
|
252
|
-
|
|
253
|
-
// First call - should execute subprocess
|
|
254
|
-
const result1 = await getCurrentCliVersion();
|
|
255
|
-
expect(result1).toEqual({ version: "2.0.0-next.1" });
|
|
256
|
-
expect(child_process.exec).toHaveBeenCalledTimes(1);
|
|
257
|
-
expect(child_process.execFile).toHaveBeenCalledTimes(1);
|
|
258
|
-
|
|
259
|
-
// Second call - should use cache
|
|
260
|
-
const result2 = await getCurrentCliVersion();
|
|
261
|
-
expect(result2).toEqual({ version: "2.0.0-next.1" });
|
|
262
|
-
expect(child_process.exec).toHaveBeenCalledTimes(1); // Still 1, not 2
|
|
263
|
-
expect(child_process.execFile).toHaveBeenCalledTimes(1); // Still 1, not 2
|
|
264
|
-
});
|
|
265
|
-
|
|
266
|
-
it("should cache Docker env var result", async () => {
|
|
267
|
-
process.env.SUPERBLOCKS_IS_CSB = "true";
|
|
268
|
-
process.env.SUPERBLOCKS_CLI_VERSION = "2.0.0-next.1";
|
|
269
|
-
|
|
270
|
-
// First call
|
|
271
|
-
const result1 = await getCurrentCliVersion();
|
|
272
|
-
expect(result1).toEqual({ version: "2.0.0-next.1", alias: undefined });
|
|
273
|
-
|
|
274
|
-
// Second call - should use cache
|
|
275
|
-
const result2 = await getCurrentCliVersion();
|
|
276
|
-
expect(result2).toEqual({ version: "2.0.0-next.1", alias: undefined });
|
|
277
|
-
|
|
278
|
-
expect(child_process.exec).not.toHaveBeenCalled();
|
|
279
|
-
});
|
|
280
|
-
|
|
281
|
-
it("should NOT cache failures (allows retry on transient errors)", async () => {
|
|
282
|
-
const execMock = child_process.exec as unknown as ReturnType<
|
|
283
|
-
typeof vi.fn
|
|
284
|
-
>;
|
|
285
|
-
execMock
|
|
286
|
-
.mockImplementationOnce((_cmd, callback: any) => {
|
|
287
|
-
callback(new Error("Not found"));
|
|
288
|
-
})
|
|
289
|
-
.mockImplementationOnce((_cmd, callback: any) => {
|
|
290
|
-
callback(new Error("Still not found"));
|
|
291
|
-
});
|
|
292
|
-
|
|
293
|
-
// First call - should attempt detection and fail
|
|
294
|
-
const result1 = await getCurrentCliVersion();
|
|
295
|
-
expect(result1).toBeUndefined();
|
|
296
|
-
expect(child_process.exec).toHaveBeenCalledTimes(1);
|
|
297
|
-
|
|
298
|
-
// Second call - should retry (not cached) since failures aren't cached
|
|
299
|
-
const result2 = await getCurrentCliVersion();
|
|
300
|
-
expect(result2).toBeUndefined();
|
|
301
|
-
expect(child_process.exec).toHaveBeenCalledTimes(2); // Retried!
|
|
302
|
-
});
|
|
303
|
-
|
|
304
|
-
it("should re-detect after cache is cleared", async () => {
|
|
305
|
-
const execMock = child_process.exec as unknown as ReturnType<
|
|
306
|
-
typeof vi.fn
|
|
307
|
-
>;
|
|
308
|
-
const execFileMock = child_process.execFile as unknown as ReturnType<
|
|
309
|
-
typeof vi.fn
|
|
310
|
-
>;
|
|
311
|
-
execMock.mockImplementation((_cmd, callback: any) => {
|
|
312
|
-
callback(null, { stdout: "/usr/local/bin/superblocks\n" });
|
|
313
|
-
});
|
|
314
|
-
execFileMock.mockImplementation((_path, _args, callback: any) => {
|
|
315
|
-
callback(null, {
|
|
316
|
-
stdout: JSON.stringify({
|
|
317
|
-
cliVersion: "@superblocksteam/cli/2.0.0-next.1",
|
|
318
|
-
}),
|
|
319
|
-
});
|
|
320
|
-
});
|
|
321
|
-
|
|
322
|
-
// First detection
|
|
323
|
-
await getCurrentCliVersion();
|
|
324
|
-
expect(child_process.exec).toHaveBeenCalledTimes(1);
|
|
325
|
-
expect(child_process.execFile).toHaveBeenCalledTimes(1);
|
|
326
|
-
|
|
327
|
-
// Clear cache
|
|
328
|
-
clearCliVersionCache();
|
|
329
|
-
|
|
330
|
-
// Should re-detect
|
|
331
|
-
await getCurrentCliVersion();
|
|
332
|
-
expect(child_process.exec).toHaveBeenCalledTimes(2); // 1 + 1
|
|
333
|
-
expect(child_process.execFile).toHaveBeenCalledTimes(2); // 1 + 1
|
|
334
|
-
});
|
|
335
|
-
});
|
|
336
|
-
});
|