@nimbus-sh/sdk 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +105 -21
- package/dist/index.d.ts +8 -8
- package/dist/index.js +8 -8
- package/dist/sandbox.d.ts +43 -4
- package/dist/sandbox.d.ts.map +1 -1
- package/dist/sandbox.js +232 -16
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +3 -2
- package/dist/token.d.ts +3 -4
- package/dist/token.d.ts.map +1 -1
- package/dist/token.js +3 -4
- package/dist/worker.d.ts +11 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +9 -0
- package/package.json +9 -7
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# @nimbus-sh/sdk
|
|
2
2
|
|
|
3
|
-
SDK for Nimbus — programmatic sandbox handles,
|
|
4
|
-
errors, and session URL helpers.
|
|
3
|
+
SDK for Nimbus — Worker embedder, programmatic sandbox handles,
|
|
4
|
+
token mint/verify, typed errors, and session URL helpers.
|
|
5
5
|
|
|
6
6
|
## Install
|
|
7
7
|
|
|
@@ -9,41 +9,85 @@ errors, and session URL helpers.
|
|
|
9
9
|
npm install @nimbus-sh/sdk @nimbus-sh/worker @nimbus-sh/config
|
|
10
10
|
```
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
Use `@nimbus-sh/sdk/worker` as the public Worker embedder entrypoint.
|
|
13
|
+
`@nimbus-sh/worker` is still installed because it carries the runtime assets
|
|
14
|
+
and Durable Object implementation, but application code imports the
|
|
15
|
+
deploy-time API through the SDK.
|
|
16
|
+
|
|
17
|
+
Create a deployable Nimbus Worker:
|
|
14
18
|
|
|
15
19
|
```bash
|
|
16
|
-
npx
|
|
20
|
+
npx create-nimbus-app my-nimbus-worker
|
|
17
21
|
cd my-nimbus-worker
|
|
18
22
|
npm install
|
|
19
|
-
|
|
20
|
-
wrangler
|
|
23
|
+
CLOUDFLARE_ACCOUNT_ID=<account-id> npx @nimbus-sh/cli setup cloudflare --name my-nimbus-worker
|
|
24
|
+
npx wrangler secret put JWT_SECRET
|
|
25
|
+
npx wrangler deploy
|
|
21
26
|
```
|
|
22
27
|
|
|
23
|
-
|
|
28
|
+
`src/index.ts`:
|
|
24
29
|
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
```ts
|
|
31
|
+
import {
|
|
32
|
+
NimbusSession,
|
|
33
|
+
SupervisorRPC,
|
|
34
|
+
NimbusAssetsRPC,
|
|
35
|
+
NimbusLoaderRPC,
|
|
36
|
+
NimbusLoadedWorker,
|
|
37
|
+
NimbusLoadedEntrypoint,
|
|
38
|
+
NimbusDurableObjectNamespace,
|
|
39
|
+
NimbusDOStub,
|
|
40
|
+
CirrusHmrRPC,
|
|
41
|
+
createNimbusHandler,
|
|
42
|
+
} from '@nimbus-sh/sdk/worker';
|
|
43
|
+
import { defineNimbusConfig } from '@nimbus-sh/config';
|
|
44
|
+
|
|
45
|
+
export {
|
|
46
|
+
NimbusSession,
|
|
47
|
+
SupervisorRPC,
|
|
48
|
+
NimbusAssetsRPC,
|
|
49
|
+
NimbusLoaderRPC,
|
|
50
|
+
NimbusLoadedWorker,
|
|
51
|
+
NimbusLoadedEntrypoint,
|
|
52
|
+
NimbusDurableObjectNamespace,
|
|
53
|
+
NimbusDOStub,
|
|
54
|
+
CirrusHmrRPC,
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const nimbusConfig = defineNimbusConfig({
|
|
58
|
+
sandboxes: {
|
|
59
|
+
default: {
|
|
60
|
+
root: '/home/user',
|
|
61
|
+
runtimes: { preinstall: ['python'], onDemand: true },
|
|
62
|
+
tools: { namespace: 'sandbox', kind: 'sandbox' },
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
export default createNimbusHandler({
|
|
68
|
+
sdk: {
|
|
69
|
+
remote: true,
|
|
70
|
+
config: nimbusConfig,
|
|
71
|
+
},
|
|
72
|
+
});
|
|
31
73
|
```
|
|
32
74
|
|
|
33
75
|
## Programmatic sandbox quickstart
|
|
34
76
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
77
|
+
The same sandbox handle API works in two modes:
|
|
78
|
+
|
|
79
|
+
- `Nimbus.fromEnv(env, config)` for a Worker or Durable Object with the
|
|
80
|
+
`NIMBUS_SESSION` binding.
|
|
81
|
+
- `Nimbus.connect({ endpoint, token, config })` for any backend that can reach
|
|
82
|
+
a deployed Nimbus Worker.
|
|
38
83
|
|
|
39
84
|
```ts
|
|
40
|
-
import { Nimbus } from '@nimbus-sh/sdk
|
|
85
|
+
import { Nimbus } from '@nimbus-sh/sdk';
|
|
41
86
|
import { defineNimbusConfig } from '@nimbus-sh/config';
|
|
42
87
|
|
|
43
88
|
const nimbusConfig = defineNimbusConfig({
|
|
44
|
-
endpoint: 'https://my-nimbus.workers.dev',
|
|
45
89
|
sandboxes: {
|
|
46
|
-
|
|
90
|
+
default: {
|
|
47
91
|
root: '/home/user',
|
|
48
92
|
tools: { namespace: 'sandbox', kind: 'sandbox' },
|
|
49
93
|
runtimes: {
|
|
@@ -58,7 +102,6 @@ const nimbusConfig = defineNimbusConfig({
|
|
|
58
102
|
export default {
|
|
59
103
|
async fetch(_request: Request, env: Env) {
|
|
60
104
|
const box = Nimbus.fromEnv(env, nimbusConfig).sandbox('job-123', {
|
|
61
|
-
profile: 'proteus',
|
|
62
105
|
tenant: 'acme',
|
|
63
106
|
subject: 'agent',
|
|
64
107
|
});
|
|
@@ -72,10 +115,50 @@ export default {
|
|
|
72
115
|
};
|
|
73
116
|
```
|
|
74
117
|
|
|
118
|
+
Remote use:
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
import { Nimbus, issueNimbusToken } from '@nimbus-sh/sdk';
|
|
122
|
+
|
|
123
|
+
const token = await issueNimbusToken(env, {
|
|
124
|
+
tn: 'acme',
|
|
125
|
+
sub: 'agent',
|
|
126
|
+
scopes: ['sandbox:use'],
|
|
127
|
+
sid: 'job-123',
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
const box = Nimbus.connect({
|
|
131
|
+
endpoint: 'https://my-nimbus.workers.dev',
|
|
132
|
+
token,
|
|
133
|
+
config: nimbusConfig,
|
|
134
|
+
}).sandbox('job-123');
|
|
135
|
+
|
|
136
|
+
const result = await box.exec('python -c "print(2 + 2)"');
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Enable the remote API in the Nimbus Worker:
|
|
140
|
+
|
|
141
|
+
```ts
|
|
142
|
+
export default createNimbusHandler({
|
|
143
|
+
sdk: {
|
|
144
|
+
remote: true,
|
|
145
|
+
config: nimbusConfig,
|
|
146
|
+
},
|
|
147
|
+
});
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
`Nimbus.connect()` calls the versioned `/api/nimbus/v1` API internally. The
|
|
151
|
+
Worker verifies the JWT, enforces `sid` pins and `sandbox:use` scope, applies
|
|
152
|
+
the configured runtime policy, and delegates to the same `NimbusSession` RPC
|
|
153
|
+
methods used by `Nimbus.fromEnv()`.
|
|
154
|
+
|
|
75
155
|
## Sandbox handle API
|
|
76
156
|
|
|
77
157
|
```ts
|
|
78
158
|
const nimbus = Nimbus.fromEnv(env, config, { binding: 'NIMBUS_SESSION' });
|
|
159
|
+
// or:
|
|
160
|
+
const nimbus = Nimbus.connect({ endpoint, token, config });
|
|
161
|
+
|
|
79
162
|
const box = nimbus.sandbox('session-or-job-id', {
|
|
80
163
|
profile: 'default',
|
|
81
164
|
tenant: 'acme',
|
|
@@ -213,6 +296,7 @@ const { token, url } = await mintAndAttach(
|
|
|
213
296
|
| `@nimbus-sh/sdk/errors` | `NimbusAuthError` class hierarchy. |
|
|
214
297
|
| `@nimbus-sh/sdk/session` | `sessionAttachUrl`, `mintAndAttach`. |
|
|
215
298
|
| `@nimbus-sh/sdk/sandbox` | `Nimbus`, `NimbusSandbox`, programmatic exec/files/runtimes/processes/ports/tools. |
|
|
299
|
+
| `@nimbus-sh/sdk/worker` | Worker embedder entrypoint: `NimbusSession`, RPC classes, `createNimbusHandler`, auth helpers. |
|
|
216
300
|
|
|
217
301
|
## Token wire format
|
|
218
302
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @nimbus-sh/sdk —
|
|
2
|
+
* @nimbus-sh/sdk — Public SDK for Nimbus.
|
|
3
3
|
*
|
|
4
|
-
* The SDK is the
|
|
5
|
-
* verify, typed errors, session-handle
|
|
6
|
-
*
|
|
7
|
-
* from a Node SSR layer, a Worker, an Edge function, or a browser
|
|
8
|
-
* build.
|
|
4
|
+
* The SDK is the public surface for Nimbus applications: token mint /
|
|
5
|
+
* verify, typed errors, session-handle helpers, programmatic sandboxes,
|
|
6
|
+
* and the Worker embedder subpath.
|
|
9
7
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
8
|
+
* Import the deployed Worker embedder from `@nimbus-sh/sdk/worker`.
|
|
9
|
+
* The Durable Object, router, assets, VFS, and facet implementation live
|
|
10
|
+
* in `@nimbus-sh/worker` and are re-exported through that public SDK
|
|
11
|
+
* subpath.
|
|
12
12
|
*
|
|
13
13
|
* @example mint a token in your Worker's `/api/auth/mint` route
|
|
14
14
|
* ```ts
|
package/dist/index.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @nimbus-sh/sdk —
|
|
2
|
+
* @nimbus-sh/sdk — Public SDK for Nimbus.
|
|
3
3
|
*
|
|
4
|
-
* The SDK is the
|
|
5
|
-
* verify, typed errors, session-handle
|
|
6
|
-
*
|
|
7
|
-
* from a Node SSR layer, a Worker, an Edge function, or a browser
|
|
8
|
-
* build.
|
|
4
|
+
* The SDK is the public surface for Nimbus applications: token mint /
|
|
5
|
+
* verify, typed errors, session-handle helpers, programmatic sandboxes,
|
|
6
|
+
* and the Worker embedder subpath.
|
|
9
7
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
8
|
+
* Import the deployed Worker embedder from `@nimbus-sh/sdk/worker`.
|
|
9
|
+
* The Durable Object, router, assets, VFS, and facet implementation live
|
|
10
|
+
* in `@nimbus-sh/worker` and are re-exported through that public SDK
|
|
11
|
+
* subpath.
|
|
12
12
|
*
|
|
13
13
|
* @example mint a token in your Worker's `/api/auth/mint` route
|
|
14
14
|
* ```ts
|
package/dist/sandbox.d.ts
CHANGED
|
@@ -28,6 +28,21 @@ export interface NimbusFromEnvOptions {
|
|
|
28
28
|
binding?: string;
|
|
29
29
|
endpoint?: string;
|
|
30
30
|
}
|
|
31
|
+
export type NimbusHeaders = HeadersInit | (() => HeadersInit | Promise<HeadersInit>);
|
|
32
|
+
export interface NimbusConnectOptions {
|
|
33
|
+
/** Base URL of a Nimbus deployment, for example `https://nimbus.example.com`. */
|
|
34
|
+
endpoint: string;
|
|
35
|
+
/** Nimbus JWT. Sent as `Authorization: Bearer <token>` when provided. */
|
|
36
|
+
token?: string;
|
|
37
|
+
/** Additional headers, or a callback for rotating credentials. */
|
|
38
|
+
headers?: NimbusHeaders;
|
|
39
|
+
/** Custom fetch implementation. Defaults to global `fetch`. */
|
|
40
|
+
fetch?: typeof fetch;
|
|
41
|
+
/** Remote API base path. Defaults to `/api/nimbus/v1`. */
|
|
42
|
+
basePath?: string;
|
|
43
|
+
/** Sandbox profiles used by this client. The deployment should use the same config. */
|
|
44
|
+
config?: NimbusConfig;
|
|
45
|
+
}
|
|
31
46
|
export interface NimbusSandboxOptions {
|
|
32
47
|
profile?: string;
|
|
33
48
|
tenant?: string;
|
|
@@ -88,26 +103,50 @@ export interface NimbusAvailableRuntime {
|
|
|
88
103
|
}>;
|
|
89
104
|
}
|
|
90
105
|
type NimbusSessionNamespace = DurableObjectNamespace<any>;
|
|
106
|
+
type NimbusTarget = {
|
|
107
|
+
kind: 'binding';
|
|
108
|
+
namespace: NimbusSessionNamespace;
|
|
109
|
+
} | {
|
|
110
|
+
kind: 'remote';
|
|
111
|
+
endpoint: string;
|
|
112
|
+
basePath: string;
|
|
113
|
+
token?: string;
|
|
114
|
+
headers?: NimbusHeaders;
|
|
115
|
+
fetch: typeof fetch;
|
|
116
|
+
};
|
|
117
|
+
export declare class NimbusRemoteError extends Error {
|
|
118
|
+
readonly status: number;
|
|
119
|
+
readonly code: string | undefined;
|
|
120
|
+
readonly body: unknown;
|
|
121
|
+
constructor(message: string, options: {
|
|
122
|
+
status: number;
|
|
123
|
+
code?: string;
|
|
124
|
+
body?: unknown;
|
|
125
|
+
});
|
|
126
|
+
}
|
|
91
127
|
export declare class Nimbus {
|
|
92
|
-
private readonly namespace;
|
|
93
128
|
private readonly config;
|
|
94
129
|
static fromEnv(env: Record<string, unknown>, config?: NimbusConfig, options?: NimbusFromEnvOptions): Nimbus;
|
|
95
|
-
|
|
130
|
+
static connect(options: NimbusConnectOptions): Nimbus;
|
|
131
|
+
private readonly target;
|
|
132
|
+
constructor(target: NimbusSessionNamespace | NimbusTarget, config?: NimbusConfig);
|
|
96
133
|
sandbox(id: string, options?: NimbusSandboxOptions): NimbusSandbox;
|
|
97
134
|
}
|
|
98
135
|
export declare class NimbusSandbox {
|
|
99
|
-
private readonly
|
|
136
|
+
private readonly target;
|
|
100
137
|
private readonly options;
|
|
101
138
|
private readonly config;
|
|
102
139
|
readonly id: string;
|
|
103
140
|
readonly profileName: string;
|
|
104
141
|
private readonly profile;
|
|
105
142
|
private readyPromise;
|
|
106
|
-
constructor(
|
|
143
|
+
constructor(target: NimbusTarget, id: string, options: NimbusSandboxOptions, config: NimbusConfig);
|
|
107
144
|
private get tenantSegment();
|
|
108
145
|
private get doName();
|
|
109
146
|
private get root();
|
|
110
147
|
private stub;
|
|
148
|
+
private remoteStub;
|
|
149
|
+
private remoteRpc;
|
|
111
150
|
ready(): Promise<void>;
|
|
112
151
|
exec(command: string, options?: NimbusExecOptions): Promise<NimbusExecResult>;
|
|
113
152
|
startProcess(command: string, options?: NimbusExecOptions): Promise<NimbusStartResult>;
|
package/dist/sandbox.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sandbox.d.ts","sourceRoot":"","sources":["../src/sandbox.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC;AACjC,MAAM,MAAM,WAAW,GACnB,MAAM,GACN,KAAK,GACL,KAAK,GACL,KAAK,GACL,QAAQ,GACR,MAAM,GACN,OAAO,GACP,OAAO,GACP,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAElB,MAAM,WAAW,mBAAmB;IAClC,UAAU,CAAC,EAAE,WAAW,EAAE,CAAC;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,WAAW,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,mBAAmB,CAAC;IAC/B,KAAK,CAAC,EAAE;QACN,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,OAAO,CAAC,EAAE;QACR,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,SAAS,CAAC,EAAE,OAAO,CAAC;KACrB,CAAC;CACH;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;CAClD;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,iBAAiB;IAChC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAkB,SAAQ,gBAAgB;IACzD,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,OAAO,EAAE,aAAa,GAAG,IAAI,CAAC;IAC9B,KAAK,EAAE,UAAU,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC1E;AAyBD,KAAK,sBAAsB,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;AAE1D,
|
|
1
|
+
{"version":3,"file":"sandbox.d.ts","sourceRoot":"","sources":["../src/sandbox.ts"],"names":[],"mappings":"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"}
|
package/dist/sandbox.js
CHANGED
|
@@ -1,8 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @nimbus-sh/sdk/sandbox - programmatic Nimbus sandbox handle.
|
|
3
3
|
*/
|
|
4
|
+
export class NimbusRemoteError extends Error {
|
|
5
|
+
status;
|
|
6
|
+
code;
|
|
7
|
+
body;
|
|
8
|
+
constructor(message, options) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.name = 'NimbusRemoteError';
|
|
11
|
+
this.status = options.status;
|
|
12
|
+
this.code = options.code;
|
|
13
|
+
this.body = options.body;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
4
16
|
export class Nimbus {
|
|
5
|
-
namespace;
|
|
6
17
|
config;
|
|
7
18
|
static fromEnv(env, config = {}, options = {}) {
|
|
8
19
|
const bindingName = options.binding ?? 'NIMBUS_SESSION';
|
|
@@ -10,38 +21,62 @@ export class Nimbus {
|
|
|
10
21
|
if (!binding) {
|
|
11
22
|
throw new Error(`Nimbus.fromEnv: env.${bindingName} Durable Object binding is missing`);
|
|
12
23
|
}
|
|
13
|
-
return new Nimbus(binding, {
|
|
24
|
+
return new Nimbus({ kind: 'binding', namespace: binding }, {
|
|
14
25
|
...config,
|
|
15
26
|
endpoint: options.endpoint ?? config.endpoint,
|
|
16
27
|
});
|
|
17
28
|
}
|
|
18
|
-
|
|
19
|
-
|
|
29
|
+
static connect(options) {
|
|
30
|
+
if (!options.endpoint) {
|
|
31
|
+
throw new Error('Nimbus.connect: endpoint is required');
|
|
32
|
+
}
|
|
33
|
+
const fetchImpl = options.fetch ?? globalThis.fetch?.bind(globalThis);
|
|
34
|
+
if (typeof fetchImpl !== 'function') {
|
|
35
|
+
throw new Error('Nimbus.connect: fetch is unavailable; pass a custom fetch implementation');
|
|
36
|
+
}
|
|
37
|
+
const config = {
|
|
38
|
+
...(options.config ?? {}),
|
|
39
|
+
endpoint: options.endpoint,
|
|
40
|
+
};
|
|
41
|
+
return new Nimbus({
|
|
42
|
+
kind: 'remote',
|
|
43
|
+
endpoint: trimTrailingSlashes(options.endpoint),
|
|
44
|
+
basePath: normalizeBasePath(options.basePath ?? '/api/nimbus/v1'),
|
|
45
|
+
token: options.token,
|
|
46
|
+
headers: options.headers,
|
|
47
|
+
fetch: fetchImpl,
|
|
48
|
+
}, config);
|
|
49
|
+
}
|
|
50
|
+
target;
|
|
51
|
+
constructor(target, config = {}) {
|
|
20
52
|
this.config = config;
|
|
53
|
+
this.target = isNimbusTarget(target)
|
|
54
|
+
? target
|
|
55
|
+
: { kind: 'binding', namespace: target };
|
|
21
56
|
}
|
|
22
57
|
sandbox(id, options = {}) {
|
|
23
|
-
return new NimbusSandbox(this.
|
|
58
|
+
return new NimbusSandbox(this.target, String(id), options, this.config);
|
|
24
59
|
}
|
|
25
60
|
}
|
|
26
61
|
export class NimbusSandbox {
|
|
27
|
-
|
|
62
|
+
target;
|
|
28
63
|
options;
|
|
29
64
|
config;
|
|
30
65
|
id;
|
|
31
66
|
profileName;
|
|
32
67
|
profile;
|
|
33
68
|
readyPromise = null;
|
|
34
|
-
constructor(
|
|
35
|
-
this.
|
|
69
|
+
constructor(target, id, options, config) {
|
|
70
|
+
this.target = target;
|
|
36
71
|
this.options = options;
|
|
37
72
|
this.config = config;
|
|
38
|
-
this.id = id;
|
|
73
|
+
this.id = idComponent(id, 'sandbox id');
|
|
39
74
|
this.profileName = options.profile ?? 'default';
|
|
40
75
|
this.profile = config.sandboxes?.[this.profileName] ?? config.sandboxes?.default ?? {};
|
|
41
76
|
}
|
|
42
77
|
get tenantSegment() {
|
|
43
|
-
const tenant =
|
|
44
|
-
const subject =
|
|
78
|
+
const tenant = idComponent(this.options.tenant ?? 'default', 'tenant');
|
|
79
|
+
const subject = idComponent(this.options.subject ?? '_', 'subject');
|
|
45
80
|
return `${tenant}:${subject}`;
|
|
46
81
|
}
|
|
47
82
|
get doName() {
|
|
@@ -51,10 +86,81 @@ export class NimbusSandbox {
|
|
|
51
86
|
return this.options.root ?? this.profile.root ?? '/home/user';
|
|
52
87
|
}
|
|
53
88
|
stub() {
|
|
54
|
-
|
|
89
|
+
if (this.target.kind === 'remote')
|
|
90
|
+
return this.remoteStub();
|
|
91
|
+
const namespace = this.target.namespace;
|
|
55
92
|
const id = namespace.idFromName(this.doName);
|
|
56
93
|
return namespace.get(id);
|
|
57
94
|
}
|
|
95
|
+
remoteStub() {
|
|
96
|
+
return {
|
|
97
|
+
_rpcReady: (options) => this.remoteRpc('ready', [options]),
|
|
98
|
+
_rpcExec: (command, options) => this.remoteRpc('exec', [command, options]),
|
|
99
|
+
_rpcStartProcess: (command, options) => this.remoteRpc('startProcess', [command, options]),
|
|
100
|
+
_rpcRunCode: (code, options) => this.remoteRpc('runCode', [code, options]),
|
|
101
|
+
_rpcReadFile: (path) => this.remoteRpc('readFile', [path]),
|
|
102
|
+
_rpcReadFileBytes: (path) => this.remoteRpc('readFileBytes', [path]),
|
|
103
|
+
_rpcWriteFile: (path, content) => this.remoteRpc('writeFile', [path, content]),
|
|
104
|
+
_rpcReaddir: (path) => this.remoteRpc('readdir', [path]),
|
|
105
|
+
_rpcExists: (path) => this.remoteRpc('exists', [path]),
|
|
106
|
+
_rpcMkdir: (path) => this.remoteRpc('mkdir', [path]),
|
|
107
|
+
_rpcDeleteFile: (path, options) => this.remoteRpc('deleteFile', [path, options]),
|
|
108
|
+
_rpcInstallRuntime: (spec, options) => this.remoteRpc('installRuntime', [spec, options]),
|
|
109
|
+
_rpcEnsureRuntimes: (specs, options) => this.remoteRpc('ensureRuntimes', [specs, options]),
|
|
110
|
+
_rpcListRuntimes: () => this.remoteRpc('listRuntimes', []),
|
|
111
|
+
_rpcListProcesses: () => this.remoteRpc('listProcesses', []),
|
|
112
|
+
_rpcKillProcess: (pid) => this.remoteRpc('killProcess', [pid]),
|
|
113
|
+
_rpcProcessLogs: (pid, options) => this.remoteRpc('processLogs', [pid, options]),
|
|
114
|
+
_rpcListPorts: () => this.remoteRpc('listPorts', []),
|
|
115
|
+
_rpcExposePort: (port) => this.remoteRpc('exposePort', [port]),
|
|
116
|
+
_rpcUnexposePort: (port) => this.remoteRpc('unexposePort', [port]),
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
async remoteRpc(op, args) {
|
|
120
|
+
if (this.target.kind !== 'remote') {
|
|
121
|
+
throw new Error('Nimbus internal error: remoteRpc called on non-remote target');
|
|
122
|
+
}
|
|
123
|
+
const headers = new Headers(await resolveHeaders(this.target.headers));
|
|
124
|
+
headers.set('Accept', 'application/json');
|
|
125
|
+
headers.set('Content-Type', 'application/json');
|
|
126
|
+
if (this.target.token && !headers.has('Authorization')) {
|
|
127
|
+
headers.set('Authorization', `Bearer ${this.target.token}`);
|
|
128
|
+
}
|
|
129
|
+
const response = await this.target.fetch(`${this.target.endpoint}${this.target.basePath}/sandboxes/${encodeURIComponent(this.id)}/rpc`, {
|
|
130
|
+
method: 'POST',
|
|
131
|
+
headers,
|
|
132
|
+
body: JSON.stringify(encodeWire({
|
|
133
|
+
profile: this.profileName,
|
|
134
|
+
tenant: this.options.tenant,
|
|
135
|
+
subject: this.options.subject,
|
|
136
|
+
root: this.root,
|
|
137
|
+
op,
|
|
138
|
+
args,
|
|
139
|
+
})),
|
|
140
|
+
});
|
|
141
|
+
const text = await response.text();
|
|
142
|
+
let payload = null;
|
|
143
|
+
if (text) {
|
|
144
|
+
try {
|
|
145
|
+
payload = JSON.parse(text);
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
throw new NimbusRemoteError(`Nimbus remote API returned non-JSON response (${response.status})`, {
|
|
149
|
+
status: response.status,
|
|
150
|
+
body: text,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (!response.ok || payload?.ok !== true) {
|
|
155
|
+
const message = payload?.error ?? payload?.message ?? `Nimbus remote API request failed (${response.status})`;
|
|
156
|
+
throw new NimbusRemoteError(message, {
|
|
157
|
+
status: response.status,
|
|
158
|
+
code: payload?.code,
|
|
159
|
+
body: payload,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
return decodeWire(payload.result);
|
|
163
|
+
}
|
|
58
164
|
async ready() {
|
|
59
165
|
if (!this.readyPromise) {
|
|
60
166
|
const preinstall = this.profile.runtimes?.preinstall ?? [];
|
|
@@ -245,15 +351,125 @@ export class NimbusSandbox {
|
|
|
245
351
|
portUrl(port) {
|
|
246
352
|
const explicit = this.profile.preview?.baseUrl;
|
|
247
353
|
if (explicit) {
|
|
248
|
-
const base = explicit.replace('{sessionId}', encodeURIComponent(this.id))
|
|
354
|
+
const base = trimTrailingSlashes(explicit.replace('{sessionId}', encodeURIComponent(this.id)));
|
|
249
355
|
return `${base}/port/${port}/`;
|
|
250
356
|
}
|
|
251
|
-
const endpoint = this.config.endpoint
|
|
357
|
+
const endpoint = this.config.endpoint ? trimTrailingSlashes(this.config.endpoint) : '';
|
|
252
358
|
if (!endpoint)
|
|
253
359
|
return undefined;
|
|
254
360
|
return `${endpoint}/s/${encodeURIComponent(this.id)}/port/${port}/`;
|
|
255
361
|
}
|
|
256
362
|
}
|
|
257
|
-
function
|
|
258
|
-
|
|
363
|
+
function idComponent(value, field) {
|
|
364
|
+
const text = String(value);
|
|
365
|
+
if (!isIdComponent(text)) {
|
|
366
|
+
throw new Error(`Nimbus ${field} must be 1-128 ASCII letters, digits, dot, underscore, or hyphen`);
|
|
367
|
+
}
|
|
368
|
+
return text;
|
|
369
|
+
}
|
|
370
|
+
function isIdComponent(value) {
|
|
371
|
+
if (value.length < 1 || value.length > 128)
|
|
372
|
+
return false;
|
|
373
|
+
for (let i = 0; i < value.length; i++) {
|
|
374
|
+
const code = value.charCodeAt(i);
|
|
375
|
+
const isDigit = code >= 48 && code <= 57;
|
|
376
|
+
const isUpper = code >= 65 && code <= 90;
|
|
377
|
+
const isLower = code >= 97 && code <= 122;
|
|
378
|
+
const isPunctuation = code === 45 || code === 46 || code === 95;
|
|
379
|
+
if (!isDigit && !isUpper && !isLower && !isPunctuation)
|
|
380
|
+
return false;
|
|
381
|
+
}
|
|
382
|
+
return true;
|
|
383
|
+
}
|
|
384
|
+
function isNimbusTarget(value) {
|
|
385
|
+
return !!value && typeof value === 'object' && 'kind' in value;
|
|
386
|
+
}
|
|
387
|
+
function normalizeBasePath(path) {
|
|
388
|
+
const trimmed = trimSlashes(String(path || '/api/nimbus/v1'));
|
|
389
|
+
return `/${trimmed}`;
|
|
390
|
+
}
|
|
391
|
+
function trimSlashes(value) {
|
|
392
|
+
let start = 0;
|
|
393
|
+
let end = value.length;
|
|
394
|
+
while (start < end && value[start] === '/')
|
|
395
|
+
start++;
|
|
396
|
+
while (end > start && value[end - 1] === '/')
|
|
397
|
+
end--;
|
|
398
|
+
return value.slice(start, end);
|
|
399
|
+
}
|
|
400
|
+
function trimTrailingSlashes(value) {
|
|
401
|
+
let end = value.length;
|
|
402
|
+
while (end > 0 && value[end - 1] === '/')
|
|
403
|
+
end--;
|
|
404
|
+
return value.slice(0, end);
|
|
405
|
+
}
|
|
406
|
+
async function resolveHeaders(input) {
|
|
407
|
+
if (!input)
|
|
408
|
+
return undefined;
|
|
409
|
+
return typeof input === 'function' ? await input() : input;
|
|
410
|
+
}
|
|
411
|
+
function encodeWire(value) {
|
|
412
|
+
if (value instanceof Uint8Array) {
|
|
413
|
+
return {
|
|
414
|
+
__nimbusWireType: 'bytes',
|
|
415
|
+
base64: bytesToBase64(value),
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
if (value instanceof ArrayBuffer) {
|
|
419
|
+
return {
|
|
420
|
+
__nimbusWireType: 'bytes',
|
|
421
|
+
base64: bytesToBase64(new Uint8Array(value)),
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
if (ArrayBuffer.isView(value)) {
|
|
425
|
+
const view = value;
|
|
426
|
+
return {
|
|
427
|
+
__nimbusWireType: 'bytes',
|
|
428
|
+
base64: bytesToBase64(new Uint8Array(view.buffer, view.byteOffset, view.byteLength)),
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
if (Array.isArray(value))
|
|
432
|
+
return value.map(encodeWire);
|
|
433
|
+
if (value && typeof value === 'object') {
|
|
434
|
+
const out = {};
|
|
435
|
+
for (const [key, item] of Object.entries(value)) {
|
|
436
|
+
if (item !== undefined)
|
|
437
|
+
out[key] = encodeWire(item);
|
|
438
|
+
}
|
|
439
|
+
return out;
|
|
440
|
+
}
|
|
441
|
+
return value;
|
|
442
|
+
}
|
|
443
|
+
function decodeWire(value) {
|
|
444
|
+
if (value
|
|
445
|
+
&& typeof value === 'object'
|
|
446
|
+
&& value.__nimbusWireType === 'bytes'
|
|
447
|
+
&& typeof value.base64 === 'string') {
|
|
448
|
+
return base64ToBytes(value.base64);
|
|
449
|
+
}
|
|
450
|
+
if (Array.isArray(value))
|
|
451
|
+
return value.map(decodeWire);
|
|
452
|
+
if (value && typeof value === 'object') {
|
|
453
|
+
const out = {};
|
|
454
|
+
for (const [key, item] of Object.entries(value)) {
|
|
455
|
+
out[key] = decodeWire(item);
|
|
456
|
+
}
|
|
457
|
+
return out;
|
|
458
|
+
}
|
|
459
|
+
return value;
|
|
460
|
+
}
|
|
461
|
+
function bytesToBase64(bytes) {
|
|
462
|
+
let binary = '';
|
|
463
|
+
const chunk = 0x8000;
|
|
464
|
+
for (let i = 0; i < bytes.length; i += chunk) {
|
|
465
|
+
binary += String.fromCharCode(...bytes.subarray(i, i + chunk));
|
|
466
|
+
}
|
|
467
|
+
return btoa(binary);
|
|
468
|
+
}
|
|
469
|
+
function base64ToBytes(base64) {
|
|
470
|
+
const binary = atob(base64);
|
|
471
|
+
const bytes = new Uint8Array(binary.length);
|
|
472
|
+
for (let i = 0; i < binary.length; i++)
|
|
473
|
+
bytes[i] = binary.charCodeAt(i);
|
|
474
|
+
return bytes;
|
|
259
475
|
}
|
package/dist/session.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAoB,KAAK,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC9E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GACZ,MAAM,
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAoB,KAAK,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC9E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GACZ,MAAM,CAIR;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,aAAa,EAClB,KAAK,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,EACpE,IAAI,EAAE,iBAAiB,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAChE,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CAIzC"}
|
package/dist/session.js
CHANGED
|
@@ -26,8 +26,9 @@ import { issueNimbusToken } from '@nimbus-sh/worker/auth';
|
|
|
26
26
|
* ```
|
|
27
27
|
*/
|
|
28
28
|
export function sessionAttachUrl(endpoint, sessionId, token) {
|
|
29
|
-
const
|
|
30
|
-
|
|
29
|
+
const url = new URL(`/s/${encodeURIComponent(sessionId)}/`, endpoint);
|
|
30
|
+
url.searchParams.set('nimbus_token', token);
|
|
31
|
+
return url.toString();
|
|
31
32
|
}
|
|
32
33
|
/**
|
|
33
34
|
* Convenience: mint a token AND build the attach URL in one call.
|
package/dist/token.d.ts
CHANGED
|
@@ -5,10 +5,9 @@
|
|
|
5
5
|
* Why a re-export and not a copy? The auth module is the single source
|
|
6
6
|
* of truth — both Worker (verify) and SDK (mint) call the same code
|
|
7
7
|
* paths so wire-format drift is structurally impossible. The
|
|
8
|
-
* `@nimbus-sh/worker`
|
|
9
|
-
* package
|
|
10
|
-
*
|
|
11
|
-
* worker peer-dep is tree-shaken to its auth subpath.
|
|
8
|
+
* `@nimbus-sh/worker` provides the shared auth implementation. The SDK
|
|
9
|
+
* package depends on that single source of truth so token wire-format
|
|
10
|
+
* drift is structurally impossible.
|
|
12
11
|
*
|
|
13
12
|
* @example mint
|
|
14
13
|
* ```ts
|
package/dist/token.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../src/token.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../src/token.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,KAAK,aAAa,GACnB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,GACvB,MAAM,wBAAwB,CAAC"}
|
package/dist/token.js
CHANGED
|
@@ -5,10 +5,9 @@
|
|
|
5
5
|
* Why a re-export and not a copy? The auth module is the single source
|
|
6
6
|
* of truth — both Worker (verify) and SDK (mint) call the same code
|
|
7
7
|
* paths so wire-format drift is structurally impossible. The
|
|
8
|
-
* `@nimbus-sh/worker`
|
|
9
|
-
* package
|
|
10
|
-
*
|
|
11
|
-
* worker peer-dep is tree-shaken to its auth subpath.
|
|
8
|
+
* `@nimbus-sh/worker` provides the shared auth implementation. The SDK
|
|
9
|
+
* package depends on that single source of truth so token wire-format
|
|
10
|
+
* drift is structurally impossible.
|
|
12
11
|
*
|
|
13
12
|
* @example mint
|
|
14
13
|
* ```ts
|
package/dist/worker.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @nimbus-sh/sdk/worker - Cloudflare Worker embedder surface.
|
|
3
|
+
*
|
|
4
|
+
* This is the public entrypoint for deploying Nimbus itself inside a
|
|
5
|
+
* Worker. The implementation is provided by @nimbus-sh/worker, but apps
|
|
6
|
+
* should import through the SDK so the interactive app and programmatic
|
|
7
|
+
* sandbox APIs share one public package surface.
|
|
8
|
+
*/
|
|
9
|
+
export { NimbusSession, SupervisorRPC, NimbusAssetsRPC, NimbusLoaderRPC, NimbusLoadedWorker, NimbusLoadedEntrypoint, NimbusDurableObjectNamespace, NimbusDOStub, CirrusHmrRPC, createNimbusHandler, issueNimbusToken, verifyNimbusToken, NimbusAuthError, } from '@nimbus-sh/worker';
|
|
10
|
+
export type { NimbusHandler, NimbusHooks, NimbusHookContext, CustomRoutes, CreateNimbusHandlerOptions, NimbusRemoteApiConfig, NimbusRuntimePolicy, NimbusSandboxProfile, NimbusSdkConfig, NimbusSdkRouterConfig, AuthMode, NimbusAuthConfig, NimbusAuthEnv, NimbusTokenClaims, VerifiedNimbusToken, } from '@nimbus-sh/worker';
|
|
11
|
+
//# sourceMappingURL=worker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,aAAa,EACb,aAAa,EACb,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,sBAAsB,EACtB,4BAA4B,EAC5B,YAAY,EACZ,YAAY,EACZ,mBAAmB,EACnB,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,GAChB,MAAM,mBAAmB,CAAC;AAE3B,YAAY,EACV,aAAa,EACb,WAAW,EACX,iBAAiB,EACjB,YAAY,EACZ,0BAA0B,EAC1B,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,eAAe,EACf,qBAAqB,EACrB,QAAQ,EACR,gBAAgB,EAChB,aAAa,EACb,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,mBAAmB,CAAC"}
|
package/dist/worker.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @nimbus-sh/sdk/worker - Cloudflare Worker embedder surface.
|
|
3
|
+
*
|
|
4
|
+
* This is the public entrypoint for deploying Nimbus itself inside a
|
|
5
|
+
* Worker. The implementation is provided by @nimbus-sh/worker, but apps
|
|
6
|
+
* should import through the SDK so the interactive app and programmatic
|
|
7
|
+
* sandbox APIs share one public package surface.
|
|
8
|
+
*/
|
|
9
|
+
export { NimbusSession, SupervisorRPC, NimbusAssetsRPC, NimbusLoaderRPC, NimbusLoadedWorker, NimbusLoadedEntrypoint, NimbusDurableObjectNamespace, NimbusDOStub, CirrusHmrRPC, createNimbusHandler, issueNimbusToken, verifyNimbusToken, NimbusAuthError, } from '@nimbus-sh/worker';
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nimbus-sh/sdk",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "Nimbus SDK — programmatic sandboxes, token mint,
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "Nimbus SDK — Worker embedder, programmatic sandboxes, token mint, and client helpers.",
|
|
5
5
|
"homepage": "https://github.com/AshishKumar4/Nimbus",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -35,6 +35,11 @@
|
|
|
35
35
|
"types": "./dist/sandbox.d.ts",
|
|
36
36
|
"import": "./dist/sandbox.js"
|
|
37
37
|
},
|
|
38
|
+
"./worker": {
|
|
39
|
+
"workspace": "./src/worker.ts",
|
|
40
|
+
"types": "./dist/worker.d.ts",
|
|
41
|
+
"import": "./dist/worker.js"
|
|
42
|
+
},
|
|
38
43
|
"./errors": {
|
|
39
44
|
"workspace": "./src/errors.ts",
|
|
40
45
|
"types": "./dist/errors.d.ts",
|
|
@@ -52,14 +57,11 @@
|
|
|
52
57
|
"typecheck": "tsc --noEmit"
|
|
53
58
|
},
|
|
54
59
|
"peerDependencies": {
|
|
55
|
-
"@nimbus-sh/worker": "^0.1.
|
|
56
|
-
},
|
|
57
|
-
"peerDependenciesMeta": {
|
|
58
|
-
"@nimbus-sh/worker": { "optional": true }
|
|
60
|
+
"@nimbus-sh/worker": "^0.1.2"
|
|
59
61
|
},
|
|
60
62
|
"devDependencies": {
|
|
61
63
|
"@cloudflare/workers-types": "^4.20250327.0",
|
|
62
|
-
"@nimbus-sh/worker": "^0.1.
|
|
64
|
+
"@nimbus-sh/worker": "^0.1.2",
|
|
63
65
|
"typescript": "^5.7.0"
|
|
64
66
|
},
|
|
65
67
|
"publishConfig": {
|