@declaw/sdk 1.2.2 → 1.3.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 +24 -0
- package/dist/index.cjs +344 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +162 -7
- package/dist/index.d.ts +162 -7
- package/dist/index.js +339 -8
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -137,7 +137,7 @@ function getDispatcher() {
|
|
|
137
137
|
}
|
|
138
138
|
const undici = await import("undici");
|
|
139
139
|
const connOverride = parseInt(process.env.DECLAW_SDK_CONNECTIONS || "", 10);
|
|
140
|
-
const connections = Number.isFinite(connOverride) && connOverride > 0 ? connOverride :
|
|
140
|
+
const connections = Number.isFinite(connOverride) && connOverride > 0 ? connOverride : 64;
|
|
141
141
|
const streamsOverride = parseInt(process.env.DECLAW_SDK_MAX_CONCURRENT_STREAMS || "", 10);
|
|
142
142
|
const maxConcurrentStreams = Number.isFinite(streamsOverride) && streamsOverride > 0 ? streamsOverride : 1e3;
|
|
143
143
|
return new undici.Agent({
|
|
@@ -154,7 +154,9 @@ function getDispatcher() {
|
|
|
154
154
|
// stream — silently defeating the H2 multiplexing that allowH2 enables.
|
|
155
155
|
// Omitted, H2 sessions default to unlimited concurrent streams (capped
|
|
156
156
|
// by maxConcurrentStreams) and H1.1 fallback defaults to 1 (safe, no
|
|
157
|
-
// head-of-line risk on non-idempotent POSTs).
|
|
157
|
+
// head-of-line risk on non-idempotent POSTs). This is the single
|
|
158
|
+
// biggest burst-latency lever: with pipelining:1 a 100-concurrent burst
|
|
159
|
+
// queued ~36 requests behind the `connections` cap.
|
|
158
160
|
allowH2: true,
|
|
159
161
|
connect: { keepAlive: true, keepAliveInitialDelay: 5e3 }
|
|
160
162
|
});
|
|
@@ -507,7 +509,7 @@ function createInjectionDefenseConfig(opts) {
|
|
|
507
509
|
enabled: opts?.enabled ?? false,
|
|
508
510
|
sensitivity: opts?.sensitivity ?? "medium" /* Medium */,
|
|
509
511
|
action: opts?.action ?? "log_only" /* LogOnly */,
|
|
510
|
-
threshold: opts?.threshold ?? 0.
|
|
512
|
+
threshold: opts?.threshold ?? 0.95,
|
|
511
513
|
domains: opts?.domains,
|
|
512
514
|
judge: opts?.judge,
|
|
513
515
|
injectionMode: opts?.injectionMode
|
|
@@ -534,7 +536,7 @@ function parseInjectionDefenseConfig(data) {
|
|
|
534
536
|
enabled: data.enabled ?? false,
|
|
535
537
|
sensitivity: data.sensitivity ?? "medium" /* Medium */,
|
|
536
538
|
action: data.action ?? "log_only" /* LogOnly */,
|
|
537
|
-
threshold: data.threshold ?? 0.
|
|
539
|
+
threshold: data.threshold ?? 0.95,
|
|
538
540
|
domains: data.domains,
|
|
539
541
|
judge: data.judge ? { enabled: data.judge.enabled ?? false, always: data.judge.always, policy: data.judge.policy } : void 0,
|
|
540
542
|
injectionMode: data.injection_mode ?? data.injectionMode
|
|
@@ -912,14 +914,14 @@ function fullInjectionDefensePolicy(opts) {
|
|
|
912
914
|
injectionDefense: createInjectionDefenseConfig({
|
|
913
915
|
enabled: true,
|
|
914
916
|
action: opts?.action ?? "block",
|
|
915
|
-
threshold: opts?.threshold ?? 0.
|
|
917
|
+
threshold: opts?.threshold ?? 0.95,
|
|
916
918
|
domains: opts?.domains,
|
|
917
919
|
injectionMode: opts?.mode ?? "balanced",
|
|
918
920
|
judge: { enabled: true, always: opts?.alwaysJudge ?? false, policy: opts?.agentPolicy ?? "" }
|
|
919
921
|
}),
|
|
920
922
|
customPolicy: createCustomPolicyConfig({
|
|
921
923
|
enabled: true,
|
|
922
|
-
policyRef: "prompt-injection@
|
|
924
|
+
policyRef: "prompt-injection@v3",
|
|
923
925
|
defaultDeny: false
|
|
924
926
|
})
|
|
925
927
|
});
|
|
@@ -960,7 +962,7 @@ function securityPolicyToJSON(policy) {
|
|
|
960
962
|
action: injDefConfig.action,
|
|
961
963
|
threshold: injDefConfig.threshold
|
|
962
964
|
};
|
|
963
|
-
if (injDefConfig.domains !== void 0) {
|
|
965
|
+
if (injDefConfig.domains !== void 0 && injDefConfig.domains.length > 0) {
|
|
964
966
|
injDef.domains = injDefConfig.domains;
|
|
965
967
|
}
|
|
966
968
|
if (injDefConfig.injectionMode !== void 0) {
|
|
@@ -2072,6 +2074,311 @@ function volumeAttachmentToJSON(att) {
|
|
|
2072
2074
|
return out;
|
|
2073
2075
|
}
|
|
2074
2076
|
|
|
2077
|
+
// src/vault/models.ts
|
|
2078
|
+
function parseVaultScope(data) {
|
|
2079
|
+
const scope = {
|
|
2080
|
+
domainRegex: String(data.domain_regex ?? "")
|
|
2081
|
+
};
|
|
2082
|
+
if (data.injection_type !== void 0 && data.injection_type !== null) {
|
|
2083
|
+
scope.injectionType = String(data.injection_type);
|
|
2084
|
+
}
|
|
2085
|
+
if (data.header_name !== void 0 && data.header_name !== null) {
|
|
2086
|
+
scope.headerName = String(data.header_name);
|
|
2087
|
+
}
|
|
2088
|
+
if (data.value_prefix !== void 0 && data.value_prefix !== null) {
|
|
2089
|
+
scope.valuePrefix = String(data.value_prefix);
|
|
2090
|
+
}
|
|
2091
|
+
if (data.basic_username !== void 0 && data.basic_username !== null) {
|
|
2092
|
+
scope.basicUsername = String(data.basic_username);
|
|
2093
|
+
}
|
|
2094
|
+
if (data.extra_headers !== void 0 && data.extra_headers !== null) {
|
|
2095
|
+
scope.extraHeaders = data.extra_headers;
|
|
2096
|
+
}
|
|
2097
|
+
if (data.query_params !== void 0 && data.query_params !== null) {
|
|
2098
|
+
scope.queryParams = data.query_params;
|
|
2099
|
+
}
|
|
2100
|
+
return scope;
|
|
2101
|
+
}
|
|
2102
|
+
function parseVaultSecret(data) {
|
|
2103
|
+
const secret = {
|
|
2104
|
+
secretId: String(data.secret_id ?? ""),
|
|
2105
|
+
name: String(data.name ?? ""),
|
|
2106
|
+
createdAt: String(data.created_at ?? ""),
|
|
2107
|
+
updatedAt: String(data.updated_at ?? "")
|
|
2108
|
+
};
|
|
2109
|
+
const rawScopes = data.scopes;
|
|
2110
|
+
if (rawScopes && rawScopes.length > 0) {
|
|
2111
|
+
secret.scopes = rawScopes.map(parseVaultScope);
|
|
2112
|
+
}
|
|
2113
|
+
if (data.rotated_at !== void 0 && data.rotated_at !== null) {
|
|
2114
|
+
secret.rotatedAt = String(data.rotated_at);
|
|
2115
|
+
}
|
|
2116
|
+
if (data.rotation_interval_days !== void 0 && data.rotation_interval_days !== null) {
|
|
2117
|
+
secret.rotationIntervalDays = Number(data.rotation_interval_days);
|
|
2118
|
+
}
|
|
2119
|
+
if (data.rotation_due !== void 0 && data.rotation_due !== null) {
|
|
2120
|
+
secret.rotationDue = Boolean(data.rotation_due);
|
|
2121
|
+
}
|
|
2122
|
+
return secret;
|
|
2123
|
+
}
|
|
2124
|
+
function parseVaultPreset(data) {
|
|
2125
|
+
const rawScopes = data.scopes ?? [];
|
|
2126
|
+
const preset = {
|
|
2127
|
+
key: String(data.key ?? ""),
|
|
2128
|
+
name: String(data.name ?? ""),
|
|
2129
|
+
category: String(data.category ?? ""),
|
|
2130
|
+
keyHint: String(data.key_hint ?? ""),
|
|
2131
|
+
scopes: rawScopes.map(parseVaultScope)
|
|
2132
|
+
};
|
|
2133
|
+
if (data.docs_url !== void 0 && data.docs_url !== null) {
|
|
2134
|
+
preset.docsUrl = String(data.docs_url);
|
|
2135
|
+
}
|
|
2136
|
+
return preset;
|
|
2137
|
+
}
|
|
2138
|
+
function vaultScopeToJSON(scope) {
|
|
2139
|
+
const out = {
|
|
2140
|
+
domain_regex: scope.domainRegex
|
|
2141
|
+
};
|
|
2142
|
+
if (scope.injectionType !== void 0) {
|
|
2143
|
+
out.injection_type = scope.injectionType;
|
|
2144
|
+
}
|
|
2145
|
+
if (scope.headerName !== void 0) {
|
|
2146
|
+
out.header_name = scope.headerName;
|
|
2147
|
+
}
|
|
2148
|
+
if (scope.valuePrefix !== void 0) {
|
|
2149
|
+
out.value_prefix = scope.valuePrefix;
|
|
2150
|
+
}
|
|
2151
|
+
if (scope.basicUsername !== void 0) {
|
|
2152
|
+
out.basic_username = scope.basicUsername;
|
|
2153
|
+
}
|
|
2154
|
+
if (scope.extraHeaders !== void 0) {
|
|
2155
|
+
out.extra_headers = scope.extraHeaders;
|
|
2156
|
+
}
|
|
2157
|
+
if (scope.queryParams !== void 0) {
|
|
2158
|
+
out.query_params = scope.queryParams;
|
|
2159
|
+
}
|
|
2160
|
+
return out;
|
|
2161
|
+
}
|
|
2162
|
+
|
|
2163
|
+
// src/vault/vault.ts
|
|
2164
|
+
var DEFAULT_TEAM_NAME = "default";
|
|
2165
|
+
var DEFAULT_ENV_NAME = "prod";
|
|
2166
|
+
var defaultTeamCache = /* @__PURE__ */ new Map();
|
|
2167
|
+
function cacheKey(config) {
|
|
2168
|
+
return `${config.apiUrl}\0${config.apiKey}`;
|
|
2169
|
+
}
|
|
2170
|
+
async function resolveDefaultTeamId(config, create, timeout) {
|
|
2171
|
+
const key = cacheKey(config);
|
|
2172
|
+
const cached = defaultTeamCache.get(key);
|
|
2173
|
+
if (cached !== void 0) return cached;
|
|
2174
|
+
const client = getSharedClient(config);
|
|
2175
|
+
const resp = await client.get("/teams", { timeout });
|
|
2176
|
+
const rows = resp.teams ?? [];
|
|
2177
|
+
let best = null;
|
|
2178
|
+
for (const t of rows) {
|
|
2179
|
+
if (t.name === DEFAULT_TEAM_NAME) {
|
|
2180
|
+
if (best === null || t.created_at < best.created_at) {
|
|
2181
|
+
best = t;
|
|
2182
|
+
}
|
|
2183
|
+
}
|
|
2184
|
+
}
|
|
2185
|
+
if (best !== null) {
|
|
2186
|
+
defaultTeamCache.set(key, best.team_id);
|
|
2187
|
+
return best.team_id;
|
|
2188
|
+
}
|
|
2189
|
+
if (!create) return null;
|
|
2190
|
+
const created = await client.post("/teams", {
|
|
2191
|
+
json: { name: DEFAULT_TEAM_NAME },
|
|
2192
|
+
timeout
|
|
2193
|
+
});
|
|
2194
|
+
defaultTeamCache.set(key, created.team_id);
|
|
2195
|
+
return created.team_id;
|
|
2196
|
+
}
|
|
2197
|
+
async function ensureDefaultEnv(config, teamId, timeout) {
|
|
2198
|
+
const client = getSharedClient(config);
|
|
2199
|
+
const resp = await client.get(
|
|
2200
|
+
`/teams/${encodeURIComponent(teamId)}/environments`,
|
|
2201
|
+
{ timeout }
|
|
2202
|
+
);
|
|
2203
|
+
const rows = resp.environments ?? [];
|
|
2204
|
+
if (rows.some((e) => e.name === DEFAULT_ENV_NAME)) return;
|
|
2205
|
+
try {
|
|
2206
|
+
await client.post(`/teams/${encodeURIComponent(teamId)}/environments`, {
|
|
2207
|
+
json: { name: DEFAULT_ENV_NAME },
|
|
2208
|
+
timeout
|
|
2209
|
+
});
|
|
2210
|
+
} catch {
|
|
2211
|
+
const resp2 = await client.get(
|
|
2212
|
+
`/teams/${encodeURIComponent(teamId)}/environments`,
|
|
2213
|
+
{ timeout }
|
|
2214
|
+
);
|
|
2215
|
+
const rows2 = resp2.environments ?? [];
|
|
2216
|
+
if (rows2.some((e) => e.name === DEFAULT_ENV_NAME)) return;
|
|
2217
|
+
throw new Error(`Failed to ensure default environment "${DEFAULT_ENV_NAME}" on team ${teamId}`);
|
|
2218
|
+
}
|
|
2219
|
+
}
|
|
2220
|
+
async function expandVaultRefs(config, refs, timeout) {
|
|
2221
|
+
if (Object.keys(refs).length === 0) return refs;
|
|
2222
|
+
const needsTeam = Object.values(refs).some((v) => !v.startsWith("vault://"));
|
|
2223
|
+
if (!needsTeam) return refs;
|
|
2224
|
+
const teamId = await resolveDefaultTeamId(config, false, timeout);
|
|
2225
|
+
if (teamId === null) {
|
|
2226
|
+
throw new Error("vault_refs given but no vault secrets exist for this account");
|
|
2227
|
+
}
|
|
2228
|
+
const out = {};
|
|
2229
|
+
for (const [envVar, ref] of Object.entries(refs)) {
|
|
2230
|
+
out[envVar] = ref.startsWith("vault://") ? ref : `vault://${teamId}/${DEFAULT_ENV_NAME}/${ref}`;
|
|
2231
|
+
}
|
|
2232
|
+
return out;
|
|
2233
|
+
}
|
|
2234
|
+
function buildConfig(opts) {
|
|
2235
|
+
return new ConnectionConfig({
|
|
2236
|
+
apiKey: opts?.apiKey,
|
|
2237
|
+
domain: opts?.domain,
|
|
2238
|
+
apiUrl: opts?.apiUrl,
|
|
2239
|
+
requestTimeout: opts?.requestTimeout
|
|
2240
|
+
});
|
|
2241
|
+
}
|
|
2242
|
+
var Vault = class _Vault {
|
|
2243
|
+
// -------------------------------------------------------------------------
|
|
2244
|
+
// Secrets
|
|
2245
|
+
// -------------------------------------------------------------------------
|
|
2246
|
+
/**
|
|
2247
|
+
* Store a secret's value (server-side, in OpenBao) plus its injection
|
|
2248
|
+
* scopes, under the auto-provisioned default team + "prod" environment.
|
|
2249
|
+
* Returns metadata only — the value is never echoed.
|
|
2250
|
+
*
|
|
2251
|
+
* POST /teams/{teamId}/vault/secrets
|
|
2252
|
+
*/
|
|
2253
|
+
static async createSecret(input, opts) {
|
|
2254
|
+
const config = buildConfig(opts);
|
|
2255
|
+
const teamId = await resolveDefaultTeamId(config, true, opts?.requestTimeout);
|
|
2256
|
+
if (teamId === null) throw new Error("Failed to resolve or create default team");
|
|
2257
|
+
await ensureDefaultEnv(config, teamId, opts?.requestTimeout);
|
|
2258
|
+
const body = {
|
|
2259
|
+
environment: DEFAULT_ENV_NAME,
|
|
2260
|
+
value: input.value
|
|
2261
|
+
};
|
|
2262
|
+
if (input.name) body.name = input.name;
|
|
2263
|
+
if (input.provider) body.provider = input.provider;
|
|
2264
|
+
if (input.scopes && input.scopes.length > 0) {
|
|
2265
|
+
body.scopes = input.scopes.map(vaultScopeToJSON);
|
|
2266
|
+
}
|
|
2267
|
+
if (input.rotationIntervalDays && input.rotationIntervalDays > 0) {
|
|
2268
|
+
body.rotation_interval_days = input.rotationIntervalDays;
|
|
2269
|
+
}
|
|
2270
|
+
const client = getSharedClient(config);
|
|
2271
|
+
const resp = await client.post(
|
|
2272
|
+
`/teams/${encodeURIComponent(teamId)}/vault/secrets`,
|
|
2273
|
+
{ json: body, timeout: opts?.requestTimeout }
|
|
2274
|
+
);
|
|
2275
|
+
return parseVaultSecret(resp);
|
|
2276
|
+
}
|
|
2277
|
+
/**
|
|
2278
|
+
* List secret metadata for the default team. Returns an empty array if no
|
|
2279
|
+
* default team has been provisioned yet.
|
|
2280
|
+
*
|
|
2281
|
+
* GET /teams/{teamId}/vault/secrets -> {secrets}
|
|
2282
|
+
*/
|
|
2283
|
+
static async listSecrets(opts) {
|
|
2284
|
+
const config = buildConfig(opts);
|
|
2285
|
+
const teamId = await resolveDefaultTeamId(config, false, opts?.requestTimeout);
|
|
2286
|
+
if (teamId === null) return [];
|
|
2287
|
+
const client = getSharedClient(config);
|
|
2288
|
+
const resp = await client.get(
|
|
2289
|
+
`/teams/${encodeURIComponent(teamId)}/vault/secrets`,
|
|
2290
|
+
{ timeout: opts?.requestTimeout }
|
|
2291
|
+
);
|
|
2292
|
+
const rows = resp.secrets ?? [];
|
|
2293
|
+
return rows.map(parseVaultSecret);
|
|
2294
|
+
}
|
|
2295
|
+
/**
|
|
2296
|
+
* Replace a secret's value by name (server-side); scopes are unchanged.
|
|
2297
|
+
*
|
|
2298
|
+
* POST /teams/{teamId}/vault/secrets/{secretId}/rotate {value}
|
|
2299
|
+
*/
|
|
2300
|
+
static async rotateSecret(name, value, opts) {
|
|
2301
|
+
const config = buildConfig(opts);
|
|
2302
|
+
const teamId = await resolveDefaultTeamId(config, false, opts?.requestTimeout);
|
|
2303
|
+
if (teamId === null) throw new Error(`vault secret "${name}" not found`);
|
|
2304
|
+
const secretId = await _Vault._resolveSecretId(config, teamId, name, opts?.requestTimeout);
|
|
2305
|
+
const client = getSharedClient(config);
|
|
2306
|
+
await client.post(
|
|
2307
|
+
`/teams/${encodeURIComponent(teamId)}/vault/secrets/${encodeURIComponent(secretId)}/rotate`,
|
|
2308
|
+
{ json: { value }, timeout: opts?.requestTimeout }
|
|
2309
|
+
);
|
|
2310
|
+
}
|
|
2311
|
+
/**
|
|
2312
|
+
* Delete a secret by name — metadata and stored value.
|
|
2313
|
+
*
|
|
2314
|
+
* DELETE /teams/{teamId}/vault/secrets/{secretId}
|
|
2315
|
+
*/
|
|
2316
|
+
static async deleteSecret(name, opts) {
|
|
2317
|
+
const config = buildConfig(opts);
|
|
2318
|
+
const teamId = await resolveDefaultTeamId(config, false, opts?.requestTimeout);
|
|
2319
|
+
if (teamId === null) throw new Error(`vault secret "${name}" not found`);
|
|
2320
|
+
const secretId = await _Vault._resolveSecretId(config, teamId, name, opts?.requestTimeout);
|
|
2321
|
+
const client = getSharedClient(config);
|
|
2322
|
+
await client.delete(
|
|
2323
|
+
`/teams/${encodeURIComponent(teamId)}/vault/secrets/${encodeURIComponent(secretId)}`,
|
|
2324
|
+
{ timeout: opts?.requestTimeout }
|
|
2325
|
+
);
|
|
2326
|
+
}
|
|
2327
|
+
/**
|
|
2328
|
+
* Replace a secret's injection scopes by name; the value is unchanged. Use
|
|
2329
|
+
* this to change a secret's destination(s) or injection format in place
|
|
2330
|
+
* instead of delete + recreate. At least one scope is required.
|
|
2331
|
+
*
|
|
2332
|
+
* POST /teams/{teamId}/vault/secrets/{secretId}/scopes
|
|
2333
|
+
*/
|
|
2334
|
+
static async updateScopes(name, scopes, opts) {
|
|
2335
|
+
if (!scopes || scopes.length === 0) {
|
|
2336
|
+
throw new Error("at least one scope is required");
|
|
2337
|
+
}
|
|
2338
|
+
const config = buildConfig(opts);
|
|
2339
|
+
const teamId = await resolveDefaultTeamId(config, false, opts?.requestTimeout);
|
|
2340
|
+
if (teamId === null) throw new Error(`vault secret "${name}" not found`);
|
|
2341
|
+
const secretId = await _Vault._resolveSecretId(config, teamId, name, opts?.requestTimeout);
|
|
2342
|
+
const client = getSharedClient(config);
|
|
2343
|
+
await client.post(
|
|
2344
|
+
`/teams/${encodeURIComponent(teamId)}/vault/secrets/${encodeURIComponent(secretId)}/scopes`,
|
|
2345
|
+
{ json: { scopes: scopes.map(vaultScopeToJSON) }, timeout: opts?.requestTimeout }
|
|
2346
|
+
);
|
|
2347
|
+
}
|
|
2348
|
+
// -------------------------------------------------------------------------
|
|
2349
|
+
// Presets
|
|
2350
|
+
// -------------------------------------------------------------------------
|
|
2351
|
+
/**
|
|
2352
|
+
* List built-in provider preset catalog (templates only, no secret material).
|
|
2353
|
+
*
|
|
2354
|
+
* GET /vault/presets -> {presets}
|
|
2355
|
+
*/
|
|
2356
|
+
static async listPresets(opts) {
|
|
2357
|
+
const client = getSharedClient(buildConfig(opts));
|
|
2358
|
+
const resp = await client.get("/vault/presets", {
|
|
2359
|
+
timeout: opts?.requestTimeout
|
|
2360
|
+
});
|
|
2361
|
+
const rows = resp.presets ?? [];
|
|
2362
|
+
return rows.map(parseVaultPreset);
|
|
2363
|
+
}
|
|
2364
|
+
// -------------------------------------------------------------------------
|
|
2365
|
+
// Internal helpers
|
|
2366
|
+
// -------------------------------------------------------------------------
|
|
2367
|
+
/** Maps a secret name to its id within the given team. */
|
|
2368
|
+
static async _resolveSecretId(config, teamId, name, timeout) {
|
|
2369
|
+
const client = getSharedClient(config);
|
|
2370
|
+
const resp = await client.get(
|
|
2371
|
+
`/teams/${encodeURIComponent(teamId)}/vault/secrets`,
|
|
2372
|
+
{ timeout }
|
|
2373
|
+
);
|
|
2374
|
+
const rows = resp.secrets ?? [];
|
|
2375
|
+
for (const s of rows) {
|
|
2376
|
+
if (s.name === name) return String(s.secret_id ?? "");
|
|
2377
|
+
}
|
|
2378
|
+
throw new Error(`vault secret "${name}" not found`);
|
|
2379
|
+
}
|
|
2380
|
+
};
|
|
2381
|
+
|
|
2075
2382
|
// src/sandbox/sandbox.ts
|
|
2076
2383
|
var DEFAULT_TEMPLATE = "base";
|
|
2077
2384
|
var DEFAULT_TIMEOUT = 300;
|
|
@@ -2217,6 +2524,9 @@ var Sandbox = class _Sandbox {
|
|
|
2217
2524
|
if (opts?.envs) {
|
|
2218
2525
|
body.envs = opts.envs;
|
|
2219
2526
|
}
|
|
2527
|
+
if (opts?.vaultRefs) {
|
|
2528
|
+
body.vault_refs = await expandVaultRefs(config, opts.vaultRefs, opts.requestTimeout);
|
|
2529
|
+
}
|
|
2220
2530
|
if (opts?.network) {
|
|
2221
2531
|
body.network = networkOptsToJSON(opts.network);
|
|
2222
2532
|
} else if (opts?.allowInternetAccess === false) {
|
|
@@ -3120,7 +3430,16 @@ function assertValidVolumeId3(id) {
|
|
|
3120
3430
|
}
|
|
3121
3431
|
}
|
|
3122
3432
|
var Volumes = class {
|
|
3123
|
-
/**
|
|
3433
|
+
/**
|
|
3434
|
+
* Create a volume named `name`, optionally populated with `data`.
|
|
3435
|
+
*
|
|
3436
|
+
* `POST /volumes` is the canonical create endpoint. With `data` (a gzip tar.gz)
|
|
3437
|
+
* the body is ingested into a new file-granular volume (or a legacy tarball
|
|
3438
|
+
* blob if no file-granular backend is configured). Creating an empty volume
|
|
3439
|
+
* (no `data`, or an empty buffer) requires a file-granular backend.
|
|
3440
|
+
* `empty(name)` / `ingest(name, data)` remain available for explicit,
|
|
3441
|
+
* backend-specific control.
|
|
3442
|
+
*/
|
|
3124
3443
|
static async create(name, data, opts) {
|
|
3125
3444
|
if (!name) {
|
|
3126
3445
|
throw new InvalidArgumentError("volume name is required");
|
|
@@ -3132,6 +3451,13 @@ var Volumes = class {
|
|
|
3132
3451
|
requestTimeout: opts?.requestTimeout
|
|
3133
3452
|
});
|
|
3134
3453
|
const client = getSharedClient(config);
|
|
3454
|
+
if (data === void 0 || data.byteLength === 0) {
|
|
3455
|
+
const resp2 = await client.post("/volumes", {
|
|
3456
|
+
params: { name },
|
|
3457
|
+
timeout: opts?.requestTimeout
|
|
3458
|
+
});
|
|
3459
|
+
return parseVolumeInfo(resp2);
|
|
3460
|
+
}
|
|
3135
3461
|
const body = data instanceof Uint8Array ? data : new Uint8Array(data);
|
|
3136
3462
|
const resp = await client.post("/volumes", {
|
|
3137
3463
|
params: { name },
|
|
@@ -3435,6 +3761,7 @@ export {
|
|
|
3435
3761
|
TemplateError,
|
|
3436
3762
|
TimeoutError,
|
|
3437
3763
|
TransformDirection,
|
|
3764
|
+
Vault,
|
|
3438
3765
|
VolumeFiles,
|
|
3439
3766
|
VolumeLocks,
|
|
3440
3767
|
Volumes,
|
|
@@ -3486,6 +3813,9 @@ export {
|
|
|
3486
3813
|
parseSnapshotInfo,
|
|
3487
3814
|
parseTemplateBuildStatus,
|
|
3488
3815
|
parseToxicityConfig,
|
|
3816
|
+
parseVaultPreset,
|
|
3817
|
+
parseVaultScope,
|
|
3818
|
+
parseVaultSecret,
|
|
3489
3819
|
parseVolumeInfo,
|
|
3490
3820
|
parseWriteInfo,
|
|
3491
3821
|
requiresTlsInterception,
|
|
@@ -3493,6 +3823,7 @@ export {
|
|
|
3493
3823
|
securityPolicyToJSON,
|
|
3494
3824
|
toxicityConfigToJSON,
|
|
3495
3825
|
validateNetworkEntry,
|
|
3826
|
+
vaultScopeToJSON,
|
|
3496
3827
|
volumeAttachmentToJSON
|
|
3497
3828
|
};
|
|
3498
3829
|
//# sourceMappingURL=index.js.map
|