@renderinc/sdk 0.2.1 → 0.3.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 (62) hide show
  1. package/dist/experimental/object/api.d.ts +2 -1
  2. package/dist/experimental/object/api.d.ts.map +1 -1
  3. package/dist/experimental/object/api.js +20 -3
  4. package/dist/experimental/object/client.d.ts +3 -1
  5. package/dist/experimental/object/client.d.ts.map +1 -1
  6. package/dist/experimental/object/client.js +47 -6
  7. package/dist/experimental/object/index.d.ts +1 -1
  8. package/dist/experimental/object/index.d.ts.map +1 -1
  9. package/dist/experimental/object/types.d.ts +17 -0
  10. package/dist/experimental/object/types.d.ts.map +1 -1
  11. package/dist/generated/schema.d.ts +167 -28
  12. package/dist/generated/schema.d.ts.map +1 -1
  13. package/dist/workflows/uds.d.ts.map +1 -1
  14. package/dist/workflows/uds.js +3 -2
  15. package/package.json +4 -1
  16. package/CHANGELOG.md +0 -33
  17. package/biome.json +0 -84
  18. package/examples/client/main.ts +0 -42
  19. package/examples/client/package-lock.json +0 -601
  20. package/examples/client/package.json +0 -16
  21. package/examples/client/tsconfig.json +0 -17
  22. package/examples/task/main.ts +0 -90
  23. package/examples/task/package-lock.json +0 -584
  24. package/examples/task/package.json +0 -16
  25. package/examples/task/tsconfig.json +0 -17
  26. package/src/errors.test.ts +0 -75
  27. package/src/errors.ts +0 -73
  28. package/src/experimental/experimental.ts +0 -56
  29. package/src/experimental/index.ts +0 -24
  30. package/src/experimental/object/api.ts +0 -91
  31. package/src/experimental/object/client.test.ts +0 -138
  32. package/src/experimental/object/client.ts +0 -317
  33. package/src/experimental/object/index.ts +0 -22
  34. package/src/experimental/object/types.test.ts +0 -87
  35. package/src/experimental/object/types.ts +0 -131
  36. package/src/generated/schema.ts +0 -12937
  37. package/src/index.ts +0 -7
  38. package/src/render.ts +0 -35
  39. package/src/utils/create-api-client.ts +0 -13
  40. package/src/utils/get-base-url.test.ts +0 -58
  41. package/src/utils/get-base-url.ts +0 -16
  42. package/src/version.ts +0 -37
  43. package/src/workflows/client/client.test.ts +0 -68
  44. package/src/workflows/client/client.ts +0 -142
  45. package/src/workflows/client/create-client.ts +0 -17
  46. package/src/workflows/client/index.ts +0 -3
  47. package/src/workflows/client/sse.ts +0 -95
  48. package/src/workflows/client/types.ts +0 -56
  49. package/src/workflows/executor.ts +0 -124
  50. package/src/workflows/index.ts +0 -7
  51. package/src/workflows/registry.test.ts +0 -76
  52. package/src/workflows/registry.ts +0 -88
  53. package/src/workflows/runner.ts +0 -38
  54. package/src/workflows/schema.ts +0 -348
  55. package/src/workflows/task.ts +0 -117
  56. package/src/workflows/types.test.ts +0 -52
  57. package/src/workflows/types.ts +0 -89
  58. package/src/workflows/uds.ts +0 -139
  59. package/test-types.ts +0 -14
  60. package/tsconfig.build.json +0 -4
  61. package/tsconfig.json +0 -23
  62. package/vitest.config.ts +0 -8
@@ -1,17 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2020",
4
- "module": "NodeNext",
5
- "lib": ["ES2020"],
6
- "outDir": "./dist",
7
- "rootDir": ".",
8
- "strict": true,
9
- "esModuleInterop": true,
10
- "skipLibCheck": true,
11
- "forceConsistentCasingInFileNames": true,
12
- "moduleResolution": "NodeNext",
13
- "resolveJsonModule": true
14
- },
15
- "include": ["**/*.ts"],
16
- "exclude": ["node_modules", "dist"]
17
- }
@@ -1,75 +0,0 @@
1
- import {
2
- AbortError,
3
- ClientError,
4
- RenderError,
5
- ServerError,
6
- TaskRunError,
7
- TimeoutError,
8
- } from "./errors.js";
9
-
10
- describe("errors", () => {
11
- describe("RenderError", () => {
12
- it("has correct name and message", () => {
13
- const err = new RenderError("test message");
14
- expect(err.name).toBe("RenderError");
15
- expect(err.message).toBe("test message");
16
- expect(err instanceof Error).toBe(true);
17
- expect(err instanceof RenderError).toBe(true);
18
- });
19
- });
20
-
21
- describe("TaskRunError", () => {
22
- it("has correct name and properties", () => {
23
- const err = new TaskRunError("task failed", "run-123", "internal error");
24
- expect(err.name).toBe("TaskRunError");
25
- expect(err.message).toBe("task failed");
26
- expect(err.taskRunId).toBe("run-123");
27
- expect(err.taskError).toBe("internal error");
28
- expect(err instanceof RenderError).toBe(true);
29
- });
30
-
31
- it("works with optional properties", () => {
32
- const err = new TaskRunError("task failed");
33
- expect(err.taskRunId).toBeUndefined();
34
- expect(err.taskError).toBeUndefined();
35
- });
36
- });
37
-
38
- describe("ClientError", () => {
39
- it("has correct name and properties", () => {
40
- const err = new ClientError("not found", 404, { detail: "missing" });
41
- expect(err.name).toBe("ClientError");
42
- expect(err.statusCode).toBe(404);
43
- expect(err.response).toEqual({ detail: "missing" });
44
- expect(err instanceof RenderError).toBe(true);
45
- });
46
- });
47
-
48
- describe("ServerError", () => {
49
- it("has correct name and properties", () => {
50
- const err = new ServerError("server error", 500, { detail: "crash" });
51
- expect(err.name).toBe("ServerError");
52
- expect(err.statusCode).toBe(500);
53
- expect(err.response).toEqual({ detail: "crash" });
54
- expect(err instanceof RenderError).toBe(true);
55
- });
56
- });
57
-
58
- describe("TimeoutError", () => {
59
- it("has correct name and inherits from RenderError", () => {
60
- const err = new TimeoutError("request timed out");
61
- expect(err.name).toBe("TimeoutError");
62
- expect(err.message).toBe("request timed out");
63
- expect(err instanceof RenderError).toBe(true);
64
- });
65
- });
66
-
67
- describe("AbortError", () => {
68
- it("has correct name and fixed message", () => {
69
- const err = new AbortError();
70
- expect(err.name).toBe("AbortError");
71
- expect(err.message).toBe("The operation was aborted.");
72
- expect(err instanceof Error).toBe(true);
73
- });
74
- });
75
- });
package/src/errors.ts DELETED
@@ -1,73 +0,0 @@
1
- /**
2
- * Base error class for all Render SDK errors
3
- */
4
- export class RenderError extends Error {
5
- constructor(message: string) {
6
- super(message);
7
- this.name = "RenderError";
8
- Object.setPrototypeOf(this, RenderError.prototype);
9
- }
10
- }
11
-
12
- /**
13
- * Error for task execution failures
14
- */
15
- export class TaskRunError extends RenderError {
16
- constructor(
17
- message: string,
18
- public taskRunId?: string,
19
- public taskError?: string,
20
- ) {
21
- super(message);
22
- this.name = "TaskRunError";
23
- Object.setPrototypeOf(this, TaskRunError.prototype);
24
- }
25
- }
26
-
27
- /**
28
- * Error for HTTP client errors (4xx)
29
- */
30
- export class ClientError extends RenderError {
31
- constructor(
32
- message: string,
33
- public statusCode: number,
34
- public response?: any,
35
- ) {
36
- super(message);
37
- this.name = "ClientError";
38
- Object.setPrototypeOf(this, ClientError.prototype);
39
- }
40
- }
41
-
42
- /**
43
- * Error for HTTP server errors (5xx)
44
- */
45
- export class ServerError extends RenderError {
46
- constructor(
47
- message: string,
48
- public statusCode: number,
49
- public response?: any,
50
- ) {
51
- super(message);
52
- this.name = "ServerError";
53
- Object.setPrototypeOf(this, ServerError.prototype);
54
- }
55
- }
56
-
57
- /**
58
- * Error for request timeouts
59
- */
60
- export class TimeoutError extends RenderError {
61
- constructor(message: string) {
62
- super(message);
63
- this.name = "TimeoutError";
64
- Object.setPrototypeOf(this, TimeoutError.prototype);
65
- }
66
- }
67
-
68
- export class AbortError extends Error {
69
- constructor() {
70
- super("The operation was aborted.");
71
- this.name = "AbortError";
72
- }
73
- }
@@ -1,56 +0,0 @@
1
- import type { Client } from "openapi-fetch";
2
- import type { paths } from "../generated/schema.js";
3
- import { ObjectClient } from "./object/client.js";
4
-
5
- /**
6
- * StorageClient provides access to experimental storage features
7
- *
8
- * @example
9
- * ```typescript
10
- * // Access object storage
11
- * await render.experimental.storage.objects.put({
12
- * ownerId: "tea-xxxxx",
13
- * region: "oregon",
14
- * key: "file.png",
15
- * data: buffer
16
- * });
17
- * ```
18
- */
19
- export class StorageClient {
20
- /** Object storage client for managing binary objects */
21
- public readonly objects: ObjectClient;
22
-
23
- constructor(apiClient: Client<paths>) {
24
- this.objects = new ObjectClient(apiClient);
25
- }
26
- }
27
-
28
- /**
29
- * ExperimentalClient provides access to experimental Render SDK features
30
- *
31
- * Features in this namespace may change or be removed without a migration plan.
32
- * When a feature stabilizes, it will be promoted to the main SDK namespace.
33
- *
34
- * @example
35
- * ```typescript
36
- * import { Render } from '@renderinc/sdk';
37
- *
38
- * const render = new Render();
39
- *
40
- * // Access experimental object storage
41
- * await render.experimental.storage.objects.put({
42
- * ownerId: "tea-xxxxx",
43
- * region: "oregon",
44
- * key: "file.png",
45
- * data: buffer
46
- * });
47
- * ```
48
- */
49
- export class ExperimentalClient {
50
- /** Storage client for managing storage features */
51
- public readonly storage: StorageClient;
52
-
53
- constructor(apiClient: Client<paths>) {
54
- this.storage = new StorageClient(apiClient);
55
- }
56
- }
@@ -1,24 +0,0 @@
1
- // Experimental client
2
-
3
- export { ExperimentalClient, StorageClient } from "./experimental.js";
4
- // Object storage exports
5
- export {
6
- type DeleteObjectInput,
7
- type GetObjectInput,
8
- ObjectApi,
9
- ObjectClient,
10
- type ObjectData,
11
- type ObjectIdentifier,
12
- type ObjectScope,
13
- type PresignedDownloadUrl,
14
- type PresignedUploadUrl,
15
- type PutObjectInput,
16
- type PutObjectInputBuffer,
17
- type PutObjectInputStream,
18
- type PutObjectResult,
19
- Region,
20
- type ScopedDeleteObjectInput,
21
- type ScopedGetObjectInput,
22
- ScopedObjectClient,
23
- type ScopedPutObjectInput,
24
- } from "./object/index.js";
@@ -1,91 +0,0 @@
1
- import type { Client } from "openapi-fetch";
2
- import { RenderError } from "../../errors.js";
3
- import type { paths } from "../../generated/schema.js";
4
- import type { PresignedDownloadUrl, PresignedUploadUrl, Region } from "./types.js";
5
-
6
- /**
7
- * Layer 2: Typed Object API Client
8
- *
9
- * Provides idiomatic TypeScript wrapper around the raw OpenAPI client.
10
- * Handles presigned URL flow but still exposes the two-step nature
11
- * (get URL, then upload/download). Useful for advanced use cases
12
- * requiring fine-grained control.
13
- */
14
- export class ObjectApi {
15
- constructor(private readonly apiClient: Client<paths>) {}
16
-
17
- /**
18
- * Get a presigned URL for uploading an object
19
- *
20
- * @param ownerId - Owner ID (workspace team ID)
21
- * @param region - Storage region
22
- * @param key - Object key (path)
23
- * @param sizeBytes - Size of the object in bytes
24
- * @returns Presigned upload URL with expiration and size limit
25
- */
26
- async getUploadUrl(
27
- ownerId: string,
28
- region: Region | string,
29
- key: string,
30
- sizeBytes: number,
31
- ): Promise<PresignedUploadUrl> {
32
- const { data, error } = await this.apiClient.PUT("/blobs/{ownerId}/{region}/{key}", {
33
- params: { path: { ownerId, region: region as Region, key } },
34
- body: { sizeBytes },
35
- });
36
-
37
- if (error) {
38
- throw new RenderError(`Failed to get upload URL: ${error.message || "Unknown error"}`);
39
- }
40
-
41
- return {
42
- url: data.url,
43
- expiresAt: new Date(data.expiresAt),
44
- maxSizeBytes: data.maxSizeBytes,
45
- };
46
- }
47
-
48
- /**
49
- * Get a presigned URL for downloading an object
50
- *
51
- * @param ownerId - Owner ID (workspace team ID)
52
- * @param region - Storage region
53
- * @param key - Object key (path)
54
- * @returns Presigned download URL with expiration
55
- */
56
- async getDownloadUrl(
57
- ownerId: string,
58
- region: Region | string,
59
- key: string,
60
- ): Promise<PresignedDownloadUrl> {
61
- const { data, error } = await this.apiClient.GET("/blobs/{ownerId}/{region}/{key}", {
62
- params: { path: { ownerId, region: region as Region, key } },
63
- });
64
-
65
- if (error) {
66
- throw new RenderError(`Failed to get download URL: ${error.message || "Unknown error"}`);
67
- }
68
-
69
- return {
70
- url: data.url,
71
- expiresAt: new Date(data.expiresAt),
72
- };
73
- }
74
-
75
- /**
76
- * Delete an object
77
- *
78
- * @param ownerId - Owner ID (workspace team ID)
79
- * @param region - Storage region
80
- * @param key - Object key (path)
81
- */
82
- async delete(ownerId: string, region: Region | string, key: string): Promise<void> {
83
- const { error } = await this.apiClient.DELETE("/blobs/{ownerId}/{region}/{key}", {
84
- params: { path: { ownerId, region: region as Region, key } },
85
- });
86
-
87
- if (error) {
88
- throw new RenderError(`Failed to delete object: ${error.message || "Unknown error"}`);
89
- }
90
- }
91
- }
@@ -1,138 +0,0 @@
1
- import { Readable } from "node:stream";
2
- import type { Client } from "openapi-fetch";
3
- import { RenderError } from "../../errors.js";
4
- import type { paths } from "../../generated/schema.js";
5
- import { ObjectClient } from "./client.js";
6
- import type { PutObjectInput } from "./types.js";
7
-
8
- describe("ObjectClient", () => {
9
- describe("resolveSize (via put validation)", () => {
10
- // Test resolveSize indirectly by calling put() which will fail
11
- // at the API call stage, but size validation happens first.
12
- const putMock = vi.fn().mockRejectedValue(new Error("should not reach API"));
13
- const mockApiClient = { PUT: putMock } as unknown as Client<paths>;
14
-
15
- const client = new ObjectClient(mockApiClient);
16
-
17
- it("auto-calculates Buffer size", async () => {
18
- const buffer = Buffer.from("hello");
19
- putMock.mockResolvedValueOnce({
20
- data: { url: "http://test" },
21
- error: null,
22
- });
23
-
24
- // Will fail at fetch, but that's after size validation
25
- await expect(
26
- client.put({
27
- ownerId: "tea-test",
28
- region: "oregon",
29
- key: "test.txt",
30
- data: buffer,
31
- }),
32
- ).rejects.toThrow(); // fetch not available in test
33
-
34
- expect(putMock).toHaveBeenCalledWith(
35
- "/blobs/{ownerId}/{region}/{key}",
36
- expect.objectContaining({
37
- body: { sizeBytes: 5 },
38
- }),
39
- );
40
- });
41
-
42
- it("auto-calculates Uint8Array size", async () => {
43
- const arr = new Uint8Array([1, 2, 3, 4]);
44
- putMock.mockResolvedValueOnce({
45
- data: { url: "http://test" },
46
- error: null,
47
- });
48
-
49
- await expect(
50
- client.put({
51
- ownerId: "tea-test",
52
- region: "oregon",
53
- key: "test.bin",
54
- data: arr,
55
- }),
56
- ).rejects.toThrow();
57
-
58
- expect(putMock).toHaveBeenCalledWith(
59
- "/blobs/{ownerId}/{region}/{key}",
60
- expect.objectContaining({
61
- body: { sizeBytes: 4 },
62
- }),
63
- );
64
- });
65
-
66
- it("throws on size mismatch for Buffer", async () => {
67
- const buffer = Buffer.from("hello");
68
- await expect(
69
- client.put({
70
- ownerId: "tea-test",
71
- region: "oregon",
72
- key: "test.txt",
73
- data: buffer,
74
- size: 10,
75
- }),
76
- ).rejects.toThrow(RenderError);
77
- await expect(
78
- client.put({
79
- ownerId: "tea-test",
80
- region: "oregon",
81
- key: "test.txt",
82
- data: buffer,
83
- size: 10,
84
- }),
85
- ).rejects.toThrow("Size mismatch");
86
- });
87
-
88
- it("requires size for stream input", async () => {
89
- const stream = Readable.from(["hello"]);
90
- const invalidInput = {
91
- ownerId: "tea-test",
92
- region: "oregon",
93
- key: "test.txt",
94
- data: stream,
95
- // Intentionally omit size to test validation (invalid at runtime)
96
- } as unknown as PutObjectInput;
97
- await expect(client.put(invalidInput)).rejects.toThrow(RenderError);
98
- await expect(client.put(invalidInput)).rejects.toThrow("Size is required");
99
- });
100
-
101
- it("requires size for string input", async () => {
102
- await expect(
103
- client.put({
104
- ownerId: "tea-test",
105
- region: "oregon",
106
- key: "test.txt",
107
- data: "hello",
108
- }),
109
- ).rejects.toThrow("Size is required");
110
- });
111
-
112
- it("throws on zero size", async () => {
113
- const stream = Readable.from(["hello"]);
114
- await expect(
115
- client.put({
116
- ownerId: "tea-test",
117
- region: "oregon",
118
- key: "test.txt",
119
- data: stream,
120
- size: 0,
121
- }),
122
- ).rejects.toThrow("Size must be a positive integer");
123
- });
124
-
125
- it("throws on negative size", async () => {
126
- const stream = Readable.from(["hello"]);
127
- await expect(
128
- client.put({
129
- ownerId: "tea-test",
130
- region: "oregon",
131
- key: "test.txt",
132
- data: stream,
133
- size: -1,
134
- }),
135
- ).rejects.toThrow("Size must be a positive integer");
136
- });
137
- });
138
- });