@the-open-engine/zeroshot 6.29.0 → 6.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/cli/index.js +2 -4
- package/lib/agent-cli-provider/adapters/codex.d.ts.map +1 -1
- package/lib/agent-cli-provider/adapters/codex.js +0 -1
- package/lib/agent-cli-provider/adapters/codex.js.map +1 -1
- package/lib/agent-cli-provider/contract-actions.d.ts +1 -1
- package/lib/agent-cli-provider/contract-actions.d.ts.map +1 -1
- package/lib/agent-cli-provider/contract-actions.js +5 -5
- package/lib/agent-cli-provider/contract-actions.js.map +1 -1
- package/lib/agent-cli-provider/contract-invoke.d.ts +1 -1
- package/lib/agent-cli-provider/contract-invoke.d.ts.map +1 -1
- package/lib/agent-cli-provider/contract-invoke.js +2 -2
- package/lib/agent-cli-provider/contract-invoke.js.map +1 -1
- package/lib/agent-cli-provider/contract-support.d.ts +1 -1
- package/lib/agent-cli-provider/contract-support.d.ts.map +1 -1
- package/lib/agent-cli-provider/contract-support.js +2 -2
- package/lib/agent-cli-provider/contract-support.js.map +1 -1
- package/lib/agent-cli-provider/contract.d.ts +1 -0
- package/lib/agent-cli-provider/contract.d.ts.map +1 -1
- package/lib/agent-cli-provider/contract.js +1 -1
- package/lib/agent-cli-provider/contract.js.map +1 -1
- package/lib/agent-cli-provider/index.d.ts +1 -1
- package/lib/agent-cli-provider/index.d.ts.map +1 -1
- package/lib/agent-cli-provider/index.js +2 -1
- package/lib/agent-cli-provider/index.js.map +1 -1
- package/lib/agent-cli-provider/provider-registry.d.ts +1 -0
- package/lib/agent-cli-provider/provider-registry.d.ts.map +1 -1
- package/lib/agent-cli-provider/provider-registry.js +4 -0
- package/lib/agent-cli-provider/provider-registry.js.map +1 -1
- package/lib/agent-cli-provider/single-agent-runtime.d.ts +3 -3
- package/lib/agent-cli-provider/single-agent-runtime.d.ts.map +1 -1
- package/lib/agent-cli-provider/single-agent-runtime.js +22 -48
- package/lib/agent-cli-provider/single-agent-runtime.js.map +1 -1
- package/lib/cluster/client.cjs +30 -7
- package/lib/cluster/client.d.cts +52 -0
- package/lib/cluster/client.d.mts +52 -0
- package/lib/cluster/client.d.ts +4 -6
- package/lib/cluster/client.mjs +32 -9
- package/lib/cluster/connection-state.cjs +25 -0
- package/lib/cluster/connection-state.d.cts +13 -0
- package/lib/cluster/connection-state.d.mts +13 -0
- package/lib/cluster/connection-state.d.ts +13 -0
- package/lib/cluster/connection-state.mjs +21 -0
- package/lib/{target/hosted-run/contracts.js → cluster/connection-types.cjs} +0 -1
- package/lib/cluster/connection-types.d.cts +33 -0
- package/lib/cluster/connection-types.d.mts +33 -0
- package/lib/cluster/connection-types.d.ts +33 -0
- package/lib/cluster/connection-types.mjs +1 -0
- package/lib/cluster/connection.cjs +18 -46
- package/lib/cluster/connection.d.cts +26 -0
- package/lib/cluster/connection.d.mts +26 -0
- package/lib/cluster/connection.d.ts +7 -25
- package/lib/cluster/connection.mjs +12 -42
- package/lib/cluster/errors.cjs +9 -1
- package/lib/cluster/errors.d.cts +29 -0
- package/lib/cluster/errors.d.mts +29 -0
- package/lib/cluster/errors.d.ts +4 -0
- package/lib/cluster/errors.mjs +7 -0
- package/lib/cluster/frames.d.cts +12 -0
- package/lib/cluster/frames.d.mts +12 -0
- package/lib/cluster/generated/protocol-schema.d.cts +1 -0
- package/lib/cluster/generated/protocol-schema.d.mts +1 -0
- package/lib/cluster/generated/protocol.d.cts +781 -0
- package/lib/cluster/generated/protocol.d.mts +781 -0
- package/lib/cluster/index.cjs +2 -2
- package/lib/cluster/index.d.cts +13 -0
- package/lib/cluster/index.d.mts +13 -0
- package/lib/cluster/index.d.ts +3 -3
- package/lib/cluster/index.mjs +2 -2
- package/lib/cluster/json-source.cjs +1 -0
- package/lib/cluster/json-source.d.cts +5 -0
- package/lib/cluster/json-source.d.mts +5 -0
- package/lib/cluster/json-source.d.ts +1 -0
- package/lib/cluster/json-source.mjs +1 -0
- package/lib/cluster/payload-value.cjs +1 -0
- package/lib/cluster/payload-value.d.cts +8 -0
- package/lib/cluster/payload-value.d.mts +8 -0
- package/lib/cluster/payload-value.d.ts +1 -0
- package/lib/cluster/payload-value.mjs +1 -0
- package/lib/cluster/queue.d.cts +15 -0
- package/lib/cluster/queue.d.mts +15 -0
- package/lib/cluster/socket.cjs +8 -0
- package/lib/cluster/socket.d.cts +13 -0
- package/lib/cluster/socket.d.mts +13 -0
- package/lib/cluster/socket.d.ts +2 -0
- package/lib/cluster/socket.mjs +7 -0
- package/lib/cluster/subscriptions.d.cts +73 -0
- package/lib/cluster/subscriptions.d.mts +73 -0
- package/lib/cluster/subscriptions.d.ts +5 -1
- package/lib/cluster/validators.cjs +1 -0
- package/lib/cluster/validators.d.cts +7 -0
- package/lib/cluster/validators.d.mts +7 -0
- package/lib/cluster/validators.d.ts +1 -0
- package/lib/cluster/validators.mjs +1 -0
- package/lib/cluster-worker/engine-adapter-common.js +37 -0
- package/lib/cluster-worker/engine-adapter.js +24 -30
- package/lib/cluster-worker/engine-start.js +59 -0
- package/lib/cluster-worker/index.js +49 -67
- package/lib/cluster-worker/profiles.js +1 -42
- package/lib/cluster-worker/runtime-dependencies.js +49 -0
- package/lib/cluster-worker/runtime-support.js +2 -34
- package/lib/cluster-worker/terminal-normalizer.js +9 -10
- package/lib/hosted-session/authority.cjs +61 -0
- package/lib/hosted-session/authority.d.cts +3 -0
- package/lib/hosted-session/authority.d.mts +3 -0
- package/lib/hosted-session/authority.d.ts +3 -0
- package/lib/hosted-session/authority.mjs +57 -0
- package/lib/hosted-session/coordinator.cjs +78 -51
- package/lib/hosted-session/coordinator.d.cts +11 -0
- package/lib/hosted-session/coordinator.d.mts +11 -0
- package/lib/hosted-session/coordinator.d.ts +4 -2
- package/lib/hosted-session/coordinator.mjs +75 -51
- package/lib/hosted-session/errors.cjs +25 -0
- package/lib/hosted-session/errors.d.cts +10 -0
- package/lib/hosted-session/errors.d.mts +10 -0
- package/lib/hosted-session/errors.d.ts +10 -0
- package/lib/hosted-session/errors.mjs +19 -0
- package/lib/hosted-session/index.cjs +4 -1
- package/lib/hosted-session/index.d.cts +2 -0
- package/lib/hosted-session/index.d.mts +2 -0
- package/lib/hosted-session/index.d.ts +2 -2
- package/lib/hosted-session/index.mjs +1 -1
- package/lib/hosted-session/reconnecting-watch.cjs +131 -0
- package/lib/hosted-session/reconnecting-watch.d.cts +13 -0
- package/lib/hosted-session/reconnecting-watch.d.mts +13 -0
- package/lib/hosted-session/reconnecting-watch.d.ts +13 -0
- package/lib/hosted-session/reconnecting-watch.mjs +127 -0
- package/lib/hosted-session/types.d.cts +32 -0
- package/lib/hosted-session/types.d.mts +32 -0
- package/lib/hosted-session/types.d.ts +19 -7
- package/lib/hosted-target/access-url.cjs +44 -0
- package/lib/hosted-target/access-url.d.cts +2 -0
- package/lib/hosted-target/access-url.d.mts +2 -0
- package/lib/hosted-target/access-url.d.ts +2 -0
- package/lib/hosted-target/access-url.mjs +41 -0
- package/lib/hosted-target/adapter-request.cjs +12 -0
- package/lib/hosted-target/adapter-request.d.cts +17 -0
- package/lib/hosted-target/adapter-request.d.mts +17 -0
- package/lib/hosted-target/adapter-request.d.ts +17 -0
- package/lib/hosted-target/adapter-request.mjs +9 -0
- package/lib/hosted-target/adapter-types.cjs +2 -0
- package/lib/hosted-target/adapter-types.d.cts +27 -0
- package/lib/hosted-target/adapter-types.d.mts +27 -0
- package/lib/hosted-target/adapter-types.d.ts +27 -0
- package/lib/hosted-target/adapter-types.mjs +1 -0
- package/lib/hosted-target/bounds.cjs +10 -0
- package/lib/hosted-target/bounds.d.cts +7 -0
- package/lib/hosted-target/bounds.d.mts +7 -0
- package/lib/hosted-target/bounds.d.ts +7 -0
- package/lib/hosted-target/bounds.mjs +7 -0
- package/lib/hosted-target/capsule-error-response.cjs +76 -0
- package/lib/hosted-target/capsule-error-response.d.cts +2 -0
- package/lib/hosted-target/capsule-error-response.d.mts +2 -0
- package/lib/hosted-target/capsule-error-response.d.ts +2 -0
- package/lib/hosted-target/capsule-error-response.mjs +73 -0
- package/lib/hosted-target/errors.cjs +88 -0
- package/lib/hosted-target/errors.d.cts +36 -0
- package/lib/hosted-target/errors.d.mts +36 -0
- package/lib/hosted-target/errors.d.ts +36 -0
- package/lib/hosted-target/errors.mjs +75 -0
- package/lib/hosted-target/index.cjs +16 -0
- package/lib/hosted-target/index.d.cts +3 -0
- package/lib/hosted-target/index.d.mts +3 -0
- package/lib/hosted-target/index.d.ts +3 -0
- package/lib/hosted-target/index.mjs +2 -0
- package/lib/hosted-target/response-validation.cjs +169 -0
- package/lib/hosted-target/response-validation.d.cts +5 -0
- package/lib/hosted-target/response-validation.d.mts +5 -0
- package/lib/hosted-target/response-validation.d.ts +5 -0
- package/lib/hosted-target/response-validation.mjs +163 -0
- package/lib/hosted-target/retry-executor.cjs +51 -0
- package/lib/hosted-target/retry-executor.d.cts +8 -0
- package/lib/hosted-target/retry-executor.d.mts +8 -0
- package/lib/hosted-target/retry-executor.d.ts +8 -0
- package/lib/hosted-target/retry-executor.mjs +48 -0
- package/lib/hosted-target/retry.cjs +78 -0
- package/lib/hosted-target/retry.d.cts +9 -0
- package/lib/hosted-target/retry.d.mts +9 -0
- package/lib/hosted-target/retry.d.ts +9 -0
- package/lib/hosted-target/retry.mjs +73 -0
- package/lib/hosted-target/target-adapter.cjs +10 -0
- package/lib/hosted-target/target-adapter.d.cts +3 -0
- package/lib/hosted-target/target-adapter.d.mts +3 -0
- package/lib/hosted-target/target-adapter.d.ts +3 -0
- package/lib/hosted-target/target-adapter.mjs +7 -0
- package/lib/hosted-target/types.cjs +4 -0
- package/lib/hosted-target/types.d.cts +50 -0
- package/lib/hosted-target/types.d.mts +50 -0
- package/lib/hosted-target/types.d.ts +50 -0
- package/lib/hosted-target/types.mjs +1 -0
- package/lib/hosted-target/zero-cloud-v1-adapter.cjs +185 -0
- package/lib/hosted-target/zero-cloud-v1-adapter.d.cts +13 -0
- package/lib/hosted-target/zero-cloud-v1-adapter.d.mts +13 -0
- package/lib/hosted-target/zero-cloud-v1-adapter.d.ts +13 -0
- package/lib/hosted-target/zero-cloud-v1-adapter.mjs +181 -0
- package/lib/start-cluster.js +3 -3
- package/lib/target/bounded-response.cjs +51 -0
- package/lib/target/bounded-response.d.cts +1 -0
- package/lib/target/bounded-response.d.mts +1 -0
- package/lib/target/bounded-response.d.ts +1 -0
- package/lib/target/bounded-response.js +51 -0
- package/lib/target/bounded-response.mjs +48 -0
- package/lib/target/credential-lock.js +1 -3
- package/lib/target/credential-store.js +9 -4
- package/lib/target/device-flow.cjs +213 -0
- package/lib/target/device-flow.d.cts +54 -0
- package/lib/target/device-flow.d.mts +54 -0
- package/lib/target/device-flow.d.ts +26 -14
- package/lib/target/device-flow.js +162 -58
- package/lib/target/device-flow.mjs +203 -0
- package/lib/target/discovery-errors.cjs +10 -0
- package/lib/target/discovery-errors.d.cts +3 -0
- package/lib/target/discovery-errors.d.mts +3 -0
- package/lib/target/discovery-errors.d.ts +3 -0
- package/lib/target/discovery-errors.js +10 -0
- package/lib/target/discovery-errors.mjs +6 -0
- package/lib/target/discovery-sections.cjs +191 -0
- package/lib/target/discovery-sections.d.cts +52 -0
- package/lib/target/discovery-sections.d.mts +52 -0
- package/lib/target/discovery-sections.d.ts +52 -0
- package/lib/target/discovery-sections.js +191 -0
- package/lib/target/discovery-sections.mjs +179 -0
- package/lib/target/discovery-validation.cjs +109 -0
- package/lib/target/discovery-validation.d.cts +28 -0
- package/lib/target/discovery-validation.d.mts +28 -0
- package/lib/target/discovery-validation.d.ts +28 -0
- package/lib/target/discovery-validation.js +109 -0
- package/lib/target/discovery-validation.mjs +99 -0
- package/lib/target/discovery.cjs +112 -0
- package/lib/target/discovery.d.cts +74 -0
- package/lib/target/discovery.d.mts +74 -0
- package/lib/target/discovery.d.ts +67 -5
- package/lib/target/discovery.js +94 -79
- package/lib/target/discovery.mjs +105 -0
- package/lib/target/index.d.ts +6 -6
- package/lib/target/index.js +36 -36
- package/lib/target/oauth-http.d.ts +2 -0
- package/lib/target/oauth-http.js +25 -0
- package/lib/target/refresh-exchange.d.ts +11 -0
- package/lib/target/refresh-exchange.js +24 -0
- package/lib/target/refresh-revocation.d.ts +8 -0
- package/lib/target/refresh-revocation.js +19 -0
- package/lib/target/route-template.cjs +85 -0
- package/lib/target/route-template.d.cts +7 -0
- package/lib/target/route-template.d.mts +7 -0
- package/lib/target/route-template.d.ts +7 -0
- package/lib/target/route-template.js +85 -0
- package/lib/target/route-template.mjs +81 -0
- package/lib/target/session-errors.d.ts +4 -0
- package/lib/target/session-errors.js +12 -0
- package/lib/target/session-verification.d.ts +10 -0
- package/lib/target/session-verification.js +42 -0
- package/lib/target/target-registry.d.ts +7 -3
- package/lib/target/target-registry.js +41 -10
- package/lib/target/target-session-manager.d.ts +48 -0
- package/lib/target/target-session-manager.js +226 -0
- package/lib/target/target-session.d.ts +39 -32
- package/lib/target/target-session.js +63 -151
- package/lib/target/token-response.cjs +51 -0
- package/lib/target/token-response.d.cts +7 -0
- package/lib/target/token-response.d.mts +7 -0
- package/lib/target/token-response.d.ts +7 -0
- package/lib/target/token-response.js +51 -0
- package/lib/target/token-response.mjs +48 -0
- package/package.json +14 -7
- package/protocol/openengine-cluster/v1/worker.schema.json +171 -9
- package/scripts/build-cluster.js +23 -3
- package/scripts/opcore-introduced-check.js +0 -2
- package/src/agent-cli-provider/adapters/codex.ts +0 -1
- package/src/agent-cli-provider/contract-actions.ts +9 -5
- package/src/agent-cli-provider/contract-invoke.ts +3 -2
- package/src/agent-cli-provider/contract-support.ts +12 -6
- package/src/agent-cli-provider/contract.ts +6 -1
- package/src/agent-cli-provider/index.ts +1 -0
- package/src/agent-cli-provider/provider-registry.ts +4 -0
- package/src/agent-cli-provider/single-agent-runtime.ts +32 -45
- package/src/cluster/client.ts +42 -15
- package/src/cluster/connection-state.ts +33 -0
- package/src/cluster/connection-types.ts +28 -0
- package/src/cluster/connection.ts +37 -68
- package/src/cluster/errors.ts +5 -0
- package/src/cluster/index.ts +3 -1
- package/src/cluster/json-source.ts +1 -0
- package/src/cluster/payload-value.ts +1 -0
- package/src/cluster/socket.ts +13 -0
- package/src/cluster/subscriptions.ts +7 -2
- package/src/cluster/validators.ts +1 -0
- package/src/cluster/ws.d.ts +1 -1
- package/src/hosted-session/authority.ts +77 -0
- package/src/hosted-session/coordinator.ts +113 -56
- package/src/hosted-session/errors.ts +21 -0
- package/src/hosted-session/index.ts +14 -2
- package/src/hosted-session/reconnecting-watch.ts +148 -0
- package/src/hosted-session/types.ts +22 -8
- package/src/hosted-target/access-url.ts +46 -0
- package/src/hosted-target/adapter-request.ts +28 -0
- package/src/hosted-target/adapter-types.ts +39 -0
- package/src/hosted-target/bounds.ts +1 -0
- package/src/hosted-target/capsule-error-response.ts +107 -0
- package/src/hosted-target/errors.ts +36 -35
- package/src/hosted-target/index.ts +10 -23
- package/src/hosted-target/response-validation.ts +170 -62
- package/src/hosted-target/retry-executor.ts +62 -0
- package/src/hosted-target/retry.ts +47 -11
- package/src/hosted-target/target-adapter.ts +12 -8
- package/src/hosted-target/types.ts +19 -18
- package/src/hosted-target/zero-cloud-v1-adapter.ts +229 -316
- package/src/isolation-manager.js +1 -16
- package/src/target/bounded-response.ts +68 -0
- package/src/target/credential-lock.ts +1 -3
- package/src/target/credential-store.ts +14 -10
- package/src/target/device-flow.ts +209 -85
- package/src/target/discovery-errors.ts +6 -0
- package/src/target/discovery-sections.ts +251 -0
- package/src/target/discovery-validation.ts +144 -0
- package/src/target/discovery.ts +163 -97
- package/src/target/index.ts +15 -11
- package/src/target/oauth-http.ts +27 -0
- package/src/target/refresh-exchange.ts +36 -0
- package/src/target/refresh-revocation.ts +29 -0
- package/src/target/route-template.ts +105 -0
- package/src/target/session-errors.ts +9 -0
- package/src/target/session-verification.ts +51 -0
- package/src/target/target-registry.ts +60 -27
- package/src/target/target-session-manager.ts +285 -0
- package/src/target/target-session.ts +105 -226
- package/src/target/token-response.ts +62 -0
- package/docker/zeroshot-oecp/Cargo.toml +0 -12
- package/docker/zeroshot-oecp/Dockerfile +0 -65
- package/docker/zeroshot-oecp/src/main.rs +0 -32
- package/lib/target/bounded-json.d.ts +0 -6
- package/lib/target/bounded-json.js +0 -43
- package/lib/target/hosted-run/client.d.ts +0 -26
- package/lib/target/hosted-run/client.js +0 -158
- package/lib/target/hosted-run/commands.d.ts +0 -4
- package/lib/target/hosted-run/commands.js +0 -113
- package/lib/target/hosted-run/contracts.d.ts +0 -49
- package/lib/target/hosted-run/input.d.ts +0 -5
- package/lib/target/hosted-run/input.js +0 -200
- package/lib/target/hosted-run.d.ts +0 -4
- package/lib/target/hosted-run.js +0 -12
- package/src/target/bounded-json.ts +0 -48
- package/src/target/hosted-run/client.ts +0 -198
- package/src/target/hosted-run/commands.ts +0 -140
- package/src/target/hosted-run/contracts.ts +0 -53
- package/src/target/hosted-run/input.ts +0 -199
- package/src/target/hosted-run.ts +0 -8
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createTargetAdapter = createTargetAdapter;
|
|
4
|
+
const zero_cloud_v1_adapter_js_1 = require("./zero-cloud-v1-adapter.cjs");
|
|
5
|
+
function createTargetAdapter(options) {
|
|
6
|
+
if (options.descriptor.adapter.majorVersion !== 1) {
|
|
7
|
+
throw new Error('Unsupported hosted target adapter version');
|
|
8
|
+
}
|
|
9
|
+
return new zero_cloud_v1_adapter_js_1.ZeroCloudV1TargetAdapter(options);
|
|
10
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { CreateTargetAdapterOptions, TargetAdapter } from './adapter-types.js';
|
|
2
|
+
export type { CreateTargetAdapterOptions, CredentialInstallCapability, TargetAdapter, } from './adapter-types.js';
|
|
3
|
+
export declare function createTargetAdapter(options: CreateTargetAdapterOptions): TargetAdapter;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { CreateTargetAdapterOptions, TargetAdapter } from './adapter-types.js';
|
|
2
|
+
export type { CreateTargetAdapterOptions, CredentialInstallCapability, TargetAdapter, } from './adapter-types.js';
|
|
3
|
+
export declare function createTargetAdapter(options: CreateTargetAdapterOptions): TargetAdapter;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { CreateTargetAdapterOptions, TargetAdapter } from './adapter-types.js';
|
|
2
|
+
export type { CreateTargetAdapterOptions, CredentialInstallCapability, TargetAdapter, } from './adapter-types.js';
|
|
3
|
+
export declare function createTargetAdapter(options: CreateTargetAdapterOptions): TargetAdapter;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ZeroCloudV1TargetAdapter } from './zero-cloud-v1-adapter.mjs';
|
|
2
|
+
export function createTargetAdapter(options) {
|
|
3
|
+
if (options.descriptor.adapter.majorVersion !== 1) {
|
|
4
|
+
throw new Error('Unsupported hosted target adapter version');
|
|
5
|
+
}
|
|
6
|
+
return new ZeroCloudV1TargetAdapter(options);
|
|
7
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { TargetAdapterError } from './errors.js';
|
|
2
|
+
export interface TargetAccessTokenProvider {
|
|
3
|
+
getAccessToken(signal?: AbortSignal): Promise<string>;
|
|
4
|
+
}
|
|
5
|
+
export type CapsuleState = 'provisioning' | 'ready' | 'terminating' | 'terminated' | 'failed';
|
|
6
|
+
export declare const KNOWN_CAPSULE_STATES: readonly ["provisioning", "ready", "terminating", "terminated", "failed"];
|
|
7
|
+
export interface Capsule {
|
|
8
|
+
readonly id: string;
|
|
9
|
+
readonly state: CapsuleState;
|
|
10
|
+
readonly label: string | null;
|
|
11
|
+
readonly createdAt: string;
|
|
12
|
+
}
|
|
13
|
+
export interface CapsuleAccess {
|
|
14
|
+
readonly protocol: 'openengine.cluster/v1';
|
|
15
|
+
readonly websocketUrl: string;
|
|
16
|
+
readonly accessToken: string;
|
|
17
|
+
readonly tokenType: 'Bearer';
|
|
18
|
+
readonly expiresAt: string;
|
|
19
|
+
}
|
|
20
|
+
export interface CapsuleListPage {
|
|
21
|
+
readonly capsules: readonly Capsule[];
|
|
22
|
+
readonly nextCursor: string | null;
|
|
23
|
+
}
|
|
24
|
+
export interface CapsuleLimits {
|
|
25
|
+
readonly activeCapsules: number;
|
|
26
|
+
readonly maxActiveCapsules: number | null;
|
|
27
|
+
}
|
|
28
|
+
export interface AllocateRequest {
|
|
29
|
+
readonly idempotencyKey: string;
|
|
30
|
+
readonly label?: string;
|
|
31
|
+
readonly size?: 'tiny' | 'small' | 'standard' | 'large';
|
|
32
|
+
}
|
|
33
|
+
export interface ListRequest {
|
|
34
|
+
readonly cursor?: string;
|
|
35
|
+
readonly limit?: number;
|
|
36
|
+
}
|
|
37
|
+
export interface HttpTransport {
|
|
38
|
+
fetch(url: string, init: RequestInit & {
|
|
39
|
+
redirect: 'manual';
|
|
40
|
+
}): Promise<Response>;
|
|
41
|
+
}
|
|
42
|
+
export interface Clock {
|
|
43
|
+
now(): number;
|
|
44
|
+
}
|
|
45
|
+
export interface RetryPolicy {
|
|
46
|
+
shouldRetry(attempt: number, elapsed: number, error: TargetAdapterError): {
|
|
47
|
+
retry: boolean;
|
|
48
|
+
delayMs: number;
|
|
49
|
+
};
|
|
50
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { TargetAdapterError } from './errors.js';
|
|
2
|
+
export interface TargetAccessTokenProvider {
|
|
3
|
+
getAccessToken(signal?: AbortSignal): Promise<string>;
|
|
4
|
+
}
|
|
5
|
+
export type CapsuleState = 'provisioning' | 'ready' | 'terminating' | 'terminated' | 'failed';
|
|
6
|
+
export declare const KNOWN_CAPSULE_STATES: readonly ["provisioning", "ready", "terminating", "terminated", "failed"];
|
|
7
|
+
export interface Capsule {
|
|
8
|
+
readonly id: string;
|
|
9
|
+
readonly state: CapsuleState;
|
|
10
|
+
readonly label: string | null;
|
|
11
|
+
readonly createdAt: string;
|
|
12
|
+
}
|
|
13
|
+
export interface CapsuleAccess {
|
|
14
|
+
readonly protocol: 'openengine.cluster/v1';
|
|
15
|
+
readonly websocketUrl: string;
|
|
16
|
+
readonly accessToken: string;
|
|
17
|
+
readonly tokenType: 'Bearer';
|
|
18
|
+
readonly expiresAt: string;
|
|
19
|
+
}
|
|
20
|
+
export interface CapsuleListPage {
|
|
21
|
+
readonly capsules: readonly Capsule[];
|
|
22
|
+
readonly nextCursor: string | null;
|
|
23
|
+
}
|
|
24
|
+
export interface CapsuleLimits {
|
|
25
|
+
readonly activeCapsules: number;
|
|
26
|
+
readonly maxActiveCapsules: number | null;
|
|
27
|
+
}
|
|
28
|
+
export interface AllocateRequest {
|
|
29
|
+
readonly idempotencyKey: string;
|
|
30
|
+
readonly label?: string;
|
|
31
|
+
readonly size?: 'tiny' | 'small' | 'standard' | 'large';
|
|
32
|
+
}
|
|
33
|
+
export interface ListRequest {
|
|
34
|
+
readonly cursor?: string;
|
|
35
|
+
readonly limit?: number;
|
|
36
|
+
}
|
|
37
|
+
export interface HttpTransport {
|
|
38
|
+
fetch(url: string, init: RequestInit & {
|
|
39
|
+
redirect: 'manual';
|
|
40
|
+
}): Promise<Response>;
|
|
41
|
+
}
|
|
42
|
+
export interface Clock {
|
|
43
|
+
now(): number;
|
|
44
|
+
}
|
|
45
|
+
export interface RetryPolicy {
|
|
46
|
+
shouldRetry(attempt: number, elapsed: number, error: TargetAdapterError): {
|
|
47
|
+
retry: boolean;
|
|
48
|
+
delayMs: number;
|
|
49
|
+
};
|
|
50
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { TargetAdapterError } from './errors.js';
|
|
2
|
+
export interface TargetAccessTokenProvider {
|
|
3
|
+
getAccessToken(signal?: AbortSignal): Promise<string>;
|
|
4
|
+
}
|
|
5
|
+
export type CapsuleState = 'provisioning' | 'ready' | 'terminating' | 'terminated' | 'failed';
|
|
6
|
+
export declare const KNOWN_CAPSULE_STATES: readonly ["provisioning", "ready", "terminating", "terminated", "failed"];
|
|
7
|
+
export interface Capsule {
|
|
8
|
+
readonly id: string;
|
|
9
|
+
readonly state: CapsuleState;
|
|
10
|
+
readonly label: string | null;
|
|
11
|
+
readonly createdAt: string;
|
|
12
|
+
}
|
|
13
|
+
export interface CapsuleAccess {
|
|
14
|
+
readonly protocol: 'openengine.cluster/v1';
|
|
15
|
+
readonly websocketUrl: string;
|
|
16
|
+
readonly accessToken: string;
|
|
17
|
+
readonly tokenType: 'Bearer';
|
|
18
|
+
readonly expiresAt: string;
|
|
19
|
+
}
|
|
20
|
+
export interface CapsuleListPage {
|
|
21
|
+
readonly capsules: readonly Capsule[];
|
|
22
|
+
readonly nextCursor: string | null;
|
|
23
|
+
}
|
|
24
|
+
export interface CapsuleLimits {
|
|
25
|
+
readonly activeCapsules: number;
|
|
26
|
+
readonly maxActiveCapsules: number | null;
|
|
27
|
+
}
|
|
28
|
+
export interface AllocateRequest {
|
|
29
|
+
readonly idempotencyKey: string;
|
|
30
|
+
readonly label?: string;
|
|
31
|
+
readonly size?: 'tiny' | 'small' | 'standard' | 'large';
|
|
32
|
+
}
|
|
33
|
+
export interface ListRequest {
|
|
34
|
+
readonly cursor?: string;
|
|
35
|
+
readonly limit?: number;
|
|
36
|
+
}
|
|
37
|
+
export interface HttpTransport {
|
|
38
|
+
fetch(url: string, init: RequestInit & {
|
|
39
|
+
redirect: 'manual';
|
|
40
|
+
}): Promise<Response>;
|
|
41
|
+
}
|
|
42
|
+
export interface Clock {
|
|
43
|
+
now(): number;
|
|
44
|
+
}
|
|
45
|
+
export interface RetryPolicy {
|
|
46
|
+
shouldRetry(attempt: number, elapsed: number, error: TargetAdapterError): {
|
|
47
|
+
retry: boolean;
|
|
48
|
+
delayMs: number;
|
|
49
|
+
};
|
|
50
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const KNOWN_CAPSULE_STATES = ['provisioning', 'ready', 'terminating', 'terminated', 'failed'];
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ZeroCloudV1TargetAdapter = void 0;
|
|
4
|
+
const bounds_js_1 = require("./bounds.cjs");
|
|
5
|
+
const errors_js_1 = require("./errors.cjs");
|
|
6
|
+
const retry_js_1 = require("./retry.cjs");
|
|
7
|
+
const response_validation_js_1 = require("./response-validation.cjs");
|
|
8
|
+
const bounded_response_js_1 = require("../target/bounded-response.cjs");
|
|
9
|
+
const capsule_error_response_js_1 = require("./capsule-error-response.cjs");
|
|
10
|
+
const access_url_js_1 = require("./access-url.cjs");
|
|
11
|
+
const retry_executor_js_1 = require("./retry-executor.cjs");
|
|
12
|
+
const adapter_request_js_1 = require("./adapter-request.cjs");
|
|
13
|
+
const DEFAULT_TRANSPORT = {
|
|
14
|
+
fetch(url, init) {
|
|
15
|
+
return globalThis.fetch(url, init);
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
const DEFAULT_CLOCK = { now: () => Date.now() };
|
|
19
|
+
function throwIfAborted(signal) {
|
|
20
|
+
if (signal?.aborted)
|
|
21
|
+
throw signal.reason ?? new globalThis.DOMException('The operation was aborted', 'AbortError');
|
|
22
|
+
}
|
|
23
|
+
function validOpaque(value, field) {
|
|
24
|
+
if (value.length === 0 || value.length > 1024)
|
|
25
|
+
throw new errors_js_1.TargetProtocolError(`${field} is invalid`);
|
|
26
|
+
}
|
|
27
|
+
function jsonRequest(body) {
|
|
28
|
+
return JSON.stringify(body);
|
|
29
|
+
}
|
|
30
|
+
class ZeroCloudV1TargetAdapter {
|
|
31
|
+
#descriptor;
|
|
32
|
+
#organizationId;
|
|
33
|
+
#tokenProvider;
|
|
34
|
+
#transport;
|
|
35
|
+
#clock;
|
|
36
|
+
#retryPolicy;
|
|
37
|
+
constructor(options) {
|
|
38
|
+
this.#descriptor = options.descriptor;
|
|
39
|
+
this.#organizationId = options.organization.id;
|
|
40
|
+
validOpaque(this.#organizationId, 'organization id');
|
|
41
|
+
this.#tokenProvider = options.tokenProvider;
|
|
42
|
+
this.#transport = options.transport ?? DEFAULT_TRANSPORT;
|
|
43
|
+
this.#clock = options.clock ?? DEFAULT_CLOCK;
|
|
44
|
+
this.#retryPolicy = options.retryPolicy ?? new retry_js_1.DefaultRetryPolicy();
|
|
45
|
+
}
|
|
46
|
+
get credentialInstall() {
|
|
47
|
+
const descriptor = this.#descriptor.credentialInstall;
|
|
48
|
+
return descriptor === null
|
|
49
|
+
? Object.freeze({ supported: false })
|
|
50
|
+
: Object.freeze({ supported: true, descriptor });
|
|
51
|
+
}
|
|
52
|
+
allocate(request, signal) {
|
|
53
|
+
try {
|
|
54
|
+
if (!bounds_js_1.IDEMPOTENCY_KEY_PATTERN.test(request.idempotencyKey))
|
|
55
|
+
throw new errors_js_1.TargetProtocolError('Idempotency key is invalid');
|
|
56
|
+
if (request.label !== undefined && (request.label.length < 1 || request.label.length > 100)) {
|
|
57
|
+
throw new errors_js_1.TargetProtocolError('Capsule label is outside the supported bounds');
|
|
58
|
+
}
|
|
59
|
+
if (request.size !== undefined && !this.#descriptor.sizes.catalog.includes(request.size)) {
|
|
60
|
+
throw new errors_js_1.TargetProtocolError('Capsule size is not advertised by the target');
|
|
61
|
+
}
|
|
62
|
+
const body = {
|
|
63
|
+
...(request.label === undefined ? {} : { label: request.label }),
|
|
64
|
+
...(request.size === undefined ? {} : { size: request.size }),
|
|
65
|
+
};
|
|
66
|
+
return this.#execute('allocate', 'POST', this.#descriptor.capsule.routes.allocate, { org_id: this.#organizationId }, 201, response_validation_js_1.assertCapsule, signal, {
|
|
67
|
+
body: jsonRequest(body),
|
|
68
|
+
headers: { 'Idempotency-Key': request.idempotencyKey },
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
return Promise.reject(error);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
async list(request = {}, signal) {
|
|
76
|
+
if (request.cursor !== undefined)
|
|
77
|
+
validOpaque(request.cursor, 'cursor');
|
|
78
|
+
if (request.limit !== undefined &&
|
|
79
|
+
(!Number.isSafeInteger(request.limit) ||
|
|
80
|
+
request.limit < 1 ||
|
|
81
|
+
request.limit > this.#descriptor.pagination.maxPageSize)) {
|
|
82
|
+
throw new errors_js_1.TargetProtocolError('Pagination limit is outside the advertised bounds');
|
|
83
|
+
}
|
|
84
|
+
const page = await this.#execute('list', 'GET', this.#descriptor.capsule.routes.list, {
|
|
85
|
+
org_id: this.#organizationId,
|
|
86
|
+
cursor: request.cursor,
|
|
87
|
+
limit: request.limit,
|
|
88
|
+
}, 200, response_validation_js_1.assertCapsuleListPage, signal);
|
|
89
|
+
if (request.cursor !== undefined && page.nextCursor === request.cursor)
|
|
90
|
+
throw new errors_js_1.TargetProtocolError('Target returned a pagination loop');
|
|
91
|
+
return page;
|
|
92
|
+
}
|
|
93
|
+
inspect(capsuleId, signal) {
|
|
94
|
+
validOpaque(capsuleId, 'capsule id');
|
|
95
|
+
return this.#execute('inspect', 'GET', this.#descriptor.capsule.routes.inspect, { org_id: this.#organizationId, capsule_id: capsuleId }, 200, response_validation_js_1.assertCapsule, signal);
|
|
96
|
+
}
|
|
97
|
+
terminate(capsuleId, signal) {
|
|
98
|
+
validOpaque(capsuleId, 'capsule id');
|
|
99
|
+
return this.#execute('terminate', 'DELETE', this.#descriptor.capsule.routes.terminate, { org_id: this.#organizationId, capsule_id: capsuleId }, 202, response_validation_js_1.assertCapsule, signal);
|
|
100
|
+
}
|
|
101
|
+
limits(signal) {
|
|
102
|
+
return this.#execute('limits', 'GET', this.#descriptor.capsule.routes.limits, { org_id: this.#organizationId }, 200, response_validation_js_1.assertCapsuleLimits, signal);
|
|
103
|
+
}
|
|
104
|
+
async access(capsuleId, signal) {
|
|
105
|
+
validOpaque(capsuleId, 'capsule id');
|
|
106
|
+
const result = await this.#execute('access', 'POST', this.#descriptor.capsule.routes.access, { capsule_id: capsuleId }, 200, response_validation_js_1.assertCapsuleAccess, signal, {
|
|
107
|
+
body: jsonRequest({ protocol: 'openengine.cluster/v1' }),
|
|
108
|
+
});
|
|
109
|
+
(0, access_url_js_1.validateAccessUrl)(result.websocketUrl, capsuleId, this.#descriptor);
|
|
110
|
+
return result;
|
|
111
|
+
}
|
|
112
|
+
#execute(...args) {
|
|
113
|
+
return Promise.resolve().then(() => this.#executeExpanded(args));
|
|
114
|
+
}
|
|
115
|
+
#executeExpanded(args) {
|
|
116
|
+
const [operation, method, template, values, expectedStatus, validate, signal, request = {},] = args;
|
|
117
|
+
let path;
|
|
118
|
+
try {
|
|
119
|
+
path = template.expand(values);
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
throw new errors_js_1.TargetProtocolError('Capsule route expansion is unsafe');
|
|
123
|
+
}
|
|
124
|
+
return (0, retry_executor_js_1.withTargetRetry)(operation, async () => {
|
|
125
|
+
const response = await this.#request(method, path, signal, request);
|
|
126
|
+
if (response.status >= 300 && response.status < 400) {
|
|
127
|
+
await response.body?.cancel().catch(() => undefined);
|
|
128
|
+
throw new errors_js_1.TargetProtocolError('Capsule redirects are forbidden');
|
|
129
|
+
}
|
|
130
|
+
if (response.status !== expectedStatus) {
|
|
131
|
+
if (response.status >= 200 && response.status < 300) {
|
|
132
|
+
await response.body?.cancel().catch(() => undefined);
|
|
133
|
+
throw new errors_js_1.TargetProtocolError('Target returned an unexpected success status');
|
|
134
|
+
}
|
|
135
|
+
await (0, capsule_error_response_js_1.throwCapsuleServerError)(response, (errorResponse) => this.#readJson(errorResponse), this.#clock);
|
|
136
|
+
}
|
|
137
|
+
return validate(await this.#readJson(response));
|
|
138
|
+
}, signal, { clock: this.#clock, policy: this.#retryPolicy });
|
|
139
|
+
}
|
|
140
|
+
async #request(method, path, signal, request) {
|
|
141
|
+
throwIfAborted(signal);
|
|
142
|
+
const url = (0, adapter_request_js_1.requestUrl)(path, this.#descriptor);
|
|
143
|
+
let token;
|
|
144
|
+
try {
|
|
145
|
+
token = await this.#tokenProvider.getAccessToken(signal);
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
throw new errors_js_1.TargetAuthError('Target access authorization failed');
|
|
149
|
+
}
|
|
150
|
+
const init = {
|
|
151
|
+
method,
|
|
152
|
+
headers: {
|
|
153
|
+
Accept: 'application/json',
|
|
154
|
+
Authorization: `Bearer ${token}`,
|
|
155
|
+
...(request.body === undefined ? {} : { 'Content-Type': 'application/json' }),
|
|
156
|
+
...request.headers,
|
|
157
|
+
},
|
|
158
|
+
redirect: 'manual',
|
|
159
|
+
};
|
|
160
|
+
if (request.body !== undefined)
|
|
161
|
+
init.body = request.body;
|
|
162
|
+
if (signal !== undefined)
|
|
163
|
+
init.signal = signal;
|
|
164
|
+
try {
|
|
165
|
+
const response = await this.#transport.fetch(url.href, init);
|
|
166
|
+
if (response.url && new globalThis.URL(response.url).href !== url.href) {
|
|
167
|
+
await response.body?.cancel().catch(() => undefined);
|
|
168
|
+
throw new errors_js_1.TargetProtocolError('Capsule response changed target route');
|
|
169
|
+
}
|
|
170
|
+
return response;
|
|
171
|
+
}
|
|
172
|
+
catch (error) {
|
|
173
|
+
if (error instanceof errors_js_1.TargetAdapterError)
|
|
174
|
+
throw error;
|
|
175
|
+
throwIfAborted(signal);
|
|
176
|
+
throw new errors_js_1.TargetTransportError('Capsule transport failed');
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
#readJson(response) {
|
|
180
|
+
return (0, bounded_response_js_1.readBoundedResponseJson)(response, bounds_js_1.MAX_RESPONSE_BYTES, (kind) => new errors_js_1.TargetProtocolError(kind === 'size'
|
|
181
|
+
? 'Capsule response exceeds the size limit'
|
|
182
|
+
: 'Capsule response is not valid UTF-8 JSON'));
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
exports.ZeroCloudV1TargetAdapter = ZeroCloudV1TargetAdapter;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { TargetAdapter, CreateTargetAdapterOptions } from './adapter-types.js';
|
|
2
|
+
import type { AllocateRequest, Capsule, CapsuleAccess, CapsuleLimits, CapsuleListPage, ListRequest } from './types.js';
|
|
3
|
+
export declare class ZeroCloudV1TargetAdapter implements TargetAdapter {
|
|
4
|
+
#private;
|
|
5
|
+
constructor(options: CreateTargetAdapterOptions);
|
|
6
|
+
get credentialInstall(): TargetAdapter['credentialInstall'];
|
|
7
|
+
allocate(request: AllocateRequest, signal?: AbortSignal): Promise<Capsule>;
|
|
8
|
+
list(request?: ListRequest, signal?: AbortSignal): Promise<CapsuleListPage>;
|
|
9
|
+
inspect(capsuleId: string, signal?: AbortSignal): Promise<Capsule>;
|
|
10
|
+
terminate(capsuleId: string, signal?: AbortSignal): Promise<Capsule>;
|
|
11
|
+
limits(signal?: AbortSignal): Promise<CapsuleLimits>;
|
|
12
|
+
access(capsuleId: string, signal?: AbortSignal): Promise<CapsuleAccess>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { TargetAdapter, CreateTargetAdapterOptions } from './adapter-types.js';
|
|
2
|
+
import type { AllocateRequest, Capsule, CapsuleAccess, CapsuleLimits, CapsuleListPage, ListRequest } from './types.js';
|
|
3
|
+
export declare class ZeroCloudV1TargetAdapter implements TargetAdapter {
|
|
4
|
+
#private;
|
|
5
|
+
constructor(options: CreateTargetAdapterOptions);
|
|
6
|
+
get credentialInstall(): TargetAdapter['credentialInstall'];
|
|
7
|
+
allocate(request: AllocateRequest, signal?: AbortSignal): Promise<Capsule>;
|
|
8
|
+
list(request?: ListRequest, signal?: AbortSignal): Promise<CapsuleListPage>;
|
|
9
|
+
inspect(capsuleId: string, signal?: AbortSignal): Promise<Capsule>;
|
|
10
|
+
terminate(capsuleId: string, signal?: AbortSignal): Promise<Capsule>;
|
|
11
|
+
limits(signal?: AbortSignal): Promise<CapsuleLimits>;
|
|
12
|
+
access(capsuleId: string, signal?: AbortSignal): Promise<CapsuleAccess>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { TargetAdapter, CreateTargetAdapterOptions } from './adapter-types.js';
|
|
2
|
+
import type { AllocateRequest, Capsule, CapsuleAccess, CapsuleLimits, CapsuleListPage, ListRequest } from './types.js';
|
|
3
|
+
export declare class ZeroCloudV1TargetAdapter implements TargetAdapter {
|
|
4
|
+
#private;
|
|
5
|
+
constructor(options: CreateTargetAdapterOptions);
|
|
6
|
+
get credentialInstall(): TargetAdapter['credentialInstall'];
|
|
7
|
+
allocate(request: AllocateRequest, signal?: AbortSignal): Promise<Capsule>;
|
|
8
|
+
list(request?: ListRequest, signal?: AbortSignal): Promise<CapsuleListPage>;
|
|
9
|
+
inspect(capsuleId: string, signal?: AbortSignal): Promise<Capsule>;
|
|
10
|
+
terminate(capsuleId: string, signal?: AbortSignal): Promise<Capsule>;
|
|
11
|
+
limits(signal?: AbortSignal): Promise<CapsuleLimits>;
|
|
12
|
+
access(capsuleId: string, signal?: AbortSignal): Promise<CapsuleAccess>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { IDEMPOTENCY_KEY_PATTERN, MAX_RESPONSE_BYTES } from './bounds.mjs';
|
|
2
|
+
import { TargetAdapterError, TargetAuthError, TargetProtocolError, TargetTransportError, } from './errors.mjs';
|
|
3
|
+
import { DefaultRetryPolicy } from './retry.mjs';
|
|
4
|
+
import { assertCapsule, assertCapsuleAccess, assertCapsuleLimits, assertCapsuleListPage, } from './response-validation.mjs';
|
|
5
|
+
import { readBoundedResponseJson } from '../target/bounded-response.mjs';
|
|
6
|
+
import { throwCapsuleServerError } from './capsule-error-response.mjs';
|
|
7
|
+
import { validateAccessUrl } from './access-url.mjs';
|
|
8
|
+
import { withTargetRetry } from './retry-executor.mjs';
|
|
9
|
+
import { requestUrl, } from './adapter-request.mjs';
|
|
10
|
+
const DEFAULT_TRANSPORT = {
|
|
11
|
+
fetch(url, init) {
|
|
12
|
+
return globalThis.fetch(url, init);
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
const DEFAULT_CLOCK = { now: () => Date.now() };
|
|
16
|
+
function throwIfAborted(signal) {
|
|
17
|
+
if (signal?.aborted)
|
|
18
|
+
throw signal.reason ?? new globalThis.DOMException('The operation was aborted', 'AbortError');
|
|
19
|
+
}
|
|
20
|
+
function validOpaque(value, field) {
|
|
21
|
+
if (value.length === 0 || value.length > 1024)
|
|
22
|
+
throw new TargetProtocolError(`${field} is invalid`);
|
|
23
|
+
}
|
|
24
|
+
function jsonRequest(body) {
|
|
25
|
+
return JSON.stringify(body);
|
|
26
|
+
}
|
|
27
|
+
export class ZeroCloudV1TargetAdapter {
|
|
28
|
+
#descriptor;
|
|
29
|
+
#organizationId;
|
|
30
|
+
#tokenProvider;
|
|
31
|
+
#transport;
|
|
32
|
+
#clock;
|
|
33
|
+
#retryPolicy;
|
|
34
|
+
constructor(options) {
|
|
35
|
+
this.#descriptor = options.descriptor;
|
|
36
|
+
this.#organizationId = options.organization.id;
|
|
37
|
+
validOpaque(this.#organizationId, 'organization id');
|
|
38
|
+
this.#tokenProvider = options.tokenProvider;
|
|
39
|
+
this.#transport = options.transport ?? DEFAULT_TRANSPORT;
|
|
40
|
+
this.#clock = options.clock ?? DEFAULT_CLOCK;
|
|
41
|
+
this.#retryPolicy = options.retryPolicy ?? new DefaultRetryPolicy();
|
|
42
|
+
}
|
|
43
|
+
get credentialInstall() {
|
|
44
|
+
const descriptor = this.#descriptor.credentialInstall;
|
|
45
|
+
return descriptor === null
|
|
46
|
+
? Object.freeze({ supported: false })
|
|
47
|
+
: Object.freeze({ supported: true, descriptor });
|
|
48
|
+
}
|
|
49
|
+
allocate(request, signal) {
|
|
50
|
+
try {
|
|
51
|
+
if (!IDEMPOTENCY_KEY_PATTERN.test(request.idempotencyKey))
|
|
52
|
+
throw new TargetProtocolError('Idempotency key is invalid');
|
|
53
|
+
if (request.label !== undefined && (request.label.length < 1 || request.label.length > 100)) {
|
|
54
|
+
throw new TargetProtocolError('Capsule label is outside the supported bounds');
|
|
55
|
+
}
|
|
56
|
+
if (request.size !== undefined && !this.#descriptor.sizes.catalog.includes(request.size)) {
|
|
57
|
+
throw new TargetProtocolError('Capsule size is not advertised by the target');
|
|
58
|
+
}
|
|
59
|
+
const body = {
|
|
60
|
+
...(request.label === undefined ? {} : { label: request.label }),
|
|
61
|
+
...(request.size === undefined ? {} : { size: request.size }),
|
|
62
|
+
};
|
|
63
|
+
return this.#execute('allocate', 'POST', this.#descriptor.capsule.routes.allocate, { org_id: this.#organizationId }, 201, assertCapsule, signal, {
|
|
64
|
+
body: jsonRequest(body),
|
|
65
|
+
headers: { 'Idempotency-Key': request.idempotencyKey },
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
return Promise.reject(error);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async list(request = {}, signal) {
|
|
73
|
+
if (request.cursor !== undefined)
|
|
74
|
+
validOpaque(request.cursor, 'cursor');
|
|
75
|
+
if (request.limit !== undefined &&
|
|
76
|
+
(!Number.isSafeInteger(request.limit) ||
|
|
77
|
+
request.limit < 1 ||
|
|
78
|
+
request.limit > this.#descriptor.pagination.maxPageSize)) {
|
|
79
|
+
throw new TargetProtocolError('Pagination limit is outside the advertised bounds');
|
|
80
|
+
}
|
|
81
|
+
const page = await this.#execute('list', 'GET', this.#descriptor.capsule.routes.list, {
|
|
82
|
+
org_id: this.#organizationId,
|
|
83
|
+
cursor: request.cursor,
|
|
84
|
+
limit: request.limit,
|
|
85
|
+
}, 200, assertCapsuleListPage, signal);
|
|
86
|
+
if (request.cursor !== undefined && page.nextCursor === request.cursor)
|
|
87
|
+
throw new TargetProtocolError('Target returned a pagination loop');
|
|
88
|
+
return page;
|
|
89
|
+
}
|
|
90
|
+
inspect(capsuleId, signal) {
|
|
91
|
+
validOpaque(capsuleId, 'capsule id');
|
|
92
|
+
return this.#execute('inspect', 'GET', this.#descriptor.capsule.routes.inspect, { org_id: this.#organizationId, capsule_id: capsuleId }, 200, assertCapsule, signal);
|
|
93
|
+
}
|
|
94
|
+
terminate(capsuleId, signal) {
|
|
95
|
+
validOpaque(capsuleId, 'capsule id');
|
|
96
|
+
return this.#execute('terminate', 'DELETE', this.#descriptor.capsule.routes.terminate, { org_id: this.#organizationId, capsule_id: capsuleId }, 202, assertCapsule, signal);
|
|
97
|
+
}
|
|
98
|
+
limits(signal) {
|
|
99
|
+
return this.#execute('limits', 'GET', this.#descriptor.capsule.routes.limits, { org_id: this.#organizationId }, 200, assertCapsuleLimits, signal);
|
|
100
|
+
}
|
|
101
|
+
async access(capsuleId, signal) {
|
|
102
|
+
validOpaque(capsuleId, 'capsule id');
|
|
103
|
+
const result = await this.#execute('access', 'POST', this.#descriptor.capsule.routes.access, { capsule_id: capsuleId }, 200, assertCapsuleAccess, signal, {
|
|
104
|
+
body: jsonRequest({ protocol: 'openengine.cluster/v1' }),
|
|
105
|
+
});
|
|
106
|
+
validateAccessUrl(result.websocketUrl, capsuleId, this.#descriptor);
|
|
107
|
+
return result;
|
|
108
|
+
}
|
|
109
|
+
#execute(...args) {
|
|
110
|
+
return Promise.resolve().then(() => this.#executeExpanded(args));
|
|
111
|
+
}
|
|
112
|
+
#executeExpanded(args) {
|
|
113
|
+
const [operation, method, template, values, expectedStatus, validate, signal, request = {},] = args;
|
|
114
|
+
let path;
|
|
115
|
+
try {
|
|
116
|
+
path = template.expand(values);
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
throw new TargetProtocolError('Capsule route expansion is unsafe');
|
|
120
|
+
}
|
|
121
|
+
return withTargetRetry(operation, async () => {
|
|
122
|
+
const response = await this.#request(method, path, signal, request);
|
|
123
|
+
if (response.status >= 300 && response.status < 400) {
|
|
124
|
+
await response.body?.cancel().catch(() => undefined);
|
|
125
|
+
throw new TargetProtocolError('Capsule redirects are forbidden');
|
|
126
|
+
}
|
|
127
|
+
if (response.status !== expectedStatus) {
|
|
128
|
+
if (response.status >= 200 && response.status < 300) {
|
|
129
|
+
await response.body?.cancel().catch(() => undefined);
|
|
130
|
+
throw new TargetProtocolError('Target returned an unexpected success status');
|
|
131
|
+
}
|
|
132
|
+
await throwCapsuleServerError(response, (errorResponse) => this.#readJson(errorResponse), this.#clock);
|
|
133
|
+
}
|
|
134
|
+
return validate(await this.#readJson(response));
|
|
135
|
+
}, signal, { clock: this.#clock, policy: this.#retryPolicy });
|
|
136
|
+
}
|
|
137
|
+
async #request(method, path, signal, request) {
|
|
138
|
+
throwIfAborted(signal);
|
|
139
|
+
const url = requestUrl(path, this.#descriptor);
|
|
140
|
+
let token;
|
|
141
|
+
try {
|
|
142
|
+
token = await this.#tokenProvider.getAccessToken(signal);
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
throw new TargetAuthError('Target access authorization failed');
|
|
146
|
+
}
|
|
147
|
+
const init = {
|
|
148
|
+
method,
|
|
149
|
+
headers: {
|
|
150
|
+
Accept: 'application/json',
|
|
151
|
+
Authorization: `Bearer ${token}`,
|
|
152
|
+
...(request.body === undefined ? {} : { 'Content-Type': 'application/json' }),
|
|
153
|
+
...request.headers,
|
|
154
|
+
},
|
|
155
|
+
redirect: 'manual',
|
|
156
|
+
};
|
|
157
|
+
if (request.body !== undefined)
|
|
158
|
+
init.body = request.body;
|
|
159
|
+
if (signal !== undefined)
|
|
160
|
+
init.signal = signal;
|
|
161
|
+
try {
|
|
162
|
+
const response = await this.#transport.fetch(url.href, init);
|
|
163
|
+
if (response.url && new globalThis.URL(response.url).href !== url.href) {
|
|
164
|
+
await response.body?.cancel().catch(() => undefined);
|
|
165
|
+
throw new TargetProtocolError('Capsule response changed target route');
|
|
166
|
+
}
|
|
167
|
+
return response;
|
|
168
|
+
}
|
|
169
|
+
catch (error) {
|
|
170
|
+
if (error instanceof TargetAdapterError)
|
|
171
|
+
throw error;
|
|
172
|
+
throwIfAborted(signal);
|
|
173
|
+
throw new TargetTransportError('Capsule transport failed');
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
#readJson(response) {
|
|
177
|
+
return readBoundedResponseJson(response, MAX_RESPONSE_BYTES, (kind) => new TargetProtocolError(kind === 'size'
|
|
178
|
+
? 'Capsule response exceeds the size limit'
|
|
179
|
+
: 'Capsule response is not valid UTF-8 JSON'));
|
|
180
|
+
}
|
|
181
|
+
}
|
package/lib/start-cluster.js
CHANGED
|
@@ -176,17 +176,17 @@ function applyProviderOverrideToConfig(config, providerOverride, settings) {
|
|
|
176
176
|
console.log(chalk.dim(`Provider override: ${providerOverride} (all agents)`));
|
|
177
177
|
}
|
|
178
178
|
|
|
179
|
-
function resolveParameterizedConfigFile(config
|
|
179
|
+
function resolveParameterizedConfigFile(config) {
|
|
180
180
|
if (!config?.params || Object.keys(config.params).length === 0) {
|
|
181
181
|
return config;
|
|
182
182
|
}
|
|
183
183
|
|
|
184
184
|
const resolver = new TemplateResolver(path.join(PACKAGE_ROOT, 'cluster-templates'));
|
|
185
|
-
return resolver.resolveTemplate(config,
|
|
185
|
+
return resolver.resolveTemplate(config, {});
|
|
186
186
|
}
|
|
187
187
|
|
|
188
188
|
function prepareClusterConfig(config, settings = {}, providerOverride) {
|
|
189
|
-
const prepared = resolveParameterizedConfigFile(config
|
|
189
|
+
const prepared = resolveParameterizedConfigFile(config);
|
|
190
190
|
ensureConfigProviderDefaults(prepared, settings);
|
|
191
191
|
if (providerOverride) {
|
|
192
192
|
applyProviderOverrideToConfig(prepared, providerOverride, settings);
|