@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.
- package/CHANGELOG.md +26 -0
- package/README.md +15 -15
- package/biome.json +84 -0
- package/dist/experimental/blob/api.d.ts +11 -0
- package/dist/experimental/blob/api.d.ts.map +1 -0
- package/dist/experimental/blob/api.js +44 -0
- package/dist/experimental/blob/client.d.ts +21 -0
- package/dist/experimental/blob/client.d.ts.map +1 -0
- package/dist/experimental/blob/client.js +127 -0
- package/dist/experimental/blob/index.d.ts +5 -0
- package/dist/experimental/blob/index.d.ts.map +1 -0
- package/dist/experimental/blob/index.js +8 -0
- package/dist/experimental/blob/types.d.ts +49 -0
- package/dist/experimental/blob/types.d.ts.map +1 -0
- package/dist/experimental/blob/types.js +2 -0
- package/dist/experimental/experimental.d.ts +8 -0
- package/dist/experimental/experimental.d.ts.map +1 -0
- package/dist/experimental/experimental.js +10 -0
- package/dist/experimental/index.d.ts +3 -0
- package/dist/experimental/index.d.ts.map +1 -0
- package/dist/experimental/index.js +9 -0
- package/dist/generated/schema.d.ts +9782 -0
- package/dist/generated/schema.d.ts.map +1 -0
- package/dist/generated/schema.js +2 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -2
- package/dist/render.d.ts +2 -0
- package/dist/render.d.ts.map +1 -1
- package/dist/render.js +4 -2
- package/dist/utils/create-api-client.d.ts +1 -1
- package/dist/utils/create-api-client.d.ts.map +1 -1
- package/dist/utils/create-api-client.js +2 -0
- package/dist/version.d.ts +3 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +23 -0
- package/dist/workflows/client/client.d.ts +1 -1
- package/dist/workflows/client/client.d.ts.map +1 -1
- package/dist/workflows/client/sse.d.ts +2 -2
- package/dist/workflows/client/sse.d.ts.map +1 -1
- package/dist/workflows/client/sse.js +2 -0
- package/dist/workflows/client/types.d.ts +1 -1
- package/dist/workflows/client/types.d.ts.map +1 -1
- package/dist/workflows/executor.d.ts +2 -2
- package/dist/workflows/executor.d.ts.map +1 -1
- package/dist/workflows/registry.d.ts +1 -1
- package/dist/workflows/registry.d.ts.map +1 -1
- package/dist/workflows/registry.js +13 -6
- package/dist/workflows/runner.d.ts.map +1 -1
- package/dist/workflows/runner.js +2 -0
- package/dist/workflows/schema.d.ts +9 -0
- package/dist/workflows/schema.d.ts.map +1 -1
- package/dist/workflows/task.d.ts +1 -0
- package/dist/workflows/task.d.ts.map +1 -1
- package/dist/workflows/task.js +34 -0
- package/dist/workflows/types.d.ts +3 -1
- package/dist/workflows/types.d.ts.map +1 -1
- package/dist/workflows/uds.d.ts +1 -1
- package/dist/workflows/uds.d.ts.map +1 -1
- package/dist/workflows/uds.js +9 -39
- package/examples/client/main.ts +42 -0
- package/examples/client/package-lock.json +601 -0
- package/examples/client/package.json +16 -0
- package/examples/client/tsconfig.json +17 -0
- package/examples/task/main.ts +90 -0
- package/examples/task/package-lock.json +585 -0
- package/examples/task/package.json +16 -0
- package/examples/task/tsconfig.json +17 -0
- package/package.json +13 -22
- package/src/errors.ts +73 -0
- package/src/experimental/blob/api.ts +91 -0
- package/src/experimental/blob/client.ts +317 -0
- package/src/experimental/blob/index.ts +22 -0
- package/src/experimental/blob/types.ts +131 -0
- package/src/experimental/experimental.ts +33 -0
- package/src/experimental/index.ts +24 -0
- package/src/generated/schema.ts +12729 -0
- package/src/index.ts +7 -0
- package/src/render.ts +35 -0
- package/src/utils/create-api-client.ts +13 -0
- package/src/utils/get-base-url.ts +16 -0
- package/src/version.ts +37 -0
- package/src/workflows/client/client.ts +142 -0
- package/src/workflows/client/create-client.ts +17 -0
- package/src/workflows/client/index.ts +3 -0
- package/src/workflows/client/sse.ts +95 -0
- package/src/workflows/client/types.ts +56 -0
- package/src/workflows/executor.ts +124 -0
- package/src/workflows/index.ts +7 -0
- package/src/workflows/registry.test.ts +76 -0
- package/src/workflows/registry.ts +88 -0
- package/src/workflows/runner.ts +38 -0
- package/src/workflows/schema.ts +348 -0
- package/src/workflows/task.ts +117 -0
- package/src/workflows/types.ts +89 -0
- package/src/workflows/uds.ts +179 -0
- package/test-types.ts +14 -0
- package/tsconfig.build.json +4 -0
- package/tsconfig.json +23 -0
- 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 @
|
|
18
|
+
npm install @render/sdk
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
Or with yarn:
|
|
22
22
|
|
|
23
23
|
```bash
|
|
24
|
-
yarn add @
|
|
24
|
+
yarn add @render/sdk
|
|
25
25
|
```
|
|
26
26
|
|
|
27
27
|
Or with pnpm:
|
|
28
28
|
|
|
29
29
|
```bash
|
|
30
|
-
pnpm add @
|
|
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 '@
|
|
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 '@
|
|
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 '@
|
|
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 '@
|
|
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 '@
|
|
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 '@
|
|
330
|
+
import { Render } from '@render/sdk';
|
|
331
331
|
import {
|
|
332
332
|
RenderError,
|
|
333
333
|
ClientError,
|
|
334
334
|
ServerError,
|
|
335
335
|
AbortError,
|
|
336
|
-
} from '@
|
|
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 '@
|
|
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 '@
|
|
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 '@
|
|
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 '@
|
|
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 '@
|
|
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,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; } });
|