@computesdk/render 1.1.7 → 1.1.9

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/README.md CHANGED
@@ -19,26 +19,45 @@ RENDER_OWNER_ID=your_render_owner_id
19
19
 
20
20
  ## Usage
21
21
 
22
+ ### Gateway Mode (Recommended)
23
+
24
+ Use the gateway for zero-config auto-detection:
25
+
26
+ ```typescript
27
+ import { compute } from 'computesdk';
28
+
29
+ // Auto-detects Render from RENDER_API_KEY environment variable
30
+ const sandbox = await compute.sandbox.create();
31
+ console.log(`Created sandbox: ${sandbox.id}`);
32
+
33
+ // List all sandboxes
34
+ const sandboxes = await compute.sandbox.list();
35
+
36
+ // Destroy the sandbox
37
+ await sandbox.destroy();
38
+ ```
39
+
40
+ ### Direct Mode
41
+
42
+ For direct SDK usage without the gateway:
43
+
22
44
  ```typescript
23
45
  import { render } from '@computesdk/render';
24
46
 
25
- const provider = render({
47
+ const compute = render({
26
48
  apiKey: 'your_api_key',
27
49
  ownerId: 'your_owner_id'
28
50
  });
29
51
 
30
52
  // Create a sandbox
31
- const sandbox = await provider.sandbox.create({ runtime: 'node' });
32
- console.log(`Created sandbox: ${sandbox.sandboxId}`);
33
-
34
- // Get sandbox by ID
35
- const retrieved = await provider.sandbox.getById(sandbox.sandboxId);
53
+ const sandbox = await compute.sandbox.create({ runtime: 'node' });
54
+ console.log(`Created sandbox: ${sandbox.id}`);
36
55
 
37
56
  // List all sandboxes
38
- const sandboxes = await provider.sandbox.list();
57
+ const sandboxes = await compute.sandbox.list();
39
58
 
40
59
  // Destroy the sandbox
41
- await provider.sandbox.destroy(sandbox.sandboxId);
60
+ await sandbox.destroy();
42
61
  ```
43
62
 
44
63
  ## Currently Implemented
package/dist/index.js CHANGED
@@ -178,7 +178,7 @@ var render = (0, import_provider.defineProvider)({
178
178
  runCode: async (_sandbox, _code, _runtime) => {
179
179
  throw new Error("Render runCode method not implemented yet");
180
180
  },
181
- runCommand: async (_sandbox, _command, _args, _options) => {
181
+ runCommand: async (_sandbox, _command, _options) => {
182
182
  throw new Error("Render runCommand method not implemented yet");
183
183
  },
184
184
  getInfo: async (_sandbox) => {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Render Provider - Factory-based Implementation\n */\n\nimport { defineProvider } from '@computesdk/provider';\n\nimport type { Runtime, CodeResult, CommandResult, SandboxInfo, CreateSandboxOptions, FileEntry, RunCommandOptions } from '@computesdk/provider';\n\n/**\n * Render sandbox interface\n */\ninterface RenderSandbox {\n serviceId: string;\n ownerId: string;\n}\n\nexport interface RenderConfig {\n /** Render API key - if not provided, will fallback to RENDER_API_KEY environment variable */\n apiKey?: string;\n /** Render Owner ID - if not provided, will fallback to RENDER_OWNER_ID environment variable */\n ownerId?: string;\n}\n\nexport const getAndValidateCredentials = (config: RenderConfig) => {\n const apiKey = config.apiKey || (typeof process !== 'undefined' && process.env?.RENDER_API_KEY) || '';\n const ownerId = config.ownerId || (typeof process !== 'undefined' && process.env?.RENDER_OWNER_ID) || '';\n\n if (!apiKey) {\n throw new Error(\n 'Missing Render API key. Provide apiKey in config or set RENDER_API_KEY environment variable.'\n );\n }\n\n if (!ownerId) {\n throw new Error(\n 'Missing Render Owner ID. Provide ownerId in config or set RENDER_OWNER_ID environment variable.'\n );\n }\n\n return { apiKey, ownerId };\n};\n\nexport const fetchRender = async (\n apiKey: string,\n endpoint: string,\n options: RequestInit = {}\n) => {\n const url = `https://api.render.com/v1${endpoint}`;\n const requestOptions = {\n method: 'GET',\n ...options,\n headers: {\n 'Accept': 'application/json',\n 'Authorization': `Bearer ${apiKey}`,\n ...(options.headers || {})\n }\n };\n \n const response = await fetch(url, requestOptions);\n\n if (!response.ok) {\n throw new Error(`Render API error: ${response.status} ${response.statusText}`);\n }\n\n // Handle 204 No Content responses (like DELETE operations)\n if (response.status === 204) {\n return {};\n }\n\n return response.json();\n};\n\n\n\n/**\n * Create a Render provider instance using the factory pattern\n */\nexport const render = defineProvider<RenderSandbox, RenderConfig>({\n name: 'render',\n methods: {\n sandbox: {\n // Collection operations (compute.sandbox.*)\n create: async (config: RenderConfig, options?: CreateSandboxOptions) => {\n const { apiKey, ownerId } = getAndValidateCredentials(config);\n\n try {\n const createServiceData = {\n type: 'web_service',\n autoDeploy: 'yes',\n image: {\n ownerId: ownerId,\n imagePath: options?.runtime === 'node' ? 'docker.io/traefik/whoami' : 'docker.io/traefik/whoami'\n },\n serviceDetails: {\n runtime: 'image',\n envSpecificDetails: {\n dockerCommand: options?.runtime === 'node' ? '/whoami --port 10000' : '/whoami --port 10000'\n },\n pullRequestPreviewsEnabled: 'no'\n },\n ownerId: ownerId,\n name: `render-sandbox-${Date.now()}`\n };\n\n\n const responseData = await fetchRender(apiKey, '/services', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(createServiceData)\n });\n \n if (!responseData) {\n throw new Error('No service returned from Render API');\n }\n \n // Render API returns { service: { id: \"...\", ... }, deployId: \"...\" }\n const service = responseData.service;\n if (!service || !service.id) {\n throw new Error(`Service ID is undefined. Full response: ${JSON.stringify(responseData, null, 2)}`);\n }\n\n const renderSandbox: RenderSandbox = {\n serviceId: service.id,\n ownerId,\n };\n\n return {\n sandbox: renderSandbox,\n sandboxId: service.id\n };\n } catch (error) {\n throw new Error(\n `Failed to create Render sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n getById: async (config: RenderConfig, sandboxId: string) => {\n const { apiKey, ownerId } = getAndValidateCredentials(config);\n\n try {\n const responseData = await fetchRender(apiKey, `/services/${sandboxId}`);\n \n // If service doesn't exist, the API will throw an error which we catch\n if (!responseData) {\n return null;\n }\n \n // Service should be defined if we get here\n if (!responseData.id) {\n throw new Error('Service data is missing from Render response');\n }\n \n const renderSandbox: RenderSandbox = {\n serviceId: responseData.id,\n ownerId,\n };\n\n return {\n sandbox: renderSandbox,\n sandboxId: responseData.id\n };\n } catch (error) {\n // If it's a 404, return null to indicate service not found\n if (error instanceof Error && error.message.includes('404')) {\n return null;\n }\n throw new Error(\n `Failed to get Render sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n \n list: async (config: RenderConfig) => {\n const { apiKey, ownerId } = getAndValidateCredentials(config);\n\n try {\n const responseData = await fetchRender(apiKey, '/services?includePreviews=true&limit=20');\n \n // Extract services from the array response - each item has a \"service\" property\n const items = responseData || [];\n \n // Transform each service into the expected format\n const sandboxes = items.map((item: any) => {\n const service = item.service;\n const renderSandbox: RenderSandbox = {\n serviceId: service.id,\n ownerId,\n };\n\n return {\n sandbox: renderSandbox,\n sandboxId: service.id\n };\n });\n\n return sandboxes;\n } catch (error) {\n throw new Error(\n `Failed to list Render sandboxes: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n destroy: async (config: RenderConfig, sandboxId: string) => {\n const { apiKey } = getAndValidateCredentials(config);\n\n try {\n await fetchRender(apiKey, `/services/${sandboxId}`, {\n method: 'DELETE'\n });\n } catch (error) {\n // For destroy operations, we typically don't throw if the service is already gone\n console.warn(`Render destroy warning: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n // Instance operations (minimal stubs - not implemented yet)\n runCode: async (_sandbox: RenderSandbox, _code: string, _runtime?: Runtime) => {\n throw new Error('Render runCode method not implemented yet');\n },\n\n runCommand: async (_sandbox: RenderSandbox, _command: string, _args?: string[], _options?: RunCommandOptions) => {\n throw new Error('Render runCommand method not implemented yet');\n },\n\n getInfo: async (_sandbox: RenderSandbox) => {\n throw new Error('Render getInfo method not implemented yet');\n },\n\n getUrl: async (_sandbox: RenderSandbox, _options: { port: number; protocol?: string }) => {\n throw new Error('Render getUrl method not implemented yet');\n },\n\n },\n },\n});\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Render Provider - Factory-based Implementation\n */\n\nimport { defineProvider } from '@computesdk/provider';\n\nimport type { Runtime, CodeResult, CommandResult, SandboxInfo, CreateSandboxOptions, FileEntry, RunCommandOptions } from '@computesdk/provider';\n\n/**\n * Render sandbox interface\n */\ninterface RenderSandbox {\n serviceId: string;\n ownerId: string;\n}\n\nexport interface RenderConfig {\n /** Render API key - if not provided, will fallback to RENDER_API_KEY environment variable */\n apiKey?: string;\n /** Render Owner ID - if not provided, will fallback to RENDER_OWNER_ID environment variable */\n ownerId?: string;\n}\n\nexport const getAndValidateCredentials = (config: RenderConfig) => {\n const apiKey = config.apiKey || (typeof process !== 'undefined' && process.env?.RENDER_API_KEY) || '';\n const ownerId = config.ownerId || (typeof process !== 'undefined' && process.env?.RENDER_OWNER_ID) || '';\n\n if (!apiKey) {\n throw new Error(\n 'Missing Render API key. Provide apiKey in config or set RENDER_API_KEY environment variable.'\n );\n }\n\n if (!ownerId) {\n throw new Error(\n 'Missing Render Owner ID. Provide ownerId in config or set RENDER_OWNER_ID environment variable.'\n );\n }\n\n return { apiKey, ownerId };\n};\n\nexport const fetchRender = async (\n apiKey: string,\n endpoint: string,\n options: RequestInit = {}\n) => {\n const url = `https://api.render.com/v1${endpoint}`;\n const requestOptions = {\n method: 'GET',\n ...options,\n headers: {\n 'Accept': 'application/json',\n 'Authorization': `Bearer ${apiKey}`,\n ...(options.headers || {})\n }\n };\n \n const response = await fetch(url, requestOptions);\n\n if (!response.ok) {\n throw new Error(`Render API error: ${response.status} ${response.statusText}`);\n }\n\n // Handle 204 No Content responses (like DELETE operations)\n if (response.status === 204) {\n return {};\n }\n\n return response.json();\n};\n\n\n\n/**\n * Create a Render provider instance using the factory pattern\n */\nexport const render = defineProvider<RenderSandbox, RenderConfig>({\n name: 'render',\n methods: {\n sandbox: {\n // Collection operations (compute.sandbox.*)\n create: async (config: RenderConfig, options?: CreateSandboxOptions) => {\n const { apiKey, ownerId } = getAndValidateCredentials(config);\n\n try {\n const createServiceData = {\n type: 'web_service',\n autoDeploy: 'yes',\n image: {\n ownerId: ownerId,\n imagePath: options?.runtime === 'node' ? 'docker.io/traefik/whoami' : 'docker.io/traefik/whoami'\n },\n serviceDetails: {\n runtime: 'image',\n envSpecificDetails: {\n dockerCommand: options?.runtime === 'node' ? '/whoami --port 10000' : '/whoami --port 10000'\n },\n pullRequestPreviewsEnabled: 'no'\n },\n ownerId: ownerId,\n name: `render-sandbox-${Date.now()}`\n };\n\n\n const responseData = await fetchRender(apiKey, '/services', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(createServiceData)\n });\n \n if (!responseData) {\n throw new Error('No service returned from Render API');\n }\n \n // Render API returns { service: { id: \"...\", ... }, deployId: \"...\" }\n const service = responseData.service;\n if (!service || !service.id) {\n throw new Error(`Service ID is undefined. Full response: ${JSON.stringify(responseData, null, 2)}`);\n }\n\n const renderSandbox: RenderSandbox = {\n serviceId: service.id,\n ownerId,\n };\n\n return {\n sandbox: renderSandbox,\n sandboxId: service.id\n };\n } catch (error) {\n throw new Error(\n `Failed to create Render sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n getById: async (config: RenderConfig, sandboxId: string) => {\n const { apiKey, ownerId } = getAndValidateCredentials(config);\n\n try {\n const responseData = await fetchRender(apiKey, `/services/${sandboxId}`);\n \n // If service doesn't exist, the API will throw an error which we catch\n if (!responseData) {\n return null;\n }\n \n // Service should be defined if we get here\n if (!responseData.id) {\n throw new Error('Service data is missing from Render response');\n }\n \n const renderSandbox: RenderSandbox = {\n serviceId: responseData.id,\n ownerId,\n };\n\n return {\n sandbox: renderSandbox,\n sandboxId: responseData.id\n };\n } catch (error) {\n // If it's a 404, return null to indicate service not found\n if (error instanceof Error && error.message.includes('404')) {\n return null;\n }\n throw new Error(\n `Failed to get Render sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n \n list: async (config: RenderConfig) => {\n const { apiKey, ownerId } = getAndValidateCredentials(config);\n\n try {\n const responseData = await fetchRender(apiKey, '/services?includePreviews=true&limit=20');\n \n // Extract services from the array response - each item has a \"service\" property\n const items = responseData || [];\n \n // Transform each service into the expected format\n const sandboxes = items.map((item: any) => {\n const service = item.service;\n const renderSandbox: RenderSandbox = {\n serviceId: service.id,\n ownerId,\n };\n\n return {\n sandbox: renderSandbox,\n sandboxId: service.id\n };\n });\n\n return sandboxes;\n } catch (error) {\n throw new Error(\n `Failed to list Render sandboxes: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n destroy: async (config: RenderConfig, sandboxId: string) => {\n const { apiKey } = getAndValidateCredentials(config);\n\n try {\n await fetchRender(apiKey, `/services/${sandboxId}`, {\n method: 'DELETE'\n });\n } catch (error) {\n // For destroy operations, we typically don't throw if the service is already gone\n console.warn(`Render destroy warning: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n // Instance operations (minimal stubs - not implemented yet)\n runCode: async (_sandbox: RenderSandbox, _code: string, _runtime?: Runtime) => {\n throw new Error('Render runCode method not implemented yet');\n },\n\n runCommand: async (_sandbox: RenderSandbox, _command: string, _options?: RunCommandOptions) => {\n throw new Error('Render runCommand method not implemented yet');\n },\n\n getInfo: async (_sandbox: RenderSandbox) => {\n throw new Error('Render getInfo method not implemented yet');\n },\n\n getUrl: async (_sandbox: RenderSandbox, _options: { port: number; protocol?: string }) => {\n throw new Error('Render getUrl method not implemented yet');\n },\n\n },\n },\n});\n"],"mappings":"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","names":[]}
package/dist/index.mjs CHANGED
@@ -152,7 +152,7 @@ var render = defineProvider({
152
152
  runCode: async (_sandbox, _code, _runtime) => {
153
153
  throw new Error("Render runCode method not implemented yet");
154
154
  },
155
- runCommand: async (_sandbox, _command, _args, _options) => {
155
+ runCommand: async (_sandbox, _command, _options) => {
156
156
  throw new Error("Render runCommand method not implemented yet");
157
157
  },
158
158
  getInfo: async (_sandbox) => {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Render Provider - Factory-based Implementation\n */\n\nimport { defineProvider } from '@computesdk/provider';\n\nimport type { Runtime, CodeResult, CommandResult, SandboxInfo, CreateSandboxOptions, FileEntry, RunCommandOptions } from '@computesdk/provider';\n\n/**\n * Render sandbox interface\n */\ninterface RenderSandbox {\n serviceId: string;\n ownerId: string;\n}\n\nexport interface RenderConfig {\n /** Render API key - if not provided, will fallback to RENDER_API_KEY environment variable */\n apiKey?: string;\n /** Render Owner ID - if not provided, will fallback to RENDER_OWNER_ID environment variable */\n ownerId?: string;\n}\n\nexport const getAndValidateCredentials = (config: RenderConfig) => {\n const apiKey = config.apiKey || (typeof process !== 'undefined' && process.env?.RENDER_API_KEY) || '';\n const ownerId = config.ownerId || (typeof process !== 'undefined' && process.env?.RENDER_OWNER_ID) || '';\n\n if (!apiKey) {\n throw new Error(\n 'Missing Render API key. Provide apiKey in config or set RENDER_API_KEY environment variable.'\n );\n }\n\n if (!ownerId) {\n throw new Error(\n 'Missing Render Owner ID. Provide ownerId in config or set RENDER_OWNER_ID environment variable.'\n );\n }\n\n return { apiKey, ownerId };\n};\n\nexport const fetchRender = async (\n apiKey: string,\n endpoint: string,\n options: RequestInit = {}\n) => {\n const url = `https://api.render.com/v1${endpoint}`;\n const requestOptions = {\n method: 'GET',\n ...options,\n headers: {\n 'Accept': 'application/json',\n 'Authorization': `Bearer ${apiKey}`,\n ...(options.headers || {})\n }\n };\n \n const response = await fetch(url, requestOptions);\n\n if (!response.ok) {\n throw new Error(`Render API error: ${response.status} ${response.statusText}`);\n }\n\n // Handle 204 No Content responses (like DELETE operations)\n if (response.status === 204) {\n return {};\n }\n\n return response.json();\n};\n\n\n\n/**\n * Create a Render provider instance using the factory pattern\n */\nexport const render = defineProvider<RenderSandbox, RenderConfig>({\n name: 'render',\n methods: {\n sandbox: {\n // Collection operations (compute.sandbox.*)\n create: async (config: RenderConfig, options?: CreateSandboxOptions) => {\n const { apiKey, ownerId } = getAndValidateCredentials(config);\n\n try {\n const createServiceData = {\n type: 'web_service',\n autoDeploy: 'yes',\n image: {\n ownerId: ownerId,\n imagePath: options?.runtime === 'node' ? 'docker.io/traefik/whoami' : 'docker.io/traefik/whoami'\n },\n serviceDetails: {\n runtime: 'image',\n envSpecificDetails: {\n dockerCommand: options?.runtime === 'node' ? '/whoami --port 10000' : '/whoami --port 10000'\n },\n pullRequestPreviewsEnabled: 'no'\n },\n ownerId: ownerId,\n name: `render-sandbox-${Date.now()}`\n };\n\n\n const responseData = await fetchRender(apiKey, '/services', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(createServiceData)\n });\n \n if (!responseData) {\n throw new Error('No service returned from Render API');\n }\n \n // Render API returns { service: { id: \"...\", ... }, deployId: \"...\" }\n const service = responseData.service;\n if (!service || !service.id) {\n throw new Error(`Service ID is undefined. Full response: ${JSON.stringify(responseData, null, 2)}`);\n }\n\n const renderSandbox: RenderSandbox = {\n serviceId: service.id,\n ownerId,\n };\n\n return {\n sandbox: renderSandbox,\n sandboxId: service.id\n };\n } catch (error) {\n throw new Error(\n `Failed to create Render sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n getById: async (config: RenderConfig, sandboxId: string) => {\n const { apiKey, ownerId } = getAndValidateCredentials(config);\n\n try {\n const responseData = await fetchRender(apiKey, `/services/${sandboxId}`);\n \n // If service doesn't exist, the API will throw an error which we catch\n if (!responseData) {\n return null;\n }\n \n // Service should be defined if we get here\n if (!responseData.id) {\n throw new Error('Service data is missing from Render response');\n }\n \n const renderSandbox: RenderSandbox = {\n serviceId: responseData.id,\n ownerId,\n };\n\n return {\n sandbox: renderSandbox,\n sandboxId: responseData.id\n };\n } catch (error) {\n // If it's a 404, return null to indicate service not found\n if (error instanceof Error && error.message.includes('404')) {\n return null;\n }\n throw new Error(\n `Failed to get Render sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n \n list: async (config: RenderConfig) => {\n const { apiKey, ownerId } = getAndValidateCredentials(config);\n\n try {\n const responseData = await fetchRender(apiKey, '/services?includePreviews=true&limit=20');\n \n // Extract services from the array response - each item has a \"service\" property\n const items = responseData || [];\n \n // Transform each service into the expected format\n const sandboxes = items.map((item: any) => {\n const service = item.service;\n const renderSandbox: RenderSandbox = {\n serviceId: service.id,\n ownerId,\n };\n\n return {\n sandbox: renderSandbox,\n sandboxId: service.id\n };\n });\n\n return sandboxes;\n } catch (error) {\n throw new Error(\n `Failed to list Render sandboxes: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n destroy: async (config: RenderConfig, sandboxId: string) => {\n const { apiKey } = getAndValidateCredentials(config);\n\n try {\n await fetchRender(apiKey, `/services/${sandboxId}`, {\n method: 'DELETE'\n });\n } catch (error) {\n // For destroy operations, we typically don't throw if the service is already gone\n console.warn(`Render destroy warning: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n // Instance operations (minimal stubs - not implemented yet)\n runCode: async (_sandbox: RenderSandbox, _code: string, _runtime?: Runtime) => {\n throw new Error('Render runCode method not implemented yet');\n },\n\n runCommand: async (_sandbox: RenderSandbox, _command: string, _args?: string[], _options?: RunCommandOptions) => {\n throw new Error('Render runCommand method not implemented yet');\n },\n\n getInfo: async (_sandbox: RenderSandbox) => {\n throw new Error('Render getInfo method not implemented yet');\n },\n\n getUrl: async (_sandbox: RenderSandbox, _options: { port: number; protocol?: string }) => {\n throw new Error('Render getUrl method not implemented yet');\n },\n\n },\n },\n});\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Render Provider - Factory-based Implementation\n */\n\nimport { defineProvider } from '@computesdk/provider';\n\nimport type { Runtime, CodeResult, CommandResult, SandboxInfo, CreateSandboxOptions, FileEntry, RunCommandOptions } from '@computesdk/provider';\n\n/**\n * Render sandbox interface\n */\ninterface RenderSandbox {\n serviceId: string;\n ownerId: string;\n}\n\nexport interface RenderConfig {\n /** Render API key - if not provided, will fallback to RENDER_API_KEY environment variable */\n apiKey?: string;\n /** Render Owner ID - if not provided, will fallback to RENDER_OWNER_ID environment variable */\n ownerId?: string;\n}\n\nexport const getAndValidateCredentials = (config: RenderConfig) => {\n const apiKey = config.apiKey || (typeof process !== 'undefined' && process.env?.RENDER_API_KEY) || '';\n const ownerId = config.ownerId || (typeof process !== 'undefined' && process.env?.RENDER_OWNER_ID) || '';\n\n if (!apiKey) {\n throw new Error(\n 'Missing Render API key. Provide apiKey in config or set RENDER_API_KEY environment variable.'\n );\n }\n\n if (!ownerId) {\n throw new Error(\n 'Missing Render Owner ID. Provide ownerId in config or set RENDER_OWNER_ID environment variable.'\n );\n }\n\n return { apiKey, ownerId };\n};\n\nexport const fetchRender = async (\n apiKey: string,\n endpoint: string,\n options: RequestInit = {}\n) => {\n const url = `https://api.render.com/v1${endpoint}`;\n const requestOptions = {\n method: 'GET',\n ...options,\n headers: {\n 'Accept': 'application/json',\n 'Authorization': `Bearer ${apiKey}`,\n ...(options.headers || {})\n }\n };\n \n const response = await fetch(url, requestOptions);\n\n if (!response.ok) {\n throw new Error(`Render API error: ${response.status} ${response.statusText}`);\n }\n\n // Handle 204 No Content responses (like DELETE operations)\n if (response.status === 204) {\n return {};\n }\n\n return response.json();\n};\n\n\n\n/**\n * Create a Render provider instance using the factory pattern\n */\nexport const render = defineProvider<RenderSandbox, RenderConfig>({\n name: 'render',\n methods: {\n sandbox: {\n // Collection operations (compute.sandbox.*)\n create: async (config: RenderConfig, options?: CreateSandboxOptions) => {\n const { apiKey, ownerId } = getAndValidateCredentials(config);\n\n try {\n const createServiceData = {\n type: 'web_service',\n autoDeploy: 'yes',\n image: {\n ownerId: ownerId,\n imagePath: options?.runtime === 'node' ? 'docker.io/traefik/whoami' : 'docker.io/traefik/whoami'\n },\n serviceDetails: {\n runtime: 'image',\n envSpecificDetails: {\n dockerCommand: options?.runtime === 'node' ? '/whoami --port 10000' : '/whoami --port 10000'\n },\n pullRequestPreviewsEnabled: 'no'\n },\n ownerId: ownerId,\n name: `render-sandbox-${Date.now()}`\n };\n\n\n const responseData = await fetchRender(apiKey, '/services', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(createServiceData)\n });\n \n if (!responseData) {\n throw new Error('No service returned from Render API');\n }\n \n // Render API returns { service: { id: \"...\", ... }, deployId: \"...\" }\n const service = responseData.service;\n if (!service || !service.id) {\n throw new Error(`Service ID is undefined. Full response: ${JSON.stringify(responseData, null, 2)}`);\n }\n\n const renderSandbox: RenderSandbox = {\n serviceId: service.id,\n ownerId,\n };\n\n return {\n sandbox: renderSandbox,\n sandboxId: service.id\n };\n } catch (error) {\n throw new Error(\n `Failed to create Render sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n getById: async (config: RenderConfig, sandboxId: string) => {\n const { apiKey, ownerId } = getAndValidateCredentials(config);\n\n try {\n const responseData = await fetchRender(apiKey, `/services/${sandboxId}`);\n \n // If service doesn't exist, the API will throw an error which we catch\n if (!responseData) {\n return null;\n }\n \n // Service should be defined if we get here\n if (!responseData.id) {\n throw new Error('Service data is missing from Render response');\n }\n \n const renderSandbox: RenderSandbox = {\n serviceId: responseData.id,\n ownerId,\n };\n\n return {\n sandbox: renderSandbox,\n sandboxId: responseData.id\n };\n } catch (error) {\n // If it's a 404, return null to indicate service not found\n if (error instanceof Error && error.message.includes('404')) {\n return null;\n }\n throw new Error(\n `Failed to get Render sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n \n list: async (config: RenderConfig) => {\n const { apiKey, ownerId } = getAndValidateCredentials(config);\n\n try {\n const responseData = await fetchRender(apiKey, '/services?includePreviews=true&limit=20');\n \n // Extract services from the array response - each item has a \"service\" property\n const items = responseData || [];\n \n // Transform each service into the expected format\n const sandboxes = items.map((item: any) => {\n const service = item.service;\n const renderSandbox: RenderSandbox = {\n serviceId: service.id,\n ownerId,\n };\n\n return {\n sandbox: renderSandbox,\n sandboxId: service.id\n };\n });\n\n return sandboxes;\n } catch (error) {\n throw new Error(\n `Failed to list Render sandboxes: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n destroy: async (config: RenderConfig, sandboxId: string) => {\n const { apiKey } = getAndValidateCredentials(config);\n\n try {\n await fetchRender(apiKey, `/services/${sandboxId}`, {\n method: 'DELETE'\n });\n } catch (error) {\n // For destroy operations, we typically don't throw if the service is already gone\n console.warn(`Render destroy warning: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n // Instance operations (minimal stubs - not implemented yet)\n runCode: async (_sandbox: RenderSandbox, _code: string, _runtime?: Runtime) => {\n throw new Error('Render runCode method not implemented yet');\n },\n\n runCommand: async (_sandbox: RenderSandbox, _command: string, _options?: RunCommandOptions) => {\n throw new Error('Render runCommand method not implemented yet');\n },\n\n getInfo: async (_sandbox: RenderSandbox) => {\n throw new Error('Render getInfo method not implemented yet');\n },\n\n getUrl: async (_sandbox: RenderSandbox, _options: { port: number; protocol?: string }) => {\n throw new Error('Render getUrl method not implemented yet');\n },\n\n },\n },\n});\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@computesdk/render",
3
- "version": "1.1.7",
3
+ "version": "1.1.9",
4
4
  "description": "Render provider for ComputeSDK - managed cloud containers with automatic scaling",
5
5
  "author": "ComputeSDK Team",
6
6
  "license": "MIT",
@@ -18,8 +18,8 @@
18
18
  "dist"
19
19
  ],
20
20
  "dependencies": {
21
- "@computesdk/provider": "1.0.1",
22
- "computesdk": "1.10.1"
21
+ "@computesdk/provider": "1.0.3",
22
+ "computesdk": "1.10.2"
23
23
  },
24
24
  "keywords": [
25
25
  "computesdk",
@@ -49,7 +49,7 @@
49
49
  "tsup": "^8.0.0",
50
50
  "typescript": "^5.0.0",
51
51
  "vitest": "^1.0.0",
52
- "@computesdk/test-utils": "1.5.0"
52
+ "@computesdk/test-utils": "1.5.1"
53
53
  },
54
54
  "scripts": {
55
55
  "build": "tsup",