@giselles-ai/sandkit 0.1.0 → 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/README.md +5 -1
- package/dist/adapters/drizzle.d.ts +2 -2
- package/dist/adapters/memory.d.ts +2 -2
- package/dist/adapters/sqlite-bun.d.ts +2 -2
- package/dist/{chunk-FSDVHEEX.js → chunk-2M2AZUOC.js} +2 -2
- package/dist/chunk-5MXHFOJH.js +50 -0
- package/dist/chunk-5MXHFOJH.js.map +1 -0
- package/dist/{chunk-7DLK7LOM.js → chunk-6GHZO3Y5.js} +2 -2
- package/dist/{chunk-VISDS5T7.js → chunk-NKTNTBOY.js} +97 -4
- package/dist/chunk-NKTNTBOY.js.map +1 -0
- package/dist/{chunk-REGOUXVI.js → chunk-UEAKE56H.js} +2 -2
- package/dist/index.d.ts +5 -5
- package/dist/index.js +5 -5
- package/dist/integrations/mock.d.ts +3 -3
- package/dist/integrations/mock.js +1 -1
- package/dist/integrations/vercel.d.ts +3 -3
- package/dist/integrations/vercel.js +19 -7
- package/dist/integrations/vercel.js.map +1 -1
- package/dist/policies/ai-gateway.d.ts +1 -1
- package/dist/policies/ai-gateway.js +2 -2
- package/dist/policies/codex.d.ts +1 -1
- package/dist/policies/codex.js +2 -2
- package/dist/policies/gemini.d.ts +1 -1
- package/dist/policies/gemini.js +2 -2
- package/dist/{types-BEKQnjeb.d.ts → types-B5N9o-ew.d.ts} +2 -2
- package/dist/{types-Cy36bS1j.d.ts → types-BRMAvcWc.d.ts} +1 -1
- package/dist/{types-BCgprbo8.d.ts → types-Dpr_BkF9.d.ts} +3 -0
- package/package.json +1 -1
- package/dist/chunk-VISDS5T7.js.map +0 -1
- package/dist/chunk-XM4HGRXW.js +0 -37
- package/dist/chunk-XM4HGRXW.js.map +0 -1
- /package/dist/{chunk-FSDVHEEX.js.map → chunk-2M2AZUOC.js.map} +0 -0
- /package/dist/{chunk-7DLK7LOM.js.map → chunk-6GHZO3Y5.js.map} +0 -0
- /package/dist/{chunk-REGOUXVI.js.map → chunk-UEAKE56H.js.map} +0 -0
package/README.md
CHANGED
|
@@ -137,7 +137,10 @@ If you do not pass `database`, Sandkit defaults to the in-memory adapter. That d
|
|
|
137
137
|
|
|
138
138
|
- `codex()` reads `CODEX_API_KEY`
|
|
139
139
|
- `gemini()` reads `GEMINI_API_KEY`
|
|
140
|
-
- `github()` reads `GITHUB_TOKEN`
|
|
140
|
+
- `github()` reads `GITHUB_TOKEN` and maps it through Vercel Sandbox firewall transforms:
|
|
141
|
+
- `Authorization: Basic <base64(x-access-token:<token>)>` on requests to `github.com`, intended for Git-over-HTTPS operations
|
|
142
|
+
- `Authorization: Bearer <token>` on requests to `api.github.com`
|
|
143
|
+
- no Authorization header for `*.githubusercontent.com`
|
|
141
144
|
- `aiGateway()` reads `AI_GATEWAY_API_KEY` from host env and allows the hostname (plus wildcard) from `AI_GATEWAY_BASE_URL`.
|
|
142
145
|
`AI_GATEWAY_BASE_URL` ports are ignored for allow-listing; only host/domain matches are used.
|
|
143
146
|
|
|
@@ -157,6 +160,7 @@ npx @giselles-ai/sandkit generate
|
|
|
157
160
|
|
|
158
161
|
## Examples
|
|
159
162
|
|
|
163
|
+
- `examples/workflow-hello-git`
|
|
160
164
|
- `examples/sandbox-openclaw`
|
|
161
165
|
- `smoke/drizzle-sample`
|
|
162
166
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { SQLWrapper } from 'drizzle-orm';
|
|
2
|
-
import { a as SandkitAdapter } from '../types-
|
|
3
|
-
import '../types-
|
|
2
|
+
import { a as SandkitAdapter } from '../types-BRMAvcWc.js';
|
|
3
|
+
import '../types-Dpr_BkF9.js';
|
|
4
4
|
|
|
5
5
|
interface DrizzleWorkspaceTableShape {
|
|
6
6
|
readonly id: SQLWrapper;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Database } from 'bun:sqlite';
|
|
2
|
-
import { a as SandkitAdapter } from '../types-
|
|
3
|
-
import '../types-
|
|
2
|
+
import { a as SandkitAdapter } from '../types-BRMAvcWc.js';
|
|
3
|
+
import '../types-Dpr_BkF9.js';
|
|
4
4
|
|
|
5
5
|
declare function createBunSqliteAdapter(db: Database): SandkitAdapter;
|
|
6
6
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
allowService
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-NKTNTBOY.js";
|
|
4
4
|
|
|
5
5
|
// src/policies/codex.ts
|
|
6
6
|
var CODEX_DOMAINS = ["api.openai.com", "*.openai.com", "openrouter.ai", "*.openrouter.ai"];
|
|
@@ -42,4 +42,4 @@ export {
|
|
|
42
42
|
codex,
|
|
43
43
|
allowCodex
|
|
44
44
|
};
|
|
45
|
-
//# sourceMappingURL=chunk-
|
|
45
|
+
//# sourceMappingURL=chunk-2M2AZUOC.js.map
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// src/policies/github.ts
|
|
2
|
+
var GITHUB_DOMAINS = ["github.com", "api.github.com", "*.githubusercontent.com"];
|
|
3
|
+
function resolveGithubCredential(options) {
|
|
4
|
+
if (options === void 0) {
|
|
5
|
+
return { kind: "default" };
|
|
6
|
+
}
|
|
7
|
+
if (typeof options.token !== "string" || options.token.trim().length === 0) {
|
|
8
|
+
throw new Error(
|
|
9
|
+
'github(...) explicit override requires a non-empty "token". Omit the options object to use GITHUB_TOKEN.'
|
|
10
|
+
);
|
|
11
|
+
}
|
|
12
|
+
return { kind: "value", value: options.token };
|
|
13
|
+
}
|
|
14
|
+
function resolveGithubDefaultApiKey() {
|
|
15
|
+
return process.env.GITHUB_TOKEN;
|
|
16
|
+
}
|
|
17
|
+
function github(options) {
|
|
18
|
+
const credential = resolveGithubCredential(options);
|
|
19
|
+
return {
|
|
20
|
+
id: "github",
|
|
21
|
+
name: "GitHub",
|
|
22
|
+
description: "Allow requests to github.com and api.github.com through Vercel Sandbox firewall header transforms.",
|
|
23
|
+
domains: GITHUB_DOMAINS,
|
|
24
|
+
domainHeaders: {
|
|
25
|
+
"github.com": [
|
|
26
|
+
{
|
|
27
|
+
headerName: "authorization",
|
|
28
|
+
valuePrefix: "Basic ",
|
|
29
|
+
credentialPrefix: "x-access-token:",
|
|
30
|
+
valueEncoding: "base64",
|
|
31
|
+
credential
|
|
32
|
+
}
|
|
33
|
+
],
|
|
34
|
+
"api.github.com": [
|
|
35
|
+
{
|
|
36
|
+
headerName: "authorization",
|
|
37
|
+
valuePrefix: "Bearer ",
|
|
38
|
+
credential
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
"*.githubusercontent.com": []
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export {
|
|
47
|
+
resolveGithubDefaultApiKey,
|
|
48
|
+
github
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=chunk-5MXHFOJH.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/policies/github.ts"],"sourcesContent":["import type { PolicyServiceDescriptor } from \"./types.ts\";\n\nconst GITHUB_DOMAINS = [\"github.com\", \"api.github.com\", \"*.githubusercontent.com\"] as const;\n\nexport interface GithubOptions {\n readonly token?: string;\n}\n\nfunction resolveGithubCredential(options?: GithubOptions) {\n if (options === undefined) {\n return { kind: \"default\" } as const;\n }\n\n if (typeof options.token !== \"string\" || options.token.trim().length === 0) {\n throw new Error(\n 'github(...) explicit override requires a non-empty \"token\". Omit the options object to use GITHUB_TOKEN.',\n );\n }\n\n return { kind: \"value\", value: options.token } as const;\n}\n\nexport function resolveGithubDefaultApiKey(): string | undefined {\n return process.env.GITHUB_TOKEN;\n}\n\nexport function github(options?: GithubOptions): PolicyServiceDescriptor {\n const credential = resolveGithubCredential(options);\n\n return {\n id: \"github\",\n name: \"GitHub\",\n description:\n \"Allow requests to github.com and api.github.com through Vercel Sandbox firewall header transforms.\",\n domains: GITHUB_DOMAINS,\n domainHeaders: {\n \"github.com\": [\n {\n headerName: \"authorization\",\n valuePrefix: \"Basic \",\n credentialPrefix: \"x-access-token:\",\n valueEncoding: \"base64\",\n credential,\n },\n ],\n \"api.github.com\": [\n {\n headerName: \"authorization\",\n valuePrefix: \"Bearer \",\n credential,\n },\n ],\n \"*.githubusercontent.com\": [],\n },\n };\n}\n"],"mappings":";AAEA,IAAM,iBAAiB,CAAC,cAAc,kBAAkB,yBAAyB;AAMjF,SAAS,wBAAwB,SAAyB;AACxD,MAAI,YAAY,QAAW;AACzB,WAAO,EAAE,MAAM,UAAU;AAAA,EAC3B;AAEA,MAAI,OAAO,QAAQ,UAAU,YAAY,QAAQ,MAAM,KAAK,EAAE,WAAW,GAAG;AAC1E,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,MAAM,SAAS,OAAO,QAAQ,MAAM;AAC/C;AAEO,SAAS,6BAAiD;AAC/D,SAAO,QAAQ,IAAI;AACrB;AAEO,SAAS,OAAO,SAAkD;AACvE,QAAM,aAAa,wBAAwB,OAAO;AAElD,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aACE;AAAA,IACF,SAAS;AAAA,IACT,eAAe;AAAA,MACb,cAAc;AAAA,QACZ;AAAA,UACE,YAAY;AAAA,UACZ,aAAa;AAAA,UACb,kBAAkB;AAAA,UAClB,eAAe;AAAA,UACf;AAAA,QACF;AAAA,MACF;AAAA,MACA,kBAAkB;AAAA,QAChB;AAAA,UACE,YAAY;AAAA,UACZ,aAAa;AAAA,UACb;AAAA,QACF;AAAA,MACF;AAAA,MACA,2BAA2B,CAAC;AAAA,IAC9B;AAAA,EACF;AACF;","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
allowService
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-NKTNTBOY.js";
|
|
4
4
|
|
|
5
5
|
// src/policies/gemini.ts
|
|
6
6
|
var GEMINI_DOMAINS = ["ai.google.dev", "*.ai.google.dev", "generativelanguage.googleapis.com"];
|
|
@@ -41,4 +41,4 @@ export {
|
|
|
41
41
|
gemini,
|
|
42
42
|
allowGemini
|
|
43
43
|
};
|
|
44
|
-
//# sourceMappingURL=chunk-
|
|
44
|
+
//# sourceMappingURL=chunk-6GHZO3Y5.js.map
|
|
@@ -22,12 +22,18 @@ function normalizeCredentialSource(source) {
|
|
|
22
22
|
}
|
|
23
23
|
function normalizeHeaderTransform(header) {
|
|
24
24
|
const headerName = header.headerName.trim().toLowerCase();
|
|
25
|
+
const valueEncoding = header.valueEncoding ?? "plain";
|
|
25
26
|
if (!headerName) {
|
|
26
27
|
throw new Error("Policy header transform must include a header name.");
|
|
27
28
|
}
|
|
29
|
+
if (valueEncoding !== "plain" && valueEncoding !== "base64") {
|
|
30
|
+
throw new Error(`Policy header transform for "${headerName}" has unsupported valueEncoding.`);
|
|
31
|
+
}
|
|
28
32
|
return {
|
|
29
33
|
headerName,
|
|
30
34
|
valuePrefix: header.valuePrefix,
|
|
35
|
+
credentialPrefix: header.credentialPrefix,
|
|
36
|
+
valueEncoding,
|
|
31
37
|
credential: normalizeCredentialSource(header.credential)
|
|
32
38
|
};
|
|
33
39
|
}
|
|
@@ -46,12 +52,26 @@ function normalizeService(service) {
|
|
|
46
52
|
if (domains.length === 0) {
|
|
47
53
|
throw new Error(`Policy service "${id}" must declare at least one domain.`);
|
|
48
54
|
}
|
|
55
|
+
const normalizedDomainHeaders = service.domainHeaders === void 0 ? void 0 : Object.fromEntries(
|
|
56
|
+
Object.entries(service.domainHeaders).map(([domain, headers]) => [
|
|
57
|
+
domain.trim(),
|
|
58
|
+
headers.map((header) => normalizeHeaderTransform(header))
|
|
59
|
+
]).filter(([domain]) => Boolean(domain))
|
|
60
|
+
);
|
|
61
|
+
for (const domain of Object.keys(normalizedDomainHeaders ?? {})) {
|
|
62
|
+
if (!domains.includes(domain)) {
|
|
63
|
+
throw new Error(
|
|
64
|
+
`Policy service "${id}" defines domainHeaders for "${domain}" but does not declare that domain.`
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
49
68
|
return {
|
|
50
69
|
id,
|
|
51
70
|
name,
|
|
52
71
|
description: service.description?.trim() || void 0,
|
|
53
72
|
domains,
|
|
54
|
-
headers: service.headers?.map((header) => normalizeHeaderTransform(header))
|
|
73
|
+
headers: service.headers?.map((header) => normalizeHeaderTransform(header)),
|
|
74
|
+
domainHeaders: normalizedDomainHeaders
|
|
55
75
|
};
|
|
56
76
|
}
|
|
57
77
|
function normalizeServices(services) {
|
|
@@ -104,8 +124,22 @@ function redactWorkspacePolicy(policy) {
|
|
|
104
124
|
headers: service.headers?.map((header) => ({
|
|
105
125
|
headerName: header.headerName,
|
|
106
126
|
valuePrefix: header.valuePrefix,
|
|
127
|
+
credentialPrefix: header.credentialPrefix,
|
|
128
|
+
valueEncoding: header.valueEncoding,
|
|
107
129
|
credential: header.credential.kind === "value" ? { kind: "redacted" } : header.credential
|
|
108
|
-
}))
|
|
130
|
+
})),
|
|
131
|
+
domainHeaders: service.domainHeaders === void 0 ? void 0 : Object.fromEntries(
|
|
132
|
+
Object.entries(service.domainHeaders).map(([domain, headers]) => [
|
|
133
|
+
domain,
|
|
134
|
+
headers.map((header) => ({
|
|
135
|
+
headerName: header.headerName,
|
|
136
|
+
valuePrefix: header.valuePrefix,
|
|
137
|
+
credentialPrefix: header.credentialPrefix,
|
|
138
|
+
valueEncoding: header.valueEncoding,
|
|
139
|
+
credential: header.credential.kind === "value" ? { kind: "redacted" } : header.credential
|
|
140
|
+
}))
|
|
141
|
+
])
|
|
142
|
+
)
|
|
109
143
|
}))
|
|
110
144
|
};
|
|
111
145
|
}
|
|
@@ -121,6 +155,15 @@ function assertWorkspacePolicyIsDurable(policy) {
|
|
|
121
155
|
);
|
|
122
156
|
}
|
|
123
157
|
}
|
|
158
|
+
for (const headers of Object.values(service.domainHeaders ?? {})) {
|
|
159
|
+
for (const header of headers) {
|
|
160
|
+
if (header.credential.kind === "value") {
|
|
161
|
+
throw new Error(
|
|
162
|
+
`Workspace policy for service "${service.id}" contains an explicit secret and cannot be stored durably.`
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
124
167
|
}
|
|
125
168
|
}
|
|
126
169
|
function parseWorkspacePolicy(value) {
|
|
@@ -158,6 +201,8 @@ function parseWorkspacePolicy(value) {
|
|
|
158
201
|
return normalizeHeaderTransform({
|
|
159
202
|
headerName: header.headerName,
|
|
160
203
|
valuePrefix: typeof header.valuePrefix === "string" ? header.valuePrefix : void 0,
|
|
204
|
+
credentialPrefix: typeof header.credentialPrefix === "string" ? header.credentialPrefix : void 0,
|
|
205
|
+
valueEncoding: header.valueEncoding === "base64" || header.valueEncoding === "plain" ? header.valueEncoding : void 0,
|
|
161
206
|
credential: {
|
|
162
207
|
kind: "default"
|
|
163
208
|
}
|
|
@@ -167,6 +212,8 @@ function parseWorkspacePolicy(value) {
|
|
|
167
212
|
return normalizeHeaderTransform({
|
|
168
213
|
headerName: header.headerName,
|
|
169
214
|
valuePrefix: typeof header.valuePrefix === "string" ? header.valuePrefix : void 0,
|
|
215
|
+
credentialPrefix: typeof header.credentialPrefix === "string" ? header.credentialPrefix : void 0,
|
|
216
|
+
valueEncoding: header.valueEncoding === "base64" || header.valueEncoding === "plain" ? header.valueEncoding : void 0,
|
|
170
217
|
credential: { kind: "redacted" }
|
|
171
218
|
});
|
|
172
219
|
}
|
|
@@ -175,12 +222,58 @@ function parseWorkspacePolicy(value) {
|
|
|
175
222
|
);
|
|
176
223
|
});
|
|
177
224
|
})();
|
|
225
|
+
const domainHeaders = service.domainHeaders === void 0 ? void 0 : (() => {
|
|
226
|
+
if (!isRecord(service.domainHeaders)) {
|
|
227
|
+
throw new Error(`service at index ${index} has invalid domain headers`);
|
|
228
|
+
}
|
|
229
|
+
return Object.fromEntries(
|
|
230
|
+
Object.entries(service.domainHeaders).map(([domain, rawHeaders]) => {
|
|
231
|
+
if (!isRecordArray(rawHeaders)) {
|
|
232
|
+
throw new Error(
|
|
233
|
+
`service at index ${index} has invalid domain headers for ${domain}`
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
return [
|
|
237
|
+
domain,
|
|
238
|
+
rawHeaders.map((header, headerIndex) => {
|
|
239
|
+
if (typeof header.headerName !== "string" || !isRecord(header.credential) || typeof header.credential.kind !== "string") {
|
|
240
|
+
throw new Error(
|
|
241
|
+
`service at index ${index} has invalid domain header transform for ${domain} at ${headerIndex}`
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
if (header.credential.kind === "default") {
|
|
245
|
+
return normalizeHeaderTransform({
|
|
246
|
+
headerName: header.headerName,
|
|
247
|
+
valuePrefix: typeof header.valuePrefix === "string" ? header.valuePrefix : void 0,
|
|
248
|
+
credentialPrefix: typeof header.credentialPrefix === "string" ? header.credentialPrefix : void 0,
|
|
249
|
+
valueEncoding: header.valueEncoding === "base64" || header.valueEncoding === "plain" ? header.valueEncoding : void 0,
|
|
250
|
+
credential: { kind: "default" }
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
if (header.credential.kind === "redacted") {
|
|
254
|
+
return normalizeHeaderTransform({
|
|
255
|
+
headerName: header.headerName,
|
|
256
|
+
valuePrefix: typeof header.valuePrefix === "string" ? header.valuePrefix : void 0,
|
|
257
|
+
credentialPrefix: typeof header.credentialPrefix === "string" ? header.credentialPrefix : void 0,
|
|
258
|
+
valueEncoding: header.valueEncoding === "base64" || header.valueEncoding === "plain" ? header.valueEncoding : void 0,
|
|
259
|
+
credential: { kind: "redacted" }
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
throw new Error(
|
|
263
|
+
`service at index ${index} contains a non-durable credential source in domain headers`
|
|
264
|
+
);
|
|
265
|
+
})
|
|
266
|
+
];
|
|
267
|
+
})
|
|
268
|
+
);
|
|
269
|
+
})();
|
|
178
270
|
return normalizeService({
|
|
179
271
|
id: service.id,
|
|
180
272
|
name: service.name,
|
|
181
273
|
description: typeof service.description === "string" ? service.description : void 0,
|
|
182
274
|
domains: service.domains,
|
|
183
|
-
headers
|
|
275
|
+
headers,
|
|
276
|
+
domainHeaders
|
|
184
277
|
});
|
|
185
278
|
});
|
|
186
279
|
return allowServices(services);
|
|
@@ -199,4 +292,4 @@ export {
|
|
|
199
292
|
assertWorkspacePolicyIsDurable,
|
|
200
293
|
parseWorkspacePolicy
|
|
201
294
|
};
|
|
202
|
-
//# sourceMappingURL=chunk-
|
|
295
|
+
//# sourceMappingURL=chunk-NKTNTBOY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/policies/dsl.ts"],"sourcesContent":["import type { JsonValue } from \"../types.ts\";\nimport type {\n PolicyServiceCredentialSource,\n PolicyServiceDescriptor,\n PolicyServiceHeaderTransform,\n WorkspacePolicy,\n} from \"./types.ts\";\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isStringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.every((entry) => typeof entry === \"string\");\n}\n\nfunction isRecordArray(value: unknown): value is Record<string, unknown>[] {\n return Array.isArray(value) && value.every((entry) => isRecord(entry));\n}\n\nfunction normalizeCredentialSource(\n source: PolicyServiceCredentialSource,\n): PolicyServiceCredentialSource {\n if (source.kind === \"default\") {\n return { kind: \"default\" };\n }\n\n if (source.kind === \"value\") {\n if (!source.value) {\n throw new Error(\"Policy credential value must not be empty.\");\n }\n return { kind: \"value\", value: source.value };\n }\n\n return { kind: \"redacted\" };\n}\n\nfunction normalizeHeaderTransform(\n header: PolicyServiceHeaderTransform,\n): PolicyServiceHeaderTransform {\n const headerName = header.headerName.trim().toLowerCase();\n const valueEncoding = header.valueEncoding ?? \"plain\";\n if (!headerName) {\n throw new Error(\"Policy header transform must include a header name.\");\n }\n if (valueEncoding !== \"plain\" && valueEncoding !== \"base64\") {\n throw new Error(`Policy header transform for \"${headerName}\" has unsupported valueEncoding.`);\n }\n\n return {\n headerName,\n valuePrefix: header.valuePrefix,\n credentialPrefix: header.credentialPrefix,\n valueEncoding,\n credential: normalizeCredentialSource(header.credential),\n };\n}\n\nfunction normalizeService(service: PolicyServiceDescriptor): PolicyServiceDescriptor {\n const id = service.id.trim();\n const name = service.name.trim();\n const domains = [\n ...new Set(service.domains.map((domain) => domain.trim()).filter(Boolean)),\n ].sort();\n\n if (!id) {\n throw new Error(\"Policy service id must not be empty.\");\n }\n\n if (!name) {\n throw new Error(`Policy service \"${id}\" must have a name.`);\n }\n\n if (domains.length === 0) {\n throw new Error(`Policy service \"${id}\" must declare at least one domain.`);\n }\n\n const normalizedDomainHeaders =\n service.domainHeaders === undefined\n ? undefined\n : Object.fromEntries(\n Object.entries(service.domainHeaders)\n .map(([domain, headers]) => [\n domain.trim(),\n headers.map((header) => normalizeHeaderTransform(header)),\n ])\n .filter(([domain]) => Boolean(domain)),\n );\n\n for (const domain of Object.keys(normalizedDomainHeaders ?? {})) {\n if (!domains.includes(domain)) {\n throw new Error(\n `Policy service \"${id}\" defines domainHeaders for \"${domain}\" but does not declare that domain.`,\n );\n }\n }\n\n return {\n id,\n name,\n description: service.description?.trim() || undefined,\n domains,\n headers: service.headers?.map((header) => normalizeHeaderTransform(header)),\n domainHeaders: normalizedDomainHeaders,\n };\n}\n\nfunction normalizeServices(\n services: readonly PolicyServiceDescriptor[],\n): readonly PolicyServiceDescriptor[] {\n if (services.length === 0) {\n throw new Error(\"allowServices(...) requires at least one service descriptor.\");\n }\n\n const deduped = new Map<string, PolicyServiceDescriptor>();\n for (const service of services) {\n const normalized = normalizeService(service);\n deduped.set(normalized.id, normalized);\n }\n\n return [...deduped.values()].sort((left, right) => left.id.localeCompare(right.id));\n}\n\nexport function allowAll(): WorkspacePolicy {\n return { mode: \"allow-all\" };\n}\n\nexport function denyAll(): WorkspacePolicy {\n return { mode: \"deny-all\" };\n}\n\nexport function allowService(service: PolicyServiceDescriptor): WorkspacePolicy {\n return allowServices([service]);\n}\n\nexport function allowServices(services: readonly PolicyServiceDescriptor[]): WorkspacePolicy {\n return {\n mode: \"allow-services\",\n services: normalizeServices(services),\n };\n}\n\nexport function describeWorkspacePolicy(policy: WorkspacePolicy): string {\n switch (policy.mode) {\n case \"allow-all\":\n return \"allow-all\";\n case \"deny-all\":\n return \"deny-all\";\n case \"allow-services\":\n return `allow-services:${policy.services.map((service) => service.id).join(\",\")}`;\n }\n}\n\nexport function serializeWorkspacePolicy(policy: WorkspacePolicy): JsonValue {\n return policy as unknown as JsonValue;\n}\n\nexport function redactWorkspacePolicy(policy: WorkspacePolicy): WorkspacePolicy {\n if (policy.mode !== \"allow-services\") {\n return policy;\n }\n\n return {\n mode: \"allow-services\",\n services: policy.services.map((service) => ({\n ...service,\n headers: service.headers?.map((header) => ({\n headerName: header.headerName,\n valuePrefix: header.valuePrefix,\n credentialPrefix: header.credentialPrefix,\n valueEncoding: header.valueEncoding,\n credential: header.credential.kind === \"value\" ? { kind: \"redacted\" } : header.credential,\n })),\n domainHeaders:\n service.domainHeaders === undefined\n ? undefined\n : Object.fromEntries(\n Object.entries(service.domainHeaders).map(([domain, headers]) => [\n domain,\n headers.map((header) => ({\n headerName: header.headerName,\n valuePrefix: header.valuePrefix,\n credentialPrefix: header.credentialPrefix,\n valueEncoding: header.valueEncoding,\n credential:\n header.credential.kind === \"value\" ? { kind: \"redacted\" } : header.credential,\n })),\n ]),\n ),\n })),\n };\n}\n\nexport function assertWorkspacePolicyIsDurable(policy: WorkspacePolicy): void {\n if (policy.mode !== \"allow-services\") {\n return;\n }\n\n for (const service of policy.services) {\n for (const header of service.headers ?? []) {\n if (header.credential.kind === \"value\") {\n throw new Error(\n `Workspace policy for service \"${service.id}\" contains an explicit secret and cannot be stored durably.`,\n );\n }\n }\n for (const headers of Object.values(service.domainHeaders ?? {})) {\n for (const header of headers) {\n if (header.credential.kind === \"value\") {\n throw new Error(\n `Workspace policy for service \"${service.id}\" contains an explicit secret and cannot be stored durably.`,\n );\n }\n }\n }\n }\n}\n\nexport function parseWorkspacePolicy(value: unknown): WorkspacePolicy {\n if (!isRecord(value) || typeof value.mode !== \"string\") {\n throw new Error(\"expected workspace policy object\");\n }\n\n if (value.mode === \"allow-all\") {\n return allowAll();\n }\n\n if (value.mode === \"deny-all\") {\n return denyAll();\n }\n\n if (value.mode === \"allow-services\") {\n if (!Array.isArray(value.services)) {\n throw new Error(\"allow-services policy must include a services array\");\n }\n\n const services = value.services.map((service, index) => {\n if (!isRecord(service)) {\n throw new Error(`service at index ${index} must be an object`);\n }\n\n if (\n typeof service.id !== \"string\" ||\n typeof service.name !== \"string\" ||\n !isStringArray(service.domains)\n ) {\n throw new Error(`service at index ${index} has an invalid shape`);\n }\n\n const headers =\n service.headers === undefined\n ? undefined\n : (() => {\n if (!isRecordArray(service.headers)) {\n throw new Error(`service at index ${index} has invalid headers`);\n }\n\n return service.headers.map((header, headerIndex) => {\n if (\n typeof header.headerName !== \"string\" ||\n !isRecord(header.credential) ||\n typeof header.credential.kind !== \"string\"\n ) {\n throw new Error(\n `service at index ${index} has invalid header transform at ${headerIndex}`,\n );\n }\n\n if (header.credential.kind === \"default\") {\n return normalizeHeaderTransform({\n headerName: header.headerName,\n valuePrefix:\n typeof header.valuePrefix === \"string\" ? header.valuePrefix : undefined,\n credentialPrefix:\n typeof header.credentialPrefix === \"string\"\n ? header.credentialPrefix\n : undefined,\n valueEncoding:\n header.valueEncoding === \"base64\" || header.valueEncoding === \"plain\"\n ? header.valueEncoding\n : undefined,\n credential: {\n kind: \"default\",\n },\n });\n }\n\n if (header.credential.kind === \"redacted\") {\n return normalizeHeaderTransform({\n headerName: header.headerName,\n valuePrefix:\n typeof header.valuePrefix === \"string\" ? header.valuePrefix : undefined,\n credentialPrefix:\n typeof header.credentialPrefix === \"string\"\n ? header.credentialPrefix\n : undefined,\n valueEncoding:\n header.valueEncoding === \"base64\" || header.valueEncoding === \"plain\"\n ? header.valueEncoding\n : undefined,\n credential: { kind: \"redacted\" },\n });\n }\n\n throw new Error(\n `service at index ${index} contains a non-durable credential source`,\n );\n });\n })();\n\n const domainHeaders =\n service.domainHeaders === undefined\n ? undefined\n : (() => {\n if (!isRecord(service.domainHeaders)) {\n throw new Error(`service at index ${index} has invalid domain headers`);\n }\n\n return Object.fromEntries(\n Object.entries(service.domainHeaders).map(([domain, rawHeaders]) => {\n if (!isRecordArray(rawHeaders)) {\n throw new Error(\n `service at index ${index} has invalid domain headers for ${domain}`,\n );\n }\n\n return [\n domain,\n rawHeaders.map((header, headerIndex) => {\n if (\n typeof header.headerName !== \"string\" ||\n !isRecord(header.credential) ||\n typeof header.credential.kind !== \"string\"\n ) {\n throw new Error(\n `service at index ${index} has invalid domain header transform for ${domain} at ${headerIndex}`,\n );\n }\n\n if (header.credential.kind === \"default\") {\n return normalizeHeaderTransform({\n headerName: header.headerName,\n valuePrefix:\n typeof header.valuePrefix === \"string\" ? header.valuePrefix : undefined,\n credentialPrefix:\n typeof header.credentialPrefix === \"string\"\n ? header.credentialPrefix\n : undefined,\n valueEncoding:\n header.valueEncoding === \"base64\" || header.valueEncoding === \"plain\"\n ? header.valueEncoding\n : undefined,\n credential: { kind: \"default\" },\n });\n }\n\n if (header.credential.kind === \"redacted\") {\n return normalizeHeaderTransform({\n headerName: header.headerName,\n valuePrefix:\n typeof header.valuePrefix === \"string\" ? header.valuePrefix : undefined,\n credentialPrefix:\n typeof header.credentialPrefix === \"string\"\n ? header.credentialPrefix\n : undefined,\n valueEncoding:\n header.valueEncoding === \"base64\" || header.valueEncoding === \"plain\"\n ? header.valueEncoding\n : undefined,\n credential: { kind: \"redacted\" },\n });\n }\n\n throw new Error(\n `service at index ${index} contains a non-durable credential source in domain headers`,\n );\n }),\n ];\n }),\n );\n })();\n\n return normalizeService({\n id: service.id,\n name: service.name,\n description: typeof service.description === \"string\" ? service.description : undefined,\n domains: service.domains,\n headers,\n domainHeaders,\n });\n });\n\n return allowServices(services);\n }\n\n throw new Error(`unsupported workspace policy mode \"${value.mode}\"`);\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
allowService
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-NKTNTBOY.js";
|
|
4
4
|
|
|
5
5
|
// src/policies/ai-gateway.ts
|
|
6
6
|
var DEFAULT_AI_GATEWAY_BASE_URL = "https://ai-gateway.vercel.sh/v1";
|
|
@@ -55,4 +55,4 @@ export {
|
|
|
55
55
|
aiGateway,
|
|
56
56
|
allowAiGateway
|
|
57
57
|
};
|
|
58
|
-
//# sourceMappingURL=chunk-
|
|
58
|
+
//# sourceMappingURL=chunk-UEAKE56H.js.map
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { S as SandkitOptions, a as SandboxDriverFactory, C as CommandResult, b as SandboxRunCommandOptions, W as WorkspaceSessionProcess, c as WorkspaceSessionProcessStartInput, d as WorkspaceSandboxLease, e as WorkspaceCreateOptions } from './types-
|
|
2
|
-
import { W as WorkspacePolicy, P as PolicyServiceDescriptor } from './types-
|
|
3
|
-
export { a as PolicyServiceCredentialSource } from './types-
|
|
1
|
+
import { S as SandkitOptions, a as SandboxDriverFactory, C as CommandResult, b as SandboxRunCommandOptions, W as WorkspaceSessionProcess, c as WorkspaceSessionProcessStartInput, d as WorkspaceSandboxLease, e as WorkspaceCreateOptions } from './types-B5N9o-ew.js';
|
|
2
|
+
import { W as WorkspacePolicy, P as PolicyServiceDescriptor } from './types-Dpr_BkF9.js';
|
|
3
|
+
export { a as PolicyServiceCredentialSource } from './types-Dpr_BkF9.js';
|
|
4
4
|
export { aiGateway } from './policies/ai-gateway.js';
|
|
5
5
|
export { codex } from './policies/codex.js';
|
|
6
6
|
export { gemini } from './policies/gemini.js';
|
|
7
|
-
export { S as SharedSetup } from './types-
|
|
7
|
+
export { S as SharedSetup } from './types-BRMAvcWc.js';
|
|
8
8
|
|
|
9
9
|
interface SandkitContext {
|
|
10
10
|
readonly adapter: NonNullable<SandkitOptions["database"]>;
|
|
@@ -71,7 +71,7 @@ declare function allowService(service: PolicyServiceDescriptor): WorkspacePolicy
|
|
|
71
71
|
declare function allowServices(services: readonly PolicyServiceDescriptor[]): WorkspacePolicy;
|
|
72
72
|
|
|
73
73
|
interface GithubOptions {
|
|
74
|
-
readonly
|
|
74
|
+
readonly token?: string;
|
|
75
75
|
}
|
|
76
76
|
declare function github(options?: GithubOptions): PolicyServiceDescriptor;
|
|
77
77
|
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
github
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-5MXHFOJH.js";
|
|
4
4
|
import "./chunk-UDFWES6J.js";
|
|
5
5
|
import "./chunk-BDPTYR6V.js";
|
|
6
6
|
import "./chunk-RMMOQD5Y.js";
|
|
@@ -9,13 +9,13 @@ import {
|
|
|
9
9
|
} from "./chunk-CSOBTLWV.js";
|
|
10
10
|
import {
|
|
11
11
|
codex
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-2M2AZUOC.js";
|
|
13
13
|
import {
|
|
14
14
|
gemini
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-6GHZO3Y5.js";
|
|
16
16
|
import {
|
|
17
17
|
aiGateway
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-UEAKE56H.js";
|
|
19
19
|
import {
|
|
20
20
|
getSandboxDriverFactory
|
|
21
21
|
} from "./chunk-HVYCAAZQ.js";
|
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
parseWorkspacePolicy,
|
|
31
31
|
redactWorkspacePolicy,
|
|
32
32
|
serializeWorkspacePolicy
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-NKTNTBOY.js";
|
|
34
34
|
|
|
35
35
|
// src/core/context.ts
|
|
36
36
|
function resolveDeprecatedNetworkOption(options) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { a as SandboxDriverFactory, f as SandboxCreateOptions, g as SandboxDriver, P as PersistedSandboxState, h as SandkitSandboxProvider } from '../types-
|
|
2
|
-
import { W as WorkspaceRecord } from '../types-
|
|
3
|
-
import '../types-
|
|
1
|
+
import { a as SandboxDriverFactory, f as SandboxCreateOptions, g as SandboxDriver, P as PersistedSandboxState, h as SandkitSandboxProvider } from '../types-B5N9o-ew.js';
|
|
2
|
+
import { W as WorkspaceRecord } from '../types-BRMAvcWc.js';
|
|
3
|
+
import '../types-Dpr_BkF9.js';
|
|
4
4
|
|
|
5
5
|
declare class MockSandboxDriverFactory implements SandboxDriverFactory {
|
|
6
6
|
#private;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { V as VercelSandboxOptions, h as SandkitSandboxProvider } from '../types-
|
|
2
|
-
import '../types-
|
|
3
|
-
import '../types-
|
|
1
|
+
import { V as VercelSandboxOptions, h as SandkitSandboxProvider } from '../types-B5N9o-ew.js';
|
|
2
|
+
import '../types-BRMAvcWc.js';
|
|
3
|
+
import '../types-Dpr_BkF9.js';
|
|
4
4
|
|
|
5
5
|
declare function vercelSandbox(options?: VercelSandboxOptions): SandkitSandboxProvider;
|
|
6
6
|
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import {
|
|
2
2
|
resolveGithubDefaultApiKey
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-5MXHFOJH.js";
|
|
4
4
|
import {
|
|
5
5
|
resolveCodexDefaultApiKey
|
|
6
|
-
} from "../chunk-
|
|
6
|
+
} from "../chunk-2M2AZUOC.js";
|
|
7
7
|
import {
|
|
8
8
|
resolveGeminiDefaultApiKey
|
|
9
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-6GHZO3Y5.js";
|
|
10
10
|
import {
|
|
11
11
|
resolveAiGatewayDefaultApiKey
|
|
12
|
-
} from "../chunk-
|
|
12
|
+
} from "../chunk-UEAKE56H.js";
|
|
13
13
|
import {
|
|
14
14
|
createSandboxProvider
|
|
15
15
|
} from "../chunk-HVYCAAZQ.js";
|
|
16
|
-
import "../chunk-
|
|
16
|
+
import "../chunk-NKTNTBOY.js";
|
|
17
17
|
|
|
18
18
|
// src/drivers/vercel-sandbox.ts
|
|
19
19
|
import { Sandbox } from "@vercel/sandbox";
|
|
@@ -66,6 +66,12 @@ function resolveCredentialValue(serviceId, header) {
|
|
|
66
66
|
`Workspace policy for service "${serviceId}" contains a redacted credential and cannot be applied.`
|
|
67
67
|
);
|
|
68
68
|
}
|
|
69
|
+
function encodeHeaderValue(value, encoding) {
|
|
70
|
+
if (encoding === "base64") {
|
|
71
|
+
return Buffer.from(value, "utf8").toString("base64");
|
|
72
|
+
}
|
|
73
|
+
return value;
|
|
74
|
+
}
|
|
69
75
|
function compileHeaderRules(serviceId, headers) {
|
|
70
76
|
if (!headers || headers.length === 0) {
|
|
71
77
|
return [];
|
|
@@ -73,7 +79,10 @@ function compileHeaderRules(serviceId, headers) {
|
|
|
73
79
|
const resolvedHeaders = Object.fromEntries(
|
|
74
80
|
headers.map((header) => [
|
|
75
81
|
header.headerName,
|
|
76
|
-
`${header.valuePrefix ?? ""}${
|
|
82
|
+
`${header.valuePrefix ?? ""}${encodeHeaderValue(
|
|
83
|
+
`${header.credentialPrefix ?? ""}${resolveCredentialValue(serviceId, header)}`,
|
|
84
|
+
header.valueEncoding
|
|
85
|
+
)}`
|
|
77
86
|
])
|
|
78
87
|
);
|
|
79
88
|
return [
|
|
@@ -95,8 +104,11 @@ function compileVercelNetworkPolicy(policy) {
|
|
|
95
104
|
case "allow-services": {
|
|
96
105
|
const allow = {};
|
|
97
106
|
for (const service of policy.services) {
|
|
98
|
-
const rules = compileHeaderRules(service.id, service.headers);
|
|
99
107
|
for (const domain of service.domains) {
|
|
108
|
+
const rules = compileHeaderRules(
|
|
109
|
+
service.id,
|
|
110
|
+
service.domainHeaders?.[domain] ?? service.headers
|
|
111
|
+
);
|
|
100
112
|
const existing = allow[domain] ?? [];
|
|
101
113
|
allow[domain] = [...existing, ...rules];
|
|
102
114
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/drivers/vercel-sandbox.ts","../../src/policies/default-credentials.ts","../../src/drivers/vercel-network-policy.ts","../../src/integrations/vercel.ts"],"sourcesContent":["import { Sandbox } from \"@vercel/sandbox\";\n\nimport type { WorkspacePolicy } from \"../policies/types.ts\";\nimport type {\n CommandResult,\n PersistedSandboxState,\n SandboxSessionLease,\n SandboxDriver,\n WorkspaceSessionLog,\n WorkspaceSessionProcess,\n WorkspaceSessionProcessStartInput,\n SandboxCreateOptions,\n SandboxDriverFactory,\n WorkspaceRecord,\n VercelSandboxOptions,\n} from \"../types.ts\";\nimport { compileVercelNetworkPolicy } from \"./vercel-network-policy.ts\";\n\ninterface VercelCommandFinished {\n exitCode: number;\n stdout(): Promise<string>;\n stderr(): Promise<string>;\n}\n\ninterface VercelCommandHandle {\n wait(): Promise<VercelCommandFinished>;\n readonly cmdId?: string;\n readonly logs?: () => unknown;\n}\n\ninterface VercelPersistedState {\n snapshotId?: string;\n}\n\nclass VercelSandboxDriver implements SandboxDriver {\n readonly #sandbox: Awaited<ReturnType<typeof Sandbox.get>>;\n readonly provider = \"vercel-sandbox\";\n\n constructor(sandbox: Awaited<ReturnType<typeof Sandbox.get>>) {\n this.#sandbox = sandbox;\n }\n\n get id(): string {\n return this.#sandbox.sandboxId;\n }\n\n async applyPolicy(policy: WorkspacePolicy): Promise<void> {\n await this.#sandbox.updateNetworkPolicy(compileVercelNetworkPolicy(policy));\n }\n\n async getSessionLease(): Promise<SandboxSessionLease> {\n const sandbox = this.#sandbox;\n const observedAt = new Date().toISOString();\n const timeoutMs =\n typeof sandbox.timeout === \"number\" && Number.isFinite(sandbox.timeout) && sandbox.timeout > 0\n ? sandbox.timeout\n : 60_000;\n\n return {\n sandboxId: sandbox.sandboxId,\n observedAt,\n expiresAt: new Date(Date.parse(observedAt) + timeoutMs).toISOString(),\n };\n }\n\n async runCommand(command: string, args: string[]): Promise<CommandResult> {\n const result = await this.#sandbox.runCommand(command, args);\n const finished = await this.#toCommandFinished(result);\n\n return {\n exitCode: finished.exitCode,\n stdout: await finished.stdout(),\n stderr: await finished.stderr(),\n };\n }\n\n async startProcess(input: WorkspaceSessionProcessStartInput): Promise<WorkspaceSessionProcess> {\n const started = await this.#sandbox.runCommand({\n cmd: input.command,\n args: [...input.args],\n detached: true,\n });\n if (!isVercelCommandHandle(started)) {\n throw new Error(\"Unexpected Vercel sandbox startProcess() response shape.\");\n }\n\n const processId = started.cmdId ?? `${this.#sandbox.sandboxId}-${Date.now()}`;\n const commandLogBroadcast = createCommandLogBroadcaster(\n getCommandLogIterator(started),\n input.onStdout,\n input.onStderr,\n );\n\n return {\n processId,\n wait: async (): Promise<CommandResult> => {\n const finished = await started.wait();\n return {\n exitCode: finished.exitCode,\n stdout: await finished.stdout(),\n stderr: await finished.stderr(),\n };\n },\n logs: commandLogBroadcast ? () => commandLogBroadcast() : undefined,\n };\n }\n\n async url(port: number): Promise<string> {\n try {\n return this.#sandbox.domain(port);\n } catch (error) {\n if (!(error instanceof Error) || !error.message.includes(\"No route for port\")) {\n throw error;\n }\n\n const refreshed = await Sandbox.get({ sandboxId: this.#sandbox.sandboxId });\n return refreshed.domain(port);\n }\n }\n\n async extendTimeout(durationMs: number): Promise<void> {\n const extendTimeout = (\n this.#sandbox as { extendTimeout?: (durationMs: number) => Promise<unknown> }\n ).extendTimeout;\n if (!extendTimeout) {\n throw new Error(\"This Vercel sandbox does not support extendTimeout().\");\n }\n\n await extendTimeout.call(this.#sandbox, durationMs);\n }\n\n async snapshot(): Promise<PersistedSandboxState> {\n // Vercel sandbox snapshot() restores through a new sandbox and implicitly stops the source sandbox.\n // Keep this behavior as a provider detail in the driver implementation.\n const snapshot = await this.#sandbox.snapshot();\n\n return {\n kind: \"vercel-sandbox-snapshot\",\n sessionId: this.#sandbox.sandboxId,\n state: {\n snapshotId: snapshot.snapshotId,\n },\n };\n }\n\n async #toCommandFinished(raw: unknown): Promise<VercelCommandFinished> {\n if (typeof raw !== \"object\" || raw === null) {\n throw new Error(\"Unexpected Vercel sandbox command response\");\n }\n\n const candidate = raw as { wait?: () => Promise<VercelCommandFinished> };\n if (candidate.wait) {\n return candidate.wait();\n }\n\n return raw as VercelCommandFinished;\n }\n}\n\nfunction isVercelCommandHandle(value: unknown): value is VercelCommandHandle {\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n\n const candidate = value as { wait?: unknown; cmdId?: unknown };\n if (typeof candidate.wait !== \"function\") {\n return false;\n }\n\n return candidate.cmdId === undefined || typeof candidate.cmdId === \"string\";\n}\n\nfunction isIterable<T = unknown>(value: unknown): value is Iterable<T> {\n return (\n value !== null &&\n (typeof value === \"object\" || typeof value === \"function\") &&\n typeof (value as Iterable<T>)[Symbol.iterator] === \"function\"\n );\n}\n\nfunction isAsyncIterable<T = unknown>(value: unknown): value is AsyncIterable<T> {\n return (\n value !== null &&\n (typeof value === \"object\" || typeof value === \"function\") &&\n typeof (value as AsyncIterable<T>)[Symbol.asyncIterator] === \"function\"\n );\n}\n\nfunction getCommandLogIterator(raw: VercelCommandHandle): AsyncIterable<unknown> | undefined {\n const rawLogs = raw.logs?.();\n if (rawLogs === undefined) {\n return undefined;\n }\n if (isAsyncIterable<unknown>(rawLogs)) {\n return rawLogs;\n }\n if (isIterable<unknown>(rawLogs)) {\n return toAsyncIterableFromSync(rawLogs);\n }\n return undefined;\n}\n\nfunction toAsyncIterableFromSync<T>(iterable: Iterable<T>): AsyncIterable<T> {\n return {\n async *[Symbol.asyncIterator]() {\n for (const value of iterable) {\n yield value;\n }\n },\n };\n}\n\nfunction createCommandLogBroadcaster(\n logs: AsyncIterable<unknown> | undefined,\n onStdout?: (chunk: string) => void,\n onStderr?: (chunk: string) => void,\n): (() => AsyncIterable<WorkspaceSessionLog>) | undefined {\n if (!logs) {\n return undefined;\n }\n\n const bufferedLogs: WorkspaceSessionLog[] = [];\n const waiters: Array<() => void> = [];\n let completed = false;\n let error: unknown = null;\n let pumpStarted = false;\n\n const notifyWaiters = () => {\n while (waiters.length > 0) {\n waiters.pop()?.();\n }\n };\n\n const run = async (): Promise<void> => {\n if (pumpStarted) {\n return;\n }\n pumpStarted = true;\n\n try {\n for await (const log of logs) {\n const normalized = normalizeCommandLog(log);\n if (!normalized) {\n continue;\n }\n\n bufferedLogs.push(normalized);\n if (normalized.stream === \"stderr\") {\n onStderr?.(normalized.chunk);\n } else {\n onStdout?.(normalized.chunk);\n }\n notifyWaiters();\n }\n } catch (cause) {\n error = cause;\n } finally {\n completed = true;\n notifyWaiters();\n }\n };\n\n void run().catch(() => {});\n\n const waitForWork = (): Promise<void> => {\n return new Promise<void>((resolve) => {\n waiters.push(resolve);\n });\n };\n\n const createLogIterable = (): AsyncIterable<WorkspaceSessionLog> => {\n return {\n async *[Symbol.asyncIterator]() {\n let index = 0;\n while (true) {\n if (index < bufferedLogs.length) {\n yield bufferedLogs[index++]!;\n continue;\n }\n if (error !== null) {\n throw error instanceof Error ? error : new Error(\"startProcess logs failed.\");\n }\n if (completed) {\n return;\n }\n await waitForWork();\n }\n },\n };\n };\n\n return createLogIterable;\n}\n\nexport function normalizeCommandLog(log: unknown): WorkspaceSessionLog | null {\n if (typeof log === \"string\") {\n return { stream: \"stdout\", chunk: log };\n }\n if (typeof log !== \"object\" || log === null) {\n return null;\n }\n\n const candidate = log as {\n stream?: unknown;\n output?: unknown;\n chunk?: unknown;\n text?: unknown;\n message?: unknown;\n data?: unknown;\n };\n const streamValue = candidate.stream;\n const stream = streamValue === \"stderr\" || streamValue === \"stdout\" ? streamValue : \"stdout\";\n const rawChunk =\n candidate.data ??\n candidate.output ??\n candidate.chunk ??\n candidate.text ??\n candidate.message ??\n null;\n\n if (typeof rawChunk !== \"string\") {\n return null;\n }\n\n return { stream, chunk: rawChunk };\n}\n\nclass VercelSandboxDriverFactory implements SandboxDriverFactory {\n readonly #runtime: string;\n readonly #defaultTimeout: number;\n\n constructor(options: VercelSandboxOptions = {}) {\n this.#runtime = options.runtime ?? \"node24\";\n this.#defaultTimeout = normalizeSandboxTimeout(\n options.defaultTimeout ?? options.timeout,\n \"Vercel sandbox default timeout\",\n );\n }\n\n isSessionUnavailableError(error: unknown): boolean {\n if (!(error instanceof Error)) {\n return false;\n }\n\n const message = error.message.toLowerCase();\n return (\n message.includes(\"not found\") ||\n message.includes(\"does not exist\") ||\n message.includes(\"sandbox_stopped\") ||\n message.includes(\"sandbox stopped\")\n );\n }\n\n async createSandbox(\n _workspace: WorkspaceRecord,\n options: SandboxCreateOptions,\n ): Promise<SandboxDriver> {\n const timeout = this.#defaultTimeoutForCreate(options);\n\n const sandbox = await Sandbox.create({\n runtime: this.#runtime,\n timeout,\n ports: options.exposedPorts,\n networkPolicy: compileVercelNetworkPolicy(options.policy),\n });\n\n return new VercelSandboxDriver(sandbox);\n }\n\n async resumeSandbox(\n workspace: WorkspaceRecord,\n snapshot: PersistedSandboxState,\n options: SandboxCreateOptions,\n ): Promise<SandboxDriver> {\n const timeout = this.#defaultTimeoutForCreate(options);\n const state = snapshot.state as VercelPersistedState | undefined;\n const snapshotId = state?.snapshotId;\n const fallbackSandboxId = workspace.sandboxId ?? snapshot.sessionId;\n\n const sandbox =\n snapshotId === undefined || typeof snapshotId !== \"string\"\n ? await (fallbackSandboxId === undefined\n ? (() => {\n throw new Error(\"Persisted sandbox state is missing restore information\");\n })()\n : Sandbox.get({ sandboxId: fallbackSandboxId }))\n : await Sandbox.create({\n source: {\n type: \"snapshot\",\n snapshotId,\n },\n timeout,\n ports: options.exposedPorts,\n networkPolicy: compileVercelNetworkPolicy(options.policy),\n });\n\n // Reattaching to an existing live sandbox should not mutate provider state.\n // Updating the network policy here races with commit/snapshot shutdown and can\n // fail on otherwise read-only flows like getActiveLease().\n return new VercelSandboxDriver(sandbox);\n }\n\n #defaultTimeoutForCreate(options: SandboxCreateOptions): number {\n return normalizeSandboxTimeout(options.timeoutMs ?? this.#defaultTimeout, \"runtime timeout\");\n }\n}\n\nfunction normalizeSandboxTimeout(value: unknown, label: string): number {\n if (value === undefined) {\n return 60_000;\n }\n\n if (\n typeof value !== \"number\" ||\n !Number.isInteger(value) ||\n !Number.isFinite(value) ||\n value <= 0\n ) {\n throw new Error(`${label} must be a positive integer in milliseconds.`);\n }\n\n return value;\n}\n\nexport function createVercelSandboxDriverFactory(\n options: VercelSandboxOptions = {},\n): SandboxDriverFactory {\n return new VercelSandboxDriverFactory(options);\n}\n","import { resolveAiGatewayDefaultApiKey } from \"./ai-gateway.ts\";\nimport { resolveCodexDefaultApiKey } from \"./codex.ts\";\nimport { resolveGeminiDefaultApiKey } from \"./gemini.ts\";\nimport { resolveGithubDefaultApiKey } from \"./github.ts\";\n\nexport function resolveDefaultCredentialValue(serviceId: string): string | undefined {\n switch (serviceId) {\n case \"codex\":\n return resolveCodexDefaultApiKey();\n case \"gemini\":\n return resolveGeminiDefaultApiKey();\n case \"github\":\n return resolveGithubDefaultApiKey();\n case \"aiGateway\":\n return resolveAiGatewayDefaultApiKey();\n default:\n return undefined;\n }\n}\n\nexport function describeDefaultCredentialSource(serviceId: string): string {\n switch (serviceId) {\n case \"codex\":\n return \"CODEX_API_KEY\";\n case \"gemini\":\n return \"GEMINI_API_KEY\";\n case \"github\":\n return \"GITHUB_TOKEN\";\n case \"aiGateway\":\n return \"AI_GATEWAY_API_KEY\";\n default:\n return `default credential for service \"${serviceId}\"`;\n }\n}\n","import type {\n NetworkPolicy as VercelNetworkPolicy,\n NetworkPolicyRule as VercelNetworkPolicyRule,\n} from \"@vercel/sandbox\";\n\nimport {\n describeDefaultCredentialSource,\n resolveDefaultCredentialValue,\n} from \"../policies/default-credentials.ts\";\nimport type { PolicyServiceHeaderTransform, WorkspacePolicy } from \"../policies/types.ts\";\n\nfunction resolveCredentialValue(serviceId: string, header: PolicyServiceHeaderTransform): string {\n if (header.credential.kind === \"value\") {\n return header.credential.value;\n }\n\n if (header.credential.kind === \"default\") {\n const value = resolveDefaultCredentialValue(serviceId);\n if (!value) {\n throw new Error(\n `Workspace policy for service \"${serviceId}\" requires ${describeDefaultCredentialSource(serviceId)}.`,\n );\n }\n return value;\n }\n\n throw new Error(\n `Workspace policy for service \"${serviceId}\" contains a redacted credential and cannot be applied.`,\n );\n}\n\nfunction compileHeaderRules(\n serviceId: string,\n headers: readonly PolicyServiceHeaderTransform[] | undefined,\n): VercelNetworkPolicyRule[] {\n if (!headers || headers.length === 0) {\n return [];\n }\n\n const resolvedHeaders = Object.fromEntries(\n headers.map((header) => [\n header.headerName,\n `${header.valuePrefix ?? \"\"}${resolveCredentialValue(serviceId, header)}`,\n ]),\n );\n\n return [\n {\n transform: [\n {\n headers: resolvedHeaders,\n },\n ],\n },\n ];\n}\n\nexport function compileVercelNetworkPolicy(policy: WorkspacePolicy): VercelNetworkPolicy {\n switch (policy.mode) {\n case \"allow-all\":\n return \"allow-all\";\n case \"deny-all\":\n return \"deny-all\";\n case \"allow-services\": {\n const allow: Record<string, VercelNetworkPolicyRule[]> = {};\n\n for (const service of policy.services) {\n const rules = compileHeaderRules(service.id, service.headers);\n for (const domain of service.domains) {\n const existing = allow[domain] ?? [];\n allow[domain] = [...existing, ...rules];\n }\n }\n\n return { allow };\n }\n }\n}\n","import { createVercelSandboxDriverFactory } from \"../drivers/vercel-sandbox.ts\";\nimport { createSandboxProvider } from \"../types.ts\";\nimport type { SandkitSandboxProvider, VercelSandboxOptions } from \"../types.ts\";\n\nexport type { SandkitSandboxProvider, VercelSandboxOptions } from \"../types.ts\";\n\nexport function vercelSandbox(options: VercelSandboxOptions = {}): SandkitSandboxProvider {\n return createSandboxProvider(\"vercel\", createVercelSandboxDriverFactory(options));\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/drivers/vercel-sandbox.ts","../../src/policies/default-credentials.ts","../../src/drivers/vercel-network-policy.ts","../../src/integrations/vercel.ts"],"sourcesContent":["import { Sandbox } from \"@vercel/sandbox\";\n\nimport type { WorkspacePolicy } from \"../policies/types.ts\";\nimport type {\n CommandResult,\n PersistedSandboxState,\n SandboxSessionLease,\n SandboxDriver,\n WorkspaceSessionLog,\n WorkspaceSessionProcess,\n WorkspaceSessionProcessStartInput,\n SandboxCreateOptions,\n SandboxDriverFactory,\n WorkspaceRecord,\n VercelSandboxOptions,\n} from \"../types.ts\";\nimport { compileVercelNetworkPolicy } from \"./vercel-network-policy.ts\";\n\ninterface VercelCommandFinished {\n exitCode: number;\n stdout(): Promise<string>;\n stderr(): Promise<string>;\n}\n\ninterface VercelCommandHandle {\n wait(): Promise<VercelCommandFinished>;\n readonly cmdId?: string;\n readonly logs?: () => unknown;\n}\n\ninterface VercelPersistedState {\n snapshotId?: string;\n}\n\nclass VercelSandboxDriver implements SandboxDriver {\n readonly #sandbox: Awaited<ReturnType<typeof Sandbox.get>>;\n readonly provider = \"vercel-sandbox\";\n\n constructor(sandbox: Awaited<ReturnType<typeof Sandbox.get>>) {\n this.#sandbox = sandbox;\n }\n\n get id(): string {\n return this.#sandbox.sandboxId;\n }\n\n async applyPolicy(policy: WorkspacePolicy): Promise<void> {\n await this.#sandbox.updateNetworkPolicy(compileVercelNetworkPolicy(policy));\n }\n\n async getSessionLease(): Promise<SandboxSessionLease> {\n const sandbox = this.#sandbox;\n const observedAt = new Date().toISOString();\n const timeoutMs =\n typeof sandbox.timeout === \"number\" && Number.isFinite(sandbox.timeout) && sandbox.timeout > 0\n ? sandbox.timeout\n : 60_000;\n\n return {\n sandboxId: sandbox.sandboxId,\n observedAt,\n expiresAt: new Date(Date.parse(observedAt) + timeoutMs).toISOString(),\n };\n }\n\n async runCommand(command: string, args: string[]): Promise<CommandResult> {\n const result = await this.#sandbox.runCommand(command, args);\n const finished = await this.#toCommandFinished(result);\n\n return {\n exitCode: finished.exitCode,\n stdout: await finished.stdout(),\n stderr: await finished.stderr(),\n };\n }\n\n async startProcess(input: WorkspaceSessionProcessStartInput): Promise<WorkspaceSessionProcess> {\n const started = await this.#sandbox.runCommand({\n cmd: input.command,\n args: [...input.args],\n detached: true,\n });\n if (!isVercelCommandHandle(started)) {\n throw new Error(\"Unexpected Vercel sandbox startProcess() response shape.\");\n }\n\n const processId = started.cmdId ?? `${this.#sandbox.sandboxId}-${Date.now()}`;\n const commandLogBroadcast = createCommandLogBroadcaster(\n getCommandLogIterator(started),\n input.onStdout,\n input.onStderr,\n );\n\n return {\n processId,\n wait: async (): Promise<CommandResult> => {\n const finished = await started.wait();\n return {\n exitCode: finished.exitCode,\n stdout: await finished.stdout(),\n stderr: await finished.stderr(),\n };\n },\n logs: commandLogBroadcast ? () => commandLogBroadcast() : undefined,\n };\n }\n\n async url(port: number): Promise<string> {\n try {\n return this.#sandbox.domain(port);\n } catch (error) {\n if (!(error instanceof Error) || !error.message.includes(\"No route for port\")) {\n throw error;\n }\n\n const refreshed = await Sandbox.get({ sandboxId: this.#sandbox.sandboxId });\n return refreshed.domain(port);\n }\n }\n\n async extendTimeout(durationMs: number): Promise<void> {\n const extendTimeout = (\n this.#sandbox as { extendTimeout?: (durationMs: number) => Promise<unknown> }\n ).extendTimeout;\n if (!extendTimeout) {\n throw new Error(\"This Vercel sandbox does not support extendTimeout().\");\n }\n\n await extendTimeout.call(this.#sandbox, durationMs);\n }\n\n async snapshot(): Promise<PersistedSandboxState> {\n // Vercel sandbox snapshot() restores through a new sandbox and implicitly stops the source sandbox.\n // Keep this behavior as a provider detail in the driver implementation.\n const snapshot = await this.#sandbox.snapshot();\n\n return {\n kind: \"vercel-sandbox-snapshot\",\n sessionId: this.#sandbox.sandboxId,\n state: {\n snapshotId: snapshot.snapshotId,\n },\n };\n }\n\n async #toCommandFinished(raw: unknown): Promise<VercelCommandFinished> {\n if (typeof raw !== \"object\" || raw === null) {\n throw new Error(\"Unexpected Vercel sandbox command response\");\n }\n\n const candidate = raw as { wait?: () => Promise<VercelCommandFinished> };\n if (candidate.wait) {\n return candidate.wait();\n }\n\n return raw as VercelCommandFinished;\n }\n}\n\nfunction isVercelCommandHandle(value: unknown): value is VercelCommandHandle {\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n\n const candidate = value as { wait?: unknown; cmdId?: unknown };\n if (typeof candidate.wait !== \"function\") {\n return false;\n }\n\n return candidate.cmdId === undefined || typeof candidate.cmdId === \"string\";\n}\n\nfunction isIterable<T = unknown>(value: unknown): value is Iterable<T> {\n return (\n value !== null &&\n (typeof value === \"object\" || typeof value === \"function\") &&\n typeof (value as Iterable<T>)[Symbol.iterator] === \"function\"\n );\n}\n\nfunction isAsyncIterable<T = unknown>(value: unknown): value is AsyncIterable<T> {\n return (\n value !== null &&\n (typeof value === \"object\" || typeof value === \"function\") &&\n typeof (value as AsyncIterable<T>)[Symbol.asyncIterator] === \"function\"\n );\n}\n\nfunction getCommandLogIterator(raw: VercelCommandHandle): AsyncIterable<unknown> | undefined {\n const rawLogs = raw.logs?.();\n if (rawLogs === undefined) {\n return undefined;\n }\n if (isAsyncIterable<unknown>(rawLogs)) {\n return rawLogs;\n }\n if (isIterable<unknown>(rawLogs)) {\n return toAsyncIterableFromSync(rawLogs);\n }\n return undefined;\n}\n\nfunction toAsyncIterableFromSync<T>(iterable: Iterable<T>): AsyncIterable<T> {\n return {\n async *[Symbol.asyncIterator]() {\n for (const value of iterable) {\n yield value;\n }\n },\n };\n}\n\nfunction createCommandLogBroadcaster(\n logs: AsyncIterable<unknown> | undefined,\n onStdout?: (chunk: string) => void,\n onStderr?: (chunk: string) => void,\n): (() => AsyncIterable<WorkspaceSessionLog>) | undefined {\n if (!logs) {\n return undefined;\n }\n\n const bufferedLogs: WorkspaceSessionLog[] = [];\n const waiters: Array<() => void> = [];\n let completed = false;\n let error: unknown = null;\n let pumpStarted = false;\n\n const notifyWaiters = () => {\n while (waiters.length > 0) {\n waiters.pop()?.();\n }\n };\n\n const run = async (): Promise<void> => {\n if (pumpStarted) {\n return;\n }\n pumpStarted = true;\n\n try {\n for await (const log of logs) {\n const normalized = normalizeCommandLog(log);\n if (!normalized) {\n continue;\n }\n\n bufferedLogs.push(normalized);\n if (normalized.stream === \"stderr\") {\n onStderr?.(normalized.chunk);\n } else {\n onStdout?.(normalized.chunk);\n }\n notifyWaiters();\n }\n } catch (cause) {\n error = cause;\n } finally {\n completed = true;\n notifyWaiters();\n }\n };\n\n void run().catch(() => {});\n\n const waitForWork = (): Promise<void> => {\n return new Promise<void>((resolve) => {\n waiters.push(resolve);\n });\n };\n\n const createLogIterable = (): AsyncIterable<WorkspaceSessionLog> => {\n return {\n async *[Symbol.asyncIterator]() {\n let index = 0;\n while (true) {\n if (index < bufferedLogs.length) {\n yield bufferedLogs[index++]!;\n continue;\n }\n if (error !== null) {\n throw error instanceof Error ? error : new Error(\"startProcess logs failed.\");\n }\n if (completed) {\n return;\n }\n await waitForWork();\n }\n },\n };\n };\n\n return createLogIterable;\n}\n\nexport function normalizeCommandLog(log: unknown): WorkspaceSessionLog | null {\n if (typeof log === \"string\") {\n return { stream: \"stdout\", chunk: log };\n }\n if (typeof log !== \"object\" || log === null) {\n return null;\n }\n\n const candidate = log as {\n stream?: unknown;\n output?: unknown;\n chunk?: unknown;\n text?: unknown;\n message?: unknown;\n data?: unknown;\n };\n const streamValue = candidate.stream;\n const stream = streamValue === \"stderr\" || streamValue === \"stdout\" ? streamValue : \"stdout\";\n const rawChunk =\n candidate.data ??\n candidate.output ??\n candidate.chunk ??\n candidate.text ??\n candidate.message ??\n null;\n\n if (typeof rawChunk !== \"string\") {\n return null;\n }\n\n return { stream, chunk: rawChunk };\n}\n\nclass VercelSandboxDriverFactory implements SandboxDriverFactory {\n readonly #runtime: string;\n readonly #defaultTimeout: number;\n\n constructor(options: VercelSandboxOptions = {}) {\n this.#runtime = options.runtime ?? \"node24\";\n this.#defaultTimeout = normalizeSandboxTimeout(\n options.defaultTimeout ?? options.timeout,\n \"Vercel sandbox default timeout\",\n );\n }\n\n isSessionUnavailableError(error: unknown): boolean {\n if (!(error instanceof Error)) {\n return false;\n }\n\n const message = error.message.toLowerCase();\n return (\n message.includes(\"not found\") ||\n message.includes(\"does not exist\") ||\n message.includes(\"sandbox_stopped\") ||\n message.includes(\"sandbox stopped\")\n );\n }\n\n async createSandbox(\n _workspace: WorkspaceRecord,\n options: SandboxCreateOptions,\n ): Promise<SandboxDriver> {\n const timeout = this.#defaultTimeoutForCreate(options);\n\n const sandbox = await Sandbox.create({\n runtime: this.#runtime,\n timeout,\n ports: options.exposedPorts,\n networkPolicy: compileVercelNetworkPolicy(options.policy),\n });\n\n return new VercelSandboxDriver(sandbox);\n }\n\n async resumeSandbox(\n workspace: WorkspaceRecord,\n snapshot: PersistedSandboxState,\n options: SandboxCreateOptions,\n ): Promise<SandboxDriver> {\n const timeout = this.#defaultTimeoutForCreate(options);\n const state = snapshot.state as VercelPersistedState | undefined;\n const snapshotId = state?.snapshotId;\n const fallbackSandboxId = workspace.sandboxId ?? snapshot.sessionId;\n\n const sandbox =\n snapshotId === undefined || typeof snapshotId !== \"string\"\n ? await (fallbackSandboxId === undefined\n ? (() => {\n throw new Error(\"Persisted sandbox state is missing restore information\");\n })()\n : Sandbox.get({ sandboxId: fallbackSandboxId }))\n : await Sandbox.create({\n source: {\n type: \"snapshot\",\n snapshotId,\n },\n timeout,\n ports: options.exposedPorts,\n networkPolicy: compileVercelNetworkPolicy(options.policy),\n });\n\n // Reattaching to an existing live sandbox should not mutate provider state.\n // Updating the network policy here races with commit/snapshot shutdown and can\n // fail on otherwise read-only flows like getActiveLease().\n return new VercelSandboxDriver(sandbox);\n }\n\n #defaultTimeoutForCreate(options: SandboxCreateOptions): number {\n return normalizeSandboxTimeout(options.timeoutMs ?? this.#defaultTimeout, \"runtime timeout\");\n }\n}\n\nfunction normalizeSandboxTimeout(value: unknown, label: string): number {\n if (value === undefined) {\n return 60_000;\n }\n\n if (\n typeof value !== \"number\" ||\n !Number.isInteger(value) ||\n !Number.isFinite(value) ||\n value <= 0\n ) {\n throw new Error(`${label} must be a positive integer in milliseconds.`);\n }\n\n return value;\n}\n\nexport function createVercelSandboxDriverFactory(\n options: VercelSandboxOptions = {},\n): SandboxDriverFactory {\n return new VercelSandboxDriverFactory(options);\n}\n","import { resolveAiGatewayDefaultApiKey } from \"./ai-gateway.ts\";\nimport { resolveCodexDefaultApiKey } from \"./codex.ts\";\nimport { resolveGeminiDefaultApiKey } from \"./gemini.ts\";\nimport { resolveGithubDefaultApiKey } from \"./github.ts\";\n\nexport function resolveDefaultCredentialValue(serviceId: string): string | undefined {\n switch (serviceId) {\n case \"codex\":\n return resolveCodexDefaultApiKey();\n case \"gemini\":\n return resolveGeminiDefaultApiKey();\n case \"github\":\n return resolveGithubDefaultApiKey();\n case \"aiGateway\":\n return resolveAiGatewayDefaultApiKey();\n default:\n return undefined;\n }\n}\n\nexport function describeDefaultCredentialSource(serviceId: string): string {\n switch (serviceId) {\n case \"codex\":\n return \"CODEX_API_KEY\";\n case \"gemini\":\n return \"GEMINI_API_KEY\";\n case \"github\":\n return \"GITHUB_TOKEN\";\n case \"aiGateway\":\n return \"AI_GATEWAY_API_KEY\";\n default:\n return `default credential for service \"${serviceId}\"`;\n }\n}\n","import type {\n NetworkPolicy as VercelNetworkPolicy,\n NetworkPolicyRule as VercelNetworkPolicyRule,\n} from \"@vercel/sandbox\";\n\nimport {\n describeDefaultCredentialSource,\n resolveDefaultCredentialValue,\n} from \"../policies/default-credentials.ts\";\nimport type { PolicyServiceHeaderTransform, WorkspacePolicy } from \"../policies/types.ts\";\n\nfunction resolveCredentialValue(serviceId: string, header: PolicyServiceHeaderTransform): string {\n if (header.credential.kind === \"value\") {\n return header.credential.value;\n }\n\n if (header.credential.kind === \"default\") {\n const value = resolveDefaultCredentialValue(serviceId);\n if (!value) {\n throw new Error(\n `Workspace policy for service \"${serviceId}\" requires ${describeDefaultCredentialSource(serviceId)}.`,\n );\n }\n return value;\n }\n\n throw new Error(\n `Workspace policy for service \"${serviceId}\" contains a redacted credential and cannot be applied.`,\n );\n}\n\nfunction encodeHeaderValue(\n value: string,\n encoding: PolicyServiceHeaderTransform[\"valueEncoding\"],\n): string {\n if (encoding === \"base64\") {\n return Buffer.from(value, \"utf8\").toString(\"base64\");\n }\n\n return value;\n}\n\nfunction compileHeaderRules(\n serviceId: string,\n headers: readonly PolicyServiceHeaderTransform[] | undefined,\n): VercelNetworkPolicyRule[] {\n if (!headers || headers.length === 0) {\n return [];\n }\n\n const resolvedHeaders = Object.fromEntries(\n headers.map((header) => [\n header.headerName,\n `${header.valuePrefix ?? \"\"}${encodeHeaderValue(\n `${header.credentialPrefix ?? \"\"}${resolveCredentialValue(serviceId, header)}`,\n header.valueEncoding,\n )}`,\n ]),\n );\n\n return [\n {\n transform: [\n {\n headers: resolvedHeaders,\n },\n ],\n },\n ];\n}\n\nexport function compileVercelNetworkPolicy(policy: WorkspacePolicy): VercelNetworkPolicy {\n switch (policy.mode) {\n case \"allow-all\":\n return \"allow-all\";\n case \"deny-all\":\n return \"deny-all\";\n case \"allow-services\": {\n const allow: Record<string, VercelNetworkPolicyRule[]> = {};\n\n for (const service of policy.services) {\n for (const domain of service.domains) {\n const rules = compileHeaderRules(\n service.id,\n service.domainHeaders?.[domain] ?? service.headers,\n );\n const existing = allow[domain] ?? [];\n allow[domain] = [...existing, ...rules];\n }\n }\n\n return { allow };\n }\n }\n}\n","import { createVercelSandboxDriverFactory } from \"../drivers/vercel-sandbox.ts\";\nimport { createSandboxProvider } from \"../types.ts\";\nimport type { SandkitSandboxProvider, VercelSandboxOptions } from \"../types.ts\";\n\nexport type { SandkitSandboxProvider, VercelSandboxOptions } from \"../types.ts\";\n\nexport function vercelSandbox(options: VercelSandboxOptions = {}): SandkitSandboxProvider {\n return createSandboxProvider(\"vercel\", createVercelSandboxDriverFactory(options));\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA,SAAS,eAAe;;;ACKjB,SAAS,8BAA8B,WAAuC;AACnF,UAAQ,WAAW;AAAA,IACjB,KAAK;AACH,aAAO,0BAA0B;AAAA,IACnC,KAAK;AACH,aAAO,2BAA2B;AAAA,IACpC,KAAK;AACH,aAAO,2BAA2B;AAAA,IACpC,KAAK;AACH,aAAO,8BAA8B;AAAA,IACvC;AACE,aAAO;AAAA,EACX;AACF;AAEO,SAAS,gCAAgC,WAA2B;AACzE,UAAQ,WAAW;AAAA,IACjB,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO,mCAAmC,SAAS;AAAA,EACvD;AACF;;;ACtBA,SAAS,uBAAuB,WAAmB,QAA8C;AAC/F,MAAI,OAAO,WAAW,SAAS,SAAS;AACtC,WAAO,OAAO,WAAW;AAAA,EAC3B;AAEA,MAAI,OAAO,WAAW,SAAS,WAAW;AACxC,UAAM,QAAQ,8BAA8B,SAAS;AACrD,QAAI,CAAC,OAAO;AACV,YAAM,IAAI;AAAA,QACR,iCAAiC,SAAS,cAAc,gCAAgC,SAAS,CAAC;AAAA,MACpG;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,QAAM,IAAI;AAAA,IACR,iCAAiC,SAAS;AAAA,EAC5C;AACF;AAEA,SAAS,kBACP,OACA,UACQ;AACR,MAAI,aAAa,UAAU;AACzB,WAAO,OAAO,KAAK,OAAO,MAAM,EAAE,SAAS,QAAQ;AAAA,EACrD;AAEA,SAAO;AACT;AAEA,SAAS,mBACP,WACA,SAC2B;AAC3B,MAAI,CAAC,WAAW,QAAQ,WAAW,GAAG;AACpC,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,kBAAkB,OAAO;AAAA,IAC7B,QAAQ,IAAI,CAAC,WAAW;AAAA,MACtB,OAAO;AAAA,MACP,GAAG,OAAO,eAAe,EAAE,GAAG;AAAA,QAC5B,GAAG,OAAO,oBAAoB,EAAE,GAAG,uBAAuB,WAAW,MAAM,CAAC;AAAA,QAC5E,OAAO;AAAA,MACT,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAEA,SAAO;AAAA,IACL;AAAA,MACE,WAAW;AAAA,QACT;AAAA,UACE,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,2BAA2B,QAA8C;AACvF,UAAQ,OAAO,MAAM;AAAA,IACnB,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK,kBAAkB;AACrB,YAAM,QAAmD,CAAC;AAE1D,iBAAW,WAAW,OAAO,UAAU;AACrC,mBAAW,UAAU,QAAQ,SAAS;AACpC,gBAAM,QAAQ;AAAA,YACZ,QAAQ;AAAA,YACR,QAAQ,gBAAgB,MAAM,KAAK,QAAQ;AAAA,UAC7C;AACA,gBAAM,WAAW,MAAM,MAAM,KAAK,CAAC;AACnC,gBAAM,MAAM,IAAI,CAAC,GAAG,UAAU,GAAG,KAAK;AAAA,QACxC;AAAA,MACF;AAEA,aAAO,EAAE,MAAM;AAAA,IACjB;AAAA,EACF;AACF;;;AF5DA,IAAM,sBAAN,MAAmD;AAAA,EACxC;AAAA,EACA,WAAW;AAAA,EAEpB,YAAY,SAAkD;AAC5D,SAAK,WAAW;AAAA,EAClB;AAAA,EAEA,IAAI,KAAa;AACf,WAAO,KAAK,SAAS;AAAA,EACvB;AAAA,EAEA,MAAM,YAAY,QAAwC;AACxD,UAAM,KAAK,SAAS,oBAAoB,2BAA2B,MAAM,CAAC;AAAA,EAC5E;AAAA,EAEA,MAAM,kBAAgD;AACpD,UAAM,UAAU,KAAK;AACrB,UAAM,cAAa,oBAAI,KAAK,GAAE,YAAY;AAC1C,UAAM,YACJ,OAAO,QAAQ,YAAY,YAAY,OAAO,SAAS,QAAQ,OAAO,KAAK,QAAQ,UAAU,IACzF,QAAQ,UACR;AAEN,WAAO;AAAA,MACL,WAAW,QAAQ;AAAA,MACnB;AAAA,MACA,WAAW,IAAI,KAAK,KAAK,MAAM,UAAU,IAAI,SAAS,EAAE,YAAY;AAAA,IACtE;AAAA,EACF;AAAA,EAEA,MAAM,WAAW,SAAiB,MAAwC;AACxE,UAAM,SAAS,MAAM,KAAK,SAAS,WAAW,SAAS,IAAI;AAC3D,UAAM,WAAW,MAAM,KAAK,mBAAmB,MAAM;AAErD,WAAO;AAAA,MACL,UAAU,SAAS;AAAA,MACnB,QAAQ,MAAM,SAAS,OAAO;AAAA,MAC9B,QAAQ,MAAM,SAAS,OAAO;AAAA,IAChC;AAAA,EACF;AAAA,EAEA,MAAM,aAAa,OAA4E;AAC7F,UAAM,UAAU,MAAM,KAAK,SAAS,WAAW;AAAA,MAC7C,KAAK,MAAM;AAAA,MACX,MAAM,CAAC,GAAG,MAAM,IAAI;AAAA,MACpB,UAAU;AAAA,IACZ,CAAC;AACD,QAAI,CAAC,sBAAsB,OAAO,GAAG;AACnC,YAAM,IAAI,MAAM,0DAA0D;AAAA,IAC5E;AAEA,UAAM,YAAY,QAAQ,SAAS,GAAG,KAAK,SAAS,SAAS,IAAI,KAAK,IAAI,CAAC;AAC3E,UAAM,sBAAsB;AAAA,MAC1B,sBAAsB,OAAO;AAAA,MAC7B,MAAM;AAAA,MACN,MAAM;AAAA,IACR;AAEA,WAAO;AAAA,MACL;AAAA,MACA,MAAM,YAAoC;AACxC,cAAM,WAAW,MAAM,QAAQ,KAAK;AACpC,eAAO;AAAA,UACL,UAAU,SAAS;AAAA,UACnB,QAAQ,MAAM,SAAS,OAAO;AAAA,UAC9B,QAAQ,MAAM,SAAS,OAAO;AAAA,QAChC;AAAA,MACF;AAAA,MACA,MAAM,sBAAsB,MAAM,oBAAoB,IAAI;AAAA,IAC5D;AAAA,EACF;AAAA,EAEA,MAAM,IAAI,MAA+B;AACvC,QAAI;AACF,aAAO,KAAK,SAAS,OAAO,IAAI;AAAA,IAClC,SAAS,OAAO;AACd,UAAI,EAAE,iBAAiB,UAAU,CAAC,MAAM,QAAQ,SAAS,mBAAmB,GAAG;AAC7E,cAAM;AAAA,MACR;AAEA,YAAM,YAAY,MAAM,QAAQ,IAAI,EAAE,WAAW,KAAK,SAAS,UAAU,CAAC;AAC1E,aAAO,UAAU,OAAO,IAAI;AAAA,IAC9B;AAAA,EACF;AAAA,EAEA,MAAM,cAAc,YAAmC;AACrD,UAAM,gBACJ,KAAK,SACL;AACF,QAAI,CAAC,eAAe;AAClB,YAAM,IAAI,MAAM,uDAAuD;AAAA,IACzE;AAEA,UAAM,cAAc,KAAK,KAAK,UAAU,UAAU;AAAA,EACpD;AAAA,EAEA,MAAM,WAA2C;AAG/C,UAAM,WAAW,MAAM,KAAK,SAAS,SAAS;AAE9C,WAAO;AAAA,MACL,MAAM;AAAA,MACN,WAAW,KAAK,SAAS;AAAA,MACzB,OAAO;AAAA,QACL,YAAY,SAAS;AAAA,MACvB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,mBAAmB,KAA8C;AACrE,QAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM;AAC3C,YAAM,IAAI,MAAM,4CAA4C;AAAA,IAC9D;AAEA,UAAM,YAAY;AAClB,QAAI,UAAU,MAAM;AAClB,aAAO,UAAU,KAAK;AAAA,IACxB;AAEA,WAAO;AAAA,EACT;AACF;AAEA,SAAS,sBAAsB,OAA8C;AAC3E,MAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AAC/C,WAAO;AAAA,EACT;AAEA,QAAM,YAAY;AAClB,MAAI,OAAO,UAAU,SAAS,YAAY;AACxC,WAAO;AAAA,EACT;AAEA,SAAO,UAAU,UAAU,UAAa,OAAO,UAAU,UAAU;AACrE;AAEA,SAAS,WAAwB,OAAsC;AACrE,SACE,UAAU,SACT,OAAO,UAAU,YAAY,OAAO,UAAU,eAC/C,OAAQ,MAAsB,OAAO,QAAQ,MAAM;AAEvD;AAEA,SAAS,gBAA6B,OAA2C;AAC/E,SACE,UAAU,SACT,OAAO,UAAU,YAAY,OAAO,UAAU,eAC/C,OAAQ,MAA2B,OAAO,aAAa,MAAM;AAEjE;AAEA,SAAS,sBAAsB,KAA8D;AAC3F,QAAM,UAAU,IAAI,OAAO;AAC3B,MAAI,YAAY,QAAW;AACzB,WAAO;AAAA,EACT;AACA,MAAI,gBAAyB,OAAO,GAAG;AACrC,WAAO;AAAA,EACT;AACA,MAAI,WAAoB,OAAO,GAAG;AAChC,WAAO,wBAAwB,OAAO;AAAA,EACxC;AACA,SAAO;AACT;AAEA,SAAS,wBAA2B,UAAyC;AAC3E,SAAO;AAAA,IACL,QAAQ,OAAO,aAAa,IAAI;AAC9B,iBAAW,SAAS,UAAU;AAC5B,cAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,4BACP,MACA,UACA,UACwD;AACxD,MAAI,CAAC,MAAM;AACT,WAAO;AAAA,EACT;AAEA,QAAM,eAAsC,CAAC;AAC7C,QAAM,UAA6B,CAAC;AACpC,MAAI,YAAY;AAChB,MAAI,QAAiB;AACrB,MAAI,cAAc;AAElB,QAAM,gBAAgB,MAAM;AAC1B,WAAO,QAAQ,SAAS,GAAG;AACzB,cAAQ,IAAI,IAAI;AAAA,IAClB;AAAA,EACF;AAEA,QAAM,MAAM,YAA2B;AACrC,QAAI,aAAa;AACf;AAAA,IACF;AACA,kBAAc;AAEd,QAAI;AACF,uBAAiB,OAAO,MAAM;AAC5B,cAAM,aAAa,oBAAoB,GAAG;AAC1C,YAAI,CAAC,YAAY;AACf;AAAA,QACF;AAEA,qBAAa,KAAK,UAAU;AAC5B,YAAI,WAAW,WAAW,UAAU;AAClC,qBAAW,WAAW,KAAK;AAAA,QAC7B,OAAO;AACL,qBAAW,WAAW,KAAK;AAAA,QAC7B;AACA,sBAAc;AAAA,MAChB;AAAA,IACF,SAAS,OAAO;AACd,cAAQ;AAAA,IACV,UAAE;AACA,kBAAY;AACZ,oBAAc;AAAA,IAChB;AAAA,EACF;AAEA,OAAK,IAAI,EAAE,MAAM,MAAM;AAAA,EAAC,CAAC;AAEzB,QAAM,cAAc,MAAqB;AACvC,WAAO,IAAI,QAAc,CAAC,YAAY;AACpC,cAAQ,KAAK,OAAO;AAAA,IACtB,CAAC;AAAA,EACH;AAEA,QAAM,oBAAoB,MAA0C;AAClE,WAAO;AAAA,MACL,QAAQ,OAAO,aAAa,IAAI;AAC9B,YAAI,QAAQ;AACZ,eAAO,MAAM;AACX,cAAI,QAAQ,aAAa,QAAQ;AAC/B,kBAAM,aAAa,OAAO;AAC1B;AAAA,UACF;AACA,cAAI,UAAU,MAAM;AAClB,kBAAM,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,2BAA2B;AAAA,UAC9E;AACA,cAAI,WAAW;AACb;AAAA,UACF;AACA,gBAAM,YAAY;AAAA,QACpB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,oBAAoB,KAA0C;AAC5E,MAAI,OAAO,QAAQ,UAAU;AAC3B,WAAO,EAAE,QAAQ,UAAU,OAAO,IAAI;AAAA,EACxC;AACA,MAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM;AAC3C,WAAO;AAAA,EACT;AAEA,QAAM,YAAY;AAQlB,QAAM,cAAc,UAAU;AAC9B,QAAM,SAAS,gBAAgB,YAAY,gBAAgB,WAAW,cAAc;AACpF,QAAM,WACJ,UAAU,QACV,UAAU,UACV,UAAU,SACV,UAAU,QACV,UAAU,WACV;AAEF,MAAI,OAAO,aAAa,UAAU;AAChC,WAAO;AAAA,EACT;AAEA,SAAO,EAAE,QAAQ,OAAO,SAAS;AACnC;AAEA,IAAM,6BAAN,MAAiE;AAAA,EACtD;AAAA,EACA;AAAA,EAET,YAAY,UAAgC,CAAC,GAAG;AAC9C,SAAK,WAAW,QAAQ,WAAW;AACnC,SAAK,kBAAkB;AAAA,MACrB,QAAQ,kBAAkB,QAAQ;AAAA,MAClC;AAAA,IACF;AAAA,EACF;AAAA,EAEA,0BAA0B,OAAyB;AACjD,QAAI,EAAE,iBAAiB,QAAQ;AAC7B,aAAO;AAAA,IACT;AAEA,UAAM,UAAU,MAAM,QAAQ,YAAY;AAC1C,WACE,QAAQ,SAAS,WAAW,KAC5B,QAAQ,SAAS,gBAAgB,KACjC,QAAQ,SAAS,iBAAiB,KAClC,QAAQ,SAAS,iBAAiB;AAAA,EAEtC;AAAA,EAEA,MAAM,cACJ,YACA,SACwB;AACxB,UAAM,UAAU,KAAK,yBAAyB,OAAO;AAErD,UAAM,UAAU,MAAM,QAAQ,OAAO;AAAA,MACnC,SAAS,KAAK;AAAA,MACd;AAAA,MACA,OAAO,QAAQ;AAAA,MACf,eAAe,2BAA2B,QAAQ,MAAM;AAAA,IAC1D,CAAC;AAED,WAAO,IAAI,oBAAoB,OAAO;AAAA,EACxC;AAAA,EAEA,MAAM,cACJ,WACA,UACA,SACwB;AACxB,UAAM,UAAU,KAAK,yBAAyB,OAAO;AACrD,UAAM,QAAQ,SAAS;AACvB,UAAM,aAAa,OAAO;AAC1B,UAAM,oBAAoB,UAAU,aAAa,SAAS;AAE1D,UAAM,UACJ,eAAe,UAAa,OAAO,eAAe,WAC9C,OAAO,sBAAsB,UACxB,MAAM;AACL,YAAM,IAAI,MAAM,wDAAwD;AAAA,IAC1E,GAAG,IACH,QAAQ,IAAI,EAAE,WAAW,kBAAkB,CAAC,KAChD,MAAM,QAAQ,OAAO;AAAA,MACnB,QAAQ;AAAA,QACN,MAAM;AAAA,QACN;AAAA,MACF;AAAA,MACA;AAAA,MACA,OAAO,QAAQ;AAAA,MACf,eAAe,2BAA2B,QAAQ,MAAM;AAAA,IAC1D,CAAC;AAKP,WAAO,IAAI,oBAAoB,OAAO;AAAA,EACxC;AAAA,EAEA,yBAAyB,SAAuC;AAC9D,WAAO,wBAAwB,QAAQ,aAAa,KAAK,iBAAiB,iBAAiB;AAAA,EAC7F;AACF;AAEA,SAAS,wBAAwB,OAAgB,OAAuB;AACtE,MAAI,UAAU,QAAW;AACvB,WAAO;AAAA,EACT;AAEA,MACE,OAAO,UAAU,YACjB,CAAC,OAAO,UAAU,KAAK,KACvB,CAAC,OAAO,SAAS,KAAK,KACtB,SAAS,GACT;AACA,UAAM,IAAI,MAAM,GAAG,KAAK,8CAA8C;AAAA,EACxE;AAEA,SAAO;AACT;AAEO,SAAS,iCACd,UAAgC,CAAC,GACX;AACtB,SAAO,IAAI,2BAA2B,OAAO;AAC/C;;;AGtaO,SAAS,cAAc,UAAgC,CAAC,GAA2B;AACxF,SAAO,sBAAsB,UAAU,iCAAiC,OAAO,CAAC;AAClF;","names":[]}
|
package/dist/policies/codex.d.ts
CHANGED
package/dist/policies/codex.js
CHANGED
package/dist/policies/gemini.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as SandkitAdapter, S as SharedSetup, W as WorkspaceRecord, b as WorkspaceMetadata, c as WorkspaceStatus } from './types-
|
|
2
|
-
import { W as WorkspacePolicy } from './types-
|
|
1
|
+
import { a as SandkitAdapter, S as SharedSetup, W as WorkspaceRecord, b as WorkspaceMetadata, c as WorkspaceStatus } from './types-BRMAvcWc.js';
|
|
2
|
+
import { W as WorkspacePolicy } from './types-Dpr_BkF9.js';
|
|
3
3
|
|
|
4
4
|
type JsonPrimitive = boolean | number | string | null;
|
|
5
5
|
type JsonValue = JsonPrimitive | JsonValue[] | {
|
|
@@ -4,6 +4,7 @@ interface PolicyServiceDescriptor {
|
|
|
4
4
|
readonly description?: string;
|
|
5
5
|
readonly domains: readonly string[];
|
|
6
6
|
readonly headers?: readonly PolicyServiceHeaderTransform[];
|
|
7
|
+
readonly domainHeaders?: Readonly<Record<string, readonly PolicyServiceHeaderTransform[]>>;
|
|
7
8
|
}
|
|
8
9
|
interface PolicyServiceCredentialDefault {
|
|
9
10
|
readonly kind: "default";
|
|
@@ -19,6 +20,8 @@ type PolicyServiceCredentialSource = PolicyServiceCredentialDefault | PolicyServ
|
|
|
19
20
|
interface PolicyServiceHeaderTransform {
|
|
20
21
|
readonly headerName: string;
|
|
21
22
|
readonly valuePrefix?: string;
|
|
23
|
+
readonly credentialPrefix?: string;
|
|
24
|
+
readonly valueEncoding?: "plain" | "base64";
|
|
22
25
|
readonly credential: PolicyServiceCredentialSource;
|
|
23
26
|
}
|
|
24
27
|
interface WorkspaceAllowAllPolicy {
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/policies/dsl.ts"],"sourcesContent":["import type { JsonValue } from \"../types.ts\";\nimport type {\n PolicyServiceCredentialSource,\n PolicyServiceDescriptor,\n PolicyServiceHeaderTransform,\n WorkspacePolicy,\n} from \"./types.ts\";\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isStringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.every((entry) => typeof entry === \"string\");\n}\n\nfunction isRecordArray(value: unknown): value is Record<string, unknown>[] {\n return Array.isArray(value) && value.every((entry) => isRecord(entry));\n}\n\nfunction normalizeCredentialSource(\n source: PolicyServiceCredentialSource,\n): PolicyServiceCredentialSource {\n if (source.kind === \"default\") {\n return { kind: \"default\" };\n }\n\n if (source.kind === \"value\") {\n if (!source.value) {\n throw new Error(\"Policy credential value must not be empty.\");\n }\n return { kind: \"value\", value: source.value };\n }\n\n return { kind: \"redacted\" };\n}\n\nfunction normalizeHeaderTransform(\n header: PolicyServiceHeaderTransform,\n): PolicyServiceHeaderTransform {\n const headerName = header.headerName.trim().toLowerCase();\n if (!headerName) {\n throw new Error(\"Policy header transform must include a header name.\");\n }\n\n return {\n headerName,\n valuePrefix: header.valuePrefix,\n credential: normalizeCredentialSource(header.credential),\n };\n}\n\nfunction normalizeService(service: PolicyServiceDescriptor): PolicyServiceDescriptor {\n const id = service.id.trim();\n const name = service.name.trim();\n const domains = [\n ...new Set(service.domains.map((domain) => domain.trim()).filter(Boolean)),\n ].sort();\n\n if (!id) {\n throw new Error(\"Policy service id must not be empty.\");\n }\n\n if (!name) {\n throw new Error(`Policy service \"${id}\" must have a name.`);\n }\n\n if (domains.length === 0) {\n throw new Error(`Policy service \"${id}\" must declare at least one domain.`);\n }\n\n return {\n id,\n name,\n description: service.description?.trim() || undefined,\n domains,\n headers: service.headers?.map((header) => normalizeHeaderTransform(header)),\n };\n}\n\nfunction normalizeServices(\n services: readonly PolicyServiceDescriptor[],\n): readonly PolicyServiceDescriptor[] {\n if (services.length === 0) {\n throw new Error(\"allowServices(...) requires at least one service descriptor.\");\n }\n\n const deduped = new Map<string, PolicyServiceDescriptor>();\n for (const service of services) {\n const normalized = normalizeService(service);\n deduped.set(normalized.id, normalized);\n }\n\n return [...deduped.values()].sort((left, right) => left.id.localeCompare(right.id));\n}\n\nexport function allowAll(): WorkspacePolicy {\n return { mode: \"allow-all\" };\n}\n\nexport function denyAll(): WorkspacePolicy {\n return { mode: \"deny-all\" };\n}\n\nexport function allowService(service: PolicyServiceDescriptor): WorkspacePolicy {\n return allowServices([service]);\n}\n\nexport function allowServices(services: readonly PolicyServiceDescriptor[]): WorkspacePolicy {\n return {\n mode: \"allow-services\",\n services: normalizeServices(services),\n };\n}\n\nexport function describeWorkspacePolicy(policy: WorkspacePolicy): string {\n switch (policy.mode) {\n case \"allow-all\":\n return \"allow-all\";\n case \"deny-all\":\n return \"deny-all\";\n case \"allow-services\":\n return `allow-services:${policy.services.map((service) => service.id).join(\",\")}`;\n }\n}\n\nexport function serializeWorkspacePolicy(policy: WorkspacePolicy): JsonValue {\n return policy as unknown as JsonValue;\n}\n\nexport function redactWorkspacePolicy(policy: WorkspacePolicy): WorkspacePolicy {\n if (policy.mode !== \"allow-services\") {\n return policy;\n }\n\n return {\n mode: \"allow-services\",\n services: policy.services.map((service) => ({\n ...service,\n headers: service.headers?.map((header) => ({\n headerName: header.headerName,\n valuePrefix: header.valuePrefix,\n credential: header.credential.kind === \"value\" ? { kind: \"redacted\" } : header.credential,\n })),\n })),\n };\n}\n\nexport function assertWorkspacePolicyIsDurable(policy: WorkspacePolicy): void {\n if (policy.mode !== \"allow-services\") {\n return;\n }\n\n for (const service of policy.services) {\n for (const header of service.headers ?? []) {\n if (header.credential.kind === \"value\") {\n throw new Error(\n `Workspace policy for service \"${service.id}\" contains an explicit secret and cannot be stored durably.`,\n );\n }\n }\n }\n}\n\nexport function parseWorkspacePolicy(value: unknown): WorkspacePolicy {\n if (!isRecord(value) || typeof value.mode !== \"string\") {\n throw new Error(\"expected workspace policy object\");\n }\n\n if (value.mode === \"allow-all\") {\n return allowAll();\n }\n\n if (value.mode === \"deny-all\") {\n return denyAll();\n }\n\n if (value.mode === \"allow-services\") {\n if (!Array.isArray(value.services)) {\n throw new Error(\"allow-services policy must include a services array\");\n }\n\n const services = value.services.map((service, index) => {\n if (!isRecord(service)) {\n throw new Error(`service at index ${index} must be an object`);\n }\n\n if (\n typeof service.id !== \"string\" ||\n typeof service.name !== \"string\" ||\n !isStringArray(service.domains)\n ) {\n throw new Error(`service at index ${index} has an invalid shape`);\n }\n\n const headers =\n service.headers === undefined\n ? undefined\n : (() => {\n if (!isRecordArray(service.headers)) {\n throw new Error(`service at index ${index} has invalid headers`);\n }\n\n return service.headers.map((header, headerIndex) => {\n if (\n typeof header.headerName !== \"string\" ||\n !isRecord(header.credential) ||\n typeof header.credential.kind !== \"string\"\n ) {\n throw new Error(\n `service at index ${index} has invalid header transform at ${headerIndex}`,\n );\n }\n\n if (header.credential.kind === \"default\") {\n return normalizeHeaderTransform({\n headerName: header.headerName,\n valuePrefix:\n typeof header.valuePrefix === \"string\" ? header.valuePrefix : undefined,\n credential: {\n kind: \"default\",\n },\n });\n }\n\n if (header.credential.kind === \"redacted\") {\n return normalizeHeaderTransform({\n headerName: header.headerName,\n valuePrefix:\n typeof header.valuePrefix === \"string\" ? header.valuePrefix : undefined,\n credential: { kind: \"redacted\" },\n });\n }\n\n throw new Error(\n `service at index ${index} contains a non-durable credential source`,\n );\n });\n })();\n\n return normalizeService({\n id: service.id,\n name: service.name,\n description: typeof service.description === \"string\" ? service.description : undefined,\n domains: service.domains,\n headers,\n });\n });\n\n return allowServices(services);\n }\n\n throw new Error(`unsupported workspace policy mode \"${value.mode}\"`);\n}\n"],"mappings":"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","names":[]}
|
package/dist/chunk-XM4HGRXW.js
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
// src/policies/github.ts
|
|
2
|
-
var GITHUB_DOMAINS = ["github.com", "*.github.com", "api.github.com", "*.githubusercontent.com"];
|
|
3
|
-
function resolveGithubCredential(options) {
|
|
4
|
-
if (options === void 0) {
|
|
5
|
-
return { kind: "default" };
|
|
6
|
-
}
|
|
7
|
-
if (typeof options.apiKey !== "string" || options.apiKey.trim().length === 0) {
|
|
8
|
-
throw new Error(
|
|
9
|
-
'github(...) explicit override requires a non-empty "apiKey". Omit the options object to use GITHUB_TOKEN.'
|
|
10
|
-
);
|
|
11
|
-
}
|
|
12
|
-
return { kind: "value", value: options.apiKey };
|
|
13
|
-
}
|
|
14
|
-
function resolveGithubDefaultApiKey() {
|
|
15
|
-
return process.env.GITHUB_TOKEN;
|
|
16
|
-
}
|
|
17
|
-
function github(options) {
|
|
18
|
-
return {
|
|
19
|
-
id: "github",
|
|
20
|
-
name: "GitHub",
|
|
21
|
-
description: "Allow outbound access commonly needed for GitHub APIs and assets.",
|
|
22
|
-
domains: GITHUB_DOMAINS,
|
|
23
|
-
headers: [
|
|
24
|
-
{
|
|
25
|
-
headerName: "authorization",
|
|
26
|
-
valuePrefix: "Bearer ",
|
|
27
|
-
credential: resolveGithubCredential(options)
|
|
28
|
-
}
|
|
29
|
-
]
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export {
|
|
34
|
-
resolveGithubDefaultApiKey,
|
|
35
|
-
github
|
|
36
|
-
};
|
|
37
|
-
//# sourceMappingURL=chunk-XM4HGRXW.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/policies/github.ts"],"sourcesContent":["import type { PolicyServiceDescriptor } from \"./types.ts\";\n\nconst GITHUB_DOMAINS = [\"github.com\", \"*.github.com\", \"api.github.com\", \"*.githubusercontent.com\"];\n\nexport interface GithubOptions {\n readonly apiKey?: string;\n}\n\nfunction resolveGithubCredential(options?: GithubOptions) {\n if (options === undefined) {\n return { kind: \"default\" } as const;\n }\n\n if (typeof options.apiKey !== \"string\" || options.apiKey.trim().length === 0) {\n throw new Error(\n 'github(...) explicit override requires a non-empty \"apiKey\". Omit the options object to use GITHUB_TOKEN.',\n );\n }\n\n return { kind: \"value\", value: options.apiKey } as const;\n}\n\nexport function resolveGithubDefaultApiKey(): string | undefined {\n return process.env.GITHUB_TOKEN;\n}\n\nexport function github(options?: GithubOptions): PolicyServiceDescriptor {\n return {\n id: \"github\",\n name: \"GitHub\",\n description: \"Allow outbound access commonly needed for GitHub APIs and assets.\",\n domains: GITHUB_DOMAINS,\n headers: [\n {\n headerName: \"authorization\",\n valuePrefix: \"Bearer \",\n credential: resolveGithubCredential(options),\n },\n ],\n };\n}\n"],"mappings":";AAEA,IAAM,iBAAiB,CAAC,cAAc,gBAAgB,kBAAkB,yBAAyB;AAMjG,SAAS,wBAAwB,SAAyB;AACxD,MAAI,YAAY,QAAW;AACzB,WAAO,EAAE,MAAM,UAAU;AAAA,EAC3B;AAEA,MAAI,OAAO,QAAQ,WAAW,YAAY,QAAQ,OAAO,KAAK,EAAE,WAAW,GAAG;AAC5E,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,MAAM,SAAS,OAAO,QAAQ,OAAO;AAChD;AAEO,SAAS,6BAAiD;AAC/D,SAAO,QAAQ,IAAI;AACrB;AAEO,SAAS,OAAO,SAAkD;AACvE,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,IACb,SAAS;AAAA,IACT,SAAS;AAAA,MACP;AAAA,QACE,YAAY;AAAA,QACZ,aAAa;AAAA,QACb,YAAY,wBAAwB,OAAO;AAAA,MAC7C;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|