@blaxel/core 0.2.54 → 0.2.55-preview.17

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.
@@ -2,6 +2,7 @@
2
2
  // Browser-compatible exports for Node.js modules
3
3
  // In browser environments, Node.js built-in modules are not available
4
4
  // All Node.js modules are null in browser
5
+ export const crypto = null;
5
6
  export const fs = null;
6
7
  export const os = null;
7
8
  export const path = null;
@@ -1,188 +1,22 @@
1
- import { settings } from "./settings.js";
2
- import * as Sentry from "@sentry/node";
3
- import { makeNodeTransport } from "@sentry/node";
4
- // Isolated Sentry client for SDK-only error tracking (doesn't interfere with user's Sentry)
5
- let sentryClient = null;
6
- const capturedExceptions = new Set();
7
- let handlersRegistered = false;
8
- // SDK path patterns to identify errors originating from our SDK
9
- const SDK_PATTERNS = [
10
- "@blaxel/",
11
- "blaxel-sdk",
12
- "/node_modules/@blaxel/",
13
- "/@blaxel/core/",
14
- "/@blaxel/telemetry/",
15
- ];
1
+ /* eslint-disable */
2
+ // Browser/Edge-compatible exports for Sentry
3
+ // In browser/edge environments, @sentry/node is not available
4
+ // All functions are no-ops
16
5
  /**
17
- * Check if an error originated from the SDK based on its stack trace.
18
- * Returns true if the stack trace contains any SDK-related paths.
19
- */
20
- function isFromSDK(error) {
21
- const stack = error.stack || "";
22
- return SDK_PATTERNS.some((pattern) => stack.includes(pattern));
23
- }
24
- /**
25
- * Initialize an isolated Sentry client for SDK error tracking.
26
- * This creates a separate Sentry instance that won't interfere with any
27
- * Sentry configuration the user might have in their application.
6
+ * Initialize Sentry - no-op in browser/edge environments.
28
7
  */
29
8
  export function initSentry() {
30
- try {
31
- // Check if tracking is disabled
32
- if (!settings.tracking) {
33
- return;
34
- }
35
- const dsn = settings.sentryDsn;
36
- if (!dsn) {
37
- return;
38
- }
39
- // Create an isolated Sentry client that doesn't touch the global scope
40
- // This allows users to have their own Sentry.init() without conflicts
41
- sentryClient = new Sentry.NodeClient({
42
- dsn,
43
- environment: settings.env,
44
- release: `sdk-typescript@${settings.version}`,
45
- transport: makeNodeTransport,
46
- stackParser: Sentry.defaultStackParser,
47
- // No integrations - we handle error capturing manually
48
- integrations: [],
49
- // Disable traces for the SDK client
50
- tracesSampleRate: 0,
51
- // Filter errors before sending - only send SDK errors
52
- beforeSend(event, hint) {
53
- if (event.environment !== 'dev' && event.environment !== 'prod') {
54
- return null;
55
- }
56
- const error = hint.originalException;
57
- if (error instanceof Error) {
58
- if (!isFromSDK(error)) {
59
- // Drop errors that don't originate from SDK
60
- return null;
61
- }
62
- }
63
- return event;
64
- },
65
- });
66
- sentryClient.init();
67
- // Set SDK-specific tags
68
- const scope = new Sentry.Scope();
69
- scope.setTag("blaxel.workspace", settings.workspace);
70
- scope.setTag("blaxel.version", settings.version);
71
- scope.setTag("blaxel.commit", settings.commit);
72
- scope.setClient(sentryClient);
73
- // Register process handlers for uncaught errors (Node.js only)
74
- // Only register once to prevent memory leaks
75
- if (typeof process !== "undefined" &&
76
- typeof process.on === "function" &&
77
- !handlersRegistered) {
78
- handlersRegistered = true;
79
- // For SIGTERM/SIGINT, flush before exit
80
- const signalHandler = (signal) => {
81
- flushSentry(500)
82
- .catch(() => {
83
- // Silently fail
84
- })
85
- .finally(() => {
86
- process.exit(signal === "SIGTERM" ? 143 : 130);
87
- });
88
- };
89
- // Uncaught exception handler - only capture SDK errors
90
- const uncaughtExceptionHandler = (error) => {
91
- if (isFromSDK(error)) {
92
- captureException(error);
93
- }
94
- // Let the default Node.js behavior handle the process exit
95
- };
96
- // Unhandled rejection handler - only capture SDK errors
97
- const unhandledRejectionHandler = (reason) => {
98
- const error = reason instanceof Error ? reason : new Error(String(reason));
99
- if (isFromSDK(error)) {
100
- captureException(error);
101
- }
102
- };
103
- process.on("SIGTERM", () => signalHandler("SIGTERM"));
104
- process.on("SIGINT", () => signalHandler("SIGINT"));
105
- process.on("uncaughtException", uncaughtExceptionHandler);
106
- process.on("unhandledRejection", unhandledRejectionHandler);
107
- // Intercept console.error to capture SDK errors that are caught and logged
108
- const originalConsoleError = console.error;
109
- console.error = function (...args) {
110
- // Call the original console.error first
111
- originalConsoleError.apply(console, args);
112
- // Check if any argument is an Error from SDK and capture it
113
- for (const arg of args) {
114
- if (arg instanceof Error && isFromSDK(arg)) {
115
- captureException(arg);
116
- break; // Only capture the first SDK error to avoid duplicates
117
- }
118
- }
119
- };
120
- }
121
- }
122
- catch (error) {
123
- // Silently fail - Sentry initialization should never break the SDK
124
- if (settings.env !== "production") {
125
- console.error("[Blaxel SDK] Error initializing Sentry:", error);
126
- }
127
- }
128
- }
129
- /**
130
- * Capture an exception to the SDK's isolated Sentry client.
131
- * Only errors originating from SDK code will be captured.
132
- *
133
- * @param error - The error to capture
134
- */
135
- function captureException(error) {
136
- if (sentryClient === null) {
137
- return;
138
- }
139
- // Double-check that error is from SDK (defense in depth)
140
- if (!isFromSDK(error)) {
141
- return;
142
- }
143
- try {
144
- // Create a unique identifier for this exception to avoid duplicates
145
- const errorKey = `${error.name}:${error.message}:${error.stack?.slice(0, 200)}`;
146
- if (capturedExceptions.has(errorKey)) {
147
- return;
148
- }
149
- capturedExceptions.add(errorKey);
150
- // Clean up old exception keys to prevent memory leak
151
- if (capturedExceptions.size > 1000) {
152
- capturedExceptions.clear();
153
- }
154
- // Create a scope with SDK tags and capture the exception
155
- const scope = new Sentry.Scope();
156
- scope.setTag("blaxel.workspace", settings.workspace);
157
- scope.setTag("blaxel.version", settings.version);
158
- scope.setTag("blaxel.commit", settings.commit);
159
- scope.setClient(sentryClient);
160
- scope.captureException(error);
161
- }
162
- catch {
163
- // Silently fail - error capturing should never break the SDK
164
- }
9
+ // No-op in browser/edge environments
165
10
  }
166
11
  /**
167
- * Flush pending Sentry events.
168
- * This should be called before the process exits to ensure all events are sent.
169
- *
170
- * @param timeout - Maximum time in milliseconds to wait for flush (default: 2000)
12
+ * Flush pending Sentry events - no-op in browser/edge environments.
171
13
  */
172
- export async function flushSentry(timeout = 2000) {
173
- if (sentryClient === null) {
174
- return;
175
- }
176
- try {
177
- await sentryClient.flush(timeout);
178
- }
179
- catch {
180
- // Silently fail
181
- }
14
+ export async function flushSentry(_timeout = 2000) {
15
+ // No-op in browser/edge environments
182
16
  }
183
17
  /**
184
- * Check if Sentry is initialized and available.
18
+ * Check if Sentry is initialized - always returns false in browser/edge environments.
185
19
  */
186
20
  export function isSentryInitialized() {
187
- return sentryClient !== null;
21
+ return false;
188
22
  }
@@ -3,8 +3,8 @@ import { authentication } from "../authentication/index.js";
3
3
  import { env } from "../common/env.js";
4
4
  import { fs, os, path } from "../common/node.js";
5
5
  // Build info - these placeholders are replaced at build time by build:replace-imports
6
- const BUILD_VERSION = "0.2.54";
7
- const BUILD_COMMIT = "36d148e9b7f9dd2134c772d954c8297b3c958ec3";
6
+ const BUILD_VERSION = "0.2.55-preview.17";
7
+ const BUILD_COMMIT = "1efcf3565af2e54805e7526888bebaf2347c5886";
8
8
  const BUILD_SENTRY_DSN = "https://fd5e60e1c9820e1eef5ccebb84a07127@o4508714045276160.ingest.us.sentry.io/4510465864564736";
9
9
  // Cache for config.yaml tracking value
10
10
  let configTrackingValue = null;
@@ -163,8 +163,9 @@ class Settings {
163
163
  }
164
164
  get tracking() {
165
165
  // Environment variable has highest priority
166
- if (env.BL_TRACKING !== undefined) {
167
- return env.BL_TRACKING === "true";
166
+ if (env.DO_NOT_TRACK !== undefined) {
167
+ // DO_NOT_TRACK has inverted semantics: true means tracking disabled
168
+ return env.DO_NOT_TRACK !== "true" && env.DO_NOT_TRACK !== "1";
168
169
  }
169
170
  // Then check config.yaml
170
171
  const configValue = getConfigTracking();
@@ -1,4 +1,4 @@
1
- import { createHmac, timingSafeEqual } from 'crypto';
1
+ import { crypto } from './node.js';
2
2
  /**
3
3
  * Verify the HMAC-SHA256 signature of a webhook callback from async-sidecar
4
4
  *
@@ -31,6 +31,10 @@ export function verifyWebhookSignature(options) {
31
31
  if (!body || !signature || !secret) {
32
32
  return false;
33
33
  }
34
+ // crypto is only available in Node.js environments
35
+ if (!crypto) {
36
+ throw new Error('verifyWebhookSignature is only available in Node.js environments');
37
+ }
34
38
  try {
35
39
  // Verify timestamp if provided (prevents replay attacks)
36
40
  if (timestamp) {
@@ -44,11 +48,11 @@ export function verifyWebhookSignature(options) {
44
48
  // Extract hex signature from "sha256=<hex>" format
45
49
  const expectedSignature = signature.replace('sha256=', '');
46
50
  // Compute HMAC-SHA256 signature
47
- const hmac = createHmac('sha256', secret);
51
+ const hmac = crypto.createHmac('sha256', secret);
48
52
  hmac.update(body);
49
53
  const computedSignature = hmac.digest('hex');
50
54
  // Timing-safe comparison to prevent timing attacks
51
- return timingSafeEqual(Buffer.from(expectedSignature, 'hex'), Buffer.from(computedSignature, 'hex'));
55
+ return crypto.timingSafeEqual(Buffer.from(expectedSignature, 'hex'), Buffer.from(computedSignature, 'hex'));
52
56
  }
53
57
  catch {
54
58
  // Invalid signature format or other error
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blaxel/core",
3
- "version": "0.2.54",
3
+ "version": "0.2.55-preview.17",
4
4
  "description": "Blaxel Core SDK for TypeScript",
5
5
  "license": "MIT",
6
6
  "author": "Blaxel, INC (https://blaxel.ai)",
@@ -53,7 +53,6 @@
53
53
  "dependencies": {
54
54
  "@hey-api/client-fetch": "^0.10.0",
55
55
  "@modelcontextprotocol/sdk": "^1.20.0",
56
- "@sentry/node": "^10.27.0",
57
56
  "axios": "^1.9.0",
58
57
  "dotenv": "^16.5.0",
59
58
  "form-data": "^4.0.2",
@@ -64,6 +63,9 @@
64
63
  "yaml": "^2.7.1",
65
64
  "zod": "^3.24.3"
66
65
  },
66
+ "optionalDependencies": {
67
+ "@sentry/node": "^10.27.0"
68
+ },
67
69
  "devDependencies": {
68
70
  "@eslint/js": "^9.26.0",
69
71
  "@testing-library/dom": "^9.3.0",