mirror of
https://github.com/NVIDIA/OpenShell.git
synced 2026-10-26 06:52:57 +08:00
feat(sdk/ts): add createdAtMs to SandboxRef (#4347)
* feat(sdk/ts): add createdAtMs to SandboxRef Signed-off-by: Eric Curtin <eric.curtin@docker.com> * docs(sdk/ts): document createdAtMs on SandboxRef Signed-off-by: Eric Curtin <eric.curtin@docker.com> --------- Signed-off-by: Eric Curtin <eric.curtin@docker.com>
This commit is contained in:
@@ -130,6 +130,9 @@ if (deletion.outcome === 'accepted') {
|
||||
}
|
||||
```
|
||||
|
||||
Sandbox refs returned by `create`, `get`, and `list` include `createdAtMs`, the
|
||||
creation time in epoch milliseconds. It is absent when the gateway omits it.
|
||||
|
||||
`client.sandbox` also supports streaming and interactive exec, TCP forwarding,
|
||||
SSH sessions, sandbox provider attachment, configuration, and policy. Close
|
||||
operation-scoped streams and forwarding handles when finished. The root client
|
||||
|
||||
@@ -64,6 +64,8 @@ resolves to a different ID. Without that option, it waits for name absence,
|
||||
including any same-name replacement. Pass the same `workspace` to deletion and
|
||||
its wait when using a non-default workspace.
|
||||
|
||||
Sandbox refs from `create`, `get`, and `list` carry `createdAtMs` (epoch milliseconds), absent when the gateway omits it.
|
||||
|
||||
`connect()` constructs a lazy client; call `health()` when startup must verify
|
||||
gateway reachability. Static `oidcToken` and `edgeToken` values remain fixed for
|
||||
the client's lifetime. For long-running service automation, use the renewable
|
||||
|
||||
@@ -83,6 +83,22 @@ describe('sandbox SSH host identity', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('sandbox creation time', () => {
|
||||
it('maps created_time from get and list and leaves it absent when omitted', async () => {
|
||||
let createdTime: { seconds: bigint; nanos: number } | undefined = { seconds: 1_700_000_000n, nanos: 123_000_000 };
|
||||
const sandbox = client({
|
||||
getSandbox: () => ({ sandbox: { metadata: { id: 'id', name: 'work', createdTime } } }),
|
||||
listSandboxes: () => ({ sandboxes: [{ metadata: { id: 'id', name: 'work', createdTime } }] }),
|
||||
});
|
||||
expect((await sandbox.get('work')).createdAtMs).toBe(1_700_000_000_123);
|
||||
expect((await sandbox.list().all())[0]?.createdAtMs).toBe(1_700_000_000_123);
|
||||
createdTime = undefined;
|
||||
expect((await sandbox.get('work')).createdAtMs).toBeUndefined();
|
||||
createdTime = { seconds: 0n, nanos: 0 };
|
||||
expect((await sandbox.list().all())[0]?.createdAtMs).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('deletion outcomes', () => {
|
||||
it('defaults to strict deletion and preserves accepted identity and unknown values', async () => {
|
||||
const flags: boolean[] = [];
|
||||
|
||||
@@ -49,6 +49,11 @@ function timestampMillis(timestamp: { seconds: bigint; nanos: number } | undefin
|
||||
return millis === 0n ? undefined : millis.toString();
|
||||
}
|
||||
|
||||
function timestampEpochMs(timestamp: { seconds: bigint; nanos: number } | undefined): number | undefined {
|
||||
const millis = timestampMillis(timestamp);
|
||||
return millis ? Number(millis) : undefined;
|
||||
}
|
||||
|
||||
// Generated protobuf message shapes that callers need to populate or round-trip
|
||||
// directly. Re-export these rather than re-curating parallel surfaces.
|
||||
export type {
|
||||
@@ -225,6 +230,8 @@ export interface SandboxRef {
|
||||
/** Service URLs returned by creation, keyed by service name. */
|
||||
serviceUrls: Record<string, string>;
|
||||
restartCount: number;
|
||||
/** Creation time in epoch milliseconds; absent when the gateway omits it. */
|
||||
createdAtMs?: number;
|
||||
nextRestartAtMs?: number;
|
||||
mainProcessStartedAtMs?: number;
|
||||
}
|
||||
@@ -529,8 +536,6 @@ function sandboxRef(sandbox: Sandbox | undefined, serviceUrls: Record<string, st
|
||||
if (!meta?.id || !meta.name) {
|
||||
throw new SdkError('invalid_config', 'sandbox metadata.id and metadata.name are required in gateway responses');
|
||||
}
|
||||
const nextRestartAtMs = timestampMillis(sandbox.status?.nextRestartTime);
|
||||
const mainProcessStartedAtMs = timestampMillis(sandbox.status?.mainProcessStartedTime);
|
||||
return {
|
||||
id: meta.id,
|
||||
name: meta.name,
|
||||
@@ -549,8 +554,9 @@ function sandboxRef(sandbox: Sandbox | undefined, serviceUrls: Record<string, st
|
||||
: undefined,
|
||||
serviceUrls,
|
||||
restartCount: sandbox.status?.restartCount ?? 0,
|
||||
nextRestartAtMs: nextRestartAtMs ? Number(nextRestartAtMs) : undefined,
|
||||
mainProcessStartedAtMs: mainProcessStartedAtMs ? Number(mainProcessStartedAtMs) : undefined,
|
||||
createdAtMs: timestampEpochMs(meta.createdTime),
|
||||
nextRestartAtMs: timestampEpochMs(sandbox.status?.nextRestartTime),
|
||||
mainProcessStartedAtMs: timestampEpochMs(sandbox.status?.mainProcessStartedTime),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user