@renderinc/sdk 0.2.0 → 0.2.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.
Files changed (56) hide show
  1. package/CHANGELOG.md +9 -2
  2. package/README.md +32 -22
  3. package/dist/experimental/experimental.d.ts +6 -2
  4. package/dist/experimental/experimental.d.ts.map +1 -1
  5. package/dist/experimental/experimental.js +9 -3
  6. package/dist/experimental/index.d.ts +2 -2
  7. package/dist/experimental/index.d.ts.map +1 -1
  8. package/dist/experimental/index.js +6 -5
  9. package/dist/experimental/object/api.d.ts +11 -0
  10. package/dist/experimental/object/api.d.ts.map +1 -0
  11. package/dist/experimental/object/api.js +44 -0
  12. package/dist/experimental/object/client.d.ts +21 -0
  13. package/dist/experimental/object/client.d.ts.map +1 -0
  14. package/dist/experimental/object/client.js +127 -0
  15. package/dist/experimental/object/index.d.ts +5 -0
  16. package/dist/experimental/object/index.d.ts.map +1 -0
  17. package/dist/experimental/object/index.js +8 -0
  18. package/dist/experimental/object/types.d.ts +49 -0
  19. package/dist/experimental/object/types.d.ts.map +1 -0
  20. package/dist/generated/schema.d.ts +131 -3
  21. package/dist/generated/schema.d.ts.map +1 -1
  22. package/dist/workflows/uds.d.ts.map +1 -1
  23. package/dist/workflows/uds.js +26 -51
  24. package/examples/client/main.ts +1 -1
  25. package/examples/client/package-lock.json +4 -4
  26. package/examples/client/package.json +1 -1
  27. package/examples/task/main.ts +1 -1
  28. package/examples/task/package-lock.json +5 -6
  29. package/examples/task/package.json +1 -1
  30. package/package.json +9 -8
  31. package/src/errors.test.ts +75 -0
  32. package/src/experimental/experimental.ts +30 -7
  33. package/src/experimental/index.ts +18 -18
  34. package/src/experimental/{blob → object}/api.ts +7 -7
  35. package/src/experimental/object/client.test.ts +138 -0
  36. package/src/experimental/{blob → object}/client.ts +57 -57
  37. package/src/experimental/object/index.ts +22 -0
  38. package/src/experimental/object/types.test.ts +87 -0
  39. package/src/experimental/{blob → object}/types.ts +30 -30
  40. package/src/generated/schema.ts +217 -9
  41. package/src/utils/get-base-url.test.ts +58 -0
  42. package/src/workflows/client/client.test.ts +68 -0
  43. package/src/workflows/types.test.ts +52 -0
  44. package/src/workflows/uds.ts +29 -69
  45. package/tsconfig.json +1 -1
  46. package/{vite.config.ts → vitest.config.ts} +1 -0
  47. package/dist/workflows/client/errors.d.ts +0 -25
  48. package/dist/workflows/client/errors.d.ts.map +0 -1
  49. package/dist/workflows/client/errors.js +0 -56
  50. package/dist/workflows/client/schema.d.ts +0 -9322
  51. package/dist/workflows/client/schema.d.ts.map +0 -1
  52. package/dist/workflows/client/workflows.d.ts +0 -15
  53. package/dist/workflows/client/workflows.d.ts.map +0 -1
  54. package/dist/workflows/client/workflows.js +0 -63
  55. package/src/experimental/blob/index.ts +0 -22
  56. /package/dist/{workflows/client/schema.js → experimental/object/types.js} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,9 +1,16 @@
1
1
  # Changelog
2
2
 
3
- All notable changes to the `@render/sdk` TypeScript SDK will be documented in this file.
3
+ All notable changes to the `@renderinc/sdk` TypeScript SDK will be documented in this file.
4
4
 
5
5
  This project follows [Semantic Versioning](https://semver.org/).
6
6
 
7
+ ## [0.2.1] - 2026-01-29
8
+
9
+ ### Changed
10
+ - Updated package name in README from @render/sdk to @renderinc/sdk
11
+ - Renamed experimental blob storage API to object storage (Blob* -> Object*)
12
+ - Switched internal workflows task communication from SSE to HTTP requests
13
+
7
14
  ## [0.2.0] - 2026-01-26
8
15
 
9
16
  ### Added
@@ -20,7 +27,7 @@ This project follows [Semantic Versioning](https://semver.org/).
20
27
 
21
28
  ### Added
22
29
  - Add initial TypeScript SDK for Render Workflows
23
- - Add task registration and execution via `@render/sdk/workflows`
30
+ - Add task registration and execution via `@renderinc/sdk/workflows`
24
31
  - Add `TaskContext` for task metadata and subtask execution
25
32
  - Add configurable retry policies with exponential backoff
26
33
  - Add generated OpenAPI types for full type safety
package/README.md CHANGED
@@ -15,19 +15,19 @@ The official TypeScript SDK for Render Workflows, providing a simple and intuiti
15
15
  ## Installation
16
16
 
17
17
  ```bash
18
- npm install @render/sdk
18
+ npm install @renderinc/sdk
19
19
  ```
20
20
 
21
21
  Or with yarn:
22
22
 
23
23
  ```bash
24
- yarn add @render/sdk
24
+ yarn add @renderinc/sdk
25
25
  ```
26
26
 
27
27
  Or with pnpm:
28
28
 
29
29
  ```bash
30
- pnpm add @render/sdk
30
+ pnpm add @renderinc/sdk
31
31
  ```
32
32
 
33
33
  ## Quick Start
@@ -37,7 +37,7 @@ pnpm add @render/sdk
37
37
  Use the Render SDK to run tasks and monitor their execution:
38
38
 
39
39
  ```typescript
40
- import { Render } from '@render/sdk';
40
+ import { Render } from '@renderinc/sdk';
41
41
 
42
42
  // Create a Render SDK instance (uses RENDER_API_KEY from environment)
43
43
  const render = new Render();
@@ -57,7 +57,7 @@ const details = await render.workflows.getTaskRun(result.id);
57
57
  Alternatively, you can create a workflows client directly:
58
58
 
59
59
  ```typescript
60
- import { createWorkflowsClient } from '@render/sdk/workflows';
60
+ import { createWorkflowsClient } from '@renderinc/sdk/workflows';
61
61
 
62
62
  const client = createWorkflowsClient();
63
63
  const result = await client.runTask('my-workflow/my-task', [42, 'hello']);
@@ -68,7 +68,7 @@ const result = await client.runTask('my-workflow/my-task', [42, 'hello']);
68
68
  Define tasks that can be executed by the workflow system:
69
69
 
70
70
  ```typescript
71
- import { task, startTaskServer } from '@render/sdk/workflows';
71
+ import { task, startTaskServer } from '@renderinc/sdk/workflows';
72
72
 
73
73
  // Simple task
74
74
  const square = task(
@@ -95,8 +95,10 @@ task(
95
95
  retry: {
96
96
  maxRetries: 3,
97
97
  waitDurationMs: 1000,
98
- factor: 1.5,
98
+ backoffScaling: 1.5,
99
99
  },
100
+ timeoutSeconds: 86400, // 24h
101
+ plan: 'starter',
100
102
  },
101
103
  async function retryableTask(input: string): Promise<string> {
102
104
  // Task implementation
@@ -104,8 +106,10 @@ task(
104
106
  }
105
107
  );
106
108
 
107
- // Start the task server
108
- await startTaskServer();
109
+ // The task server starts automatically when running in a workflow environment
110
+ // (when RENDER_SDK_SOCKET_PATH is set). No need to call startTaskServer() explicitly.
111
+ //
112
+ // To disable auto-start, set RENDER_SDK_AUTO_START=false in your environment.
109
113
  ```
110
114
 
111
115
  ## API Reference
@@ -127,7 +131,7 @@ Creates a new Render SDK instance with access to all Render products.
127
131
 
128
132
  **Example:**
129
133
  ```typescript
130
- import { Render } from '@render/sdk';
134
+ import { Render } from '@renderinc/sdk';
131
135
 
132
136
  const render = new Render({
133
137
  token: 'your-api-token',
@@ -143,7 +147,7 @@ const result = await render.workflows.runTask('my-workflow/task', [42]);
143
147
  The workflows client is accessible via `render.workflows` or can be created directly using `createWorkflowsClient`:
144
148
 
145
149
  ```typescript
146
- import { createWorkflowsClient } from '@render/sdk/workflows';
150
+ import { createWorkflowsClient } from '@renderinc/sdk/workflows';
147
151
 
148
152
  const client = createWorkflowsClient({
149
153
  token: 'your-api-token',
@@ -215,7 +219,9 @@ Registers a function as a task.
215
219
  - `retry?: RetryOptions` - Optional retry configuration
216
220
  - `maxRetries: number` - Maximum number of retries
217
221
  - `waitDurationMs: number` - Wait duration between retries in milliseconds
218
- - `factor?: number` - Backoff factor (default: 1.5)
222
+ - `backoffScaling?: number` - Backoff multiplier (default: 1.5)
223
+ - `timeoutSeconds?: number` - Maximum execution time in seconds
224
+ - `plan?: string` - Resource plan for task execution (e.g., `"starter"`, `"standard"`, `"pro"`)
219
225
  - `func: TaskFunction` - The task function to register
220
226
 
221
227
  **Returns:** The registered function with the same signature
@@ -230,15 +236,17 @@ const myTask = task(
230
236
  }
231
237
  );
232
238
 
233
- // With retry options
239
+ // With retry, timeout, and plan options
234
240
  task(
235
241
  {
236
242
  name: 'retryableTask',
237
243
  retry: {
238
244
  maxRetries: 3,
239
245
  waitDurationMs: 1000,
240
- factor: 1.5,
246
+ backoffScaling: 1.5,
241
247
  },
248
+ timeoutSeconds: 300,
249
+ plan: 'starter',
242
250
  },
243
251
  function retryableTask(arg: string): string {
244
252
  return arg.toUpperCase();
@@ -317,8 +325,10 @@ interface RegisterTaskOptions {
317
325
  retry?: {
318
326
  maxRetries: number;
319
327
  waitDurationMs: number;
320
- factor?: number; // default 1.5
328
+ backoffScaling?: number; // default 1.5
321
329
  };
330
+ timeoutSeconds?: number;
331
+ plan?: string; // e.g., "starter", "standard", "pro"
322
332
  }
323
333
  ```
324
334
 
@@ -327,13 +337,13 @@ interface RegisterTaskOptions {
327
337
  The SDK provides several error classes:
328
338
 
329
339
  ```typescript
330
- import { Render } from '@render/sdk';
340
+ import { Render } from '@renderinc/sdk';
331
341
  import {
332
342
  RenderError,
333
343
  ClientError,
334
344
  ServerError,
335
345
  AbortError,
336
- } from '@render/sdk';
346
+ } from '@renderinc/sdk';
337
347
 
338
348
  const render = new Render();
339
349
 
@@ -365,7 +375,7 @@ try {
365
375
  ### Example 1: Running a Task
366
376
 
367
377
  ```typescript
368
- import { Render } from '@render/sdk';
378
+ import { Render } from '@renderinc/sdk';
369
379
 
370
380
  const render = new Render();
371
381
 
@@ -380,7 +390,7 @@ runSquareTask();
380
390
  ### Example 2: Defining Tasks with Subtasks
381
391
 
382
392
  ```typescript
383
- import { task, startTaskServer } from '@render/sdk/workflows';
393
+ import { task, startTaskServer } from '@renderinc/sdk/workflows';
384
394
 
385
395
  const square = task(
386
396
  { name: 'square' },
@@ -404,7 +414,7 @@ await startTaskServer();
404
414
  ### Example 3: Error Handling in Tasks
405
415
 
406
416
  ```typescript
407
- import { task } from '@render/sdk/workflows';
417
+ import { task } from '@renderinc/sdk/workflows';
408
418
 
409
419
  const divide = task(
410
420
  { name: 'divide' },
@@ -438,7 +448,7 @@ task(
438
448
  ### Example 4: Using AbortSignal for Cancellation
439
449
 
440
450
  ```typescript
441
- import { Render, AbortError } from '@render/sdk';
451
+ import { Render, AbortError } from '@renderinc/sdk';
442
452
 
443
453
  const render = new Render();
444
454
 
@@ -470,7 +480,7 @@ runTaskWithCancellation();
470
480
  ### Example 5: Using the Unified Render SDK
471
481
 
472
482
  ```typescript
473
- import { Render } from '@render/sdk';
483
+ import { Render } from '@renderinc/sdk';
474
484
 
475
485
  // Single entry point for all Render products
476
486
  const render = new Render({
@@ -1,8 +1,12 @@
1
1
  import type { Client } from "openapi-fetch";
2
2
  import type { paths } from "../generated/schema.js";
3
- import { BlobClient } from "./blob/client.js";
3
+ import { ObjectClient } from "./object/client.js";
4
+ export declare class StorageClient {
5
+ readonly objects: ObjectClient;
6
+ constructor(apiClient: Client<paths>);
7
+ }
4
8
  export declare class ExperimentalClient {
5
- readonly blob: BlobClient;
9
+ readonly storage: StorageClient;
6
10
  constructor(apiClient: Client<paths>);
7
11
  }
8
12
  //# sourceMappingURL=experimental.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"experimental.d.ts","sourceRoot":"","sources":["../../src/experimental/experimental.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAuB9C,qBAAa,kBAAkB;IAE7B,SAAgB,IAAI,EAAE,UAAU,CAAC;gBAErB,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC;CAGrC"}
1
+ {"version":3,"file":"experimental.d.ts","sourceRoot":"","sources":["../../src/experimental/experimental.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAgBlD,qBAAa,aAAa;IAExB,SAAgB,OAAO,EAAE,YAAY,CAAC;gBAE1B,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC;CAGrC;AAuBD,qBAAa,kBAAkB;IAE7B,SAAgB,OAAO,EAAE,aAAa,CAAC;gBAE3B,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC;CAGrC"}
@@ -1,10 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ExperimentalClient = void 0;
4
- const client_js_1 = require("./blob/client.js");
3
+ exports.ExperimentalClient = exports.StorageClient = void 0;
4
+ const client_js_1 = require("./object/client.js");
5
+ class StorageClient {
6
+ constructor(apiClient) {
7
+ this.objects = new client_js_1.ObjectClient(apiClient);
8
+ }
9
+ }
10
+ exports.StorageClient = StorageClient;
5
11
  class ExperimentalClient {
6
12
  constructor(apiClient) {
7
- this.blob = new client_js_1.BlobClient(apiClient);
13
+ this.storage = new StorageClient(apiClient);
8
14
  }
9
15
  }
10
16
  exports.ExperimentalClient = ExperimentalClient;
@@ -1,3 +1,3 @@
1
- export { BlobApi, BlobClient, type BlobData, type BlobIdentifier, type BlobScope, type DeleteBlobInput, type GetBlobInput, type PresignedDownloadUrl, type PresignedUploadUrl, type PutBlobInput, type PutBlobInputBuffer, type PutBlobInputStream, type PutBlobResult, Region, ScopedBlobClient, type ScopedDeleteBlobInput, type ScopedGetBlobInput, type ScopedPutBlobInput, } from "./blob/index.js";
2
- export { ExperimentalClient } from "./experimental.js";
1
+ export { ExperimentalClient, StorageClient } from "./experimental.js";
2
+ export { type DeleteObjectInput, type GetObjectInput, ObjectApi, ObjectClient, type ObjectData, type ObjectIdentifier, type ObjectScope, type PresignedDownloadUrl, type PresignedUploadUrl, type PutObjectInput, type PutObjectInputBuffer, type PutObjectInputStream, type PutObjectResult, Region, type ScopedDeleteObjectInput, type ScopedGetObjectInput, ScopedObjectClient, type ScopedPutObjectInput, } from "./object/index.js";
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/experimental/index.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,OAAO,EACP,UAAU,EACV,KAAK,QAAQ,EACb,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,KAAK,YAAY,EACjB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,MAAM,EACN,gBAAgB,EAChB,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,GACxB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/experimental/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEtE,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,SAAS,EACT,YAAY,EACZ,KAAK,UAAU,EACf,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,eAAe,EACpB,MAAM,EACN,KAAK,uBAAuB,EAC5B,KAAK,oBAAoB,EACzB,kBAAkB,EAClB,KAAK,oBAAoB,GAC1B,MAAM,mBAAmB,CAAC"}
@@ -1,9 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ExperimentalClient = exports.ScopedBlobClient = exports.BlobClient = exports.BlobApi = void 0;
4
- var index_js_1 = require("./blob/index.js");
5
- Object.defineProperty(exports, "BlobApi", { enumerable: true, get: function () { return index_js_1.BlobApi; } });
6
- Object.defineProperty(exports, "BlobClient", { enumerable: true, get: function () { return index_js_1.BlobClient; } });
7
- Object.defineProperty(exports, "ScopedBlobClient", { enumerable: true, get: function () { return index_js_1.ScopedBlobClient; } });
3
+ exports.ScopedObjectClient = exports.ObjectClient = exports.ObjectApi = exports.StorageClient = exports.ExperimentalClient = void 0;
8
4
  var experimental_js_1 = require("./experimental.js");
9
5
  Object.defineProperty(exports, "ExperimentalClient", { enumerable: true, get: function () { return experimental_js_1.ExperimentalClient; } });
6
+ Object.defineProperty(exports, "StorageClient", { enumerable: true, get: function () { return experimental_js_1.StorageClient; } });
7
+ var index_js_1 = require("./object/index.js");
8
+ Object.defineProperty(exports, "ObjectApi", { enumerable: true, get: function () { return index_js_1.ObjectApi; } });
9
+ Object.defineProperty(exports, "ObjectClient", { enumerable: true, get: function () { return index_js_1.ObjectClient; } });
10
+ Object.defineProperty(exports, "ScopedObjectClient", { enumerable: true, get: function () { return index_js_1.ScopedObjectClient; } });
@@ -0,0 +1,11 @@
1
+ import type { Client } from "openapi-fetch";
2
+ import type { paths } from "../../generated/schema.js";
3
+ import type { PresignedDownloadUrl, PresignedUploadUrl, Region } from "./types.js";
4
+ export declare class ObjectApi {
5
+ private readonly apiClient;
6
+ constructor(apiClient: Client<paths>);
7
+ getUploadUrl(ownerId: string, region: Region | string, key: string, sizeBytes: number): Promise<PresignedUploadUrl>;
8
+ getDownloadUrl(ownerId: string, region: Region | string, key: string): Promise<PresignedDownloadUrl>;
9
+ delete(ownerId: string, region: Region | string, key: string): Promise<void>;
10
+ }
11
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../src/experimental/object/api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,KAAK,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAUnF,qBAAa,SAAS;IACR,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAT,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC;IAW/C,YAAY,CAChB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,GAAG,MAAM,EACvB,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,kBAAkB,CAAC;IAyBxB,cAAc,CAClB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,GAAG,MAAM,EACvB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,oBAAoB,CAAC;IAsB1B,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CASnF"}
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ObjectApi = void 0;
4
+ const errors_js_1 = require("../../errors.js");
5
+ class ObjectApi {
6
+ constructor(apiClient) {
7
+ this.apiClient = apiClient;
8
+ }
9
+ async getUploadUrl(ownerId, region, key, sizeBytes) {
10
+ const { data, error } = await this.apiClient.PUT("/blobs/{ownerId}/{region}/{key}", {
11
+ params: { path: { ownerId, region: region, key } },
12
+ body: { sizeBytes },
13
+ });
14
+ if (error) {
15
+ throw new errors_js_1.RenderError(`Failed to get upload URL: ${error.message || "Unknown error"}`);
16
+ }
17
+ return {
18
+ url: data.url,
19
+ expiresAt: new Date(data.expiresAt),
20
+ maxSizeBytes: data.maxSizeBytes,
21
+ };
22
+ }
23
+ async getDownloadUrl(ownerId, region, key) {
24
+ const { data, error } = await this.apiClient.GET("/blobs/{ownerId}/{region}/{key}", {
25
+ params: { path: { ownerId, region: region, key } },
26
+ });
27
+ if (error) {
28
+ throw new errors_js_1.RenderError(`Failed to get download URL: ${error.message || "Unknown error"}`);
29
+ }
30
+ return {
31
+ url: data.url,
32
+ expiresAt: new Date(data.expiresAt),
33
+ };
34
+ }
35
+ async delete(ownerId, region, key) {
36
+ const { error } = await this.apiClient.DELETE("/blobs/{ownerId}/{region}/{key}", {
37
+ params: { path: { ownerId, region: region, key } },
38
+ });
39
+ if (error) {
40
+ throw new errors_js_1.RenderError(`Failed to delete object: ${error.message || "Unknown error"}`);
41
+ }
42
+ }
43
+ }
44
+ exports.ObjectApi = ObjectApi;
@@ -0,0 +1,21 @@
1
+ import type { Client } from "openapi-fetch";
2
+ import type { paths } from "../../generated/schema.js";
3
+ import type { DeleteObjectInput, GetObjectInput, ObjectData, ObjectScope, PutObjectInput, PutObjectResult, ScopedDeleteObjectInput, ScopedGetObjectInput, ScopedPutObjectInput } from "./types.js";
4
+ export declare class ObjectClient {
5
+ private readonly apiClient;
6
+ constructor(apiClient: Client<paths>);
7
+ put(input: PutObjectInput): Promise<PutObjectResult>;
8
+ get(input: GetObjectInput): Promise<ObjectData>;
9
+ delete(input: DeleteObjectInput): Promise<void>;
10
+ scoped(scope: ObjectScope): ScopedObjectClient;
11
+ private resolveSize;
12
+ }
13
+ export declare class ScopedObjectClient {
14
+ private readonly scope;
15
+ private readonly objectClient;
16
+ constructor(apiClient: Client<paths>, scope: ObjectScope);
17
+ put(input: ScopedPutObjectInput): Promise<PutObjectResult>;
18
+ get(input: ScopedGetObjectInput): Promise<ObjectData>;
19
+ delete(input: ScopedDeleteObjectInput): Promise<void>;
20
+ }
21
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/experimental/object/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,KAAK,EACV,iBAAiB,EACjB,cAAc,EACd,UAAU,EACV,WAAW,EACX,cAAc,EACd,eAAe,EAEf,uBAAuB,EACvB,oBAAoB,EACpB,oBAAoB,EACrB,MAAM,YAAY,CAAC;AASpB,qBAAa,YAAY;IACX,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAT,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC;IAgC/C,GAAG,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC;IAgEpD,GAAG,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC;IA+C/C,MAAM,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAoCrD,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,kBAAkB;IAU9C,OAAO,CAAC,WAAW;CA0BpB;AAQD,qBAAa,kBAAkB;IAK3B,OAAO,CAAC,QAAQ,CAAC,KAAK;IAJxB,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;gBAG1C,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,EACP,KAAK,EAAE,WAAW;IAqB/B,GAAG,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,eAAe,CAAC;IAmB1D,GAAG,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,UAAU,CAAC;IAkBrD,MAAM,CAAC,KAAK,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;CAM5D"}
@@ -0,0 +1,127 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ScopedObjectClient = exports.ObjectClient = void 0;
4
+ const errors_js_1 = require("../../errors.js");
5
+ class ObjectClient {
6
+ constructor(apiClient) {
7
+ this.apiClient = apiClient;
8
+ }
9
+ async put(input) {
10
+ const size = this.resolveSize(input);
11
+ const { data, error } = await this.apiClient.PUT("/blobs/{ownerId}/{region}/{key}", {
12
+ params: {
13
+ path: {
14
+ ownerId: input.ownerId,
15
+ region: input.region,
16
+ key: input.key,
17
+ },
18
+ },
19
+ body: { sizeBytes: size },
20
+ });
21
+ if (error) {
22
+ throw new errors_js_1.RenderError(`Failed to get upload URL: ${error.message || "Unknown error"}`);
23
+ }
24
+ const headers = {
25
+ "Content-Length": size.toString(),
26
+ };
27
+ if (input.contentType) {
28
+ headers["Content-Type"] = input.contentType;
29
+ }
30
+ const response = await fetch(data.url, {
31
+ method: "PUT",
32
+ headers,
33
+ body: input.data,
34
+ duplex: "half",
35
+ });
36
+ if (!response.ok) {
37
+ throw new errors_js_1.RenderError(`Upload failed: ${response.status} ${response.statusText}`);
38
+ }
39
+ return {
40
+ etag: response.headers.get("ETag") ?? undefined,
41
+ };
42
+ }
43
+ async get(input) {
44
+ const { data, error } = await this.apiClient.GET("/blobs/{ownerId}/{region}/{key}", {
45
+ params: {
46
+ path: {
47
+ ownerId: input.ownerId,
48
+ region: input.region,
49
+ key: input.key,
50
+ },
51
+ },
52
+ });
53
+ if (error) {
54
+ throw new errors_js_1.RenderError(`Failed to get download URL: ${error.message || "Unknown error"}`);
55
+ }
56
+ const response = await fetch(data.url);
57
+ if (!response.ok) {
58
+ throw new errors_js_1.RenderError(`Download failed: ${response.status} ${response.statusText}`);
59
+ }
60
+ const arrayBuffer = await response.arrayBuffer();
61
+ const buffer = Buffer.from(arrayBuffer);
62
+ return {
63
+ data: buffer,
64
+ size: buffer.byteLength,
65
+ contentType: response.headers.get("Content-Type") ?? undefined,
66
+ };
67
+ }
68
+ async delete(input) {
69
+ const { error } = await this.apiClient.DELETE("/blobs/{ownerId}/{region}/{key}", {
70
+ params: {
71
+ path: {
72
+ ownerId: input.ownerId,
73
+ region: input.region,
74
+ key: input.key,
75
+ },
76
+ },
77
+ });
78
+ if (error) {
79
+ throw new errors_js_1.RenderError(`Failed to delete object: ${error.message || "Unknown error"}`);
80
+ }
81
+ }
82
+ scoped(scope) {
83
+ return new ScopedObjectClient(this.apiClient, scope);
84
+ }
85
+ resolveSize(input) {
86
+ if (Buffer.isBuffer(input.data) || input.data instanceof Uint8Array) {
87
+ const actualSize = input.data.byteLength;
88
+ if (input.size !== undefined && input.size !== actualSize) {
89
+ throw new errors_js_1.RenderError(`Size mismatch: provided size ${input.size} does not match actual size ${actualSize}`);
90
+ }
91
+ return actualSize;
92
+ }
93
+ if (input.size === undefined) {
94
+ throw new errors_js_1.RenderError("Size is required for stream and string inputs. Provide the size parameter.");
95
+ }
96
+ if (input.size <= 0) {
97
+ throw new errors_js_1.RenderError("Size must be a positive integer");
98
+ }
99
+ return input.size;
100
+ }
101
+ }
102
+ exports.ObjectClient = ObjectClient;
103
+ class ScopedObjectClient {
104
+ constructor(apiClient, scope) {
105
+ this.scope = scope;
106
+ this.objectClient = new ObjectClient(apiClient);
107
+ }
108
+ async put(input) {
109
+ return this.objectClient.put({
110
+ ...this.scope,
111
+ ...input,
112
+ });
113
+ }
114
+ async get(input) {
115
+ return this.objectClient.get({
116
+ ...this.scope,
117
+ ...input,
118
+ });
119
+ }
120
+ async delete(input) {
121
+ return this.objectClient.delete({
122
+ ...this.scope,
123
+ ...input,
124
+ });
125
+ }
126
+ }
127
+ exports.ScopedObjectClient = ScopedObjectClient;
@@ -0,0 +1,5 @@
1
+ export { ObjectApi } from "./api.js";
2
+ export { ObjectClient, ScopedObjectClient } from "./client.js";
3
+ export type { DeleteObjectInput, GetObjectInput, ObjectData, ObjectIdentifier, ObjectScope, PresignedDownloadUrl, PresignedUploadUrl, PutObjectInput, PutObjectInputBuffer, PutObjectInputStream, PutObjectResult, ScopedDeleteObjectInput, ScopedGetObjectInput, ScopedPutObjectInput, } from "./types.js";
4
+ export { Region } from "./types.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/experimental/object/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAE/D,YAAY,EACV,iBAAiB,EACjB,cAAc,EACd,UAAU,EACV,gBAAgB,EAChB,WAAW,EACX,oBAAoB,EACpB,kBAAkB,EAClB,cAAc,EACd,oBAAoB,EACpB,oBAAoB,EACpB,eAAe,EACf,uBAAuB,EACvB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ScopedObjectClient = exports.ObjectClient = exports.ObjectApi = void 0;
4
+ var api_js_1 = require("./api.js");
5
+ Object.defineProperty(exports, "ObjectApi", { enumerable: true, get: function () { return api_js_1.ObjectApi; } });
6
+ var client_js_1 = require("./client.js");
7
+ Object.defineProperty(exports, "ObjectClient", { enumerable: true, get: function () { return client_js_1.ObjectClient; } });
8
+ Object.defineProperty(exports, "ScopedObjectClient", { enumerable: true, get: function () { return client_js_1.ScopedObjectClient; } });
@@ -0,0 +1,49 @@
1
+ import type { Readable } from "node:stream";
2
+ export type Region = "frankfurt" | "oregon" | "ohio" | "singapore" | "virginia";
3
+ export interface ObjectIdentifier {
4
+ ownerId: `tea-${string}`;
5
+ region: Region | string;
6
+ key: string;
7
+ }
8
+ interface PutObjectInputBase extends ObjectIdentifier {
9
+ contentType?: string;
10
+ }
11
+ export interface PutObjectInputBuffer extends PutObjectInputBase {
12
+ data: Buffer | Uint8Array | string;
13
+ size?: number;
14
+ }
15
+ export interface PutObjectInputStream extends PutObjectInputBase {
16
+ data: Readable;
17
+ size: number;
18
+ }
19
+ export type PutObjectInput = PutObjectInputBuffer | PutObjectInputStream;
20
+ export interface GetObjectInput extends ObjectIdentifier {
21
+ }
22
+ export interface DeleteObjectInput extends ObjectIdentifier {
23
+ }
24
+ export interface PresignedUploadUrl {
25
+ url: string;
26
+ expiresAt: Date;
27
+ maxSizeBytes: number;
28
+ }
29
+ export interface PresignedDownloadUrl {
30
+ url: string;
31
+ expiresAt: Date;
32
+ }
33
+ export interface ObjectData {
34
+ data: Buffer;
35
+ contentType?: string;
36
+ size: number;
37
+ }
38
+ export interface PutObjectResult {
39
+ etag?: string;
40
+ }
41
+ export interface ObjectScope {
42
+ ownerId: `tea-${string}`;
43
+ region: Region | string;
44
+ }
45
+ export type ScopedPutObjectInput = Omit<PutObjectInput, keyof ObjectScope>;
46
+ export type ScopedGetObjectInput = Omit<GetObjectInput, keyof ObjectScope>;
47
+ export type ScopedDeleteObjectInput = Omit<DeleteObjectInput, keyof ObjectScope>;
48
+ export {};
49
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/experimental/object/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAK5C,MAAM,MAAM,MAAM,GAAG,WAAW,GAAG,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,UAAU,CAAC;AAKhF,MAAM,WAAW,gBAAgB;IAE/B,OAAO,EAAE,OAAO,MAAM,EAAE,CAAC;IAEzB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IAExB,GAAG,EAAE,MAAM,CAAC;CACb;AAKD,UAAU,kBAAmB,SAAQ,gBAAgB;IAEnD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAMD,MAAM,WAAW,oBAAqB,SAAQ,kBAAkB;IAE9D,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM,CAAC;IAEnC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAMD,MAAM,WAAW,oBAAqB,SAAQ,kBAAkB;IAE9D,IAAI,EAAE,QAAQ,CAAC;IAEf,IAAI,EAAE,MAAM,CAAC;CACd;AAMD,MAAM,MAAM,cAAc,GAAG,oBAAoB,GAAG,oBAAoB,CAAC;AAKzE,MAAM,WAAW,cAAe,SAAQ,gBAAgB;CAAG;AAK3D,MAAM,WAAW,iBAAkB,SAAQ,gBAAgB;CAAG;AAK9D,MAAM,WAAW,kBAAkB;IAEjC,GAAG,EAAE,MAAM,CAAC;IAEZ,SAAS,EAAE,IAAI,CAAC;IAEhB,YAAY,EAAE,MAAM,CAAC;CACtB;AAKD,MAAM,WAAW,oBAAoB;IAEnC,GAAG,EAAE,MAAM,CAAC;IAEZ,SAAS,EAAE,IAAI,CAAC;CACjB;AAKD,MAAM,WAAW,UAAU;IAEzB,IAAI,EAAE,MAAM,CAAC;IAEb,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,IAAI,EAAE,MAAM,CAAC;CACd;AAKD,MAAM,WAAW,eAAe;IAE9B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAKD,MAAM,WAAW,WAAW;IAE1B,OAAO,EAAE,OAAO,MAAM,EAAE,CAAC;IAEzB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;CACzB;AAKD,MAAM,MAAM,oBAAoB,GAAG,IAAI,CAAC,cAAc,EAAE,MAAM,WAAW,CAAC,CAAC;AAK3E,MAAM,MAAM,oBAAoB,GAAG,IAAI,CAAC,cAAc,EAAE,MAAM,WAAW,CAAC,CAAC;AAK3E,MAAM,MAAM,uBAAuB,GAAG,IAAI,CAAC,iBAAiB,EAAE,MAAM,WAAW,CAAC,CAAC"}