@computesdk/namespace 1.4.0 → 1.5.1
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/dist/index.d.mts +38 -32
- package/dist/index.d.ts +38 -32
- package/dist/index.js +284 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +273 -3
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.d.mts
CHANGED
|
@@ -1,12 +1,30 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import { ComputeConfig } from '@computesdk/provider';
|
|
1
|
+
import * as _computesdk_provider from '@computesdk/provider';
|
|
3
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Namespace Provider
|
|
5
|
+
*
|
|
6
|
+
* Full-featured provider using the factory pattern.
|
|
7
|
+
* Supports instance lifecycle management and command execution via Namespace Compute API.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Namespace sandbox instance
|
|
11
|
+
*/
|
|
12
|
+
interface NamespaceSandbox {
|
|
13
|
+
instanceId: string;
|
|
14
|
+
name: string;
|
|
15
|
+
commandServiceEndpoint?: string;
|
|
16
|
+
token: string;
|
|
17
|
+
targetContainerName: string;
|
|
18
|
+
createdAt: Date;
|
|
19
|
+
}
|
|
4
20
|
/**
|
|
5
21
|
* Namespace provider configuration
|
|
6
22
|
*/
|
|
7
|
-
interface NamespaceConfig
|
|
23
|
+
interface NamespaceConfig {
|
|
8
24
|
/** Namespace API token - if not provided, will fallback to NSC_TOKEN environment variable */
|
|
9
25
|
token?: string;
|
|
26
|
+
/** Path to a JSON token file (e.g. from `nsc login`) containing bearer_token - fallback to NSC_TOKEN_FILE */
|
|
27
|
+
tokenFile?: string;
|
|
10
28
|
/** Virtual CPU cores for the instance */
|
|
11
29
|
virtualCpu?: number;
|
|
12
30
|
/** Memory in megabytes for the instance */
|
|
@@ -19,37 +37,25 @@ interface NamespaceConfig extends ComputeConfig {
|
|
|
19
37
|
documentedPurpose?: string;
|
|
20
38
|
/** Reason for destroying instances (default: "ComputeSDK cleanup") */
|
|
21
39
|
destroyReason?: string;
|
|
40
|
+
/** Target container name for command execution (default: "main-container") */
|
|
41
|
+
targetContainerName?: string;
|
|
22
42
|
}
|
|
23
43
|
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
*
|
|
36
|
-
* });
|
|
37
|
-
*
|
|
38
|
-
* // Full compute API available (routes through gateway)
|
|
39
|
-
* const sandbox = await compute.sandbox.create();
|
|
40
|
-
*
|
|
41
|
-
* // Execute code
|
|
42
|
-
* const result = await sandbox.runCode('console.log("Hello from Namespace!")');
|
|
43
|
-
* console.log(result.stdout);
|
|
44
|
-
*
|
|
45
|
-
* // Filesystem operations
|
|
46
|
-
* await sandbox.filesystem.writeFile('/tmp/test.txt', 'Hello!');
|
|
47
|
-
* const content = await sandbox.filesystem.readFile('/tmp/test.txt');
|
|
44
|
+
* Get and validate Namespace credentials from config and environment.
|
|
45
|
+
* Supports:
|
|
46
|
+
* - config.token (direct bearer token)
|
|
47
|
+
* - NSC_TOKEN env var (direct bearer token)
|
|
48
|
+
* - NSC_TOKEN_FILE env var (path to JSON file with bearer_token field)
|
|
49
|
+
*/
|
|
50
|
+
declare const getAndValidateCredentials: (config: NamespaceConfig) => Promise<{
|
|
51
|
+
token: string;
|
|
52
|
+
}>;
|
|
53
|
+
declare const fetchNamespace: (token: string, endpoint: string, options?: RequestInit, baseUrl?: string) => Promise<any>;
|
|
54
|
+
/**
|
|
55
|
+
* Namespace provider
|
|
48
56
|
*
|
|
49
|
-
*
|
|
50
|
-
* await sandbox.destroy();
|
|
51
|
-
* ```
|
|
57
|
+
* Creates Namespace instances and supports command execution via CommandService.
|
|
52
58
|
*/
|
|
53
|
-
declare const namespace: (config: NamespaceConfig) =>
|
|
59
|
+
declare const namespace: (config: NamespaceConfig) => _computesdk_provider.Provider<NamespaceSandbox, any, any>;
|
|
54
60
|
|
|
55
|
-
export { type NamespaceConfig, namespace };
|
|
61
|
+
export { type NamespaceConfig, type NamespaceSandbox, fetchNamespace, getAndValidateCredentials, namespace };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,12 +1,30 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import { ComputeConfig } from '@computesdk/provider';
|
|
1
|
+
import * as _computesdk_provider from '@computesdk/provider';
|
|
3
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Namespace Provider
|
|
5
|
+
*
|
|
6
|
+
* Full-featured provider using the factory pattern.
|
|
7
|
+
* Supports instance lifecycle management and command execution via Namespace Compute API.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Namespace sandbox instance
|
|
11
|
+
*/
|
|
12
|
+
interface NamespaceSandbox {
|
|
13
|
+
instanceId: string;
|
|
14
|
+
name: string;
|
|
15
|
+
commandServiceEndpoint?: string;
|
|
16
|
+
token: string;
|
|
17
|
+
targetContainerName: string;
|
|
18
|
+
createdAt: Date;
|
|
19
|
+
}
|
|
4
20
|
/**
|
|
5
21
|
* Namespace provider configuration
|
|
6
22
|
*/
|
|
7
|
-
interface NamespaceConfig
|
|
23
|
+
interface NamespaceConfig {
|
|
8
24
|
/** Namespace API token - if not provided, will fallback to NSC_TOKEN environment variable */
|
|
9
25
|
token?: string;
|
|
26
|
+
/** Path to a JSON token file (e.g. from `nsc login`) containing bearer_token - fallback to NSC_TOKEN_FILE */
|
|
27
|
+
tokenFile?: string;
|
|
10
28
|
/** Virtual CPU cores for the instance */
|
|
11
29
|
virtualCpu?: number;
|
|
12
30
|
/** Memory in megabytes for the instance */
|
|
@@ -19,37 +37,25 @@ interface NamespaceConfig extends ComputeConfig {
|
|
|
19
37
|
documentedPurpose?: string;
|
|
20
38
|
/** Reason for destroying instances (default: "ComputeSDK cleanup") */
|
|
21
39
|
destroyReason?: string;
|
|
40
|
+
/** Target container name for command execution (default: "main-container") */
|
|
41
|
+
targetContainerName?: string;
|
|
22
42
|
}
|
|
23
43
|
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
*
|
|
36
|
-
* });
|
|
37
|
-
*
|
|
38
|
-
* // Full compute API available (routes through gateway)
|
|
39
|
-
* const sandbox = await compute.sandbox.create();
|
|
40
|
-
*
|
|
41
|
-
* // Execute code
|
|
42
|
-
* const result = await sandbox.runCode('console.log("Hello from Namespace!")');
|
|
43
|
-
* console.log(result.stdout);
|
|
44
|
-
*
|
|
45
|
-
* // Filesystem operations
|
|
46
|
-
* await sandbox.filesystem.writeFile('/tmp/test.txt', 'Hello!');
|
|
47
|
-
* const content = await sandbox.filesystem.readFile('/tmp/test.txt');
|
|
44
|
+
* Get and validate Namespace credentials from config and environment.
|
|
45
|
+
* Supports:
|
|
46
|
+
* - config.token (direct bearer token)
|
|
47
|
+
* - NSC_TOKEN env var (direct bearer token)
|
|
48
|
+
* - NSC_TOKEN_FILE env var (path to JSON file with bearer_token field)
|
|
49
|
+
*/
|
|
50
|
+
declare const getAndValidateCredentials: (config: NamespaceConfig) => Promise<{
|
|
51
|
+
token: string;
|
|
52
|
+
}>;
|
|
53
|
+
declare const fetchNamespace: (token: string, endpoint: string, options?: RequestInit, baseUrl?: string) => Promise<any>;
|
|
54
|
+
/**
|
|
55
|
+
* Namespace provider
|
|
48
56
|
*
|
|
49
|
-
*
|
|
50
|
-
* await sandbox.destroy();
|
|
51
|
-
* ```
|
|
57
|
+
* Creates Namespace instances and supports command execution via CommandService.
|
|
52
58
|
*/
|
|
53
|
-
declare const namespace: (config: NamespaceConfig) =>
|
|
59
|
+
declare const namespace: (config: NamespaceConfig) => _computesdk_provider.Provider<NamespaceSandbox, any, any>;
|
|
54
60
|
|
|
55
|
-
export { type NamespaceConfig, namespace };
|
|
61
|
+
export { type NamespaceConfig, type NamespaceSandbox, fetchNamespace, getAndValidateCredentials, namespace };
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,20 +17,300 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
|
|
20
30
|
// src/index.ts
|
|
21
31
|
var index_exports = {};
|
|
22
32
|
__export(index_exports, {
|
|
33
|
+
fetchNamespace: () => fetchNamespace,
|
|
34
|
+
getAndValidateCredentials: () => getAndValidateCredentials,
|
|
23
35
|
namespace: () => namespace
|
|
24
36
|
});
|
|
25
37
|
module.exports = __toCommonJS(index_exports);
|
|
38
|
+
var fs = __toESM(require("fs/promises"));
|
|
26
39
|
var import_provider = require("@computesdk/provider");
|
|
27
|
-
var
|
|
28
|
-
|
|
40
|
+
var API_ENDPOINTS = {
|
|
41
|
+
CREATE_INSTANCE: "/namespace.cloud.compute.v1beta.ComputeService/CreateInstance",
|
|
42
|
+
DESCRIBE_INSTANCE: "/namespace.cloud.compute.v1beta.ComputeService/DescribeInstance",
|
|
43
|
+
LIST_INSTANCES: "/namespace.cloud.compute.v1beta.ComputeService/ListInstances",
|
|
44
|
+
DESTROY_INSTANCE: "/namespace.cloud.compute.v1beta.ComputeService/DestroyInstance"
|
|
45
|
+
};
|
|
46
|
+
var COMMAND_SERVICE = {
|
|
47
|
+
RUN_COMMAND_SYNC: "/namespace.cloud.compute.v1beta.CommandService/RunCommandSync"
|
|
48
|
+
};
|
|
49
|
+
async function loadTokenFromFile(filePath) {
|
|
50
|
+
const content = await fs.readFile(filePath, "utf8");
|
|
51
|
+
const tokenJson = JSON.parse(content);
|
|
52
|
+
if (!tokenJson.bearer_token) {
|
|
53
|
+
throw new Error(`Token file ${filePath} does not contain a bearer_token`);
|
|
54
|
+
}
|
|
55
|
+
return tokenJson.bearer_token;
|
|
56
|
+
}
|
|
57
|
+
var getAndValidateCredentials = async (config) => {
|
|
58
|
+
let token = config.token || typeof process !== "undefined" && process.env?.NSC_TOKEN || "";
|
|
59
|
+
if (!token) {
|
|
60
|
+
const tokenFile = config.tokenFile || typeof process !== "undefined" && process.env?.NSC_TOKEN_FILE || "";
|
|
61
|
+
if (tokenFile) {
|
|
62
|
+
token = await loadTokenFromFile(tokenFile);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (!token) {
|
|
66
|
+
throw new Error(
|
|
67
|
+
"Missing Namespace token. Provide token in config, set NSC_TOKEN, or set NSC_TOKEN_FILE environment variable (or provide tokenFile in config)."
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
return { token };
|
|
71
|
+
};
|
|
72
|
+
var handleApiErrors = (response) => {
|
|
73
|
+
if (response.error) {
|
|
74
|
+
throw new Error(`Namespace API error: ${response.error}`);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
var fetchNamespace = async (token, endpoint, options = {}, baseUrl = "https://us.compute.namespaceapis.com") => {
|
|
78
|
+
const response = await fetch(`${baseUrl}${endpoint}`, {
|
|
79
|
+
...options,
|
|
80
|
+
headers: {
|
|
81
|
+
"Content-Type": "application/json",
|
|
82
|
+
"Authorization": `Bearer ${token}`,
|
|
83
|
+
...options.headers
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
if (!response.ok) {
|
|
87
|
+
throw new Error(`Namespace API error: ${response.status} ${response.statusText}`);
|
|
88
|
+
}
|
|
89
|
+
const data = await response.json();
|
|
90
|
+
handleApiErrors(data);
|
|
91
|
+
return data;
|
|
92
|
+
};
|
|
93
|
+
var namespace = (0, import_provider.defineProvider)({
|
|
94
|
+
name: "namespace",
|
|
95
|
+
methods: {
|
|
96
|
+
sandbox: {
|
|
97
|
+
// Collection operations (map to compute.sandbox.*)
|
|
98
|
+
create: async (config, options) => {
|
|
99
|
+
const { token } = await getAndValidateCredentials(config);
|
|
100
|
+
const containerName = config.targetContainerName || "main-container";
|
|
101
|
+
try {
|
|
102
|
+
const requestBody = {
|
|
103
|
+
shape: {
|
|
104
|
+
virtual_cpu: config.virtualCpu || 2,
|
|
105
|
+
memory_megabytes: config.memoryMegabytes || 4096,
|
|
106
|
+
machine_arch: config.machineArch || "amd64",
|
|
107
|
+
os: config.os || "linux"
|
|
108
|
+
},
|
|
109
|
+
containers: [{
|
|
110
|
+
name: containerName,
|
|
111
|
+
image_ref: options?.image ?? "ubuntu:latest",
|
|
112
|
+
args: ["sleep", "infinity"],
|
|
113
|
+
...options?.envs && Object.keys(options.envs).length > 0 && {
|
|
114
|
+
environment: options.envs
|
|
115
|
+
}
|
|
116
|
+
}],
|
|
117
|
+
documented_purpose: config.documentedPurpose || "ComputeSDK sandbox",
|
|
118
|
+
deadline: new Date(Date.now() + 60 * 60 * 1e3).toISOString()
|
|
119
|
+
};
|
|
120
|
+
const responseData = await fetchNamespace(token, API_ENDPOINTS.CREATE_INSTANCE, {
|
|
121
|
+
method: "POST",
|
|
122
|
+
body: JSON.stringify(requestBody)
|
|
123
|
+
});
|
|
124
|
+
if (!responseData.metadata?.instanceId) {
|
|
125
|
+
throw new Error(`Instance ID is undefined. Full response object: ${JSON.stringify(responseData, null, 2)}`);
|
|
126
|
+
}
|
|
127
|
+
const instanceId = responseData.metadata.instanceId;
|
|
128
|
+
const commandServiceEndpoint = responseData.extendedMetadata?.commandServiceEndpoint;
|
|
129
|
+
const sandbox = {
|
|
130
|
+
instanceId,
|
|
131
|
+
name: `instance-${instanceId}`,
|
|
132
|
+
commandServiceEndpoint,
|
|
133
|
+
token,
|
|
134
|
+
targetContainerName: containerName,
|
|
135
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
136
|
+
};
|
|
137
|
+
return {
|
|
138
|
+
sandbox,
|
|
139
|
+
sandboxId: instanceId
|
|
140
|
+
};
|
|
141
|
+
} catch (error) {
|
|
142
|
+
throw new Error(
|
|
143
|
+
`Failed to create Namespace instance: ${error instanceof Error ? error.message : String(error)}`
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
getById: async (config, sandboxId) => {
|
|
148
|
+
const { token } = await getAndValidateCredentials(config);
|
|
149
|
+
try {
|
|
150
|
+
const responseData = await fetchNamespace(token, API_ENDPOINTS.DESCRIBE_INSTANCE, {
|
|
151
|
+
method: "POST",
|
|
152
|
+
body: JSON.stringify({ instance_id: sandboxId })
|
|
153
|
+
});
|
|
154
|
+
if (!responseData.metadata?.instanceId) {
|
|
155
|
+
throw new Error("Instance data is missing from Namespace response");
|
|
156
|
+
}
|
|
157
|
+
const instanceId = responseData.metadata.instanceId;
|
|
158
|
+
const commandServiceEndpoint = responseData.extendedMetadata?.commandServiceEndpoint;
|
|
159
|
+
const sandbox = {
|
|
160
|
+
instanceId,
|
|
161
|
+
name: `instance-${instanceId}`,
|
|
162
|
+
commandServiceEndpoint,
|
|
163
|
+
token,
|
|
164
|
+
targetContainerName: config.targetContainerName || "main-container",
|
|
165
|
+
createdAt: responseData.metadata?.createdAt ? new Date(responseData.metadata.createdAt) : /* @__PURE__ */ new Date(0)
|
|
166
|
+
};
|
|
167
|
+
return {
|
|
168
|
+
sandbox,
|
|
169
|
+
sandboxId: instanceId
|
|
170
|
+
};
|
|
171
|
+
} catch (error) {
|
|
172
|
+
if (error instanceof Error && error.message.includes("404")) {
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
throw new Error(
|
|
176
|
+
`Failed to get Namespace instance: ${error instanceof Error ? error.message : String(error)}`
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
list: async (config) => {
|
|
181
|
+
const { token } = await getAndValidateCredentials(config);
|
|
182
|
+
try {
|
|
183
|
+
const responseData = await fetchNamespace(token, API_ENDPOINTS.LIST_INSTANCES, {
|
|
184
|
+
method: "POST",
|
|
185
|
+
body: JSON.stringify({})
|
|
186
|
+
});
|
|
187
|
+
const instances = responseData?.instances || [];
|
|
188
|
+
return instances.filter((instanceData) => instanceData.instanceId || instanceData.metadata?.instanceId).map((instanceData) => {
|
|
189
|
+
const instanceId = instanceData.instanceId || instanceData.metadata.instanceId;
|
|
190
|
+
const commandServiceEndpoint = instanceData.extendedMetadata?.commandServiceEndpoint;
|
|
191
|
+
const sandbox = {
|
|
192
|
+
instanceId,
|
|
193
|
+
name: `instance-${instanceId}`,
|
|
194
|
+
commandServiceEndpoint,
|
|
195
|
+
token,
|
|
196
|
+
targetContainerName: config.targetContainerName || "main-container",
|
|
197
|
+
createdAt: instanceData.metadata?.createdAt ? new Date(instanceData.metadata.createdAt) : /* @__PURE__ */ new Date(0)
|
|
198
|
+
};
|
|
199
|
+
return {
|
|
200
|
+
sandbox,
|
|
201
|
+
sandboxId: instanceId
|
|
202
|
+
};
|
|
203
|
+
});
|
|
204
|
+
} catch (error) {
|
|
205
|
+
throw new Error(
|
|
206
|
+
`Failed to list Namespace instances: ${error instanceof Error ? error.message : String(error)}`
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
destroy: async (config, sandboxId) => {
|
|
211
|
+
const { token } = await getAndValidateCredentials(config);
|
|
212
|
+
try {
|
|
213
|
+
const data = await fetchNamespace(token, API_ENDPOINTS.DESTROY_INSTANCE, {
|
|
214
|
+
method: "POST",
|
|
215
|
+
body: JSON.stringify({
|
|
216
|
+
instance_id: sandboxId,
|
|
217
|
+
reason: config.destroyReason || "ComputeSDK cleanup"
|
|
218
|
+
})
|
|
219
|
+
});
|
|
220
|
+
if (data.error) {
|
|
221
|
+
console.warn(`Namespace destroy warning: ${data.error}`);
|
|
222
|
+
}
|
|
223
|
+
} catch (error) {
|
|
224
|
+
console.warn(`Namespace destroy warning: ${error instanceof Error ? error.message : String(error)}`);
|
|
225
|
+
}
|
|
226
|
+
},
|
|
227
|
+
// Command execution via Namespace CommandService
|
|
228
|
+
runCommand: async (sandbox, command, options) => {
|
|
229
|
+
if (!sandbox.commandServiceEndpoint) {
|
|
230
|
+
throw new Error("Command service endpoint not available. The instance may not support command execution.");
|
|
231
|
+
}
|
|
232
|
+
const startTime = Date.now();
|
|
233
|
+
try {
|
|
234
|
+
let fullCommand = command;
|
|
235
|
+
if (options?.env && Object.keys(options.env).length > 0) {
|
|
236
|
+
const envPrefix = Object.entries(options.env).map(([k, v]) => `${k}=${(0, import_provider.escapeShellArg)(v)}`).join(" ");
|
|
237
|
+
fullCommand = `${envPrefix} ${fullCommand}`;
|
|
238
|
+
}
|
|
239
|
+
if (options?.cwd) {
|
|
240
|
+
fullCommand = `cd ${(0, import_provider.escapeShellArg)(options.cwd)} && ${fullCommand}`;
|
|
241
|
+
}
|
|
242
|
+
if (options?.background) {
|
|
243
|
+
fullCommand = `nohup ${fullCommand} > /dev/null 2>&1 &`;
|
|
244
|
+
}
|
|
245
|
+
const result = await fetchNamespace(
|
|
246
|
+
sandbox.token,
|
|
247
|
+
COMMAND_SERVICE.RUN_COMMAND_SYNC,
|
|
248
|
+
{
|
|
249
|
+
method: "POST",
|
|
250
|
+
body: JSON.stringify({
|
|
251
|
+
instanceId: sandbox.instanceId,
|
|
252
|
+
targetContainerName: sandbox.targetContainerName,
|
|
253
|
+
command: {
|
|
254
|
+
command: ["sh", "-c", fullCommand]
|
|
255
|
+
}
|
|
256
|
+
})
|
|
257
|
+
},
|
|
258
|
+
sandbox.commandServiceEndpoint
|
|
259
|
+
);
|
|
260
|
+
const decodeBase64 = (data) => {
|
|
261
|
+
if (!data) return "";
|
|
262
|
+
try {
|
|
263
|
+
return Buffer.from(data, "base64").toString();
|
|
264
|
+
} catch {
|
|
265
|
+
return data;
|
|
266
|
+
}
|
|
267
|
+
};
|
|
268
|
+
const stdout = decodeBase64(result.stdout);
|
|
269
|
+
const stderr = decodeBase64(result.stderr);
|
|
270
|
+
return {
|
|
271
|
+
stdout,
|
|
272
|
+
stderr,
|
|
273
|
+
exitCode: result.exitCode ?? 0,
|
|
274
|
+
durationMs: Date.now() - startTime
|
|
275
|
+
};
|
|
276
|
+
} catch (error) {
|
|
277
|
+
throw new Error(
|
|
278
|
+
`Namespace command execution failed: ${error instanceof Error ? error.message : String(error)}`
|
|
279
|
+
);
|
|
280
|
+
}
|
|
281
|
+
},
|
|
282
|
+
// Not supported - throw as no-op
|
|
283
|
+
runCode: async (_sandbox, _code, _runtime, _config) => {
|
|
284
|
+
throw new Error("Namespace provider does not support runCode. Use runCommand instead.");
|
|
285
|
+
},
|
|
286
|
+
getInfo: async (sandbox) => {
|
|
287
|
+
return {
|
|
288
|
+
id: sandbox.instanceId,
|
|
289
|
+
provider: "namespace",
|
|
290
|
+
runtime: "node",
|
|
291
|
+
status: "running",
|
|
292
|
+
createdAt: sandbox.createdAt,
|
|
293
|
+
timeout: 0,
|
|
294
|
+
metadata: {
|
|
295
|
+
name: sandbox.name,
|
|
296
|
+
commandServiceEndpoint: sandbox.commandServiceEndpoint
|
|
297
|
+
}
|
|
298
|
+
};
|
|
299
|
+
},
|
|
300
|
+
// Not supported - throw as no-op
|
|
301
|
+
getUrl: async (_sandbox, _options) => {
|
|
302
|
+
throw new Error("Namespace provider does not support getUrl.");
|
|
303
|
+
},
|
|
304
|
+
getInstance: (sandbox) => {
|
|
305
|
+
return sandbox;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
29
309
|
});
|
|
30
310
|
// Annotate the CommonJS export names for ESM import in node:
|
|
31
311
|
0 && (module.exports = {
|
|
312
|
+
fetchNamespace,
|
|
313
|
+
getAndValidateCredentials,
|
|
32
314
|
namespace
|
|
33
315
|
});
|
|
34
316
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Namespace Provider - Compute Factory\n *\n * Provides a first-class Namespace provider experience by routing all operations\n * through the ComputeSDK gateway. The gateway handles infrastructure provisioning\n * via @computesdk/gateway and installs the daemon for full sandbox capabilities.\n */\n\nimport { defineCompute, type ComputeConfig } from '@computesdk/provider';\n\n/**\n * Namespace provider configuration\n */\nexport interface NamespaceConfig extends ComputeConfig {\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\n/**\n * Namespace compute factory - creates configured compute instances\n *\n * Namespace is an infrastructure provider that becomes a full sandbox provider\n * via the ComputeSDK gateway. The gateway provisions Namespace instances with the\n * daemon pre-installed, enabling full sandbox capabilities.\n *\n * @example\n * ```typescript\n * import { namespace } from '@computesdk/namespace';\n *\n * const compute = namespace({\n * token: 'nsc_xxx'\n * });\n *\n * // Full compute API available (routes through gateway)\n * const sandbox = await compute.sandbox.create();\n *\n * // Execute code\n * const result = await sandbox.runCode('console.log(\"Hello from Namespace!\")');\n * console.log(result.stdout);\n *\n * // Filesystem operations\n * await sandbox.filesystem.writeFile('/tmp/test.txt', 'Hello!');\n * const content = await sandbox.filesystem.readFile('/tmp/test.txt');\n *\n * // Cleanup\n * await sandbox.destroy();\n * ```\n */\nexport const namespace = defineCompute<NamespaceConfig>({\n provider: 'namespace'\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAQA,sBAAkD;AAoD3C,IAAM,gBAAY,+BAA+B;AAAA,EACtD,UAAU;AACZ,CAAC;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Namespace Provider\n *\n * Full-featured provider using the factory pattern.\n * Supports instance lifecycle management and command execution via Namespace Compute API.\n */\n\nimport * as fs from 'fs/promises';\nimport { defineProvider, escapeShellArg } from '@computesdk/provider';\nimport type { Runtime, CodeResult, CommandResult, SandboxInfo, CreateSandboxOptions, RunCommandOptions } from '@computesdk/provider';\n\n/**\n * Namespace sandbox instance\n */\nexport interface NamespaceSandbox {\n instanceId: string;\n name: string;\n commandServiceEndpoint?: string;\n token: string;\n targetContainerName: string;\n createdAt: Date;\n}\n\n/**\n * Namespace provider configuration\n */\nexport interface NamespaceConfig {\n /** Namespace API token - if not provided, will fallback to NSC_TOKEN environment variable */\n token?: string;\n /** Path to a JSON token file (e.g. from `nsc login`) containing bearer_token - fallback to NSC_TOKEN_FILE */\n tokenFile?: 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 /** Target container name for command execution (default: \"main-container\") */\n targetContainerName?: string;\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 COMMAND_SERVICE = {\n RUN_COMMAND_SYNC: '/namespace.cloud.compute.v1beta.CommandService/RunCommandSync',\n};\n\n/**\n * Load bearer token from a JSON token file (e.g. from `nsc login`)\n */\nasync function loadTokenFromFile(filePath: string): Promise<string> {\n const content = await fs.readFile(filePath, 'utf8');\n const tokenJson: { bearer_token?: string } = JSON.parse(content);\n if (!tokenJson.bearer_token) {\n throw new Error(`Token file ${filePath} does not contain a bearer_token`);\n }\n return tokenJson.bearer_token;\n}\n\n/**\n * Get and validate Namespace credentials from config and environment.\n * Supports:\n * - config.token (direct bearer token)\n * - NSC_TOKEN env var (direct bearer token)\n * - NSC_TOKEN_FILE env var (path to JSON file with bearer_token field)\n */\nexport const getAndValidateCredentials = async (config: NamespaceConfig) => {\n // 1. Direct token from config or env\n let token = config.token || (typeof process !== 'undefined' && process.env?.NSC_TOKEN) || '';\n\n // 2. If no direct token, try loading from token file\n if (!token) {\n const tokenFile = config.tokenFile || (typeof process !== 'undefined' && process.env?.NSC_TOKEN_FILE) || '';\n if (tokenFile) {\n token = await loadTokenFromFile(tokenFile);\n }\n }\n\n if (!token) {\n throw new Error(\n 'Missing Namespace token. Provide token in config, set NSC_TOKEN, or set NSC_TOKEN_FILE environment variable (or provide tokenFile in config).'\n );\n }\n\n return { token };\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 baseUrl: string = 'https://us.compute.namespaceapis.com'\n) => {\n const response = await fetch(`${baseUrl}${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 * Namespace provider\n *\n * Creates Namespace instances and supports command execution via CommandService.\n */\nexport const namespace = defineProvider<NamespaceSandbox, NamespaceConfig>({\n name: 'namespace',\n\n methods: {\n sandbox: {\n // Collection operations (map to compute.sandbox.*)\n create: async (config: NamespaceConfig, options?: CreateSandboxOptions) => {\n const { token } = await getAndValidateCredentials(config);\n const containerName = config.targetContainerName || 'main-container';\n\n try {\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: containerName,\n image_ref: options?.image ?? 'ubuntu:latest',\n args: ['sleep', 'infinity'],\n ...(options?.envs && Object.keys(options.envs).length > 0 && {\n environment: options.envs\n })\n }],\n documented_purpose: config.documentedPurpose || 'ComputeSDK sandbox',\n deadline: new Date(Date.now() + 60 * 60 * 1000).toISOString()\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 commandServiceEndpoint = responseData.extendedMetadata?.commandServiceEndpoint;\n\n const sandbox: NamespaceSandbox = {\n instanceId,\n name: `instance-${instanceId}`,\n commandServiceEndpoint,\n token,\n targetContainerName: containerName,\n createdAt: new Date(),\n };\n\n return {\n sandbox,\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 } = await getAndValidateCredentials(config);\n\n try {\n const responseData = await fetchNamespace(token, API_ENDPOINTS.DESCRIBE_INSTANCE, {\n method: 'POST',\n body: JSON.stringify({ instance_id: sandboxId })\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 commandServiceEndpoint = responseData.extendedMetadata?.commandServiceEndpoint;\n\n const sandbox: NamespaceSandbox = {\n instanceId,\n name: `instance-${instanceId}`,\n commandServiceEndpoint,\n token,\n targetContainerName: config.targetContainerName || 'main-container',\n createdAt: responseData.metadata?.createdAt ? new Date(responseData.metadata.createdAt) : new Date(0),\n };\n\n return {\n sandbox,\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')) {\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 } = await 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 // Filter to instances with valid IDs, then transform\n return instances\n .filter((instanceData: any) => instanceData.instanceId || instanceData.metadata?.instanceId)\n .map((instanceData: any) => {\n const instanceId = instanceData.instanceId || instanceData.metadata.instanceId;\n const commandServiceEndpoint = instanceData.extendedMetadata?.commandServiceEndpoint;\n\n const sandbox: NamespaceSandbox = {\n instanceId,\n name: `instance-${instanceId}`,\n commandServiceEndpoint,\n token,\n targetContainerName: config.targetContainerName || 'main-container',\n createdAt: instanceData.metadata?.createdAt ? new Date(instanceData.metadata.createdAt) : new Date(0),\n };\n\n return {\n sandbox,\n sandboxId: instanceId\n };\n });\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 } = await getAndValidateCredentials(config);\n\n try {\n const data = await fetchNamespace(token, API_ENDPOINTS.DESTROY_INSTANCE, {\n method: 'POST',\n body: JSON.stringify({\n instance_id: sandboxId,\n reason: config.destroyReason || \"ComputeSDK cleanup\"\n })\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 log warnings rather than throwing\n // since the resource may already be gone\n console.warn(`Namespace destroy warning: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n // Command execution via Namespace CommandService\n runCommand: async (sandbox: NamespaceSandbox, command: string, options?: RunCommandOptions): Promise<CommandResult> => {\n if (!sandbox.commandServiceEndpoint) {\n throw new Error('Command service endpoint not available. The instance may not support command execution.');\n }\n\n const startTime = Date.now();\n\n try {\n // Build the full command with options\n let fullCommand = command;\n\n // Handle environment variables\n if (options?.env && Object.keys(options.env).length > 0) {\n const envPrefix = Object.entries(options.env)\n .map(([k, v]) => `${k}=${escapeShellArg(v)}`)\n .join(' ');\n fullCommand = `${envPrefix} ${fullCommand}`;\n }\n\n // Handle working directory\n if (options?.cwd) {\n fullCommand = `cd ${escapeShellArg(options.cwd)} && ${fullCommand}`;\n }\n\n // Handle background execution\n if (options?.background) {\n fullCommand = `nohup ${fullCommand} > /dev/null 2>&1 &`;\n }\n\n // Call CommandService RunCommandSync via Connect protocol\n const result = await fetchNamespace(\n sandbox.token,\n COMMAND_SERVICE.RUN_COMMAND_SYNC,\n {\n method: 'POST',\n body: JSON.stringify({\n instanceId: sandbox.instanceId,\n targetContainerName: sandbox.targetContainerName,\n command: {\n command: ['sh', '-c', fullCommand],\n },\n })\n },\n sandbox.commandServiceEndpoint\n ) as {\n stdout?: string; // base64-encoded\n stderr?: string; // base64-encoded\n exitCode?: number;\n };\n\n // Decode base64-encoded stdout/stderr, falling back to raw string on invalid data\n const decodeBase64 = (data?: string): string => {\n if (!data) return '';\n try {\n return Buffer.from(data, 'base64').toString();\n } catch {\n return data;\n }\n };\n const stdout = decodeBase64(result.stdout);\n const stderr = decodeBase64(result.stderr);\n\n return {\n stdout,\n stderr,\n exitCode: result.exitCode ?? 0,\n durationMs: Date.now() - startTime\n };\n } catch (error) {\n // Re-throw infrastructure errors (network, auth, API) so they propagate\n // rather than being masked as command execution failures\n throw new Error(\n `Namespace command execution failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n // Not supported - throw as no-op\n runCode: async (_sandbox: NamespaceSandbox, _code: string, _runtime?: Runtime, _config?: NamespaceConfig): Promise<CodeResult> => {\n throw new Error('Namespace provider does not support runCode. Use runCommand instead.');\n },\n\n getInfo: async (sandbox: NamespaceSandbox): Promise<SandboxInfo> => {\n return {\n id: sandbox.instanceId,\n provider: 'namespace',\n runtime: 'node',\n status: 'running',\n createdAt: sandbox.createdAt,\n timeout: 0,\n metadata: {\n name: sandbox.name,\n commandServiceEndpoint: sandbox.commandServiceEndpoint,\n }\n };\n },\n\n // Not supported - throw as no-op\n getUrl: async (_sandbox: NamespaceSandbox, _options: { port: number; protocol?: string }): Promise<string> => {\n throw new Error('Namespace provider does not support getUrl.');\n },\n\n getInstance: (sandbox: NamespaceSandbox): NamespaceSandbox => {\n return sandbox;\n },\n }\n }\n});\n"],"mappings":"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","names":[]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,9 +1,279 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
import * as fs from "fs/promises";
|
|
3
|
+
import { defineProvider, escapeShellArg } from "@computesdk/provider";
|
|
4
|
+
var API_ENDPOINTS = {
|
|
5
|
+
CREATE_INSTANCE: "/namespace.cloud.compute.v1beta.ComputeService/CreateInstance",
|
|
6
|
+
DESCRIBE_INSTANCE: "/namespace.cloud.compute.v1beta.ComputeService/DescribeInstance",
|
|
7
|
+
LIST_INSTANCES: "/namespace.cloud.compute.v1beta.ComputeService/ListInstances",
|
|
8
|
+
DESTROY_INSTANCE: "/namespace.cloud.compute.v1beta.ComputeService/DestroyInstance"
|
|
9
|
+
};
|
|
10
|
+
var COMMAND_SERVICE = {
|
|
11
|
+
RUN_COMMAND_SYNC: "/namespace.cloud.compute.v1beta.CommandService/RunCommandSync"
|
|
12
|
+
};
|
|
13
|
+
async function loadTokenFromFile(filePath) {
|
|
14
|
+
const content = await fs.readFile(filePath, "utf8");
|
|
15
|
+
const tokenJson = JSON.parse(content);
|
|
16
|
+
if (!tokenJson.bearer_token) {
|
|
17
|
+
throw new Error(`Token file ${filePath} does not contain a bearer_token`);
|
|
18
|
+
}
|
|
19
|
+
return tokenJson.bearer_token;
|
|
20
|
+
}
|
|
21
|
+
var getAndValidateCredentials = async (config) => {
|
|
22
|
+
let token = config.token || typeof process !== "undefined" && process.env?.NSC_TOKEN || "";
|
|
23
|
+
if (!token) {
|
|
24
|
+
const tokenFile = config.tokenFile || typeof process !== "undefined" && process.env?.NSC_TOKEN_FILE || "";
|
|
25
|
+
if (tokenFile) {
|
|
26
|
+
token = await loadTokenFromFile(tokenFile);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
if (!token) {
|
|
30
|
+
throw new Error(
|
|
31
|
+
"Missing Namespace token. Provide token in config, set NSC_TOKEN, or set NSC_TOKEN_FILE environment variable (or provide tokenFile in config)."
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
return { token };
|
|
35
|
+
};
|
|
36
|
+
var handleApiErrors = (response) => {
|
|
37
|
+
if (response.error) {
|
|
38
|
+
throw new Error(`Namespace API error: ${response.error}`);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
var fetchNamespace = async (token, endpoint, options = {}, baseUrl = "https://us.compute.namespaceapis.com") => {
|
|
42
|
+
const response = await fetch(`${baseUrl}${endpoint}`, {
|
|
43
|
+
...options,
|
|
44
|
+
headers: {
|
|
45
|
+
"Content-Type": "application/json",
|
|
46
|
+
"Authorization": `Bearer ${token}`,
|
|
47
|
+
...options.headers
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
if (!response.ok) {
|
|
51
|
+
throw new Error(`Namespace API error: ${response.status} ${response.statusText}`);
|
|
52
|
+
}
|
|
53
|
+
const data = await response.json();
|
|
54
|
+
handleApiErrors(data);
|
|
55
|
+
return data;
|
|
56
|
+
};
|
|
57
|
+
var namespace = defineProvider({
|
|
58
|
+
name: "namespace",
|
|
59
|
+
methods: {
|
|
60
|
+
sandbox: {
|
|
61
|
+
// Collection operations (map to compute.sandbox.*)
|
|
62
|
+
create: async (config, options) => {
|
|
63
|
+
const { token } = await getAndValidateCredentials(config);
|
|
64
|
+
const containerName = config.targetContainerName || "main-container";
|
|
65
|
+
try {
|
|
66
|
+
const requestBody = {
|
|
67
|
+
shape: {
|
|
68
|
+
virtual_cpu: config.virtualCpu || 2,
|
|
69
|
+
memory_megabytes: config.memoryMegabytes || 4096,
|
|
70
|
+
machine_arch: config.machineArch || "amd64",
|
|
71
|
+
os: config.os || "linux"
|
|
72
|
+
},
|
|
73
|
+
containers: [{
|
|
74
|
+
name: containerName,
|
|
75
|
+
image_ref: options?.image ?? "ubuntu:latest",
|
|
76
|
+
args: ["sleep", "infinity"],
|
|
77
|
+
...options?.envs && Object.keys(options.envs).length > 0 && {
|
|
78
|
+
environment: options.envs
|
|
79
|
+
}
|
|
80
|
+
}],
|
|
81
|
+
documented_purpose: config.documentedPurpose || "ComputeSDK sandbox",
|
|
82
|
+
deadline: new Date(Date.now() + 60 * 60 * 1e3).toISOString()
|
|
83
|
+
};
|
|
84
|
+
const responseData = await fetchNamespace(token, API_ENDPOINTS.CREATE_INSTANCE, {
|
|
85
|
+
method: "POST",
|
|
86
|
+
body: JSON.stringify(requestBody)
|
|
87
|
+
});
|
|
88
|
+
if (!responseData.metadata?.instanceId) {
|
|
89
|
+
throw new Error(`Instance ID is undefined. Full response object: ${JSON.stringify(responseData, null, 2)}`);
|
|
90
|
+
}
|
|
91
|
+
const instanceId = responseData.metadata.instanceId;
|
|
92
|
+
const commandServiceEndpoint = responseData.extendedMetadata?.commandServiceEndpoint;
|
|
93
|
+
const sandbox = {
|
|
94
|
+
instanceId,
|
|
95
|
+
name: `instance-${instanceId}`,
|
|
96
|
+
commandServiceEndpoint,
|
|
97
|
+
token,
|
|
98
|
+
targetContainerName: containerName,
|
|
99
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
100
|
+
};
|
|
101
|
+
return {
|
|
102
|
+
sandbox,
|
|
103
|
+
sandboxId: instanceId
|
|
104
|
+
};
|
|
105
|
+
} catch (error) {
|
|
106
|
+
throw new Error(
|
|
107
|
+
`Failed to create Namespace instance: ${error instanceof Error ? error.message : String(error)}`
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
getById: async (config, sandboxId) => {
|
|
112
|
+
const { token } = await getAndValidateCredentials(config);
|
|
113
|
+
try {
|
|
114
|
+
const responseData = await fetchNamespace(token, API_ENDPOINTS.DESCRIBE_INSTANCE, {
|
|
115
|
+
method: "POST",
|
|
116
|
+
body: JSON.stringify({ instance_id: sandboxId })
|
|
117
|
+
});
|
|
118
|
+
if (!responseData.metadata?.instanceId) {
|
|
119
|
+
throw new Error("Instance data is missing from Namespace response");
|
|
120
|
+
}
|
|
121
|
+
const instanceId = responseData.metadata.instanceId;
|
|
122
|
+
const commandServiceEndpoint = responseData.extendedMetadata?.commandServiceEndpoint;
|
|
123
|
+
const sandbox = {
|
|
124
|
+
instanceId,
|
|
125
|
+
name: `instance-${instanceId}`,
|
|
126
|
+
commandServiceEndpoint,
|
|
127
|
+
token,
|
|
128
|
+
targetContainerName: config.targetContainerName || "main-container",
|
|
129
|
+
createdAt: responseData.metadata?.createdAt ? new Date(responseData.metadata.createdAt) : /* @__PURE__ */ new Date(0)
|
|
130
|
+
};
|
|
131
|
+
return {
|
|
132
|
+
sandbox,
|
|
133
|
+
sandboxId: instanceId
|
|
134
|
+
};
|
|
135
|
+
} catch (error) {
|
|
136
|
+
if (error instanceof Error && error.message.includes("404")) {
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
throw new Error(
|
|
140
|
+
`Failed to get Namespace instance: ${error instanceof Error ? error.message : String(error)}`
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
list: async (config) => {
|
|
145
|
+
const { token } = await getAndValidateCredentials(config);
|
|
146
|
+
try {
|
|
147
|
+
const responseData = await fetchNamespace(token, API_ENDPOINTS.LIST_INSTANCES, {
|
|
148
|
+
method: "POST",
|
|
149
|
+
body: JSON.stringify({})
|
|
150
|
+
});
|
|
151
|
+
const instances = responseData?.instances || [];
|
|
152
|
+
return instances.filter((instanceData) => instanceData.instanceId || instanceData.metadata?.instanceId).map((instanceData) => {
|
|
153
|
+
const instanceId = instanceData.instanceId || instanceData.metadata.instanceId;
|
|
154
|
+
const commandServiceEndpoint = instanceData.extendedMetadata?.commandServiceEndpoint;
|
|
155
|
+
const sandbox = {
|
|
156
|
+
instanceId,
|
|
157
|
+
name: `instance-${instanceId}`,
|
|
158
|
+
commandServiceEndpoint,
|
|
159
|
+
token,
|
|
160
|
+
targetContainerName: config.targetContainerName || "main-container",
|
|
161
|
+
createdAt: instanceData.metadata?.createdAt ? new Date(instanceData.metadata.createdAt) : /* @__PURE__ */ new Date(0)
|
|
162
|
+
};
|
|
163
|
+
return {
|
|
164
|
+
sandbox,
|
|
165
|
+
sandboxId: instanceId
|
|
166
|
+
};
|
|
167
|
+
});
|
|
168
|
+
} catch (error) {
|
|
169
|
+
throw new Error(
|
|
170
|
+
`Failed to list Namespace instances: ${error instanceof Error ? error.message : String(error)}`
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
},
|
|
174
|
+
destroy: async (config, sandboxId) => {
|
|
175
|
+
const { token } = await getAndValidateCredentials(config);
|
|
176
|
+
try {
|
|
177
|
+
const data = await fetchNamespace(token, API_ENDPOINTS.DESTROY_INSTANCE, {
|
|
178
|
+
method: "POST",
|
|
179
|
+
body: JSON.stringify({
|
|
180
|
+
instance_id: sandboxId,
|
|
181
|
+
reason: config.destroyReason || "ComputeSDK cleanup"
|
|
182
|
+
})
|
|
183
|
+
});
|
|
184
|
+
if (data.error) {
|
|
185
|
+
console.warn(`Namespace destroy warning: ${data.error}`);
|
|
186
|
+
}
|
|
187
|
+
} catch (error) {
|
|
188
|
+
console.warn(`Namespace destroy warning: ${error instanceof Error ? error.message : String(error)}`);
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
// Command execution via Namespace CommandService
|
|
192
|
+
runCommand: async (sandbox, command, options) => {
|
|
193
|
+
if (!sandbox.commandServiceEndpoint) {
|
|
194
|
+
throw new Error("Command service endpoint not available. The instance may not support command execution.");
|
|
195
|
+
}
|
|
196
|
+
const startTime = Date.now();
|
|
197
|
+
try {
|
|
198
|
+
let fullCommand = command;
|
|
199
|
+
if (options?.env && Object.keys(options.env).length > 0) {
|
|
200
|
+
const envPrefix = Object.entries(options.env).map(([k, v]) => `${k}=${escapeShellArg(v)}`).join(" ");
|
|
201
|
+
fullCommand = `${envPrefix} ${fullCommand}`;
|
|
202
|
+
}
|
|
203
|
+
if (options?.cwd) {
|
|
204
|
+
fullCommand = `cd ${escapeShellArg(options.cwd)} && ${fullCommand}`;
|
|
205
|
+
}
|
|
206
|
+
if (options?.background) {
|
|
207
|
+
fullCommand = `nohup ${fullCommand} > /dev/null 2>&1 &`;
|
|
208
|
+
}
|
|
209
|
+
const result = await fetchNamespace(
|
|
210
|
+
sandbox.token,
|
|
211
|
+
COMMAND_SERVICE.RUN_COMMAND_SYNC,
|
|
212
|
+
{
|
|
213
|
+
method: "POST",
|
|
214
|
+
body: JSON.stringify({
|
|
215
|
+
instanceId: sandbox.instanceId,
|
|
216
|
+
targetContainerName: sandbox.targetContainerName,
|
|
217
|
+
command: {
|
|
218
|
+
command: ["sh", "-c", fullCommand]
|
|
219
|
+
}
|
|
220
|
+
})
|
|
221
|
+
},
|
|
222
|
+
sandbox.commandServiceEndpoint
|
|
223
|
+
);
|
|
224
|
+
const decodeBase64 = (data) => {
|
|
225
|
+
if (!data) return "";
|
|
226
|
+
try {
|
|
227
|
+
return Buffer.from(data, "base64").toString();
|
|
228
|
+
} catch {
|
|
229
|
+
return data;
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
const stdout = decodeBase64(result.stdout);
|
|
233
|
+
const stderr = decodeBase64(result.stderr);
|
|
234
|
+
return {
|
|
235
|
+
stdout,
|
|
236
|
+
stderr,
|
|
237
|
+
exitCode: result.exitCode ?? 0,
|
|
238
|
+
durationMs: Date.now() - startTime
|
|
239
|
+
};
|
|
240
|
+
} catch (error) {
|
|
241
|
+
throw new Error(
|
|
242
|
+
`Namespace command execution failed: ${error instanceof Error ? error.message : String(error)}`
|
|
243
|
+
);
|
|
244
|
+
}
|
|
245
|
+
},
|
|
246
|
+
// Not supported - throw as no-op
|
|
247
|
+
runCode: async (_sandbox, _code, _runtime, _config) => {
|
|
248
|
+
throw new Error("Namespace provider does not support runCode. Use runCommand instead.");
|
|
249
|
+
},
|
|
250
|
+
getInfo: async (sandbox) => {
|
|
251
|
+
return {
|
|
252
|
+
id: sandbox.instanceId,
|
|
253
|
+
provider: "namespace",
|
|
254
|
+
runtime: "node",
|
|
255
|
+
status: "running",
|
|
256
|
+
createdAt: sandbox.createdAt,
|
|
257
|
+
timeout: 0,
|
|
258
|
+
metadata: {
|
|
259
|
+
name: sandbox.name,
|
|
260
|
+
commandServiceEndpoint: sandbox.commandServiceEndpoint
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
},
|
|
264
|
+
// Not supported - throw as no-op
|
|
265
|
+
getUrl: async (_sandbox, _options) => {
|
|
266
|
+
throw new Error("Namespace provider does not support getUrl.");
|
|
267
|
+
},
|
|
268
|
+
getInstance: (sandbox) => {
|
|
269
|
+
return sandbox;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
5
273
|
});
|
|
6
274
|
export {
|
|
275
|
+
fetchNamespace,
|
|
276
|
+
getAndValidateCredentials,
|
|
7
277
|
namespace
|
|
8
278
|
};
|
|
9
279
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Namespace Provider - Compute Factory\n *\n * Provides a first-class Namespace provider experience by routing all operations\n * through the ComputeSDK gateway. The gateway handles infrastructure provisioning\n * via @computesdk/gateway and installs the daemon for full sandbox capabilities.\n */\n\nimport { defineCompute, type ComputeConfig } from '@computesdk/provider';\n\n/**\n * Namespace provider configuration\n */\nexport interface NamespaceConfig extends ComputeConfig {\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\n/**\n * Namespace compute factory - creates configured compute instances\n *\n * Namespace is an infrastructure provider that becomes a full sandbox provider\n * via the ComputeSDK gateway. The gateway provisions Namespace instances with the\n * daemon pre-installed, enabling full sandbox capabilities.\n *\n * @example\n * ```typescript\n * import { namespace } from '@computesdk/namespace';\n *\n * const compute = namespace({\n * token: 'nsc_xxx'\n * });\n *\n * // Full compute API available (routes through gateway)\n * const sandbox = await compute.sandbox.create();\n *\n * // Execute code\n * const result = await sandbox.runCode('console.log(\"Hello from Namespace!\")');\n * console.log(result.stdout);\n *\n * // Filesystem operations\n * await sandbox.filesystem.writeFile('/tmp/test.txt', 'Hello!');\n * const content = await sandbox.filesystem.readFile('/tmp/test.txt');\n *\n * // Cleanup\n * await sandbox.destroy();\n * ```\n */\nexport const namespace = defineCompute<NamespaceConfig>({\n provider: 'namespace'\n});\n"],"mappings":";AAQA,SAAS,qBAAyC;AAoD3C,IAAM,YAAY,cAA+B;AAAA,EACtD,UAAU;AACZ,CAAC;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Namespace Provider\n *\n * Full-featured provider using the factory pattern.\n * Supports instance lifecycle management and command execution via Namespace Compute API.\n */\n\nimport * as fs from 'fs/promises';\nimport { defineProvider, escapeShellArg } from '@computesdk/provider';\nimport type { Runtime, CodeResult, CommandResult, SandboxInfo, CreateSandboxOptions, RunCommandOptions } from '@computesdk/provider';\n\n/**\n * Namespace sandbox instance\n */\nexport interface NamespaceSandbox {\n instanceId: string;\n name: string;\n commandServiceEndpoint?: string;\n token: string;\n targetContainerName: string;\n createdAt: Date;\n}\n\n/**\n * Namespace provider configuration\n */\nexport interface NamespaceConfig {\n /** Namespace API token - if not provided, will fallback to NSC_TOKEN environment variable */\n token?: string;\n /** Path to a JSON token file (e.g. from `nsc login`) containing bearer_token - fallback to NSC_TOKEN_FILE */\n tokenFile?: 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 /** Target container name for command execution (default: \"main-container\") */\n targetContainerName?: string;\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 COMMAND_SERVICE = {\n RUN_COMMAND_SYNC: '/namespace.cloud.compute.v1beta.CommandService/RunCommandSync',\n};\n\n/**\n * Load bearer token from a JSON token file (e.g. from `nsc login`)\n */\nasync function loadTokenFromFile(filePath: string): Promise<string> {\n const content = await fs.readFile(filePath, 'utf8');\n const tokenJson: { bearer_token?: string } = JSON.parse(content);\n if (!tokenJson.bearer_token) {\n throw new Error(`Token file ${filePath} does not contain a bearer_token`);\n }\n return tokenJson.bearer_token;\n}\n\n/**\n * Get and validate Namespace credentials from config and environment.\n * Supports:\n * - config.token (direct bearer token)\n * - NSC_TOKEN env var (direct bearer token)\n * - NSC_TOKEN_FILE env var (path to JSON file with bearer_token field)\n */\nexport const getAndValidateCredentials = async (config: NamespaceConfig) => {\n // 1. Direct token from config or env\n let token = config.token || (typeof process !== 'undefined' && process.env?.NSC_TOKEN) || '';\n\n // 2. If no direct token, try loading from token file\n if (!token) {\n const tokenFile = config.tokenFile || (typeof process !== 'undefined' && process.env?.NSC_TOKEN_FILE) || '';\n if (tokenFile) {\n token = await loadTokenFromFile(tokenFile);\n }\n }\n\n if (!token) {\n throw new Error(\n 'Missing Namespace token. Provide token in config, set NSC_TOKEN, or set NSC_TOKEN_FILE environment variable (or provide tokenFile in config).'\n );\n }\n\n return { token };\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 baseUrl: string = 'https://us.compute.namespaceapis.com'\n) => {\n const response = await fetch(`${baseUrl}${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 * Namespace provider\n *\n * Creates Namespace instances and supports command execution via CommandService.\n */\nexport const namespace = defineProvider<NamespaceSandbox, NamespaceConfig>({\n name: 'namespace',\n\n methods: {\n sandbox: {\n // Collection operations (map to compute.sandbox.*)\n create: async (config: NamespaceConfig, options?: CreateSandboxOptions) => {\n const { token } = await getAndValidateCredentials(config);\n const containerName = config.targetContainerName || 'main-container';\n\n try {\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: containerName,\n image_ref: options?.image ?? 'ubuntu:latest',\n args: ['sleep', 'infinity'],\n ...(options?.envs && Object.keys(options.envs).length > 0 && {\n environment: options.envs\n })\n }],\n documented_purpose: config.documentedPurpose || 'ComputeSDK sandbox',\n deadline: new Date(Date.now() + 60 * 60 * 1000).toISOString()\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 commandServiceEndpoint = responseData.extendedMetadata?.commandServiceEndpoint;\n\n const sandbox: NamespaceSandbox = {\n instanceId,\n name: `instance-${instanceId}`,\n commandServiceEndpoint,\n token,\n targetContainerName: containerName,\n createdAt: new Date(),\n };\n\n return {\n sandbox,\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 } = await getAndValidateCredentials(config);\n\n try {\n const responseData = await fetchNamespace(token, API_ENDPOINTS.DESCRIBE_INSTANCE, {\n method: 'POST',\n body: JSON.stringify({ instance_id: sandboxId })\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 commandServiceEndpoint = responseData.extendedMetadata?.commandServiceEndpoint;\n\n const sandbox: NamespaceSandbox = {\n instanceId,\n name: `instance-${instanceId}`,\n commandServiceEndpoint,\n token,\n targetContainerName: config.targetContainerName || 'main-container',\n createdAt: responseData.metadata?.createdAt ? new Date(responseData.metadata.createdAt) : new Date(0),\n };\n\n return {\n sandbox,\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')) {\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 } = await 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 // Filter to instances with valid IDs, then transform\n return instances\n .filter((instanceData: any) => instanceData.instanceId || instanceData.metadata?.instanceId)\n .map((instanceData: any) => {\n const instanceId = instanceData.instanceId || instanceData.metadata.instanceId;\n const commandServiceEndpoint = instanceData.extendedMetadata?.commandServiceEndpoint;\n\n const sandbox: NamespaceSandbox = {\n instanceId,\n name: `instance-${instanceId}`,\n commandServiceEndpoint,\n token,\n targetContainerName: config.targetContainerName || 'main-container',\n createdAt: instanceData.metadata?.createdAt ? new Date(instanceData.metadata.createdAt) : new Date(0),\n };\n\n return {\n sandbox,\n sandboxId: instanceId\n };\n });\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 } = await getAndValidateCredentials(config);\n\n try {\n const data = await fetchNamespace(token, API_ENDPOINTS.DESTROY_INSTANCE, {\n method: 'POST',\n body: JSON.stringify({\n instance_id: sandboxId,\n reason: config.destroyReason || \"ComputeSDK cleanup\"\n })\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 log warnings rather than throwing\n // since the resource may already be gone\n console.warn(`Namespace destroy warning: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n // Command execution via Namespace CommandService\n runCommand: async (sandbox: NamespaceSandbox, command: string, options?: RunCommandOptions): Promise<CommandResult> => {\n if (!sandbox.commandServiceEndpoint) {\n throw new Error('Command service endpoint not available. The instance may not support command execution.');\n }\n\n const startTime = Date.now();\n\n try {\n // Build the full command with options\n let fullCommand = command;\n\n // Handle environment variables\n if (options?.env && Object.keys(options.env).length > 0) {\n const envPrefix = Object.entries(options.env)\n .map(([k, v]) => `${k}=${escapeShellArg(v)}`)\n .join(' ');\n fullCommand = `${envPrefix} ${fullCommand}`;\n }\n\n // Handle working directory\n if (options?.cwd) {\n fullCommand = `cd ${escapeShellArg(options.cwd)} && ${fullCommand}`;\n }\n\n // Handle background execution\n if (options?.background) {\n fullCommand = `nohup ${fullCommand} > /dev/null 2>&1 &`;\n }\n\n // Call CommandService RunCommandSync via Connect protocol\n const result = await fetchNamespace(\n sandbox.token,\n COMMAND_SERVICE.RUN_COMMAND_SYNC,\n {\n method: 'POST',\n body: JSON.stringify({\n instanceId: sandbox.instanceId,\n targetContainerName: sandbox.targetContainerName,\n command: {\n command: ['sh', '-c', fullCommand],\n },\n })\n },\n sandbox.commandServiceEndpoint\n ) as {\n stdout?: string; // base64-encoded\n stderr?: string; // base64-encoded\n exitCode?: number;\n };\n\n // Decode base64-encoded stdout/stderr, falling back to raw string on invalid data\n const decodeBase64 = (data?: string): string => {\n if (!data) return '';\n try {\n return Buffer.from(data, 'base64').toString();\n } catch {\n return data;\n }\n };\n const stdout = decodeBase64(result.stdout);\n const stderr = decodeBase64(result.stderr);\n\n return {\n stdout,\n stderr,\n exitCode: result.exitCode ?? 0,\n durationMs: Date.now() - startTime\n };\n } catch (error) {\n // Re-throw infrastructure errors (network, auth, API) so they propagate\n // rather than being masked as command execution failures\n throw new Error(\n `Namespace command execution failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n // Not supported - throw as no-op\n runCode: async (_sandbox: NamespaceSandbox, _code: string, _runtime?: Runtime, _config?: NamespaceConfig): Promise<CodeResult> => {\n throw new Error('Namespace provider does not support runCode. Use runCommand instead.');\n },\n\n getInfo: async (sandbox: NamespaceSandbox): Promise<SandboxInfo> => {\n return {\n id: sandbox.instanceId,\n provider: 'namespace',\n runtime: 'node',\n status: 'running',\n createdAt: sandbox.createdAt,\n timeout: 0,\n metadata: {\n name: sandbox.name,\n commandServiceEndpoint: sandbox.commandServiceEndpoint,\n }\n };\n },\n\n // Not supported - throw as no-op\n getUrl: async (_sandbox: NamespaceSandbox, _options: { port: number; protocol?: string }): Promise<string> => {\n throw new Error('Namespace provider does not support getUrl.');\n },\n\n getInstance: (sandbox: NamespaceSandbox): NamespaceSandbox => {\n return sandbox;\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/namespace",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.1",
|
|
4
4
|
"description": "Namespace provider for ComputeSDK - cloud-native sandboxes with optional GPU support",
|
|
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.
|
|
22
|
-
"computesdk": "2.
|
|
21
|
+
"@computesdk/provider": "1.0.29",
|
|
22
|
+
"computesdk": "2.4.0"
|
|
23
23
|
},
|
|
24
24
|
"keywords": [
|
|
25
25
|
"computesdk",
|