@renderinc/sdk 0.1.0 → 0.2.0

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 (100) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/README.md +15 -15
  3. package/biome.json +84 -0
  4. package/dist/experimental/blob/api.d.ts +11 -0
  5. package/dist/experimental/blob/api.d.ts.map +1 -0
  6. package/dist/experimental/blob/api.js +44 -0
  7. package/dist/experimental/blob/client.d.ts +21 -0
  8. package/dist/experimental/blob/client.d.ts.map +1 -0
  9. package/dist/experimental/blob/client.js +127 -0
  10. package/dist/experimental/blob/index.d.ts +5 -0
  11. package/dist/experimental/blob/index.d.ts.map +1 -0
  12. package/dist/experimental/blob/index.js +8 -0
  13. package/dist/experimental/blob/types.d.ts +49 -0
  14. package/dist/experimental/blob/types.d.ts.map +1 -0
  15. package/dist/experimental/blob/types.js +2 -0
  16. package/dist/experimental/experimental.d.ts +8 -0
  17. package/dist/experimental/experimental.d.ts.map +1 -0
  18. package/dist/experimental/experimental.js +10 -0
  19. package/dist/experimental/index.d.ts +3 -0
  20. package/dist/experimental/index.d.ts.map +1 -0
  21. package/dist/experimental/index.js +9 -0
  22. package/dist/generated/schema.d.ts +9782 -0
  23. package/dist/generated/schema.d.ts.map +1 -0
  24. package/dist/generated/schema.js +2 -0
  25. package/dist/index.d.ts +3 -1
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +5 -2
  28. package/dist/render.d.ts +2 -0
  29. package/dist/render.d.ts.map +1 -1
  30. package/dist/render.js +4 -2
  31. package/dist/utils/create-api-client.d.ts +1 -1
  32. package/dist/utils/create-api-client.d.ts.map +1 -1
  33. package/dist/utils/create-api-client.js +2 -0
  34. package/dist/version.d.ts +3 -0
  35. package/dist/version.d.ts.map +1 -0
  36. package/dist/version.js +23 -0
  37. package/dist/workflows/client/client.d.ts +1 -1
  38. package/dist/workflows/client/client.d.ts.map +1 -1
  39. package/dist/workflows/client/sse.d.ts +2 -2
  40. package/dist/workflows/client/sse.d.ts.map +1 -1
  41. package/dist/workflows/client/sse.js +2 -0
  42. package/dist/workflows/client/types.d.ts +1 -1
  43. package/dist/workflows/client/types.d.ts.map +1 -1
  44. package/dist/workflows/executor.d.ts +2 -2
  45. package/dist/workflows/executor.d.ts.map +1 -1
  46. package/dist/workflows/registry.d.ts +1 -1
  47. package/dist/workflows/registry.d.ts.map +1 -1
  48. package/dist/workflows/registry.js +13 -6
  49. package/dist/workflows/runner.d.ts.map +1 -1
  50. package/dist/workflows/runner.js +2 -0
  51. package/dist/workflows/schema.d.ts +9 -0
  52. package/dist/workflows/schema.d.ts.map +1 -1
  53. package/dist/workflows/task.d.ts +1 -0
  54. package/dist/workflows/task.d.ts.map +1 -1
  55. package/dist/workflows/task.js +34 -0
  56. package/dist/workflows/types.d.ts +3 -1
  57. package/dist/workflows/types.d.ts.map +1 -1
  58. package/dist/workflows/uds.d.ts +1 -1
  59. package/dist/workflows/uds.d.ts.map +1 -1
  60. package/dist/workflows/uds.js +9 -39
  61. package/examples/client/main.ts +42 -0
  62. package/examples/client/package-lock.json +601 -0
  63. package/examples/client/package.json +16 -0
  64. package/examples/client/tsconfig.json +17 -0
  65. package/examples/task/main.ts +90 -0
  66. package/examples/task/package-lock.json +585 -0
  67. package/examples/task/package.json +16 -0
  68. package/examples/task/tsconfig.json +17 -0
  69. package/package.json +13 -22
  70. package/src/errors.ts +73 -0
  71. package/src/experimental/blob/api.ts +91 -0
  72. package/src/experimental/blob/client.ts +317 -0
  73. package/src/experimental/blob/index.ts +22 -0
  74. package/src/experimental/blob/types.ts +131 -0
  75. package/src/experimental/experimental.ts +33 -0
  76. package/src/experimental/index.ts +24 -0
  77. package/src/generated/schema.ts +12729 -0
  78. package/src/index.ts +7 -0
  79. package/src/render.ts +35 -0
  80. package/src/utils/create-api-client.ts +13 -0
  81. package/src/utils/get-base-url.ts +16 -0
  82. package/src/version.ts +37 -0
  83. package/src/workflows/client/client.ts +142 -0
  84. package/src/workflows/client/create-client.ts +17 -0
  85. package/src/workflows/client/index.ts +3 -0
  86. package/src/workflows/client/sse.ts +95 -0
  87. package/src/workflows/client/types.ts +56 -0
  88. package/src/workflows/executor.ts +124 -0
  89. package/src/workflows/index.ts +7 -0
  90. package/src/workflows/registry.test.ts +76 -0
  91. package/src/workflows/registry.ts +88 -0
  92. package/src/workflows/runner.ts +38 -0
  93. package/src/workflows/schema.ts +348 -0
  94. package/src/workflows/task.ts +117 -0
  95. package/src/workflows/types.ts +89 -0
  96. package/src/workflows/uds.ts +179 -0
  97. package/test-types.ts +14 -0
  98. package/tsconfig.build.json +4 -0
  99. package/tsconfig.json +23 -0
  100. package/vite.config.ts +7 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,26 @@
1
+ # Changelog
2
+
3
+ All notable changes to the `@render/sdk` TypeScript SDK will be documented in this file.
4
+
5
+ This project follows [Semantic Versioning](https://semver.org/).
6
+
7
+ ## [0.2.0] - 2026-01-26
8
+
9
+ ### Added
10
+ - Add experimental blob storage API with `BlobClient` and `ScopedBlobClient`
11
+ - Add plan support for task execution
12
+ - Add per-task timeout override via `timeoutSeconds` option
13
+
14
+ ### Changed
15
+ - Auto-start task server on task registration (no need to call `startTaskServer()` manually)
16
+ - Rename `wait_duration` to `wait_duration_ms` for cross-SDK consistency
17
+ - Move generated API schema to `generated/` directory
18
+
19
+ ## [0.1.0] - 2025-12-15
20
+
21
+ ### Added
22
+ - Add initial TypeScript SDK for Render Workflows
23
+ - Add task registration and execution via `@render/sdk/workflows`
24
+ - Add `TaskContext` for task metadata and subtask execution
25
+ - Add configurable retry policies with exponential backoff
26
+ - 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 @renderinc/sdk
18
+ npm install @render/sdk
19
19
  ```
20
20
 
21
21
  Or with yarn:
22
22
 
23
23
  ```bash
24
- yarn add @renderinc/sdk
24
+ yarn add @render/sdk
25
25
  ```
26
26
 
27
27
  Or with pnpm:
28
28
 
29
29
  ```bash
30
- pnpm add @renderinc/sdk
30
+ pnpm add @render/sdk
31
31
  ```
32
32
 
33
33
  ## Quick Start
@@ -37,7 +37,7 @@ pnpm add @renderinc/sdk
37
37
  Use the Render SDK to run tasks and monitor their execution:
38
38
 
39
39
  ```typescript
40
- import { Render } from '@renderinc/sdk';
40
+ import { Render } from '@render/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 '@renderinc/sdk/workflows';
60
+ import { createWorkflowsClient } from '@render/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 '@renderinc/sdk/workflows';
71
+ import { task, startTaskServer } from '@render/sdk/workflows';
72
72
 
73
73
  // Simple task
74
74
  const square = task(
@@ -127,7 +127,7 @@ Creates a new Render SDK instance with access to all Render products.
127
127
 
128
128
  **Example:**
129
129
  ```typescript
130
- import { Render } from '@renderinc/sdk';
130
+ import { Render } from '@render/sdk';
131
131
 
132
132
  const render = new Render({
133
133
  token: 'your-api-token',
@@ -143,7 +143,7 @@ const result = await render.workflows.runTask('my-workflow/task', [42]);
143
143
  The workflows client is accessible via `render.workflows` or can be created directly using `createWorkflowsClient`:
144
144
 
145
145
  ```typescript
146
- import { createWorkflowsClient } from '@renderinc/sdk/workflows';
146
+ import { createWorkflowsClient } from '@render/sdk/workflows';
147
147
 
148
148
  const client = createWorkflowsClient({
149
149
  token: 'your-api-token',
@@ -327,13 +327,13 @@ interface RegisterTaskOptions {
327
327
  The SDK provides several error classes:
328
328
 
329
329
  ```typescript
330
- import { Render } from '@renderinc/sdk';
330
+ import { Render } from '@render/sdk';
331
331
  import {
332
332
  RenderError,
333
333
  ClientError,
334
334
  ServerError,
335
335
  AbortError,
336
- } from '@renderinc/sdk';
336
+ } from '@render/sdk';
337
337
 
338
338
  const render = new Render();
339
339
 
@@ -365,7 +365,7 @@ try {
365
365
  ### Example 1: Running a Task
366
366
 
367
367
  ```typescript
368
- import { Render } from '@renderinc/sdk';
368
+ import { Render } from '@render/sdk';
369
369
 
370
370
  const render = new Render();
371
371
 
@@ -380,7 +380,7 @@ runSquareTask();
380
380
  ### Example 2: Defining Tasks with Subtasks
381
381
 
382
382
  ```typescript
383
- import { task, startTaskServer } from '@renderinc/sdk/workflows';
383
+ import { task, startTaskServer } from '@render/sdk/workflows';
384
384
 
385
385
  const square = task(
386
386
  { name: 'square' },
@@ -404,7 +404,7 @@ await startTaskServer();
404
404
  ### Example 3: Error Handling in Tasks
405
405
 
406
406
  ```typescript
407
- import { task } from '@renderinc/sdk/workflows';
407
+ import { task } from '@render/sdk/workflows';
408
408
 
409
409
  const divide = task(
410
410
  { name: 'divide' },
@@ -438,7 +438,7 @@ task(
438
438
  ### Example 4: Using AbortSignal for Cancellation
439
439
 
440
440
  ```typescript
441
- import { Render, AbortError } from '@renderinc/sdk';
441
+ import { Render, AbortError } from '@render/sdk';
442
442
 
443
443
  const render = new Render();
444
444
 
@@ -470,7 +470,7 @@ runTaskWithCancellation();
470
470
  ### Example 5: Using the Unified Render SDK
471
471
 
472
472
  ```typescript
473
- import { Render } from '@renderinc/sdk';
473
+ import { Render } from '@render/sdk';
474
474
 
475
475
  // Single entry point for all Render products
476
476
  const render = new Render({
package/biome.json ADDED
@@ -0,0 +1,84 @@
1
+ {
2
+ "$schema": "https://biomejs.dev/schemas/2.3.8/schema.json",
3
+ "vcs": {
4
+ "enabled": true,
5
+ "clientKind": "git",
6
+ "useIgnoreFile": true
7
+ },
8
+ "files": {
9
+ "ignoreUnknown": false,
10
+ "includes": ["**", "!!**/src/generated/**/*"]
11
+ },
12
+ "formatter": {
13
+ "enabled": true,
14
+ "indentStyle": "space",
15
+ "indentWidth": 2,
16
+ "lineWidth": 100
17
+ },
18
+ "linter": {
19
+ "enabled": true,
20
+ "rules": {
21
+ "recommended": true,
22
+ "performance": {
23
+ "noAccumulatingSpread": "error",
24
+ "noDelete": "error",
25
+ "noDynamicNamespaceImportAccess": "error",
26
+ "noNamespaceImport": "error",
27
+ "useTopLevelRegex": "error"
28
+ },
29
+ "complexity": {
30
+ "noCommaOperator": "error",
31
+ "noForEach": "error",
32
+ "noUselessConstructor": "error",
33
+ "noUselessEmptyExport": "error",
34
+ "noUselessFragments": "error",
35
+ "noUselessLabel": "error",
36
+ "noUselessLoneBlockStatements": "error",
37
+ "noUselessRename": "error",
38
+ "noUselessSwitchCase": "error",
39
+ "noUselessTypeConstraint": "error",
40
+ "useArrowFunction": "error",
41
+ "useLiteralKeys": "error"
42
+ },
43
+ "suspicious": {
44
+ "noExplicitAny": "off"
45
+ },
46
+ "style": {
47
+ "noImplicitBoolean": "error",
48
+ "noNegationElse": "error",
49
+ "noParameterAssign": "warn",
50
+ "noRestrictedGlobals": "error",
51
+ "noRestrictedImports": {
52
+ "level": "error",
53
+ "options": {
54
+ "paths": {
55
+ "vitest": {
56
+ "message": "Vitest functions are automatically imported.",
57
+ "allowImportNames": ["Mock"]
58
+ }
59
+ }
60
+ }
61
+ },
62
+ "useDefaultParameterLast": "error",
63
+ "useExponentiationOperator": "error",
64
+ "useNodejsImportProtocol": "error",
65
+ "useNumberNamespace": "error",
66
+ "useSingleVarDeclarator": "error",
67
+ "noCommonJs": "error",
68
+ "useNumericSeparators": "error",
69
+ "useReadonlyClassProperties": "error",
70
+ "useUnifiedTypeSignatures": "error"
71
+ }
72
+ }
73
+ },
74
+ "javascript": {
75
+ "formatter": {
76
+ "quoteStyle": "double",
77
+ "trailingCommas": "all",
78
+ "semicolons": "always",
79
+ "quoteProperties": "asNeeded",
80
+ "bracketSpacing": true,
81
+ "arrowParentheses": "always"
82
+ }
83
+ }
84
+ }
@@ -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 BlobApi {
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/blob/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,OAAO;IACN,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.BlobApi = void 0;
4
+ const errors_js_1 = require("../../errors.js");
5
+ class BlobApi {
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 blob: ${error.message || "Unknown error"}`);
41
+ }
42
+ }
43
+ }
44
+ exports.BlobApi = BlobApi;
@@ -0,0 +1,21 @@
1
+ import type { Client } from "openapi-fetch";
2
+ import type { paths } from "../../generated/schema.js";
3
+ import type { BlobData, BlobScope, DeleteBlobInput, GetBlobInput, PutBlobInput, PutBlobResult, ScopedDeleteBlobInput, ScopedGetBlobInput, ScopedPutBlobInput } from "./types.js";
4
+ export declare class BlobClient {
5
+ private readonly apiClient;
6
+ constructor(apiClient: Client<paths>);
7
+ put(input: PutBlobInput): Promise<PutBlobResult>;
8
+ get(input: GetBlobInput): Promise<BlobData>;
9
+ delete(input: DeleteBlobInput): Promise<void>;
10
+ scoped(scope: BlobScope): ScopedBlobClient;
11
+ private resolveSize;
12
+ }
13
+ export declare class ScopedBlobClient {
14
+ private readonly scope;
15
+ private readonly blobClient;
16
+ constructor(apiClient: Client<paths>, scope: BlobScope);
17
+ put(input: ScopedPutBlobInput): Promise<PutBlobResult>;
18
+ get(input: ScopedGetBlobInput): Promise<BlobData>;
19
+ delete(input: ScopedDeleteBlobInput): Promise<void>;
20
+ }
21
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/experimental/blob/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,QAAQ,EACR,SAAS,EACT,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,aAAa,EAEb,qBAAqB,EACrB,kBAAkB,EAClB,kBAAkB,EACnB,MAAM,YAAY,CAAC;AASpB,qBAAa,UAAU;IACT,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAT,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC;IAgC/C,GAAG,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;IAgEhD,GAAG,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAC;IA+C3C,MAAM,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAoCnD,MAAM,CAAC,KAAK,EAAE,SAAS,GAAG,gBAAgB;IAU1C,OAAO,CAAC,WAAW;CA0BpB;AAQD,qBAAa,gBAAgB;IAKzB,OAAO,CAAC,QAAQ,CAAC,KAAK;IAJxB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;gBAGtC,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,EACP,KAAK,EAAE,SAAS;IAqB7B,GAAG,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,aAAa,CAAC;IAmBtD,GAAG,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,QAAQ,CAAC;IAkBjD,MAAM,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;CAM1D"}
@@ -0,0 +1,127 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ScopedBlobClient = exports.BlobClient = void 0;
4
+ const errors_js_1 = require("../../errors.js");
5
+ class BlobClient {
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 blob: ${error.message || "Unknown error"}`);
80
+ }
81
+ }
82
+ scoped(scope) {
83
+ return new ScopedBlobClient(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.BlobClient = BlobClient;
103
+ class ScopedBlobClient {
104
+ constructor(apiClient, scope) {
105
+ this.scope = scope;
106
+ this.blobClient = new BlobClient(apiClient);
107
+ }
108
+ async put(input) {
109
+ return this.blobClient.put({
110
+ ...this.scope,
111
+ ...input,
112
+ });
113
+ }
114
+ async get(input) {
115
+ return this.blobClient.get({
116
+ ...this.scope,
117
+ ...input,
118
+ });
119
+ }
120
+ async delete(input) {
121
+ return this.blobClient.delete({
122
+ ...this.scope,
123
+ ...input,
124
+ });
125
+ }
126
+ }
127
+ exports.ScopedBlobClient = ScopedBlobClient;
@@ -0,0 +1,5 @@
1
+ export { BlobApi } from "./api.js";
2
+ export { BlobClient, ScopedBlobClient } from "./client.js";
3
+ export type { BlobData, BlobIdentifier, BlobScope, DeleteBlobInput, GetBlobInput, PresignedDownloadUrl, PresignedUploadUrl, PutBlobInput, PutBlobInputBuffer, PutBlobInputStream, PutBlobResult, ScopedDeleteBlobInput, ScopedGetBlobInput, ScopedPutBlobInput, } 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/blob/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE3D,YAAY,EACV,QAAQ,EACR,cAAc,EACd,SAAS,EACT,eAAe,EACf,YAAY,EACZ,oBAAoB,EACpB,kBAAkB,EAClB,YAAY,EACZ,kBAAkB,EAClB,kBAAkB,EAClB,aAAa,EACb,qBAAqB,EACrB,kBAAkB,EAClB,kBAAkB,GACnB,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.ScopedBlobClient = exports.BlobClient = exports.BlobApi = void 0;
4
+ var api_js_1 = require("./api.js");
5
+ Object.defineProperty(exports, "BlobApi", { enumerable: true, get: function () { return api_js_1.BlobApi; } });
6
+ var client_js_1 = require("./client.js");
7
+ Object.defineProperty(exports, "BlobClient", { enumerable: true, get: function () { return client_js_1.BlobClient; } });
8
+ Object.defineProperty(exports, "ScopedBlobClient", { enumerable: true, get: function () { return client_js_1.ScopedBlobClient; } });
@@ -0,0 +1,49 @@
1
+ import type { Readable } from "node:stream";
2
+ export type Region = "frankfurt" | "oregon" | "ohio" | "singapore" | "virginia";
3
+ export interface BlobIdentifier {
4
+ ownerId: `tea-${string}`;
5
+ region: Region | string;
6
+ key: string;
7
+ }
8
+ interface PutBlobInputBase extends BlobIdentifier {
9
+ contentType?: string;
10
+ }
11
+ export interface PutBlobInputBuffer extends PutBlobInputBase {
12
+ data: Buffer | Uint8Array | string;
13
+ size?: number;
14
+ }
15
+ export interface PutBlobInputStream extends PutBlobInputBase {
16
+ data: Readable;
17
+ size: number;
18
+ }
19
+ export type PutBlobInput = PutBlobInputBuffer | PutBlobInputStream;
20
+ export interface GetBlobInput extends BlobIdentifier {
21
+ }
22
+ export interface DeleteBlobInput extends BlobIdentifier {
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 BlobData {
34
+ data: Buffer;
35
+ contentType?: string;
36
+ size: number;
37
+ }
38
+ export interface PutBlobResult {
39
+ etag?: string;
40
+ }
41
+ export interface BlobScope {
42
+ ownerId: `tea-${string}`;
43
+ region: Region | string;
44
+ }
45
+ export type ScopedPutBlobInput = Omit<PutBlobInput, keyof BlobScope>;
46
+ export type ScopedGetBlobInput = Omit<GetBlobInput, keyof BlobScope>;
47
+ export type ScopedDeleteBlobInput = Omit<DeleteBlobInput, keyof BlobScope>;
48
+ export {};
49
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/experimental/blob/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,cAAc;IAE7B,OAAO,EAAE,OAAO,MAAM,EAAE,CAAC;IAEzB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IAExB,GAAG,EAAE,MAAM,CAAC;CACb;AAKD,UAAU,gBAAiB,SAAQ,cAAc;IAE/C,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAMD,MAAM,WAAW,kBAAmB,SAAQ,gBAAgB;IAE1D,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM,CAAC;IAEnC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAMD,MAAM,WAAW,kBAAmB,SAAQ,gBAAgB;IAE1D,IAAI,EAAE,QAAQ,CAAC;IAEf,IAAI,EAAE,MAAM,CAAC;CACd;AAMD,MAAM,MAAM,YAAY,GAAG,kBAAkB,GAAG,kBAAkB,CAAC;AAKnE,MAAM,WAAW,YAAa,SAAQ,cAAc;CAAG;AAKvD,MAAM,WAAW,eAAgB,SAAQ,cAAc;CAAG;AAK1D,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,QAAQ;IAEvB,IAAI,EAAE,MAAM,CAAC;IAEb,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,IAAI,EAAE,MAAM,CAAC;CACd;AAKD,MAAM,WAAW,aAAa;IAE5B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAKD,MAAM,WAAW,SAAS;IAExB,OAAO,EAAE,OAAO,MAAM,EAAE,CAAC;IAEzB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;CACzB;AAKD,MAAM,MAAM,kBAAkB,GAAG,IAAI,CAAC,YAAY,EAAE,MAAM,SAAS,CAAC,CAAC;AAKrE,MAAM,MAAM,kBAAkB,GAAG,IAAI,CAAC,YAAY,EAAE,MAAM,SAAS,CAAC,CAAC;AAKrE,MAAM,MAAM,qBAAqB,GAAG,IAAI,CAAC,eAAe,EAAE,MAAM,SAAS,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,8 @@
1
+ import type { Client } from "openapi-fetch";
2
+ import type { paths } from "../generated/schema.js";
3
+ import { BlobClient } from "./blob/client.js";
4
+ export declare class ExperimentalClient {
5
+ readonly blob: BlobClient;
6
+ constructor(apiClient: Client<paths>);
7
+ }
8
+ //# sourceMappingURL=experimental.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ExperimentalClient = void 0;
4
+ const client_js_1 = require("./blob/client.js");
5
+ class ExperimentalClient {
6
+ constructor(apiClient) {
7
+ this.blob = new client_js_1.BlobClient(apiClient);
8
+ }
9
+ }
10
+ exports.ExperimentalClient = ExperimentalClient;
@@ -0,0 +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";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,9 @@
1
+ "use strict";
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; } });
8
+ var experimental_js_1 = require("./experimental.js");
9
+ Object.defineProperty(exports, "ExperimentalClient", { enumerable: true, get: function () { return experimental_js_1.ExperimentalClient; } });