@computesdk/namespace 1.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 computesdk
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,134 @@
1
+ # @computesdk/namespace
2
+
3
+ Namespace provider for ComputeSDK that enables creating and managing containerized compute instances on Namespace's cloud infrastructure.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @computesdk/namespace
9
+ ```
10
+
11
+ ## Configuration
12
+
13
+ The Namespace provider requires the following environment variable:
14
+
15
+ ```bash
16
+ NSC_TOKEN=your_namespace_token
17
+ ```
18
+
19
+ ## Usage
20
+
21
+ ```typescript
22
+ import { namespace } from '@computesdk/namespace';
23
+
24
+ const provider = namespace({
25
+ token: 'your_nsc_token',
26
+ virtualCpu: 2,
27
+ memoryMegabytes: 4096,
28
+ documentedPurpose: 'Development sandbox'
29
+ });
30
+
31
+ // Create a sandbox
32
+ const sandbox = await provider.sandbox.create({ runtime: 'node' });
33
+ console.log(`Created sandbox: ${sandbox.sandboxId}`);
34
+
35
+ // Get sandbox details
36
+ const details = await provider.sandbox.getById(sandbox.sandboxId);
37
+ console.log(`Sandbox status:`, details);
38
+
39
+ // List all sandboxes
40
+ const sandboxes = await provider.sandbox.list();
41
+ console.log(`Found ${sandboxes.length} sandboxes`);
42
+
43
+ // Destroy the sandbox
44
+ await provider.sandbox.destroy(sandbox.sandboxId);
45
+ ```
46
+
47
+ ## API Methods
48
+
49
+ ### Sandbox Operations
50
+
51
+ #### `create(options?: CreateSandboxOptions)`
52
+ Creates a new Namespace compute instance with the specified configuration.
53
+
54
+ **Parameters:**
55
+ - `options.runtime` - Runtime environment ('node' | 'python')
56
+
57
+ **Returns:** `{ sandbox: NamespaceSandbox, sandboxId: string }`
58
+
59
+ #### `getById(sandboxId: string)`
60
+ Retrieves details for a specific sandbox instance.
61
+
62
+ **Parameters:**
63
+ - `sandboxId` - The instance ID to retrieve
64
+
65
+ **Returns:** `{ sandbox: NamespaceSandbox, sandboxId: string } | null`
66
+
67
+ #### `list()`
68
+ Lists all compute instances in your Namespace account.
69
+
70
+ **Returns:** `Array<{ sandbox: NamespaceSandbox, sandboxId: string }>`
71
+
72
+ #### `destroy(sandboxId: string)`
73
+ Destroys a compute instance and cleans up resources.
74
+
75
+ **Parameters:**
76
+ - `sandboxId` - The instance ID to destroy
77
+
78
+ ## Configuration Options
79
+
80
+ ### NamespaceConfig
81
+
82
+ | Option | Type | Default | Description |
83
+ |--------|------|---------|-------------|
84
+ | `token` | `string` | `process.env.NSC_TOKEN` | Namespace API authentication token |
85
+ | `virtualCpu` | `number` | `2` | Number of virtual CPU cores |
86
+ | `memoryMegabytes` | `number` | `4096` | Memory allocation in MB |
87
+ | `machineArch` | `string` | `'amd64'` | Machine architecture |
88
+ | `os` | `string` | `'linux'` | Operating system |
89
+ | `documentedPurpose` | `string` | `'ComputeSDK sandbox'` | Purpose documentation for the instance |
90
+ | `destroyReason` | `string` | `'ComputeSDK cleanup'` | Reason for instance destruction |
91
+
92
+ ## Supported Runtimes
93
+
94
+ - **node** - Uses `node:alpine` Docker image
95
+ - **python** - Uses `python:alpine` Docker image
96
+
97
+ ## Instance Lifecycle
98
+
99
+ 1. **Creation** - Instances are created with specified resource allocation
100
+ 2. **Container Setup** - Docker containers are automatically provisioned
101
+ 3. **Startup** - Containers start with a sleep command for 300 seconds
102
+ 4. **Management** - Full CRUD operations available via API
103
+ 5. **Cleanup** - Graceful shutdown and resource deallocation
104
+
105
+ ## API Endpoints
106
+
107
+ The provider uses Namespace's compute API:
108
+
109
+ - **Base URL:** `https://us.compute.namespaceapis.com`
110
+ - **Service:** `namespace.cloud.compute.v1beta.ComputeService`
111
+ - **Authentication:** Bearer token
112
+
113
+ ## Error Handling
114
+
115
+ The provider includes comprehensive error handling:
116
+
117
+ - **Authentication errors** - Invalid or missing NSC_TOKEN
118
+ - **Resource limits** - Quota exceeded or invalid configurations
119
+ - **Network errors** - API connectivity issues
120
+ - **Instance errors** - Non-existent or inaccessible instances
121
+
122
+ ## Environment Variables
123
+
124
+ | Variable | Required | Description |
125
+ |----------|----------|-------------|
126
+ | `NSC_TOKEN` | Yes | Namespace authentication token |
127
+
128
+ ## Notes
129
+
130
+ - All operations use Namespace's REST API over HTTPS
131
+ - Instance IDs are globally unique within your account
132
+ - Resource quotas apply based on your Namespace plan
133
+ - Containers start with basic sleep command and can be customized
134
+ - Graceful error handling for destroy operations (won't fail if instance already deleted)
@@ -0,0 +1,38 @@
1
+ import * as computesdk from 'computesdk';
2
+
3
+ /**
4
+ * Namespace Provider - Factory-based Implementation
5
+ */
6
+ /**
7
+ * Namespace sandbox interface
8
+ */
9
+ interface NamespaceSandbox {
10
+ instanceId: string;
11
+ name: string;
12
+ }
13
+ interface NamespaceConfig {
14
+ /** Namespace API token - if not provided, will fallback to NSC_TOKEN environment variable */
15
+ token?: string;
16
+ /** Virtual CPU cores for the instance */
17
+ virtualCpu?: number;
18
+ /** Memory in megabytes for the instance */
19
+ memoryMegabytes?: number;
20
+ /** Machine architecture (default: amd64) */
21
+ machineArch?: string;
22
+ /** Operating system (default: linux) */
23
+ os?: string;
24
+ /** Documented purpose for the instance */
25
+ documentedPurpose?: string;
26
+ /** Reason for destroying instances (default: "ComputeSDK cleanup") */
27
+ destroyReason?: string;
28
+ }
29
+ declare const getAndValidateCredentials: (config: NamespaceConfig) => {
30
+ token: string;
31
+ };
32
+ declare const fetchNamespace: (token: string, endpoint: string, options?: RequestInit) => Promise<any>;
33
+ /**
34
+ * Create a Namespace provider instance using the factory pattern
35
+ */
36
+ declare const namespace: (config: NamespaceConfig) => computesdk.Provider<NamespaceSandbox, any, any>;
37
+
38
+ export { type NamespaceConfig, fetchNamespace, getAndValidateCredentials, namespace };
@@ -0,0 +1,38 @@
1
+ import * as computesdk from 'computesdk';
2
+
3
+ /**
4
+ * Namespace Provider - Factory-based Implementation
5
+ */
6
+ /**
7
+ * Namespace sandbox interface
8
+ */
9
+ interface NamespaceSandbox {
10
+ instanceId: string;
11
+ name: string;
12
+ }
13
+ interface NamespaceConfig {
14
+ /** Namespace API token - if not provided, will fallback to NSC_TOKEN environment variable */
15
+ token?: string;
16
+ /** Virtual CPU cores for the instance */
17
+ virtualCpu?: number;
18
+ /** Memory in megabytes for the instance */
19
+ memoryMegabytes?: number;
20
+ /** Machine architecture (default: amd64) */
21
+ machineArch?: string;
22
+ /** Operating system (default: linux) */
23
+ os?: string;
24
+ /** Documented purpose for the instance */
25
+ documentedPurpose?: string;
26
+ /** Reason for destroying instances (default: "ComputeSDK cleanup") */
27
+ destroyReason?: string;
28
+ }
29
+ declare const getAndValidateCredentials: (config: NamespaceConfig) => {
30
+ token: string;
31
+ };
32
+ declare const fetchNamespace: (token: string, endpoint: string, options?: RequestInit) => Promise<any>;
33
+ /**
34
+ * Create a Namespace provider instance using the factory pattern
35
+ */
36
+ declare const namespace: (config: NamespaceConfig) => computesdk.Provider<NamespaceSandbox, any, any>;
37
+
38
+ export { type NamespaceConfig, fetchNamespace, getAndValidateCredentials, namespace };
package/dist/index.js ADDED
@@ -0,0 +1,216 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ fetchNamespace: () => fetchNamespace,
24
+ getAndValidateCredentials: () => getAndValidateCredentials,
25
+ namespace: () => namespace
26
+ });
27
+ module.exports = __toCommonJS(index_exports);
28
+ var import_computesdk = require("computesdk");
29
+ var getAndValidateCredentials = (config) => {
30
+ const token = config.token || typeof process !== "undefined" && process.env?.NSC_TOKEN || "";
31
+ if (!token) {
32
+ throw new Error(
33
+ "Missing Namespace token. Provide token in config or set NSC_TOKEN environment variable."
34
+ );
35
+ }
36
+ return { token };
37
+ };
38
+ var API_ENDPOINTS = {
39
+ CREATE_INSTANCE: "/namespace.cloud.compute.v1beta.ComputeService/CreateInstance",
40
+ DESCRIBE_INSTANCE: "/namespace.cloud.compute.v1beta.ComputeService/DescribeInstance",
41
+ LIST_INSTANCES: "/namespace.cloud.compute.v1beta.ComputeService/ListInstances",
42
+ DESTROY_INSTANCE: "/namespace.cloud.compute.v1beta.ComputeService/DestroyInstance"
43
+ };
44
+ var handleApiErrors = (response) => {
45
+ if (response.error) {
46
+ throw new Error(`Namespace API error: ${response.error}`);
47
+ }
48
+ };
49
+ var fetchNamespace = async (token, endpoint, options = {}) => {
50
+ const response = await fetch(`https://us.compute.namespaceapis.com${endpoint}`, {
51
+ ...options,
52
+ headers: {
53
+ "Content-Type": "application/json",
54
+ "Authorization": `Bearer ${token}`,
55
+ ...options.headers
56
+ }
57
+ });
58
+ if (!response.ok) {
59
+ throw new Error(`Namespace API error: ${response.status} ${response.statusText}`);
60
+ }
61
+ const data = await response.json();
62
+ handleApiErrors(data);
63
+ return data;
64
+ };
65
+ var namespace = (0, import_computesdk.createProvider)({
66
+ name: "namespace",
67
+ methods: {
68
+ sandbox: {
69
+ // Collection operations (compute.sandbox.*)
70
+ create: async (config, options) => {
71
+ const { token } = getAndValidateCredentials(config);
72
+ try {
73
+ const getImageRef = (runtime) => {
74
+ return runtime === "node" ? "node:alpine" : "python:alpine";
75
+ };
76
+ const requestBody = {
77
+ shape: {
78
+ virtual_cpu: config.virtualCpu || 2,
79
+ memory_megabytes: config.memoryMegabytes || 4096,
80
+ machine_arch: config.machineArch || "amd64",
81
+ os: config.os || "linux"
82
+ },
83
+ containers: [{
84
+ name: "main-container",
85
+ image_ref: getImageRef(options?.runtime),
86
+ args: ["sleep", "300"]
87
+ }],
88
+ documented_purpose: config.documentedPurpose || "ComputeSDK sandbox"
89
+ };
90
+ const responseData = await fetchNamespace(token, API_ENDPOINTS.CREATE_INSTANCE, {
91
+ method: "POST",
92
+ body: JSON.stringify(requestBody)
93
+ });
94
+ if (!responseData.metadata?.instanceId) {
95
+ throw new Error(`Instance ID is undefined. Full response object: ${JSON.stringify(responseData, null, 2)}`);
96
+ }
97
+ const instanceId = responseData.metadata.instanceId;
98
+ const instanceName = `instance-${instanceId}`;
99
+ const namespaceSandbox = {
100
+ instanceId,
101
+ name: instanceName
102
+ };
103
+ return {
104
+ sandbox: namespaceSandbox,
105
+ sandboxId: instanceId
106
+ };
107
+ } catch (error) {
108
+ throw new Error(
109
+ `Failed to create Namespace instance: ${error instanceof Error ? error.message : String(error)}`
110
+ );
111
+ }
112
+ },
113
+ getById: async (config, sandboxId) => {
114
+ const { token } = getAndValidateCredentials(config);
115
+ try {
116
+ const requestBody = {
117
+ instance_id: sandboxId
118
+ };
119
+ const responseData = await fetchNamespace(token, API_ENDPOINTS.DESCRIBE_INSTANCE, {
120
+ method: "POST",
121
+ body: JSON.stringify(requestBody)
122
+ });
123
+ if (!responseData.metadata?.instanceId) {
124
+ throw new Error("Instance data is missing from Namespace response");
125
+ }
126
+ const instanceId = responseData.metadata.instanceId;
127
+ const instanceName = `instance-${instanceId}`;
128
+ const namespaceSandbox = {
129
+ instanceId,
130
+ name: instanceName
131
+ };
132
+ return {
133
+ sandbox: namespaceSandbox,
134
+ sandboxId: instanceId
135
+ };
136
+ } catch (error) {
137
+ if (error instanceof Error && error.message.includes("404 Not Found")) {
138
+ return null;
139
+ }
140
+ throw new Error(
141
+ `Failed to get Namespace instance: ${error instanceof Error ? error.message : String(error)}`
142
+ );
143
+ }
144
+ },
145
+ list: async (config) => {
146
+ const { token } = getAndValidateCredentials(config);
147
+ try {
148
+ const responseData = await fetchNamespace(token, API_ENDPOINTS.LIST_INSTANCES, {
149
+ method: "POST",
150
+ body: JSON.stringify({})
151
+ });
152
+ const instances = responseData?.instances || [];
153
+ const namespaceSandboxes = instances.map((instanceData) => {
154
+ const instanceId = instanceData.instanceId || instanceData.metadata?.instanceId;
155
+ if (!instanceId) {
156
+ console.warn("Instance missing instanceId:", instanceData);
157
+ return null;
158
+ }
159
+ const instanceName = `instance-${instanceId}`;
160
+ const namespaceSandbox = {
161
+ instanceId,
162
+ name: instanceName
163
+ };
164
+ return {
165
+ sandbox: namespaceSandbox,
166
+ sandboxId: instanceId
167
+ };
168
+ }).filter(Boolean);
169
+ return namespaceSandboxes;
170
+ } catch (error) {
171
+ throw new Error(
172
+ `Failed to list Namespace instances: ${error instanceof Error ? error.message : String(error)}`
173
+ );
174
+ }
175
+ },
176
+ destroy: async (config, sandboxId) => {
177
+ const { token } = getAndValidateCredentials(config);
178
+ try {
179
+ const requestBody = {
180
+ instance_id: sandboxId,
181
+ reason: config.destroyReason || "ComputeSDK cleanup"
182
+ };
183
+ const data = await fetchNamespace(token, API_ENDPOINTS.DESTROY_INSTANCE, {
184
+ method: "POST",
185
+ body: JSON.stringify(requestBody)
186
+ });
187
+ if (data.error) {
188
+ console.warn(`Namespace destroy warning: ${data.error}`);
189
+ }
190
+ } catch (error) {
191
+ console.warn(`Namespace destroy warning: ${error instanceof Error ? error.message : String(error)}`);
192
+ }
193
+ },
194
+ // Instance operations (minimal stubs - not implemented yet)
195
+ runCode: async (_sandbox, _code, _runtime) => {
196
+ throw new Error("Namespace runCode method not implemented yet");
197
+ },
198
+ runCommand: async (_sandbox, _command, _args, _options) => {
199
+ throw new Error("Namespace runCommand method not implemented yet");
200
+ },
201
+ getInfo: async (_sandbox) => {
202
+ throw new Error("Namespace getInfo method not implemented yet");
203
+ },
204
+ getUrl: async (_sandbox, _options) => {
205
+ throw new Error("Namespace getUrl method not implemented yet");
206
+ }
207
+ }
208
+ }
209
+ });
210
+ // Annotate the CommonJS export names for ESM import in node:
211
+ 0 && (module.exports = {
212
+ fetchNamespace,
213
+ getAndValidateCredentials,
214
+ namespace
215
+ });
216
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Namespace Provider - Factory-based Implementation\n */\n\nimport { createProvider, createBackgroundCommand } from 'computesdk';\nimport type { Runtime, ExecutionResult, SandboxInfo, CreateSandboxOptions, FileEntry, RunCommandOptions } from 'computesdk';\n\n/**\n * Namespace sandbox interface\n */\ninterface NamespaceSandbox {\n instanceId: string;\n name: string;\n}\n\nexport interface NamespaceConfig {\n /** Namespace API token - if not provided, will fallback to NSC_TOKEN environment variable */\n token?: string;\n /** Virtual CPU cores for the instance */\n virtualCpu?: number;\n /** Memory in megabytes for the instance */\n memoryMegabytes?: number;\n /** Machine architecture (default: amd64) */\n machineArch?: string;\n /** Operating system (default: linux) */\n os?: string;\n /** Documented purpose for the instance */\n documentedPurpose?: string;\n /** Reason for destroying instances (default: \"ComputeSDK cleanup\") */\n destroyReason?: string;\n}\n\nexport const getAndValidateCredentials = (config: NamespaceConfig) => {\n const token = config.token || (typeof process !== 'undefined' && process.env?.NSC_TOKEN) || '';\n\n if (!token) {\n throw new Error(\n 'Missing Namespace token. Provide token in config or set NSC_TOKEN environment variable.'\n );\n }\n\n return { token };\n};\n\nconst API_ENDPOINTS = {\n CREATE_INSTANCE: '/namespace.cloud.compute.v1beta.ComputeService/CreateInstance',\n DESCRIBE_INSTANCE: '/namespace.cloud.compute.v1beta.ComputeService/DescribeInstance',\n LIST_INSTANCES: '/namespace.cloud.compute.v1beta.ComputeService/ListInstances',\n DESTROY_INSTANCE: '/namespace.cloud.compute.v1beta.ComputeService/DestroyInstance'\n};\n\nconst handleApiErrors = (response: any) => {\n if (response.error) {\n throw new Error(`Namespace API error: ${response.error}`);\n }\n};\n\nexport const fetchNamespace = async (\n token: string, \n endpoint: string,\n options: RequestInit = {}\n) => {\n \n const response = await fetch(`https://us.compute.namespaceapis.com${endpoint}`, {\n ...options,\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${token}`,\n ...options.headers\n }\n });\n\n if (!response.ok) {\n throw new Error(`Namespace API error: ${response.status} ${response.statusText}`);\n }\n\n const data = await response.json();\n\n // Standard error handling for all operations\n handleApiErrors(data);\n\n return data;\n};\n\n/**\n * Create a Namespace provider instance using the factory pattern\n */\nexport const namespace = createProvider<NamespaceSandbox, NamespaceConfig>({\n name: 'namespace',\n methods: {\n sandbox: {\n // Collection operations (compute.sandbox.*)\n create: async (config: NamespaceConfig, options?: CreateSandboxOptions) => {\n const { token } = getAndValidateCredentials(config);\n\n try {\n // Get image based on runtime\n const getImageRef = (runtime?: Runtime) => {\n return runtime === 'node' ? 'node:alpine' : 'python:alpine';\n };\n\n const requestBody = {\n shape: {\n virtual_cpu: config.virtualCpu || 2,\n memory_megabytes: config.memoryMegabytes || 4096,\n machine_arch: config.machineArch || 'amd64',\n os: config.os || 'linux'\n },\n containers: [{\n name: 'main-container',\n image_ref: getImageRef(options?.runtime),\n args: ['sleep', '300']\n }],\n documented_purpose: config.documentedPurpose || 'ComputeSDK sandbox'\n };\n\n const responseData = await fetchNamespace(token, API_ENDPOINTS.CREATE_INSTANCE, {\n method: 'POST',\n body: JSON.stringify(requestBody)\n });\n \n // Extract instance ID from the Namespace API response structure\n if (!responseData.metadata?.instanceId) {\n throw new Error(`Instance ID is undefined. Full response object: ${JSON.stringify(responseData, null, 2)}`);\n }\n\n const instanceId = responseData.metadata.instanceId;\n const instanceName = `instance-${instanceId}`;\n\n const namespaceSandbox: NamespaceSandbox = {\n instanceId,\n name: instanceName,\n };\n\n return {\n sandbox: namespaceSandbox,\n sandboxId: instanceId\n };\n } catch (error) {\n throw new Error(\n `Failed to create Namespace instance: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n getById: async (config: NamespaceConfig, sandboxId: string) => {\n const { token } = getAndValidateCredentials(config);\n\n try {\n const requestBody = {\n instance_id: sandboxId\n };\n\n const responseData = await fetchNamespace(token, API_ENDPOINTS.DESCRIBE_INSTANCE, {\n method: 'POST',\n body: JSON.stringify(requestBody)\n });\n \n // Extract instance ID from the Namespace API response structure\n if (!responseData.metadata?.instanceId) {\n throw new Error('Instance data is missing from Namespace response');\n }\n\n const instanceId = responseData.metadata.instanceId;\n const instanceName = `instance-${instanceId}`;\n\n const namespaceSandbox: NamespaceSandbox = {\n instanceId,\n name: instanceName,\n };\n\n return {\n sandbox: namespaceSandbox,\n sandboxId: instanceId\n };\n } catch (error) {\n // Handle 404 errors by returning null (instance not found)\n if (error instanceof Error && error.message.includes('404 Not Found')) {\n return null;\n }\n \n throw new Error(\n `Failed to get Namespace instance: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n \n list: async (config: NamespaceConfig) => {\n const { token } = getAndValidateCredentials(config);\n\n try {\n const responseData = await fetchNamespace(token, API_ENDPOINTS.LIST_INSTANCES, {\n method: 'POST',\n body: JSON.stringify({})\n });\n \n // Extract instances from the response\n const instances = responseData?.instances || [];\n \n // Transform each instance into the expected format\n const namespaceSandboxes = instances.map((instanceData: any) => {\n // For list response, instanceId is directly in the instance object, not in metadata\n const instanceId = instanceData.instanceId || instanceData.metadata?.instanceId;\n if (!instanceId) {\n console.warn('Instance missing instanceId:', instanceData);\n return null;\n }\n \n const instanceName = `instance-${instanceId}`;\n\n const namespaceSandbox: NamespaceSandbox = {\n instanceId,\n name: instanceName,\n };\n\n return {\n sandbox: namespaceSandbox,\n sandboxId: instanceId\n };\n }).filter(Boolean); // Remove any null entries\n\n return namespaceSandboxes;\n } catch (error) {\n throw new Error(\n `Failed to list Namespace instances: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n destroy: async (config: NamespaceConfig, sandboxId: string) => {\n const { token } = getAndValidateCredentials(config);\n\n try {\n const requestBody = {\n instance_id: sandboxId,\n reason: config.destroyReason || \"ComputeSDK cleanup\"\n };\n\n const data = await fetchNamespace(token, API_ENDPOINTS.DESTROY_INSTANCE, {\n method: 'POST',\n body: JSON.stringify(requestBody)\n });\n \n if (data.error) {\n // Log errors but don't throw for destroy operations\n console.warn(`Namespace destroy warning: ${data.error}`);\n }\n } catch (error) {\n // For destroy operations, we typically don't throw if the instance is already gone\n console.warn(`Namespace destroy warning: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n // Instance operations (minimal stubs - not implemented yet)\n runCode: async (_sandbox: NamespaceSandbox, _code: string, _runtime?: Runtime) => {\n throw new Error('Namespace runCode method not implemented yet');\n },\n\n runCommand: async (_sandbox: NamespaceSandbox, _command: string, _args?: string[], _options?: RunCommandOptions) => {\n throw new Error('Namespace runCommand method not implemented yet');\n },\n\n getInfo: async (_sandbox: NamespaceSandbox) => {\n throw new Error('Namespace getInfo method not implemented yet');\n },\n\n getUrl: async (_sandbox: NamespaceSandbox, _options: { port: number; protocol?: string }) => {\n throw new Error('Namespace getUrl method not implemented yet');\n },\n\n },\n },\n});"],"mappings":"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","names":[]}
package/dist/index.mjs ADDED
@@ -0,0 +1,189 @@
1
+ // src/index.ts
2
+ import { createProvider } from "computesdk";
3
+ var getAndValidateCredentials = (config) => {
4
+ const token = config.token || typeof process !== "undefined" && process.env?.NSC_TOKEN || "";
5
+ if (!token) {
6
+ throw new Error(
7
+ "Missing Namespace token. Provide token in config or set NSC_TOKEN environment variable."
8
+ );
9
+ }
10
+ return { token };
11
+ };
12
+ var API_ENDPOINTS = {
13
+ CREATE_INSTANCE: "/namespace.cloud.compute.v1beta.ComputeService/CreateInstance",
14
+ DESCRIBE_INSTANCE: "/namespace.cloud.compute.v1beta.ComputeService/DescribeInstance",
15
+ LIST_INSTANCES: "/namespace.cloud.compute.v1beta.ComputeService/ListInstances",
16
+ DESTROY_INSTANCE: "/namespace.cloud.compute.v1beta.ComputeService/DestroyInstance"
17
+ };
18
+ var handleApiErrors = (response) => {
19
+ if (response.error) {
20
+ throw new Error(`Namespace API error: ${response.error}`);
21
+ }
22
+ };
23
+ var fetchNamespace = async (token, endpoint, options = {}) => {
24
+ const response = await fetch(`https://us.compute.namespaceapis.com${endpoint}`, {
25
+ ...options,
26
+ headers: {
27
+ "Content-Type": "application/json",
28
+ "Authorization": `Bearer ${token}`,
29
+ ...options.headers
30
+ }
31
+ });
32
+ if (!response.ok) {
33
+ throw new Error(`Namespace API error: ${response.status} ${response.statusText}`);
34
+ }
35
+ const data = await response.json();
36
+ handleApiErrors(data);
37
+ return data;
38
+ };
39
+ var namespace = createProvider({
40
+ name: "namespace",
41
+ methods: {
42
+ sandbox: {
43
+ // Collection operations (compute.sandbox.*)
44
+ create: async (config, options) => {
45
+ const { token } = getAndValidateCredentials(config);
46
+ try {
47
+ const getImageRef = (runtime) => {
48
+ return runtime === "node" ? "node:alpine" : "python:alpine";
49
+ };
50
+ const requestBody = {
51
+ shape: {
52
+ virtual_cpu: config.virtualCpu || 2,
53
+ memory_megabytes: config.memoryMegabytes || 4096,
54
+ machine_arch: config.machineArch || "amd64",
55
+ os: config.os || "linux"
56
+ },
57
+ containers: [{
58
+ name: "main-container",
59
+ image_ref: getImageRef(options?.runtime),
60
+ args: ["sleep", "300"]
61
+ }],
62
+ documented_purpose: config.documentedPurpose || "ComputeSDK sandbox"
63
+ };
64
+ const responseData = await fetchNamespace(token, API_ENDPOINTS.CREATE_INSTANCE, {
65
+ method: "POST",
66
+ body: JSON.stringify(requestBody)
67
+ });
68
+ if (!responseData.metadata?.instanceId) {
69
+ throw new Error(`Instance ID is undefined. Full response object: ${JSON.stringify(responseData, null, 2)}`);
70
+ }
71
+ const instanceId = responseData.metadata.instanceId;
72
+ const instanceName = `instance-${instanceId}`;
73
+ const namespaceSandbox = {
74
+ instanceId,
75
+ name: instanceName
76
+ };
77
+ return {
78
+ sandbox: namespaceSandbox,
79
+ sandboxId: instanceId
80
+ };
81
+ } catch (error) {
82
+ throw new Error(
83
+ `Failed to create Namespace instance: ${error instanceof Error ? error.message : String(error)}`
84
+ );
85
+ }
86
+ },
87
+ getById: async (config, sandboxId) => {
88
+ const { token } = getAndValidateCredentials(config);
89
+ try {
90
+ const requestBody = {
91
+ instance_id: sandboxId
92
+ };
93
+ const responseData = await fetchNamespace(token, API_ENDPOINTS.DESCRIBE_INSTANCE, {
94
+ method: "POST",
95
+ body: JSON.stringify(requestBody)
96
+ });
97
+ if (!responseData.metadata?.instanceId) {
98
+ throw new Error("Instance data is missing from Namespace response");
99
+ }
100
+ const instanceId = responseData.metadata.instanceId;
101
+ const instanceName = `instance-${instanceId}`;
102
+ const namespaceSandbox = {
103
+ instanceId,
104
+ name: instanceName
105
+ };
106
+ return {
107
+ sandbox: namespaceSandbox,
108
+ sandboxId: instanceId
109
+ };
110
+ } catch (error) {
111
+ if (error instanceof Error && error.message.includes("404 Not Found")) {
112
+ return null;
113
+ }
114
+ throw new Error(
115
+ `Failed to get Namespace instance: ${error instanceof Error ? error.message : String(error)}`
116
+ );
117
+ }
118
+ },
119
+ list: async (config) => {
120
+ const { token } = getAndValidateCredentials(config);
121
+ try {
122
+ const responseData = await fetchNamespace(token, API_ENDPOINTS.LIST_INSTANCES, {
123
+ method: "POST",
124
+ body: JSON.stringify({})
125
+ });
126
+ const instances = responseData?.instances || [];
127
+ const namespaceSandboxes = instances.map((instanceData) => {
128
+ const instanceId = instanceData.instanceId || instanceData.metadata?.instanceId;
129
+ if (!instanceId) {
130
+ console.warn("Instance missing instanceId:", instanceData);
131
+ return null;
132
+ }
133
+ const instanceName = `instance-${instanceId}`;
134
+ const namespaceSandbox = {
135
+ instanceId,
136
+ name: instanceName
137
+ };
138
+ return {
139
+ sandbox: namespaceSandbox,
140
+ sandboxId: instanceId
141
+ };
142
+ }).filter(Boolean);
143
+ return namespaceSandboxes;
144
+ } catch (error) {
145
+ throw new Error(
146
+ `Failed to list Namespace instances: ${error instanceof Error ? error.message : String(error)}`
147
+ );
148
+ }
149
+ },
150
+ destroy: async (config, sandboxId) => {
151
+ const { token } = getAndValidateCredentials(config);
152
+ try {
153
+ const requestBody = {
154
+ instance_id: sandboxId,
155
+ reason: config.destroyReason || "ComputeSDK cleanup"
156
+ };
157
+ const data = await fetchNamespace(token, API_ENDPOINTS.DESTROY_INSTANCE, {
158
+ method: "POST",
159
+ body: JSON.stringify(requestBody)
160
+ });
161
+ if (data.error) {
162
+ console.warn(`Namespace destroy warning: ${data.error}`);
163
+ }
164
+ } catch (error) {
165
+ console.warn(`Namespace destroy warning: ${error instanceof Error ? error.message : String(error)}`);
166
+ }
167
+ },
168
+ // Instance operations (minimal stubs - not implemented yet)
169
+ runCode: async (_sandbox, _code, _runtime) => {
170
+ throw new Error("Namespace runCode method not implemented yet");
171
+ },
172
+ runCommand: async (_sandbox, _command, _args, _options) => {
173
+ throw new Error("Namespace runCommand method not implemented yet");
174
+ },
175
+ getInfo: async (_sandbox) => {
176
+ throw new Error("Namespace getInfo method not implemented yet");
177
+ },
178
+ getUrl: async (_sandbox, _options) => {
179
+ throw new Error("Namespace getUrl method not implemented yet");
180
+ }
181
+ }
182
+ }
183
+ });
184
+ export {
185
+ fetchNamespace,
186
+ getAndValidateCredentials,
187
+ namespace
188
+ };
189
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Namespace Provider - Factory-based Implementation\n */\n\nimport { createProvider, createBackgroundCommand } from 'computesdk';\nimport type { Runtime, ExecutionResult, SandboxInfo, CreateSandboxOptions, FileEntry, RunCommandOptions } from 'computesdk';\n\n/**\n * Namespace sandbox interface\n */\ninterface NamespaceSandbox {\n instanceId: string;\n name: string;\n}\n\nexport interface NamespaceConfig {\n /** Namespace API token - if not provided, will fallback to NSC_TOKEN environment variable */\n token?: string;\n /** Virtual CPU cores for the instance */\n virtualCpu?: number;\n /** Memory in megabytes for the instance */\n memoryMegabytes?: number;\n /** Machine architecture (default: amd64) */\n machineArch?: string;\n /** Operating system (default: linux) */\n os?: string;\n /** Documented purpose for the instance */\n documentedPurpose?: string;\n /** Reason for destroying instances (default: \"ComputeSDK cleanup\") */\n destroyReason?: string;\n}\n\nexport const getAndValidateCredentials = (config: NamespaceConfig) => {\n const token = config.token || (typeof process !== 'undefined' && process.env?.NSC_TOKEN) || '';\n\n if (!token) {\n throw new Error(\n 'Missing Namespace token. Provide token in config or set NSC_TOKEN environment variable.'\n );\n }\n\n return { token };\n};\n\nconst API_ENDPOINTS = {\n CREATE_INSTANCE: '/namespace.cloud.compute.v1beta.ComputeService/CreateInstance',\n DESCRIBE_INSTANCE: '/namespace.cloud.compute.v1beta.ComputeService/DescribeInstance',\n LIST_INSTANCES: '/namespace.cloud.compute.v1beta.ComputeService/ListInstances',\n DESTROY_INSTANCE: '/namespace.cloud.compute.v1beta.ComputeService/DestroyInstance'\n};\n\nconst handleApiErrors = (response: any) => {\n if (response.error) {\n throw new Error(`Namespace API error: ${response.error}`);\n }\n};\n\nexport const fetchNamespace = async (\n token: string, \n endpoint: string,\n options: RequestInit = {}\n) => {\n \n const response = await fetch(`https://us.compute.namespaceapis.com${endpoint}`, {\n ...options,\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${token}`,\n ...options.headers\n }\n });\n\n if (!response.ok) {\n throw new Error(`Namespace API error: ${response.status} ${response.statusText}`);\n }\n\n const data = await response.json();\n\n // Standard error handling for all operations\n handleApiErrors(data);\n\n return data;\n};\n\n/**\n * Create a Namespace provider instance using the factory pattern\n */\nexport const namespace = createProvider<NamespaceSandbox, NamespaceConfig>({\n name: 'namespace',\n methods: {\n sandbox: {\n // Collection operations (compute.sandbox.*)\n create: async (config: NamespaceConfig, options?: CreateSandboxOptions) => {\n const { token } = getAndValidateCredentials(config);\n\n try {\n // Get image based on runtime\n const getImageRef = (runtime?: Runtime) => {\n return runtime === 'node' ? 'node:alpine' : 'python:alpine';\n };\n\n const requestBody = {\n shape: {\n virtual_cpu: config.virtualCpu || 2,\n memory_megabytes: config.memoryMegabytes || 4096,\n machine_arch: config.machineArch || 'amd64',\n os: config.os || 'linux'\n },\n containers: [{\n name: 'main-container',\n image_ref: getImageRef(options?.runtime),\n args: ['sleep', '300']\n }],\n documented_purpose: config.documentedPurpose || 'ComputeSDK sandbox'\n };\n\n const responseData = await fetchNamespace(token, API_ENDPOINTS.CREATE_INSTANCE, {\n method: 'POST',\n body: JSON.stringify(requestBody)\n });\n \n // Extract instance ID from the Namespace API response structure\n if (!responseData.metadata?.instanceId) {\n throw new Error(`Instance ID is undefined. Full response object: ${JSON.stringify(responseData, null, 2)}`);\n }\n\n const instanceId = responseData.metadata.instanceId;\n const instanceName = `instance-${instanceId}`;\n\n const namespaceSandbox: NamespaceSandbox = {\n instanceId,\n name: instanceName,\n };\n\n return {\n sandbox: namespaceSandbox,\n sandboxId: instanceId\n };\n } catch (error) {\n throw new Error(\n `Failed to create Namespace instance: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n getById: async (config: NamespaceConfig, sandboxId: string) => {\n const { token } = getAndValidateCredentials(config);\n\n try {\n const requestBody = {\n instance_id: sandboxId\n };\n\n const responseData = await fetchNamespace(token, API_ENDPOINTS.DESCRIBE_INSTANCE, {\n method: 'POST',\n body: JSON.stringify(requestBody)\n });\n \n // Extract instance ID from the Namespace API response structure\n if (!responseData.metadata?.instanceId) {\n throw new Error('Instance data is missing from Namespace response');\n }\n\n const instanceId = responseData.metadata.instanceId;\n const instanceName = `instance-${instanceId}`;\n\n const namespaceSandbox: NamespaceSandbox = {\n instanceId,\n name: instanceName,\n };\n\n return {\n sandbox: namespaceSandbox,\n sandboxId: instanceId\n };\n } catch (error) {\n // Handle 404 errors by returning null (instance not found)\n if (error instanceof Error && error.message.includes('404 Not Found')) {\n return null;\n }\n \n throw new Error(\n `Failed to get Namespace instance: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n \n list: async (config: NamespaceConfig) => {\n const { token } = getAndValidateCredentials(config);\n\n try {\n const responseData = await fetchNamespace(token, API_ENDPOINTS.LIST_INSTANCES, {\n method: 'POST',\n body: JSON.stringify({})\n });\n \n // Extract instances from the response\n const instances = responseData?.instances || [];\n \n // Transform each instance into the expected format\n const namespaceSandboxes = instances.map((instanceData: any) => {\n // For list response, instanceId is directly in the instance object, not in metadata\n const instanceId = instanceData.instanceId || instanceData.metadata?.instanceId;\n if (!instanceId) {\n console.warn('Instance missing instanceId:', instanceData);\n return null;\n }\n \n const instanceName = `instance-${instanceId}`;\n\n const namespaceSandbox: NamespaceSandbox = {\n instanceId,\n name: instanceName,\n };\n\n return {\n sandbox: namespaceSandbox,\n sandboxId: instanceId\n };\n }).filter(Boolean); // Remove any null entries\n\n return namespaceSandboxes;\n } catch (error) {\n throw new Error(\n `Failed to list Namespace instances: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n destroy: async (config: NamespaceConfig, sandboxId: string) => {\n const { token } = getAndValidateCredentials(config);\n\n try {\n const requestBody = {\n instance_id: sandboxId,\n reason: config.destroyReason || \"ComputeSDK cleanup\"\n };\n\n const data = await fetchNamespace(token, API_ENDPOINTS.DESTROY_INSTANCE, {\n method: 'POST',\n body: JSON.stringify(requestBody)\n });\n \n if (data.error) {\n // Log errors but don't throw for destroy operations\n console.warn(`Namespace destroy warning: ${data.error}`);\n }\n } catch (error) {\n // For destroy operations, we typically don't throw if the instance is already gone\n console.warn(`Namespace destroy warning: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n // Instance operations (minimal stubs - not implemented yet)\n runCode: async (_sandbox: NamespaceSandbox, _code: string, _runtime?: Runtime) => {\n throw new Error('Namespace runCode method not implemented yet');\n },\n\n runCommand: async (_sandbox: NamespaceSandbox, _command: string, _args?: string[], _options?: RunCommandOptions) => {\n throw new Error('Namespace runCommand method not implemented yet');\n },\n\n getInfo: async (_sandbox: NamespaceSandbox) => {\n throw new Error('Namespace getInfo method not implemented yet');\n },\n\n getUrl: async (_sandbox: NamespaceSandbox, _options: { port: number; protocol?: string }) => {\n throw new Error('Namespace getUrl method not implemented yet');\n },\n\n },\n },\n});"],"mappings":"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","names":[]}
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "@computesdk/namespace",
3
+ "version": "1.0.0",
4
+ "description": "Namespace provider for ComputeSDK",
5
+ "author": "ComputeSDK Team",
6
+ "license": "MIT",
7
+ "main": "./dist/index.js",
8
+ "module": "./dist/index.mjs",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.mjs",
14
+ "require": "./dist/index.js"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist"
19
+ ],
20
+ "dependencies": {
21
+ "computesdk": "1.8.7"
22
+ },
23
+ "keywords": [
24
+ "namespace",
25
+ "sandbox",
26
+ "code-execution",
27
+ "cloud",
28
+ "compute",
29
+ "containers"
30
+ ],
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "https://github.com/computesdk/computesdk.git",
34
+ "directory": "packages/namespace"
35
+ },
36
+ "homepage": "https://github.com/computesdk/computesdk/tree/main/packages/namespace",
37
+ "bugs": {
38
+ "url": "https://github.com/computesdk/computesdk/issues"
39
+ },
40
+ "devDependencies": {
41
+ "@types/node": "^20.0.0",
42
+ "@vitest/coverage-v8": "^1.0.0",
43
+ "dotenv": "^17.2.1",
44
+ "eslint": "^8.37.0",
45
+ "rimraf": "^5.0.0",
46
+ "tsup": "^8.0.0",
47
+ "typescript": "^5.0.0",
48
+ "vitest": "^1.0.0",
49
+ "@computesdk/test-utils": "1.4.1"
50
+ },
51
+ "scripts": {
52
+ "build": "tsup",
53
+ "clean": "rimraf dist",
54
+ "dev": "tsup --watch",
55
+ "test": "vitest run",
56
+ "test:watch": "vitest watch",
57
+ "test:coverage": "vitest run --coverage",
58
+ "typecheck": "tsc --noEmit",
59
+ "lint": "eslint"
60
+ }
61
+ }