@blaxel/core 0.2.52-dev.9 → 0.2.52-preview.127

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.
Files changed (57) hide show
  1. package/dist/cjs/.tsbuildinfo +1 -1
  2. package/dist/cjs/common/autoload.js +0 -3
  3. package/dist/cjs/common/settings.js +47 -13
  4. package/dist/cjs/common/webhook.js +101 -0
  5. package/dist/cjs/index.js +1 -0
  6. package/dist/cjs/sandbox/client/sdk.gen.js +1 -124
  7. package/dist/cjs/sandbox/filesystem/filesystem.js +1 -81
  8. package/dist/cjs/types/client/types.gen.d.ts +12 -0
  9. package/dist/cjs/types/common/settings.d.ts +1 -2
  10. package/dist/cjs/types/common/webhook.d.ts +89 -0
  11. package/dist/cjs/types/index.d.ts +1 -0
  12. package/dist/cjs/types/sandbox/client/sdk.gen.d.ts +1 -36
  13. package/dist/cjs/types/sandbox/client/types.gen.d.ts +0 -315
  14. package/dist/cjs/types/sandbox/filesystem/filesystem.d.ts +2 -5
  15. package/dist/cjs/types/sandbox/filesystem/types.d.ts +0 -20
  16. package/dist/cjs-browser/.tsbuildinfo +1 -1
  17. package/dist/cjs-browser/common/autoload.js +0 -3
  18. package/dist/cjs-browser/common/settings.js +47 -13
  19. package/dist/cjs-browser/common/webhook.js +101 -0
  20. package/dist/cjs-browser/index.js +1 -0
  21. package/dist/cjs-browser/sandbox/client/sdk.gen.js +1 -124
  22. package/dist/cjs-browser/sandbox/filesystem/filesystem.js +1 -81
  23. package/dist/cjs-browser/types/client/types.gen.d.ts +12 -0
  24. package/dist/cjs-browser/types/common/settings.d.ts +1 -2
  25. package/dist/cjs-browser/types/common/webhook.d.ts +89 -0
  26. package/dist/cjs-browser/types/index.d.ts +1 -0
  27. package/dist/cjs-browser/types/sandbox/client/sdk.gen.d.ts +1 -36
  28. package/dist/cjs-browser/types/sandbox/client/types.gen.d.ts +0 -315
  29. package/dist/cjs-browser/types/sandbox/filesystem/filesystem.d.ts +2 -5
  30. package/dist/cjs-browser/types/sandbox/filesystem/types.d.ts +0 -20
  31. package/dist/esm/.tsbuildinfo +1 -1
  32. package/dist/esm/common/autoload.js +0 -3
  33. package/dist/esm/common/settings.js +47 -13
  34. package/dist/esm/common/webhook.js +97 -0
  35. package/dist/esm/index.js +1 -0
  36. package/dist/esm/sandbox/client/sdk.gen.js +0 -116
  37. package/dist/esm/sandbox/filesystem/filesystem.js +2 -82
  38. package/dist/esm-browser/.tsbuildinfo +1 -1
  39. package/dist/esm-browser/common/autoload.js +0 -3
  40. package/dist/esm-browser/common/settings.js +47 -13
  41. package/dist/esm-browser/common/webhook.js +97 -0
  42. package/dist/esm-browser/index.js +1 -0
  43. package/dist/esm-browser/sandbox/client/sdk.gen.js +0 -116
  44. package/dist/esm-browser/sandbox/filesystem/filesystem.js +2 -82
  45. package/package.json +5 -4
  46. package/dist/cjs/common/sentry.js +0 -219
  47. package/dist/cjs/common/version.js +0 -6
  48. package/dist/cjs/types/common/sentry.d.ts +0 -17
  49. package/dist/cjs/types/common/version.d.ts +0 -2
  50. package/dist/cjs-browser/common/sentry.js +0 -219
  51. package/dist/cjs-browser/common/version.js +0 -6
  52. package/dist/cjs-browser/types/common/sentry.d.ts +0 -17
  53. package/dist/cjs-browser/types/common/version.d.ts +0 -2
  54. package/dist/esm/common/sentry.js +0 -181
  55. package/dist/esm/common/version.js +0 -3
  56. package/dist/esm-browser/common/sentry.js +0 -181
  57. package/dist/esm-browser/common/version.js +0 -3
@@ -2,7 +2,6 @@ import { client } from "../client/client.gen.js";
2
2
  import { interceptors } from "../client/interceptors.js";
3
3
  import { responseInterceptors } from "../client/responseInterceptor.js";
4
4
  import { client as clientSandbox } from "../sandbox/client/client.gen.js";
5
- import { initSentry } from "./sentry.js";
6
5
  import { settings } from "./settings.js";
7
6
  client.setConfig({
8
7
  baseUrl: settings.baseUrl,
@@ -19,8 +18,6 @@ for (const interceptor of responseInterceptors) {
19
18
  client.interceptors.response.use(interceptor);
20
19
  clientSandbox.interceptors.response.use(interceptor);
21
20
  }
22
- // Initialize Sentry for SDK error tracking immediately when module loads
23
- initSentry();
24
21
  // Allow to set custom configuration for browser environment
25
22
  export function initialize(config) {
26
23
  settings.setConfig(config);
@@ -1,9 +1,25 @@
1
1
  import { authentication } from "../authentication/index.js";
2
2
  import { env } from "../common/env.js";
3
- // Build info - these placeholders are replaced at build time by build:replace-imports
4
- const BUILD_VERSION = "0.2.52-dev.9";
5
- const BUILD_COMMIT = "106270f8890bd85e35e0f6b3f9701c0c6ad9b3cf";
6
- const BUILD_SENTRY_DSN = "https://fd5e60e1c9820e1eef5ccebb84a07127@o4508714045276160.ingest.us.sentry.io/4510465864564736";
3
+ // Function to get package version
4
+ function getPackageVersion() {
5
+ try {
6
+ // Check if require is available (CommonJS environment)
7
+ if (typeof require !== "undefined") {
8
+ // Try to require package.json (Node.js only, gracefully fails in browser)
9
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
10
+ const packageJson = {"version":"0.2.52-preview.127","commit":"4acd7b5efa6c9e04c5131f55e7a87029c4889b1d"};
11
+ return packageJson.version || "unknown";
12
+ }
13
+ else {
14
+ // ESM environment - return unknown
15
+ return "unknown";
16
+ }
17
+ }
18
+ catch {
19
+ // Fallback for browser environments or if require fails
20
+ return "unknown";
21
+ }
22
+ }
7
23
  // Function to get OS and architecture
8
24
  function getOsArch() {
9
25
  try {
@@ -36,9 +52,30 @@ function getOsArch() {
36
52
  }
37
53
  return "browser/unknown";
38
54
  }
55
+ // Function to get commit hash
56
+ function getCommitHash() {
57
+ try {
58
+ // Check if require is available (CommonJS environment)
59
+ if (typeof require !== "undefined") {
60
+ // Try to require package.json and look for commit field (set during build)
61
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
62
+ const packageJson = {"version":"0.2.52-preview.127","commit":"4acd7b5efa6c9e04c5131f55e7a87029c4889b1d"};
63
+ // Check for commit in various possible locations
64
+ const commit = packageJson.commit || packageJson.buildInfo?.commit;
65
+ if (commit) {
66
+ return commit.length > 7 ? commit.substring(0, 7) : commit;
67
+ }
68
+ }
69
+ }
70
+ catch {
71
+ // Fallback for browser environments or if require fails
72
+ }
73
+ return "unknown";
74
+ }
39
75
  class Settings {
40
76
  credentials;
41
77
  config;
78
+ _version = null;
42
79
  constructor() {
43
80
  this.credentials = authentication();
44
81
  this.config = {
@@ -93,21 +130,18 @@ class Settings {
93
130
  return this.credentials.token;
94
131
  }
95
132
  get version() {
96
- return BUILD_VERSION || "unknown";
97
- }
98
- get commit() {
99
- const commit = BUILD_COMMIT || "unknown";
100
- return commit.length > 7 ? commit.substring(0, 7) : commit;
101
- }
102
- get sentryDsn() {
103
- return BUILD_SENTRY_DSN || "";
133
+ if (this._version === null) {
134
+ this._version = getPackageVersion();
135
+ }
136
+ return this._version;
104
137
  }
105
138
  get headers() {
106
139
  const osArch = getOsArch();
140
+ const commitHash = getCommitHash();
107
141
  return {
108
142
  "x-blaxel-authorization": this.authorization,
109
143
  "x-blaxel-workspace": this.workspace || "",
110
- "User-Agent": `blaxel/sdk/typescript/${this.version} (${osArch}) blaxel/${this.commit}`,
144
+ "User-Agent": `blaxel/sdk/typescript/${this.version} (${osArch}) blaxel/${commitHash}`,
111
145
  };
112
146
  }
113
147
  get name() {
@@ -0,0 +1,97 @@
1
+ import { createHmac, timingSafeEqual } from 'crypto';
2
+ /**
3
+ * Verify the HMAC-SHA256 signature of a webhook callback from async-sidecar
4
+ *
5
+ * @example
6
+ * ```typescript
7
+ * import { verifyWebhookSignature } from '@blaxel/core';
8
+ *
9
+ * // In your Express endpoint
10
+ * app.post('/webhook', express.text({ type: 'application/json' }), (req, res) => {
11
+ * const isValid = verifyWebhookSignature({
12
+ * body: req.body,
13
+ * signature: req.headers['x-blaxel-signature'] as string,
14
+ * secret: process.env.CALLBACK_SECRET!
15
+ * });
16
+ *
17
+ * if (!isValid) {
18
+ * return res.status(401).json({ error: 'Invalid signature' });
19
+ * }
20
+ *
21
+ * const data = JSON.parse(req.body);
22
+ * // Process callback...
23
+ * });
24
+ * ```
25
+ *
26
+ * @param options - Verification options
27
+ * @returns true if the signature is valid, false otherwise
28
+ */
29
+ export function verifyWebhookSignature(options) {
30
+ const { body, signature, secret, timestamp, maxAge = 300 } = options;
31
+ if (!body || !signature || !secret) {
32
+ return false;
33
+ }
34
+ try {
35
+ // Verify timestamp if provided (prevents replay attacks)
36
+ if (timestamp) {
37
+ const requestTime = parseInt(timestamp, 10);
38
+ const currentTime = Math.floor(Date.now() / 1000);
39
+ const age = Math.abs(currentTime - requestTime);
40
+ if (isNaN(requestTime) || age > maxAge) {
41
+ return false;
42
+ }
43
+ }
44
+ // Extract hex signature from "sha256=<hex>" format
45
+ const expectedSignature = signature.replace('sha256=', '');
46
+ // Compute HMAC-SHA256 signature
47
+ const hmac = createHmac('sha256', secret);
48
+ hmac.update(body);
49
+ const computedSignature = hmac.digest('hex');
50
+ // Timing-safe comparison to prevent timing attacks
51
+ return timingSafeEqual(Buffer.from(expectedSignature, 'hex'), Buffer.from(computedSignature, 'hex'));
52
+ }
53
+ catch {
54
+ // Invalid signature format or other error
55
+ return false;
56
+ }
57
+ }
58
+ /**
59
+ * Helper to verify webhook from Express request object
60
+ *
61
+ * @example
62
+ * ```typescript
63
+ * import { verifyWebhookFromRequest } from '@blaxel/core';
64
+ * import express from 'express';
65
+ *
66
+ * app.use(express.text({ type: 'application/json' }));
67
+ *
68
+ * app.post('/webhook', (req, res) => {
69
+ * if (!verifyWebhookFromRequest(req, process.env.CALLBACK_SECRET!)) {
70
+ * return res.status(401).json({ error: 'Invalid signature' });
71
+ * }
72
+ *
73
+ * const data = JSON.parse(req.body);
74
+ * console.log('Received callback:', data);
75
+ * res.json({ received: true });
76
+ * });
77
+ * ```
78
+ *
79
+ * @param request - Express request object (must use express.text() middleware)
80
+ * @param secret - The callback secret
81
+ * @param maxAge - Optional maximum age in seconds (default: 300)
82
+ * @returns true if the signature is valid, false otherwise
83
+ */
84
+ export function verifyWebhookFromRequest(request, secret, maxAge) {
85
+ const signature = request.headers['x-blaxel-signature'];
86
+ const timestamp = request.headers['x-blaxel-timestamp'];
87
+ if (typeof signature !== 'string') {
88
+ return false;
89
+ }
90
+ return verifyWebhookSignature({
91
+ body: request.body,
92
+ signature,
93
+ secret,
94
+ timestamp: typeof timestamp === 'string' ? timestamp : undefined,
95
+ maxAge
96
+ });
97
+ }
package/dist/esm/index.js CHANGED
@@ -8,6 +8,7 @@ export * from "./common/errors.js";
8
8
  export * from "./common/internal.js";
9
9
  export * from "./common/logger.js";
10
10
  export * from "./common/settings.js";
11
+ export * from "./common/webhook.js";
11
12
  export * from "./jobs/index.js";
12
13
  export * from "./mcp/index.js";
13
14
  export * from "./models/index.js";
@@ -164,38 +164,6 @@ export const getCodegenRerankingByPath = (options) => {
164
164
  ...options
165
165
  });
166
166
  };
167
- /**
168
- * Search for text content in files
169
- * Searches for text content inside files using ripgrep. Returns matching lines with context.
170
- */
171
- export const getFilesystemContentSearchByPath = (options) => {
172
- return (options.client ?? _heyApiClient).get({
173
- security: [
174
- {
175
- scheme: 'bearer',
176
- type: 'http'
177
- }
178
- ],
179
- url: '/filesystem-content-search/{path}',
180
- ...options
181
- });
182
- };
183
- /**
184
- * Find files and directories
185
- * Finds files and directories using the find command.
186
- */
187
- export const getFilesystemFindByPath = (options) => {
188
- return (options.client ?? _heyApiClient).get({
189
- security: [
190
- {
191
- scheme: 'bearer',
192
- type: 'http'
193
- }
194
- ],
195
- url: '/filesystem-find/{path}',
196
- ...options
197
- });
198
- };
199
167
  /**
200
168
  * List multipart uploads
201
169
  * List all active multipart uploads
@@ -305,22 +273,6 @@ export const postFilesystemMultipartInitiateByPath = (options) => {
305
273
  }
306
274
  });
307
275
  };
308
- /**
309
- * Fuzzy search for files and directories
310
- * Performs fuzzy search on filesystem paths using fuzzy matching algorithm. Optimized alternative to find and grep commands.
311
- */
312
- export const getFilesystemSearchByPath = (options) => {
313
- return (options.client ?? _heyApiClient).get({
314
- security: [
315
- {
316
- scheme: 'bearer',
317
- type: 'http'
318
- }
319
- ],
320
- url: '/filesystem-search/{path}',
321
- ...options
322
- });
323
- };
324
276
  /**
325
277
  * Delete file or directory
326
278
  * Delete a file or directory
@@ -373,58 +325,6 @@ export const putFilesystemByPath = (options) => {
373
325
  }
374
326
  });
375
327
  };
376
- /**
377
- * Delete directory tree
378
- * Delete a directory tree recursively
379
- */
380
- export const deleteFilesystemTreeByPath = (options) => {
381
- return (options.client ?? _heyApiClient).delete({
382
- security: [
383
- {
384
- scheme: 'bearer',
385
- type: 'http'
386
- }
387
- ],
388
- url: '/filesystem/tree/{path}',
389
- ...options
390
- });
391
- };
392
- /**
393
- * Get directory tree
394
- * Get a recursive directory tree structure starting from the specified path
395
- */
396
- export const getFilesystemTreeByPath = (options) => {
397
- return (options.client ?? _heyApiClient).get({
398
- security: [
399
- {
400
- scheme: 'bearer',
401
- type: 'http'
402
- }
403
- ],
404
- url: '/filesystem/tree/{path}',
405
- ...options
406
- });
407
- };
408
- /**
409
- * Create or update directory tree
410
- * Create or update multiple files within a directory tree structure
411
- */
412
- export const putFilesystemTreeByPath = (options) => {
413
- return (options.client ?? _heyApiClient).put({
414
- security: [
415
- {
416
- scheme: 'bearer',
417
- type: 'http'
418
- }
419
- ],
420
- url: '/filesystem/tree/{path}',
421
- ...options,
422
- headers: {
423
- 'Content-Type': 'application/json',
424
- ...options?.headers
425
- }
426
- });
427
- };
428
328
  /**
429
329
  * Stop monitoring ports for a process
430
330
  * Stop monitoring for new ports opened by a process
@@ -609,19 +509,3 @@ export const getWatchFilesystemByPath = (options) => {
609
509
  ...options
610
510
  });
611
511
  };
612
- /**
613
- * WebSocket endpoint
614
- * WebSocket endpoint for all sandbox operations
615
- */
616
- export const getWs = (options) => {
617
- return (options?.client ?? _heyApiClient).get({
618
- security: [
619
- {
620
- scheme: 'bearer',
621
- type: 'http'
622
- }
623
- ],
624
- url: '/ws',
625
- ...options
626
- });
627
- };
@@ -1,7 +1,7 @@
1
- import { fs } from "../../common/node.js";
2
1
  import { settings } from "../../common/settings.js";
2
+ import { fs } from "../../common/node.js";
3
3
  import { SandboxAction } from "../action.js";
4
- import { deleteFilesystemByPath, deleteFilesystemMultipartByUploadIdAbort, getFilesystemByPath, getFilesystemContentSearchByPath, getFilesystemFindByPath, getFilesystemSearchByPath, getWatchFilesystemByPath, postFilesystemMultipartByUploadIdComplete, postFilesystemMultipartInitiateByPath, putFilesystemByPath, putFilesystemMultipartByUploadIdPart } from "../client/index.js";
4
+ import { deleteFilesystemByPath, getFilesystemByPath, getWatchFilesystemByPath, putFilesystemByPath, postFilesystemMultipartInitiateByPath, putFilesystemMultipartByUploadIdPart, postFilesystemMultipartByUploadIdComplete, deleteFilesystemMultipartByUploadIdAbort } from "../client/index.js";
5
5
  // Multipart upload constants
6
6
  const MULTIPART_THRESHOLD = 5 * 1024 * 1024; // 5MB
7
7
  const CHUNK_SIZE = 5 * 1024 * 1024; // 5MB per part
@@ -196,86 +196,6 @@ export class SandboxFileSystem extends SandboxAction {
196
196
  }
197
197
  return data;
198
198
  }
199
- async search(query, path = "/", options) {
200
- const formattedPath = this.formatPath(path);
201
- const queryParams = {};
202
- if (options?.maxResults !== undefined) {
203
- queryParams.maxResults = options.maxResults;
204
- }
205
- if (options?.patterns && options.patterns.length > 0) {
206
- queryParams.patterns = options.patterns.join(',');
207
- }
208
- if (options?.excludeDirs && options.excludeDirs.length > 0) {
209
- queryParams.excludeDirs = options.excludeDirs.join(',');
210
- }
211
- if (options?.excludeHidden !== undefined) {
212
- queryParams.excludeHidden = options.excludeHidden;
213
- }
214
- const result = await getFilesystemSearchByPath({
215
- path: { path: formattedPath },
216
- query: queryParams,
217
- baseUrl: this.url,
218
- client: this.client,
219
- });
220
- this.handleResponseError(result.response, result.data, result.error);
221
- return result.data;
222
- }
223
- async find(path, options) {
224
- const formattedPath = this.formatPath(path);
225
- const queryParams = {};
226
- if (options?.type) {
227
- queryParams.type = options.type;
228
- }
229
- if (options?.patterns && options.patterns.length > 0) {
230
- queryParams.patterns = options.patterns.join(',');
231
- }
232
- if (options?.maxResults !== undefined) {
233
- queryParams.maxResults = options.maxResults;
234
- }
235
- if (options?.excludeDirs && options.excludeDirs.length > 0) {
236
- queryParams.excludeDirs = options.excludeDirs.join(',');
237
- }
238
- if (options?.excludeHidden !== undefined) {
239
- queryParams.excludeHidden = options.excludeHidden;
240
- }
241
- const result = await getFilesystemFindByPath({
242
- path: { path: formattedPath },
243
- query: queryParams,
244
- baseUrl: this.url,
245
- client: this.client,
246
- });
247
- this.handleResponseError(result.response, result.data, result.error);
248
- return result.data;
249
- }
250
- async grep(query, path = "/", options) {
251
- const formattedPath = this.formatPath(path);
252
- const queryParams = {
253
- query,
254
- };
255
- if (options?.caseSensitive !== undefined) {
256
- queryParams.caseSensitive = options.caseSensitive;
257
- }
258
- if (options?.contextLines !== undefined) {
259
- queryParams.contextLines = options.contextLines;
260
- }
261
- if (options?.maxResults !== undefined) {
262
- queryParams.maxResults = options.maxResults;
263
- }
264
- if (options?.filePattern) {
265
- queryParams.filePattern = options.filePattern;
266
- }
267
- if (options?.excludeDirs && options.excludeDirs.length > 0) {
268
- queryParams.excludeDirs = options.excludeDirs.join(',');
269
- }
270
- const result = await getFilesystemContentSearchByPath({
271
- path: { path: formattedPath },
272
- query: queryParams,
273
- baseUrl: this.url,
274
- client: this.client,
275
- });
276
- this.handleResponseError(result.response, result.data, result.error);
277
- return result.data;
278
- }
279
199
  async cp(source, destination, { maxWait = 180000 } = {}) {
280
200
  let process = await this.process.exec({
281
201
  command: `cp -r ${source} ${destination}`,