@sandbox-kit/sandbox 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/README.md +129 -2
- package/dist/client/client.d.ts +17 -0
- package/dist/client/client.js +222 -0
- package/dist/client/errors.d.ts +35 -0
- package/dist/client/errors.js +88 -0
- package/dist/client/operation.d.ts +12 -0
- package/dist/client/operation.js +73 -0
- package/dist/client/sandbox.d.ts +33 -0
- package/dist/client/sandbox.js +160 -0
- package/dist/client/types.d.ts +63 -0
- package/dist/client/types.js +3 -0
- package/dist/client/validation.d.ts +9 -0
- package/dist/client/validation.js +221 -0
- package/dist/contracts/config_paths.d.ts +44 -0
- package/dist/contracts/config_paths.js +50 -0
- package/dist/contracts/field_paths.d.ts +216 -0
- package/dist/contracts/field_paths.js +222 -0
- package/dist/contracts/sandbox_data_contracts.d.ts +206 -0
- package/dist/contracts/sandbox_data_contracts.js +22 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +6 -0
- package/dist/internal/duration_ms.d.ts +15 -0
- package/dist/internal/duration_ms.js +41 -0
- package/dist/internal/input_remap.d.ts +36 -0
- package/dist/internal/input_remap.js +1 -0
- package/dist/internal/net_validate.d.ts +4 -0
- package/dist/internal/net_validate.js +53 -0
- package/dist/internal/oneof_input.d.ts +32 -0
- package/dist/internal/oneof_input.js +1 -0
- package/dist/internal/proto_enum.d.ts +25 -0
- package/dist/internal/proto_enum.js +25 -0
- package/dist/internal/strip_proto.d.ts +46 -0
- package/dist/internal/strip_proto.js +1 -0
- package/dist/metadata/metadata_object.d.ts +7 -0
- package/dist/metadata/metadata_object.js +103 -0
- package/dist/metadata/metadata_plain.d.ts +9 -0
- package/dist/metadata/metadata_plain.js +1 -0
- package/package.json +71 -4
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
// Sandbox handle runtime behavior is handwritten. Lifecycle methods dispatch
|
|
2
|
+
// through optional Backend capabilities.
|
|
3
|
+
import { SandboxState, } from "#contracts/sandbox_data_contracts.js";
|
|
4
|
+
import { ErrorKind, sandboxError, unsupported, withContext, } from "#client/errors.js";
|
|
5
|
+
import { awaitWithSignal, clone, operationOptions, operationSignal, publicTimeoutOptions, } from "#client/operation.js";
|
|
6
|
+
export const sandboxConstructorToken = Symbol("sandbox-kit.Sandbox");
|
|
7
|
+
export class Sandbox {
|
|
8
|
+
#backend;
|
|
9
|
+
#owner;
|
|
10
|
+
#timeout;
|
|
11
|
+
#info;
|
|
12
|
+
#closed = false;
|
|
13
|
+
#tail = Promise.resolve();
|
|
14
|
+
constructor(token, init) {
|
|
15
|
+
if (token !== sandboxConstructorToken)
|
|
16
|
+
throw new TypeError("Sandbox handles are created by Client");
|
|
17
|
+
this.#backend = init.backend;
|
|
18
|
+
this.#owner = init.owner;
|
|
19
|
+
this.#info = clone(init.info);
|
|
20
|
+
this.#timeout = init.timeout;
|
|
21
|
+
}
|
|
22
|
+
get id() {
|
|
23
|
+
return this.#info.id;
|
|
24
|
+
}
|
|
25
|
+
get providerName() {
|
|
26
|
+
return this.#info.provider;
|
|
27
|
+
}
|
|
28
|
+
info() {
|
|
29
|
+
return clone(this.#info);
|
|
30
|
+
}
|
|
31
|
+
capabilities() {
|
|
32
|
+
if (this.#closed || this.#owner.isClosed() || this.#info.terminal)
|
|
33
|
+
return [];
|
|
34
|
+
return this.#backend.capabilities?.(clone(this.#info)) ?? [];
|
|
35
|
+
}
|
|
36
|
+
supports(capability) {
|
|
37
|
+
return this.capabilities().includes(capability);
|
|
38
|
+
}
|
|
39
|
+
async refresh(options = {}) {
|
|
40
|
+
return this.#serialized("refresh", options, this.#timeout, async (signal) => {
|
|
41
|
+
const method = this.#backend.refresh;
|
|
42
|
+
if (!method)
|
|
43
|
+
unsupported(this.providerName, "refresh");
|
|
44
|
+
const info = await awaitWithSignal(() => method.call(this.#backend, this.id, operationOptions(options, signal)), signal);
|
|
45
|
+
this.#info = clone({ ...info, provider: this.providerName });
|
|
46
|
+
return this.info();
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
async start(options = {}) {
|
|
50
|
+
return this.#update("start", this.#backend.start, publicTimeoutOptions(options), options);
|
|
51
|
+
}
|
|
52
|
+
async stop(options = {}) {
|
|
53
|
+
const { force, ...call } = options;
|
|
54
|
+
return this.#update("stop", this.#backend.stop, {
|
|
55
|
+
...publicTimeoutOptions(call),
|
|
56
|
+
...(force === undefined ? {} : { force }),
|
|
57
|
+
}, call);
|
|
58
|
+
}
|
|
59
|
+
async pause(options = {}) {
|
|
60
|
+
return this.#update("pause", this.#backend.pause, publicTimeoutOptions(options), options);
|
|
61
|
+
}
|
|
62
|
+
async terminate(options = {}) {
|
|
63
|
+
const { wait, ...call } = options;
|
|
64
|
+
const request = {
|
|
65
|
+
...publicTimeoutOptions(call),
|
|
66
|
+
...(wait === undefined ? {} : { wait }),
|
|
67
|
+
};
|
|
68
|
+
return this.#serialized("terminate", call, call.timeout ?? this.#timeout, async (signal) => {
|
|
69
|
+
const method = this.#backend.terminate;
|
|
70
|
+
if (!method)
|
|
71
|
+
unsupported(this.providerName, "terminate");
|
|
72
|
+
const result = await awaitWithSignal(() => method.call(this.#backend, this.id, clone(request), operationOptions(call, signal)), signal);
|
|
73
|
+
this.#info = {
|
|
74
|
+
...this.#info,
|
|
75
|
+
state: SandboxState.Terminated,
|
|
76
|
+
terminal: true,
|
|
77
|
+
};
|
|
78
|
+
return result;
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
async archive(options = {}) {
|
|
82
|
+
return this.#update("archive", this.#backend.archive, publicTimeoutOptions(options), options);
|
|
83
|
+
}
|
|
84
|
+
async delete(options = {}) {
|
|
85
|
+
const { wait, ...call } = options;
|
|
86
|
+
return this.#update("delete", this.#backend.delete, {
|
|
87
|
+
...publicTimeoutOptions(call),
|
|
88
|
+
...(wait === undefined ? {} : { wait }),
|
|
89
|
+
}, call);
|
|
90
|
+
}
|
|
91
|
+
async close(options = {}) {
|
|
92
|
+
if (this.#closed)
|
|
93
|
+
return;
|
|
94
|
+
await this.#serialized("close", options, this.#timeout, async (signal) => {
|
|
95
|
+
const close = this.#backend.closeSandbox;
|
|
96
|
+
if (close)
|
|
97
|
+
await awaitWithSignal(() => close.call(this.#backend, this.id, operationOptions(options, signal)), signal);
|
|
98
|
+
this.#closed = true;
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
async [Symbol.asyncDispose]() {
|
|
102
|
+
await this.close();
|
|
103
|
+
}
|
|
104
|
+
async #update(operation, method, request, options) {
|
|
105
|
+
return this.#serialized(operation, options, options.timeout ?? this.#timeout, async (signal) => {
|
|
106
|
+
if (!method)
|
|
107
|
+
unsupported(this.providerName, operation);
|
|
108
|
+
const info = await awaitWithSignal(() => method.call(this.#backend, this.id, clone(request), operationOptions(options, signal)), signal);
|
|
109
|
+
this.#info = clone({ ...info, provider: this.providerName });
|
|
110
|
+
return this.info();
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
async #serialized(operation, options, timeout, body) {
|
|
114
|
+
this.#ensureOpen(operation);
|
|
115
|
+
const releaseClient = this.#owner.begin(operation);
|
|
116
|
+
const previous = this.#tail;
|
|
117
|
+
let unlock;
|
|
118
|
+
this.#tail = new Promise((resolve) => {
|
|
119
|
+
unlock = resolve;
|
|
120
|
+
});
|
|
121
|
+
let acquired = false;
|
|
122
|
+
let scoped;
|
|
123
|
+
try {
|
|
124
|
+
scoped = operationSignal(options, timeout);
|
|
125
|
+
await awaitWithSignal(() => previous, scoped.signal);
|
|
126
|
+
acquired = true;
|
|
127
|
+
this.#ensureOpen(operation);
|
|
128
|
+
return await body(scoped.signal);
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
throw withContext(error, this.providerName, operation);
|
|
132
|
+
}
|
|
133
|
+
finally {
|
|
134
|
+
scoped?.dispose();
|
|
135
|
+
if (acquired)
|
|
136
|
+
unlock();
|
|
137
|
+
else
|
|
138
|
+
void previous.then(unlock, unlock);
|
|
139
|
+
releaseClient();
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
#ensureOpen(operation) {
|
|
143
|
+
if (this.#closed || this.#owner.isClosed())
|
|
144
|
+
throw sandboxError({
|
|
145
|
+
kind: ErrorKind.FailedPrecondition,
|
|
146
|
+
provider: this.providerName,
|
|
147
|
+
operation,
|
|
148
|
+
field: "sandbox",
|
|
149
|
+
message: "sandbox-kit: sandbox handle is closed",
|
|
150
|
+
});
|
|
151
|
+
if (operation !== "close" && this.#info.terminal)
|
|
152
|
+
throw sandboxError({
|
|
153
|
+
kind: ErrorKind.FailedPrecondition,
|
|
154
|
+
provider: this.providerName,
|
|
155
|
+
operation,
|
|
156
|
+
field: "sandbox",
|
|
157
|
+
message: "sandbox-kit: sandbox lifecycle is terminal",
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { MessageInitShape } from "@bufbuild/protobuf";
|
|
2
|
+
import { ConfigSchema, type APIKeyCredentials as WireAPIKeyCredentials, type AuthConfig, type BearerTokenCredentials as WireBearerTokenCredentials, type OAuthCredentials as WireOAuthCredentials, type TokenPairCredentials as WireTokenPairCredentials } from "@sandbox-kit/contracts/client";
|
|
3
|
+
import type { ArchiveOptions, CreateOptions, CreateResult, DeleteOptions, ExitResult, LifecycleCapability, PauseOptions, SandboxInfo, StartOptions, StopOptions, TerminateOptions } from "#contracts/sandbox_data_contracts.js";
|
|
4
|
+
import type { DurationFieldsToMs } from "#internal/duration_ms.js";
|
|
5
|
+
import type { RemapFields } from "#internal/input_remap.js";
|
|
6
|
+
import type { FlattenOneof } from "#internal/oneof_input.js";
|
|
7
|
+
import type { StripProto } from "#internal/strip_proto.js";
|
|
8
|
+
/** Public credential shapes (no protobuf `$typeName` / getters). */
|
|
9
|
+
export type APIKeyCredentials = StripProto<WireAPIKeyCredentials>;
|
|
10
|
+
export type TokenPairCredentials = StripProto<WireTokenPairCredentials>;
|
|
11
|
+
export type BearerTokenCredentials = StripProto<WireBearerTokenCredentials>;
|
|
12
|
+
export type OAuthCredentials = StripProto<WireOAuthCredentials>;
|
|
13
|
+
export type Scope = StripProto<import("@sandbox-kit/contracts/client").Scope>;
|
|
14
|
+
/** Public auth: set exactly one credential variant (no protobuf `{ case, value }`). */
|
|
15
|
+
export type AuthInput = FlattenOneof<NonNullable<AuthConfig["credentials"]>>;
|
|
16
|
+
/**
|
|
17
|
+
* Public client settings (ms timeout, flat auth).
|
|
18
|
+
* Prefer {@link ClientConfig} at construction (`Config` plus `provider`).
|
|
19
|
+
*/
|
|
20
|
+
export type Config = DurationFieldsToMs<RemapFields<StripProto<MessageInitShape<typeof ConfigSchema>>, {
|
|
21
|
+
auth: AuthInput;
|
|
22
|
+
}>>;
|
|
23
|
+
export interface OperationOptions {
|
|
24
|
+
readonly signal?: AbortSignal;
|
|
25
|
+
/** Operation deadline in milliseconds. */
|
|
26
|
+
readonly timeout?: number;
|
|
27
|
+
}
|
|
28
|
+
/** Public stop options: Kit call options plus optional force. */
|
|
29
|
+
export type StopCallOptions = OperationOptions & {
|
|
30
|
+
readonly force?: boolean;
|
|
31
|
+
};
|
|
32
|
+
/** Public terminate options: Kit call options plus optional wait. */
|
|
33
|
+
export type TerminateCallOptions = OperationOptions & {
|
|
34
|
+
readonly wait?: boolean;
|
|
35
|
+
};
|
|
36
|
+
/** Public delete options: Kit call options plus optional wait. */
|
|
37
|
+
export type DeleteCallOptions = OperationOptions & {
|
|
38
|
+
readonly wait?: boolean;
|
|
39
|
+
};
|
|
40
|
+
export interface Backend {
|
|
41
|
+
readonly name: string;
|
|
42
|
+
create?(request: CreateOptions, options: OperationOptions): Promise<CreateResult>;
|
|
43
|
+
attach?(id: string, options: OperationOptions): Promise<SandboxInfo>;
|
|
44
|
+
refresh?(id: string, options: OperationOptions): Promise<SandboxInfo>;
|
|
45
|
+
start?(id: string, request: StartOptions, options: OperationOptions): Promise<SandboxInfo>;
|
|
46
|
+
stop?(id: string, request: StopOptions, options: OperationOptions): Promise<SandboxInfo>;
|
|
47
|
+
pause?(id: string, request: PauseOptions, options: OperationOptions): Promise<SandboxInfo>;
|
|
48
|
+
terminate?(id: string, request: TerminateOptions, options: OperationOptions): Promise<ExitResult>;
|
|
49
|
+
archive?(id: string, request: ArchiveOptions, options: OperationOptions): Promise<SandboxInfo>;
|
|
50
|
+
delete?(id: string, request: DeleteOptions, options: OperationOptions): Promise<SandboxInfo>;
|
|
51
|
+
close(options: OperationOptions): Promise<void>;
|
|
52
|
+
closeSandbox?(id: string, options: OperationOptions): Promise<void>;
|
|
53
|
+
capabilities?(info: SandboxInfo): readonly LifecycleCapability[];
|
|
54
|
+
}
|
|
55
|
+
export interface Provider {
|
|
56
|
+
readonly name: string;
|
|
57
|
+
/** Receives public {@link Config}. */
|
|
58
|
+
initialize(config: Config): Backend;
|
|
59
|
+
}
|
|
60
|
+
/** Provider selection stays handwritten and is never part of the portable Config message. */
|
|
61
|
+
export type ClientConfig = Config & {
|
|
62
|
+
readonly provider: Provider;
|
|
63
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { CreateOptions } from "#contracts/sandbox_data_contracts.js";
|
|
2
|
+
import type { Config } from "#client/types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Rejects public {@link CreateOptions} the shared contract cannot represent.
|
|
5
|
+
* Materializes wire form privately for Protovalidate. Provider-specific checks
|
|
6
|
+
* remain in each provider adapter.
|
|
7
|
+
*/
|
|
8
|
+
export declare function validateCreateOptions(value: CreateOptions, provider?: string, operation?: string): void;
|
|
9
|
+
export declare function validateConfig(value: Config, provider?: string, operation?: string): void;
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
// Shared create/config validation is Protovalidate on materialized wire
|
|
2
|
+
// messages; secure_endpoint stays handwritten.
|
|
3
|
+
import { create, } from "@bufbuild/protobuf";
|
|
4
|
+
import { pathToString } from "@bufbuild/protobuf/reflect";
|
|
5
|
+
import { durationFromMs } from "@bufbuild/protobuf/wkt";
|
|
6
|
+
import { createValidator } from "@bufbuild/protovalidate";
|
|
7
|
+
import { ConfigSchema, } from "@sandbox-kit/contracts/client";
|
|
8
|
+
import { CreateOptionsSchema, } from "@sandbox-kit/contracts/sandbox";
|
|
9
|
+
import { materializeDurationFields } from "#internal/duration_ms.js";
|
|
10
|
+
import { metadataObjectFromMap } from "#metadata/metadata_object.js";
|
|
11
|
+
import { ErrorKind, sandboxError } from "#client/errors.js";
|
|
12
|
+
const contractValidator = createValidator({ failFast: true });
|
|
13
|
+
const stableRuleIDs = {
|
|
14
|
+
"enum.defined_only": "known_enum",
|
|
15
|
+
"duration.gte": "minimum",
|
|
16
|
+
"oneof.required": "exactly_one",
|
|
17
|
+
auth_credentials_required: "exactly_one",
|
|
18
|
+
cpu_limit: "limit",
|
|
19
|
+
memory_limit: "limit",
|
|
20
|
+
cpu_requires_positive: "requires_positive",
|
|
21
|
+
memory_requires_positive: "requires_positive",
|
|
22
|
+
restricted_requires_allowlist: "requires_any",
|
|
23
|
+
block_all_forbids_network: "forbids",
|
|
24
|
+
allow_all_forbids_allowlists: "forbids",
|
|
25
|
+
after_requires_duration: "requires_any",
|
|
26
|
+
after_forbids_duration: "forbids",
|
|
27
|
+
};
|
|
28
|
+
function validationError(input) {
|
|
29
|
+
throw sandboxError({
|
|
30
|
+
kind: ErrorKind.InvalidArgument,
|
|
31
|
+
provider: input.provider,
|
|
32
|
+
operation: input.operation,
|
|
33
|
+
field: input.field,
|
|
34
|
+
rule: input.rule,
|
|
35
|
+
message: "sandbox-kit: " + input.message,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
function validSecureEndpoint(value) {
|
|
39
|
+
try {
|
|
40
|
+
const url = new URL(value);
|
|
41
|
+
if (!url.hostname || url.username || url.password || url.hash)
|
|
42
|
+
return false;
|
|
43
|
+
if (url.protocol === "https:")
|
|
44
|
+
return true;
|
|
45
|
+
if (url.protocol !== "http:")
|
|
46
|
+
return false;
|
|
47
|
+
const host = url.hostname.toLowerCase();
|
|
48
|
+
return (host === "localhost" ||
|
|
49
|
+
host === "[::1]" ||
|
|
50
|
+
host === "::1" ||
|
|
51
|
+
/^127(?:\.[0-9]{1,3}){3}$/.test(host));
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Rejects public {@link CreateOptions} the shared contract cannot represent.
|
|
59
|
+
* Materializes wire form privately for Protovalidate. Provider-specific checks
|
|
60
|
+
* remain in each provider adapter.
|
|
61
|
+
*/
|
|
62
|
+
export function validateCreateOptions(value, provider = "", operation = "create") {
|
|
63
|
+
const message = materializeCreateOptions(value);
|
|
64
|
+
const result = contractValidator.validate(CreateOptionsSchema, message);
|
|
65
|
+
reportValidationResult(result, provider, operation);
|
|
66
|
+
}
|
|
67
|
+
function messageFieldHint(ruleID) {
|
|
68
|
+
switch (ruleID) {
|
|
69
|
+
case "cpu_limit":
|
|
70
|
+
case "cpu_requires_positive":
|
|
71
|
+
return "resources.cpu_limit_cores";
|
|
72
|
+
case "memory_limit":
|
|
73
|
+
case "memory_requires_positive":
|
|
74
|
+
return "resources.memory_limit_mib";
|
|
75
|
+
case "restricted_requires_allowlist":
|
|
76
|
+
return "network.outbound_cidrs,outbound_domains";
|
|
77
|
+
case "block_all_forbids_network":
|
|
78
|
+
return "network.outbound_cidrs,outbound_domains,private_network,linked_sandbox,inbound_cidrs,ports";
|
|
79
|
+
case "allow_all_forbids_allowlists":
|
|
80
|
+
return "network.outbound_cidrs,outbound_domains";
|
|
81
|
+
case "after_requires_duration":
|
|
82
|
+
case "after_forbids_duration":
|
|
83
|
+
return "after";
|
|
84
|
+
case "oneof.required":
|
|
85
|
+
return "tcp_port,command";
|
|
86
|
+
case "auth_credentials_required":
|
|
87
|
+
return "api_key,token_pair,bearer_token,oauth_refresh";
|
|
88
|
+
case "exactly_one":
|
|
89
|
+
return "client_secret,jwt_key";
|
|
90
|
+
default:
|
|
91
|
+
return "";
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
export function validateConfig(value, provider = "", operation = "create") {
|
|
95
|
+
const message = materializeClientConfig(value);
|
|
96
|
+
const result = contractValidator.validate(ConfigSchema, message);
|
|
97
|
+
reportValidationResult(result, provider, operation);
|
|
98
|
+
if (message.endpoint !== undefined &&
|
|
99
|
+
!validSecureEndpoint(message.endpoint)) {
|
|
100
|
+
validationError({
|
|
101
|
+
provider,
|
|
102
|
+
operation,
|
|
103
|
+
field: "endpoint",
|
|
104
|
+
rule: "secure_endpoint",
|
|
105
|
+
message: "must use HTTPS except for loopback HTTP development endpoints",
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function reportValidationResult(result, provider, operation) {
|
|
110
|
+
if (result.kind === "valid")
|
|
111
|
+
return;
|
|
112
|
+
if (result.kind === "error") {
|
|
113
|
+
throw sandboxError({
|
|
114
|
+
kind: ErrorKind.InvalidArgument,
|
|
115
|
+
provider,
|
|
116
|
+
operation,
|
|
117
|
+
field: "",
|
|
118
|
+
message: "sandbox-kit: invalid configuration",
|
|
119
|
+
}, result.error);
|
|
120
|
+
}
|
|
121
|
+
const violation = result.violations[0];
|
|
122
|
+
const ruleID = violation.ruleId;
|
|
123
|
+
let field = pathToString(violation.field);
|
|
124
|
+
const rule = stableRuleIDs[ruleID] ?? ruleID;
|
|
125
|
+
if (!field) {
|
|
126
|
+
field = messageFieldHint(ruleID);
|
|
127
|
+
}
|
|
128
|
+
validationError({
|
|
129
|
+
provider,
|
|
130
|
+
operation,
|
|
131
|
+
field,
|
|
132
|
+
rule,
|
|
133
|
+
message: violation.message || "invalid configuration",
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
/** Materializes a plain client config into the generated protobuf message. */
|
|
137
|
+
function materializeClientConfig(input) {
|
|
138
|
+
const { auth, timeout, ...rest } = input;
|
|
139
|
+
return create(ConfigSchema, {
|
|
140
|
+
...rest,
|
|
141
|
+
...(timeout === undefined ? {} : { timeout: durationFromMs(timeout) }),
|
|
142
|
+
...(auth === undefined
|
|
143
|
+
? {}
|
|
144
|
+
: { auth: { credentials: authCredentials(auth) } }),
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
/** Materializes plain create options into the generated protobuf message. */
|
|
148
|
+
function materializeCreateOptions(input) {
|
|
149
|
+
const { source, readiness, providerOptions, network, ...rest } = input;
|
|
150
|
+
const withDurations = materializeDurationFields(rest);
|
|
151
|
+
return create(CreateOptionsSchema, {
|
|
152
|
+
...withDurations,
|
|
153
|
+
...(network === undefined
|
|
154
|
+
? {}
|
|
155
|
+
: { network: materializeNetworkConfig(network) }),
|
|
156
|
+
...(source === undefined ? {} : { source: { kind: sourceKind(source) } }),
|
|
157
|
+
...(readiness === undefined
|
|
158
|
+
? {}
|
|
159
|
+
: { readiness: { check: readinessCheck(readiness) } }),
|
|
160
|
+
...(providerOptions === undefined
|
|
161
|
+
? {}
|
|
162
|
+
: { providerOptions: metadataObjectFromMap(providerOptions) }),
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
/** Wrap public string-array allowlists into wire StringAllowlist messages. */
|
|
166
|
+
function materializeNetworkConfig(network) {
|
|
167
|
+
const { outboundCidrs, outboundDomains, inboundCidrs, ...rest } = network;
|
|
168
|
+
return {
|
|
169
|
+
...rest,
|
|
170
|
+
...(outboundCidrs === undefined
|
|
171
|
+
? {}
|
|
172
|
+
: { outboundCidrs: { entries: outboundCidrs } }),
|
|
173
|
+
...(outboundDomains === undefined
|
|
174
|
+
? {}
|
|
175
|
+
: { outboundDomains: { entries: outboundDomains } }),
|
|
176
|
+
...(inboundCidrs === undefined
|
|
177
|
+
? {}
|
|
178
|
+
: { inboundCidrs: { entries: inboundCidrs } }),
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
function authCredentials(auth) {
|
|
182
|
+
if (auth.apiKey !== undefined)
|
|
183
|
+
return { case: "apiKey", value: auth.apiKey };
|
|
184
|
+
if (auth.tokenPair !== undefined)
|
|
185
|
+
return {
|
|
186
|
+
case: "tokenPair",
|
|
187
|
+
value: auth.tokenPair,
|
|
188
|
+
};
|
|
189
|
+
if (auth.bearerToken !== undefined)
|
|
190
|
+
return {
|
|
191
|
+
case: "bearerToken",
|
|
192
|
+
value: auth.bearerToken,
|
|
193
|
+
};
|
|
194
|
+
if (auth.oauthRefresh !== undefined)
|
|
195
|
+
return {
|
|
196
|
+
case: "oauthRefresh",
|
|
197
|
+
value: auth.oauthRefresh,
|
|
198
|
+
};
|
|
199
|
+
return { case: undefined };
|
|
200
|
+
}
|
|
201
|
+
function sourceKind(source) {
|
|
202
|
+
if (source.providerDefault !== undefined)
|
|
203
|
+
return {
|
|
204
|
+
case: "providerDefault",
|
|
205
|
+
value: {},
|
|
206
|
+
};
|
|
207
|
+
if (source.image !== undefined)
|
|
208
|
+
return { case: "image", value: source.image };
|
|
209
|
+
if (source.snapshot !== undefined)
|
|
210
|
+
return { case: "snapshot", value: source.snapshot };
|
|
211
|
+
if (source.warmPool !== undefined)
|
|
212
|
+
return { case: "warmPool", value: source.warmPool };
|
|
213
|
+
return { case: undefined };
|
|
214
|
+
}
|
|
215
|
+
function readinessCheck(readiness) {
|
|
216
|
+
if (readiness.tcpPort !== undefined)
|
|
217
|
+
return { case: "tcpPort", value: readiness.tcpPort };
|
|
218
|
+
if (readiness.command !== undefined)
|
|
219
|
+
return { case: "command", value: readiness.command };
|
|
220
|
+
return { case: undefined };
|
|
221
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/** Canonical path "auth". */
|
|
2
|
+
export declare const ConfigFieldAuth: "auth";
|
|
3
|
+
/** Canonical path "auth.api_key". */
|
|
4
|
+
export declare const ConfigFieldAuthApiKey: "auth.api_key";
|
|
5
|
+
/** Canonical path "auth.api_key.key". */
|
|
6
|
+
export declare const ConfigFieldAuthApiKeyKey: "auth.api_key.key";
|
|
7
|
+
/** Canonical path "auth.token_pair". */
|
|
8
|
+
export declare const ConfigFieldAuthTokenPair: "auth.token_pair";
|
|
9
|
+
/** Canonical path "auth.token_pair.id". */
|
|
10
|
+
export declare const ConfigFieldAuthTokenPairId: "auth.token_pair.id";
|
|
11
|
+
/** Canonical path "auth.token_pair.secret". */
|
|
12
|
+
export declare const ConfigFieldAuthTokenPairSecret: "auth.token_pair.secret";
|
|
13
|
+
/** Canonical path "auth.bearer_token". */
|
|
14
|
+
export declare const ConfigFieldAuthBearerToken: "auth.bearer_token";
|
|
15
|
+
/** Canonical path "auth.bearer_token.token". */
|
|
16
|
+
export declare const ConfigFieldAuthBearerTokenToken: "auth.bearer_token.token";
|
|
17
|
+
/** Canonical path "auth.oauth_refresh". */
|
|
18
|
+
export declare const ConfigFieldAuthOauthRefresh: "auth.oauth_refresh";
|
|
19
|
+
/** Canonical path "auth.oauth_refresh.refresh_token". */
|
|
20
|
+
export declare const ConfigFieldAuthOauthRefreshRefreshToken: "auth.oauth_refresh.refresh_token";
|
|
21
|
+
/** Canonical path "auth.oauth_refresh.client_id". */
|
|
22
|
+
export declare const ConfigFieldAuthOauthRefreshClientId: "auth.oauth_refresh.client_id";
|
|
23
|
+
/** Canonical path "auth.oauth_refresh.client_secret". */
|
|
24
|
+
export declare const ConfigFieldAuthOauthRefreshClientSecret: "auth.oauth_refresh.client_secret";
|
|
25
|
+
/** Canonical path "auth.oauth_refresh.jwt_key". */
|
|
26
|
+
export declare const ConfigFieldAuthOauthRefreshJwtKey: "auth.oauth_refresh.jwt_key";
|
|
27
|
+
/** Canonical path "endpoint". */
|
|
28
|
+
export declare const ConfigFieldEndpoint: "endpoint";
|
|
29
|
+
/** Canonical path "region". */
|
|
30
|
+
export declare const ConfigFieldRegion: "region";
|
|
31
|
+
/** Canonical path "scope". */
|
|
32
|
+
export declare const ConfigFieldScope: "scope";
|
|
33
|
+
/** Canonical path "scope.app_name". */
|
|
34
|
+
export declare const ConfigFieldScopeAppName: "scope.app_name";
|
|
35
|
+
/** Canonical path "scope.environment". */
|
|
36
|
+
export declare const ConfigFieldScopeEnvironment: "scope.environment";
|
|
37
|
+
/** Canonical path "scope.organization_id". */
|
|
38
|
+
export declare const ConfigFieldScopeOrganizationId: "scope.organization_id";
|
|
39
|
+
/** Canonical path "scope.project_id". */
|
|
40
|
+
export declare const ConfigFieldScopeProjectId: "scope.project_id";
|
|
41
|
+
/** Canonical path "timeout". */
|
|
42
|
+
export declare const ConfigFieldTimeout: "timeout";
|
|
43
|
+
/** Canonical path "provider". */
|
|
44
|
+
export declare const ConfigFieldProvider: "provider";
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// Config field-path constants identify client settings in errors.
|
|
2
|
+
// Values are canonical protobuf paths (snake_case), matching Go.
|
|
3
|
+
//
|
|
4
|
+
// Example:
|
|
5
|
+
//
|
|
6
|
+
// console.log(ConfigFieldEndpoint); // endpoint
|
|
7
|
+
/** Canonical path "auth". */
|
|
8
|
+
export const ConfigFieldAuth = "auth";
|
|
9
|
+
/** Canonical path "auth.api_key". */
|
|
10
|
+
export const ConfigFieldAuthApiKey = "auth.api_key";
|
|
11
|
+
/** Canonical path "auth.api_key.key". */
|
|
12
|
+
export const ConfigFieldAuthApiKeyKey = "auth.api_key.key";
|
|
13
|
+
/** Canonical path "auth.token_pair". */
|
|
14
|
+
export const ConfigFieldAuthTokenPair = "auth.token_pair";
|
|
15
|
+
/** Canonical path "auth.token_pair.id". */
|
|
16
|
+
export const ConfigFieldAuthTokenPairId = "auth.token_pair.id";
|
|
17
|
+
/** Canonical path "auth.token_pair.secret". */
|
|
18
|
+
export const ConfigFieldAuthTokenPairSecret = "auth.token_pair.secret";
|
|
19
|
+
/** Canonical path "auth.bearer_token". */
|
|
20
|
+
export const ConfigFieldAuthBearerToken = "auth.bearer_token";
|
|
21
|
+
/** Canonical path "auth.bearer_token.token". */
|
|
22
|
+
export const ConfigFieldAuthBearerTokenToken = "auth.bearer_token.token";
|
|
23
|
+
/** Canonical path "auth.oauth_refresh". */
|
|
24
|
+
export const ConfigFieldAuthOauthRefresh = "auth.oauth_refresh";
|
|
25
|
+
/** Canonical path "auth.oauth_refresh.refresh_token". */
|
|
26
|
+
export const ConfigFieldAuthOauthRefreshRefreshToken = "auth.oauth_refresh.refresh_token";
|
|
27
|
+
/** Canonical path "auth.oauth_refresh.client_id". */
|
|
28
|
+
export const ConfigFieldAuthOauthRefreshClientId = "auth.oauth_refresh.client_id";
|
|
29
|
+
/** Canonical path "auth.oauth_refresh.client_secret". */
|
|
30
|
+
export const ConfigFieldAuthOauthRefreshClientSecret = "auth.oauth_refresh.client_secret";
|
|
31
|
+
/** Canonical path "auth.oauth_refresh.jwt_key". */
|
|
32
|
+
export const ConfigFieldAuthOauthRefreshJwtKey = "auth.oauth_refresh.jwt_key";
|
|
33
|
+
/** Canonical path "endpoint". */
|
|
34
|
+
export const ConfigFieldEndpoint = "endpoint";
|
|
35
|
+
/** Canonical path "region". */
|
|
36
|
+
export const ConfigFieldRegion = "region";
|
|
37
|
+
/** Canonical path "scope". */
|
|
38
|
+
export const ConfigFieldScope = "scope";
|
|
39
|
+
/** Canonical path "scope.app_name". */
|
|
40
|
+
export const ConfigFieldScopeAppName = "scope.app_name";
|
|
41
|
+
/** Canonical path "scope.environment". */
|
|
42
|
+
export const ConfigFieldScopeEnvironment = "scope.environment";
|
|
43
|
+
/** Canonical path "scope.organization_id". */
|
|
44
|
+
export const ConfigFieldScopeOrganizationId = "scope.organization_id";
|
|
45
|
+
/** Canonical path "scope.project_id". */
|
|
46
|
+
export const ConfigFieldScopeProjectId = "scope.project_id";
|
|
47
|
+
/** Canonical path "timeout". */
|
|
48
|
+
export const ConfigFieldTimeout = "timeout";
|
|
49
|
+
/** Canonical path "provider". */
|
|
50
|
+
export const ConfigFieldProvider = "provider";
|