@vercel/sandbox 2.0.0-beta.14 → 2.0.0-beta.18
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/dist/api-client/api-client.cjs +1 -14
- package/dist/api-client/api-client.cjs.map +1 -1
- package/dist/api-client/api-client.d.cts +5509 -76
- package/dist/api-client/api-client.d.ts +5509 -76
- package/dist/api-client/api-client.js +2 -15
- package/dist/api-client/api-client.js.map +1 -1
- package/dist/api-client/base-client.cjs +2 -1
- package/dist/api-client/base-client.cjs.map +1 -1
- package/dist/api-client/base-client.js +2 -1
- package/dist/api-client/base-client.js.map +1 -1
- package/dist/api-client/index.d.ts +1 -1
- package/dist/api-client/index.js +1 -1
- package/dist/api-client/validators.cjs +60 -16
- package/dist/api-client/validators.cjs.map +1 -1
- package/dist/api-client/validators.d.cts +25546 -130
- package/dist/api-client/validators.d.ts +25546 -130
- package/dist/api-client/validators.js +55 -16
- package/dist/api-client/validators.js.map +1 -1
- package/dist/auth/api.cjs +1 -1
- package/dist/auth/api.cjs.map +1 -1
- package/dist/auth/api.js +1 -1
- package/dist/auth/api.js.map +1 -1
- package/dist/auth/index.cjs +0 -1
- package/dist/auth/index.d.cts +2 -2
- package/dist/auth/index.d.ts +2 -2
- package/dist/auth/index.js +2 -2
- package/dist/auth/project.cjs +124 -26
- package/dist/auth/project.cjs.map +1 -1
- package/dist/auth/project.d.cts +9 -13
- package/dist/auth/project.d.ts +9 -13
- package/dist/auth/project.js +125 -26
- package/dist/auth/project.js.map +1 -1
- package/dist/filesystem.cjs +499 -0
- package/dist/filesystem.cjs.map +1 -0
- package/dist/filesystem.d.cts +258 -0
- package/dist/filesystem.d.ts +258 -0
- package/dist/filesystem.js +497 -0
- package/dist/filesystem.js.map +1 -0
- package/dist/index.cjs +2 -0
- package/dist/index.d.cts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +2 -1
- package/dist/network-policy.d.cts +58 -2
- package/dist/network-policy.d.ts +58 -2
- package/dist/sandbox.cjs +137 -22
- package/dist/sandbox.cjs.map +1 -1
- package/dist/sandbox.d.cts +2068 -22
- package/dist/sandbox.d.ts +2068 -22
- package/dist/sandbox.js +137 -22
- package/dist/sandbox.js.map +1 -1
- package/dist/session.cjs +10 -7
- package/dist/session.cjs.map +1 -1
- package/dist/session.d.cts +7 -5
- package/dist/session.d.ts +7 -5
- package/dist/session.js +10 -7
- package/dist/session.js.map +1 -1
- package/dist/snapshot.cjs +63 -10
- package/dist/snapshot.cjs.map +1 -1
- package/dist/snapshot.d.cts +41 -9
- package/dist/snapshot.d.ts +41 -9
- package/dist/snapshot.js +62 -10
- package/dist/snapshot.js.map +1 -1
- package/dist/utils/network-policy.cjs +23 -39
- package/dist/utils/network-policy.cjs.map +1 -1
- package/dist/utils/network-policy.js +23 -39
- package/dist/utils/network-policy.js.map +1 -1
- package/dist/utils/paginator.cjs +41 -0
- package/dist/utils/paginator.cjs.map +1 -0
- package/dist/utils/paginator.d.cts +16 -0
- package/dist/utils/paginator.d.ts +16 -0
- package/dist/utils/paginator.js +40 -0
- package/dist/utils/paginator.js.map +1 -0
- package/dist/version.cjs +1 -1
- package/dist/version.cjs.map +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,22 +1,56 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
|
|
3
3
|
//#region src/api-client/validators.ts
|
|
4
|
+
const RuleMatcherValidator = z.object({
|
|
5
|
+
exact: z.string().optional(),
|
|
6
|
+
startsWith: z.string().optional(),
|
|
7
|
+
regex: z.string().optional()
|
|
8
|
+
});
|
|
9
|
+
const KeyValueMatcherValidator = z.object({
|
|
10
|
+
key: RuleMatcherValidator.optional(),
|
|
11
|
+
value: RuleMatcherValidator.optional()
|
|
12
|
+
});
|
|
13
|
+
const RuleMatchValidator = z.object({
|
|
14
|
+
path: RuleMatcherValidator.optional(),
|
|
15
|
+
method: z.array(z.string()).optional(),
|
|
16
|
+
queryString: z.array(KeyValueMatcherValidator).optional(),
|
|
17
|
+
headers: z.array(KeyValueMatcherValidator).optional()
|
|
18
|
+
});
|
|
4
19
|
const InjectionRuleValidator = z.object({
|
|
5
20
|
domain: z.string(),
|
|
6
21
|
headers: z.record(z.string()).optional(),
|
|
7
|
-
headerNames: z.array(z.string()).optional()
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
z.
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
22
|
+
headerNames: z.array(z.string()).optional(),
|
|
23
|
+
match: RuleMatchValidator.optional()
|
|
24
|
+
});
|
|
25
|
+
const ForwardRuleValidator = z.object({
|
|
26
|
+
domain: z.string(),
|
|
27
|
+
forwardURL: z.string(),
|
|
28
|
+
match: RuleMatchValidator.optional()
|
|
29
|
+
});
|
|
30
|
+
const NetworkPolicyTransformValidator = z.object({ headers: z.record(z.string()).optional() });
|
|
31
|
+
const NetworkPolicyRuleValidator = z.object({
|
|
32
|
+
match: RuleMatchValidator.optional(),
|
|
33
|
+
transform: z.array(NetworkPolicyTransformValidator).optional(),
|
|
34
|
+
forwardURL: z.string().optional()
|
|
35
|
+
});
|
|
36
|
+
const V2NetworkPolicyObjectValidator = z.object({
|
|
37
|
+
allow: z.union([z.array(z.string()), z.record(z.array(NetworkPolicyRuleValidator))]).optional(),
|
|
38
|
+
subnets: z.object({
|
|
39
|
+
allow: z.array(z.string()).optional(),
|
|
40
|
+
deny: z.array(z.string()).optional()
|
|
41
|
+
}).optional()
|
|
42
|
+
});
|
|
43
|
+
const NetworkPolicyModeValidator = z.union([z.object({ mode: z.literal("allow-all") }).passthrough(), z.object({ mode: z.literal("deny-all") }).passthrough()]);
|
|
44
|
+
const LegacyCustomNetworkPolicyValidator = z.object({
|
|
45
|
+
mode: z.literal("custom"),
|
|
46
|
+
allowedDomains: z.array(z.string()).optional(),
|
|
47
|
+
allowedCIDRs: z.array(z.string()).optional(),
|
|
48
|
+
deniedCIDRs: z.array(z.string()).optional(),
|
|
49
|
+
injectionRules: z.array(InjectionRuleValidator).optional(),
|
|
50
|
+
forwardRules: z.array(ForwardRuleValidator).optional()
|
|
51
|
+
}).passthrough();
|
|
52
|
+
const NetworkPolicyRequestValidator = z.union([NetworkPolicyModeValidator, V2NetworkPolicyObjectValidator.passthrough()]);
|
|
53
|
+
const NetworkPolicyResponseValidator = z.union([NetworkPolicyModeValidator, LegacyCustomNetworkPolicyValidator]);
|
|
20
54
|
const Session = z.object({
|
|
21
55
|
id: z.string(),
|
|
22
56
|
memory: z.number(),
|
|
@@ -45,7 +79,7 @@ const Session = z.object({
|
|
|
45
79
|
cwd: z.string(),
|
|
46
80
|
updatedAt: z.number(),
|
|
47
81
|
interactivePort: z.number().optional(),
|
|
48
|
-
networkPolicy:
|
|
82
|
+
networkPolicy: NetworkPolicyResponseValidator.optional(),
|
|
49
83
|
activeCpuDurationMs: z.number().optional(),
|
|
50
84
|
networkTransfer: z.object({
|
|
51
85
|
ingress: z.number(),
|
|
@@ -126,7 +160,7 @@ const Sandbox = z.object({
|
|
|
126
160
|
memory: z.number().optional(),
|
|
127
161
|
runtime: z.string().optional(),
|
|
128
162
|
timeout: z.number().optional(),
|
|
129
|
-
networkPolicy:
|
|
163
|
+
networkPolicy: NetworkPolicyResponseValidator.optional(),
|
|
130
164
|
totalEgressBytes: z.number().optional(),
|
|
131
165
|
totalIngressBytes: z.number().optional(),
|
|
132
166
|
totalActiveCpuDurationMs: z.number().optional(),
|
|
@@ -141,6 +175,11 @@ const Sandbox = z.object({
|
|
|
141
175
|
tags: z.record(z.string()).optional(),
|
|
142
176
|
snapshotExpiration: z.number().optional()
|
|
143
177
|
});
|
|
178
|
+
const StopSessionResponse = z.object({
|
|
179
|
+
session: Session.passthrough(),
|
|
180
|
+
sandbox: Sandbox.optional(),
|
|
181
|
+
snapshot: Snapshot.optional()
|
|
182
|
+
});
|
|
144
183
|
const SandboxAndSessionResponse = z.object({
|
|
145
184
|
sandbox: Sandbox,
|
|
146
185
|
session: Session.passthrough(),
|
|
@@ -154,5 +193,5 @@ const SandboxesPaginationResponse = z.object({
|
|
|
154
193
|
const UpdateSandboxResponse = z.object({ sandbox: Sandbox });
|
|
155
194
|
|
|
156
195
|
//#endregion
|
|
157
|
-
export { Command, CommandFinishedResponse, CommandResponse, CreateSnapshotResponse, CursorPagination, EmptyResponse, InjectionRuleValidator, LogError, LogLine, LogLineStderr, LogLineStdout,
|
|
196
|
+
export { Command, CommandFinishedResponse, CommandResponse, CreateSnapshotResponse, CursorPagination, EmptyResponse, ForwardRuleValidator, InjectionRuleValidator, LogError, LogLine, LogLineStderr, LogLineStdout, NetworkPolicyResponseValidator, NetworkPolicyRuleValidator, NetworkPolicyTransformValidator, Sandbox, SandboxAndSessionResponse, SandboxRoute, SandboxesPaginationResponse, Session, SessionAndRoutesResponse, SessionResponse, SessionsResponse, Snapshot, SnapshotResponse, SnapshotsResponse, StopSessionResponse, UpdateSandboxResponse, V2NetworkPolicyObjectValidator };
|
|
158
197
|
//# sourceMappingURL=validators.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validators.js","names":[],"sources":["../../src/api-client/validators.ts"],"sourcesContent":["import { z } from \"zod\";\n\nexport type SessionMetaData = z.infer<typeof Session>;\n\nexport const InjectionRuleValidator = z.object({\n domain: z.string(),\n // headers are only sent in requests\n headers: z.record(z.string()).optional(),\n // headerNames are returned in responses\n headerNames: z.array(z.string()).optional(),\n});\n\nexport const NetworkPolicyValidator = z.union([\n z.object({ mode: z.literal(\"allow-all\") }).passthrough(),\n z.object({ mode: z.literal(\"deny-all\") }).passthrough(),\n z\n .object({\n mode: z.literal(\"custom\"),\n allowedDomains: z.array(z.string()).optional(),\n allowedCIDRs: z.array(z.string()).optional(),\n deniedCIDRs: z.array(z.string()).optional(),\n injectionRules: z.array(InjectionRuleValidator).optional(),\n })\n .passthrough(),\n]);\n\nexport const Session = z.object({\n id: z.string(),\n memory: z.number(),\n vcpus: z.number(),\n region: z.string(),\n runtime: z.string(),\n timeout: z.number(),\n status: z.enum([\n \"pending\",\n \"running\",\n \"stopping\",\n \"stopped\",\n \"failed\",\n \"aborted\",\n \"snapshotting\",\n ]),\n requestedAt: z.number(),\n startedAt: z.number().optional(),\n requestedStopAt: z.number().optional(),\n stoppedAt: z.number().optional(),\n abortedAt: z.number().optional(),\n duration: z.number().optional(),\n sourceSnapshotId: z.string().optional(),\n snapshottedAt: z.number().optional(),\n createdAt: z.number(),\n cwd: z.string(),\n updatedAt: z.number(),\n interactivePort: z.number().optional(),\n networkPolicy: NetworkPolicyValidator.optional(),\n activeCpuDurationMs: z.number().optional(),\n networkTransfer: z.object({\n ingress: z.number(),\n egress: z.number(),\n }).optional(),\n});\n\nexport type SandboxRouteData = z.infer<typeof SandboxRoute>;\n\nexport const SandboxRoute = z.object({\n url: z.string(),\n subdomain: z.string(),\n port: z.number(),\n});\n\nexport type SnapshotMetadata = z.infer<typeof Snapshot>;\n\nexport const Snapshot = z.object({\n id: z.string(),\n sourceSessionId: z.string(),\n region: z.string(),\n status: z.enum([\"created\", \"deleted\", \"failed\"]),\n sizeBytes: z.number(),\n expiresAt: z.number().optional(),\n createdAt: z.number(),\n updatedAt: z.number(),\n});\n\nexport const CursorPagination = z.object({\n count: z.number(),\n next: z.string().nullable(),\n});\n\nexport type CommandData = z.infer<typeof Command>;\n\nexport const Command = z.object({\n id: z.string(),\n name: z.string(),\n args: z.array(z.string()),\n cwd: z.string(),\n sessionId: z.string(),\n exitCode: z.number().nullable(),\n startedAt: z.number(),\n});\n\nconst CommandFinished = Command.extend({\n exitCode: z.number(),\n});\n\nexport const SessionResponse = z.object({\n session: Session.passthrough(),\n});\n\nexport const SessionAndRoutesResponse = SessionResponse.extend({\n routes: z.array(SandboxRoute),\n});\n\nexport const SessionsResponse = z.object({\n sessions: z.array(Session.passthrough()),\n pagination: CursorPagination,\n});\n\nexport const CommandResponse = z.object({\n command: Command,\n});\n\nexport type CommandFinishedData = z.infer<typeof CommandFinishedResponse>[\"command\"];\n\nexport const CommandFinishedResponse = z.object({\n command: CommandFinished,\n});\n\nexport const EmptyResponse = z.object({});\n\nconst LogLineBase = z.object({ data: z.string() });\nexport const LogLineStdout = LogLineBase.extend({\n stream: z.literal(\"stdout\"),\n});\nexport const LogLineStderr = LogLineBase.extend({\n stream: z.literal(\"stderr\"),\n});\n\nexport const LogError = z.object({\n stream: z.literal(\"error\"),\n data: z.object({\n code: z.string(),\n message: z.string(),\n }),\n});\n\nexport const LogLine = z.discriminatedUnion(\"stream\", [\n LogLineStdout,\n LogLineStderr,\n LogError,\n]);\n\nexport const SnapshotsResponse = z.object({\n snapshots: z.array(Snapshot),\n pagination: CursorPagination,\n});\n\nexport const CreateSnapshotResponse = z.object({\n snapshot: Snapshot,\n session: Session.passthrough(),\n});\n\nexport const SnapshotResponse = z.object({\n snapshot: Snapshot,\n});\n\nexport const Sandbox = z.object({\n name: z.string(),\n persistent: z.boolean(),\n region: z.string().optional(),\n vcpus: z.number().optional(),\n memory: z.number().optional(),\n runtime: z.string().optional(),\n timeout: z.number().optional(),\n networkPolicy: NetworkPolicyValidator.optional(),\n totalEgressBytes: z.number().optional(),\n totalIngressBytes: z.number().optional(),\n totalActiveCpuDurationMs: z.number().optional(),\n totalDurationMs: z.number().optional(),\n createdAt: z.number(),\n updatedAt: z.number(),\n currentSessionId: z.string(),\n currentSnapshotId: z.string().optional(),\n status: Session.shape.status,\n statusUpdatedAt: z.number().optional(),\n cwd: z.string().optional(),\n tags: z.record(z.string()).optional(),\n snapshotExpiration: z.number().optional(),\n});\n\nexport type SandboxMetaData = z.infer<typeof Sandbox>;\n\nexport const SandboxAndSessionResponse = z.object({\n sandbox: Sandbox,\n session: Session.passthrough(),\n routes: z.array(SandboxRoute),\n resumed: z.boolean().optional(),\n});\n\nexport const SandboxesPaginationResponse = z.object({\n sandboxes: z.array(Sandbox),\n pagination: CursorPagination,\n});\n\nexport const UpdateSandboxResponse = z.object({\n sandbox: Sandbox,\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"validators.js","names":[],"sources":["../../src/api-client/validators.ts"],"sourcesContent":["import { z } from \"zod\";\n\nexport type SessionMetaData = z.infer<typeof Session>;\n\nconst RuleMatcherValidator = z.object({\n exact: z.string().optional(),\n startsWith: z.string().optional(),\n regex: z.string().optional(),\n});\n\nconst KeyValueMatcherValidator = z.object({\n key: RuleMatcherValidator.optional(),\n value: RuleMatcherValidator.optional(),\n});\n\nconst RuleMatchValidator = z.object({\n path: RuleMatcherValidator.optional(),\n method: z.array(z.string()).optional(),\n queryString: z.array(KeyValueMatcherValidator).optional(),\n headers: z.array(KeyValueMatcherValidator).optional(),\n});\n\nexport const InjectionRuleValidator = z.object({\n domain: z.string(),\n // headers are only sent in requests\n headers: z.record(z.string()).optional(),\n // headerNames are returned in responses\n headerNames: z.array(z.string()).optional(),\n match: RuleMatchValidator.optional(),\n});\n\nexport const ForwardRuleValidator = z.object({\n domain: z.string(),\n forwardURL: z.string(),\n match: RuleMatchValidator.optional(),\n});\n\nexport const NetworkPolicyTransformValidator = z.object({\n headers: z.record(z.string()).optional(),\n});\n\nexport const NetworkPolicyRuleValidator = z.object({\n match: RuleMatchValidator.optional(),\n transform: z.array(NetworkPolicyTransformValidator).optional(),\n forwardURL: z.string().optional(),\n});\n\nexport const V2NetworkPolicyObjectValidator = z.object({\n allow: z\n .union([\n z.array(z.string()),\n z.record(z.array(NetworkPolicyRuleValidator)),\n ])\n .optional(),\n subnets: z\n .object({\n allow: z.array(z.string()).optional(),\n deny: z.array(z.string()).optional(),\n })\n .optional(),\n});\n\nconst NetworkPolicyModeValidator = z.union([\n z.object({ mode: z.literal(\"allow-all\") }).passthrough(),\n z.object({ mode: z.literal(\"deny-all\") }).passthrough(),\n]);\n\nconst LegacyCustomNetworkPolicyValidator = z\n .object({\n mode: z.literal(\"custom\"),\n allowedDomains: z.array(z.string()).optional(),\n allowedCIDRs: z.array(z.string()).optional(),\n deniedCIDRs: z.array(z.string()).optional(),\n injectionRules: z.array(InjectionRuleValidator).optional(),\n forwardRules: z.array(ForwardRuleValidator).optional(),\n })\n .passthrough();\n\nexport const NetworkPolicyRequestValidator = z.union([\n NetworkPolicyModeValidator,\n V2NetworkPolicyObjectValidator.passthrough(),\n]);\n\nexport const NetworkPolicyResponseValidator = z.union([\n NetworkPolicyModeValidator,\n LegacyCustomNetworkPolicyValidator,\n]);\n\nexport const Session = z.object({\n id: z.string(),\n memory: z.number(),\n vcpus: z.number(),\n region: z.string(),\n runtime: z.string(),\n timeout: z.number(),\n status: z.enum([\n \"pending\",\n \"running\",\n \"stopping\",\n \"stopped\",\n \"failed\",\n \"aborted\",\n \"snapshotting\",\n ]),\n requestedAt: z.number(),\n startedAt: z.number().optional(),\n requestedStopAt: z.number().optional(),\n stoppedAt: z.number().optional(),\n abortedAt: z.number().optional(),\n duration: z.number().optional(),\n sourceSnapshotId: z.string().optional(),\n snapshottedAt: z.number().optional(),\n createdAt: z.number(),\n cwd: z.string(),\n updatedAt: z.number(),\n interactivePort: z.number().optional(),\n networkPolicy: NetworkPolicyResponseValidator.optional(),\n activeCpuDurationMs: z.number().optional(),\n networkTransfer: z.object({\n ingress: z.number(),\n egress: z.number(),\n }).optional(),\n});\n\nexport type SandboxRouteData = z.infer<typeof SandboxRoute>;\n\nexport const SandboxRoute = z.object({\n url: z.string(),\n subdomain: z.string(),\n port: z.number(),\n});\n\nexport type SnapshotMetadata = z.infer<typeof Snapshot>;\n\nexport const Snapshot = z.object({\n id: z.string(),\n sourceSessionId: z.string(),\n region: z.string(),\n status: z.enum([\"created\", \"deleted\", \"failed\"]),\n sizeBytes: z.number(),\n expiresAt: z.number().optional(),\n createdAt: z.number(),\n updatedAt: z.number(),\n});\n\nexport const CursorPagination = z.object({\n count: z.number(),\n next: z.string().nullable(),\n});\n\nexport type CommandData = z.infer<typeof Command>;\n\nexport const Command = z.object({\n id: z.string(),\n name: z.string(),\n args: z.array(z.string()),\n cwd: z.string(),\n sessionId: z.string(),\n exitCode: z.number().nullable(),\n startedAt: z.number(),\n});\n\nconst CommandFinished = Command.extend({\n exitCode: z.number(),\n});\n\nexport const SessionResponse = z.object({\n session: Session.passthrough(),\n});\n\nexport const SessionAndRoutesResponse = SessionResponse.extend({\n routes: z.array(SandboxRoute),\n});\n\nexport const SessionsResponse = z.object({\n sessions: z.array(Session.passthrough()),\n pagination: CursorPagination,\n});\n\nexport const CommandResponse = z.object({\n command: Command,\n});\n\nexport type CommandFinishedData = z.infer<typeof CommandFinishedResponse>[\"command\"];\n\nexport const CommandFinishedResponse = z.object({\n command: CommandFinished,\n});\n\nexport const EmptyResponse = z.object({});\n\nconst LogLineBase = z.object({ data: z.string() });\nexport const LogLineStdout = LogLineBase.extend({\n stream: z.literal(\"stdout\"),\n});\nexport const LogLineStderr = LogLineBase.extend({\n stream: z.literal(\"stderr\"),\n});\n\nexport const LogError = z.object({\n stream: z.literal(\"error\"),\n data: z.object({\n code: z.string(),\n message: z.string(),\n }),\n});\n\nexport const LogLine = z.discriminatedUnion(\"stream\", [\n LogLineStdout,\n LogLineStderr,\n LogError,\n]);\n\nexport const SnapshotsResponse = z.object({\n snapshots: z.array(Snapshot),\n pagination: CursorPagination,\n});\n\nexport const CreateSnapshotResponse = z.object({\n snapshot: Snapshot,\n session: Session.passthrough(),\n});\n\nexport const SnapshotResponse = z.object({\n snapshot: Snapshot,\n});\n\nexport const Sandbox = z.object({\n name: z.string(),\n persistent: z.boolean(),\n region: z.string().optional(),\n vcpus: z.number().optional(),\n memory: z.number().optional(),\n runtime: z.string().optional(),\n timeout: z.number().optional(),\n networkPolicy: NetworkPolicyResponseValidator.optional(),\n totalEgressBytes: z.number().optional(),\n totalIngressBytes: z.number().optional(),\n totalActiveCpuDurationMs: z.number().optional(),\n totalDurationMs: z.number().optional(),\n createdAt: z.number(),\n updatedAt: z.number(),\n currentSessionId: z.string(),\n currentSnapshotId: z.string().optional(),\n status: Session.shape.status,\n statusUpdatedAt: z.number().optional(),\n cwd: z.string().optional(),\n tags: z.record(z.string()).optional(),\n snapshotExpiration: z.number().optional(),\n});\n\nexport type SandboxMetaData = z.infer<typeof Sandbox>;\n\nexport const StopSessionResponse = z.object({\n session: Session.passthrough(),\n sandbox: Sandbox.optional(),\n snapshot: Snapshot.optional(),\n});\n\nexport const SandboxAndSessionResponse = z.object({\n sandbox: Sandbox,\n session: Session.passthrough(),\n routes: z.array(SandboxRoute),\n resumed: z.boolean().optional(),\n});\n\nexport const SandboxesPaginationResponse = z.object({\n sandboxes: z.array(Sandbox),\n pagination: CursorPagination,\n});\n\nexport const UpdateSandboxResponse = z.object({\n sandbox: Sandbox,\n});\n"],"mappings":"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"}
|
package/dist/auth/api.cjs
CHANGED
|
@@ -2,7 +2,7 @@ const require_error = require('./error.cjs');
|
|
|
2
2
|
|
|
3
3
|
//#region src/auth/api.ts
|
|
4
4
|
async function fetchApi(opts) {
|
|
5
|
-
const x = await fetch(`https://
|
|
5
|
+
const x = await fetch(`https://vercel.com/api${opts.endpoint}`, {
|
|
6
6
|
method: opts.method,
|
|
7
7
|
body: opts.body,
|
|
8
8
|
headers: {
|
package/dist/auth/api.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.cjs","names":["NotOk"],"sources":["../../src/auth/api.ts"],"sourcesContent":["import { NotOk } from \"./error.js\";\n\nexport async function fetchApi(opts: {\n token: string;\n endpoint: string;\n method?: string;\n body?: string;\n}): Promise<unknown> {\n const x = await fetch(`https://
|
|
1
|
+
{"version":3,"file":"api.cjs","names":["NotOk"],"sources":["../../src/auth/api.ts"],"sourcesContent":["import { NotOk } from \"./error.js\";\n\nexport async function fetchApi(opts: {\n token: string;\n endpoint: string;\n method?: string;\n body?: string;\n}): Promise<unknown> {\n const x = await fetch(`https://vercel.com/api${opts.endpoint}`, {\n method: opts.method,\n body: opts.body,\n headers: {\n Authorization: `Bearer ${opts.token}`,\n \"Content-Type\": \"application/json\",\n },\n });\n if (!x.ok) {\n let message = await x.text();\n\n try {\n const { error } = JSON.parse(message);\n message = `${error.code.toUpperCase()}: ${error.message}`;\n } catch {}\n\n throw new NotOk({\n responseText: message,\n statusCode: x.status,\n });\n }\n return (await x.json()) as unknown;\n}\n"],"mappings":";;;AAEA,eAAsB,SAAS,MAKV;CACnB,MAAM,IAAI,MAAM,MAAM,yBAAyB,KAAK,YAAY;EAC9D,QAAQ,KAAK;EACb,MAAM,KAAK;EACX,SAAS;GACP,eAAe,UAAU,KAAK;GAC9B,gBAAgB;GACjB;EACF,CAAC;AACF,KAAI,CAAC,EAAE,IAAI;EACT,IAAI,UAAU,MAAM,EAAE,MAAM;AAE5B,MAAI;GACF,MAAM,EAAE,UAAU,KAAK,MAAM,QAAQ;AACrC,aAAU,GAAG,MAAM,KAAK,aAAa,CAAC,IAAI,MAAM;UAC1C;AAER,QAAM,IAAIA,oBAAM;GACd,cAAc;GACd,YAAY,EAAE;GACf,CAAC;;AAEJ,QAAQ,MAAM,EAAE,MAAM"}
|
package/dist/auth/api.js
CHANGED
|
@@ -2,7 +2,7 @@ import { NotOk } from "./error.js";
|
|
|
2
2
|
|
|
3
3
|
//#region src/auth/api.ts
|
|
4
4
|
async function fetchApi(opts) {
|
|
5
|
-
const x = await fetch(`https://
|
|
5
|
+
const x = await fetch(`https://vercel.com/api${opts.endpoint}`, {
|
|
6
6
|
method: opts.method,
|
|
7
7
|
body: opts.body,
|
|
8
8
|
headers: {
|
package/dist/auth/api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","names":[],"sources":["../../src/auth/api.ts"],"sourcesContent":["import { NotOk } from \"./error.js\";\n\nexport async function fetchApi(opts: {\n token: string;\n endpoint: string;\n method?: string;\n body?: string;\n}): Promise<unknown> {\n const x = await fetch(`https://
|
|
1
|
+
{"version":3,"file":"api.js","names":[],"sources":["../../src/auth/api.ts"],"sourcesContent":["import { NotOk } from \"./error.js\";\n\nexport async function fetchApi(opts: {\n token: string;\n endpoint: string;\n method?: string;\n body?: string;\n}): Promise<unknown> {\n const x = await fetch(`https://vercel.com/api${opts.endpoint}`, {\n method: opts.method,\n body: opts.body,\n headers: {\n Authorization: `Bearer ${opts.token}`,\n \"Content-Type\": \"application/json\",\n },\n });\n if (!x.ok) {\n let message = await x.text();\n\n try {\n const { error } = JSON.parse(message);\n message = `${error.code.toUpperCase()}: ${error.message}`;\n } catch {}\n\n throw new NotOk({\n responseText: message,\n statusCode: x.status,\n });\n }\n return (await x.json()) as unknown;\n}\n"],"mappings":";;;AAEA,eAAsB,SAAS,MAKV;CACnB,MAAM,IAAI,MAAM,MAAM,yBAAyB,KAAK,YAAY;EAC9D,QAAQ,KAAK;EACb,MAAM,KAAK;EACX,SAAS;GACP,eAAe,UAAU,KAAK;GAC9B,gBAAgB;GACjB;EACF,CAAC;AACF,KAAI,CAAC,EAAE,IAAI;EACT,IAAI,UAAU,MAAM,EAAE,MAAM;AAE5B,MAAI;GACF,MAAM,EAAE,UAAU,KAAK,MAAM,QAAQ;AACrC,aAAU,GAAG,MAAM,KAAK,aAAa,CAAC,IAAI,MAAM;UAC1C;AAER,QAAM,IAAI,MAAM;GACd,cAAc;GACd,YAAY,EAAE;GACf,CAAC;;AAEJ,QAAQ,MAAM,EAAE,MAAM"}
|
package/dist/auth/index.cjs
CHANGED
|
@@ -8,5 +8,4 @@ exports.getAuth = require_file.getAuth;
|
|
|
8
8
|
exports.inferScope = require_project.inferScope;
|
|
9
9
|
exports.isOAuthError = require_oauth.isOAuthError;
|
|
10
10
|
exports.pollForToken = require_poll_for_token.pollForToken;
|
|
11
|
-
exports.selectTeam = require_project.selectTeam;
|
|
12
11
|
exports.updateAuthConfig = require_file.updateAuthConfig;
|
package/dist/auth/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getAuth, updateAuthConfig } from "./file.cjs";
|
|
2
2
|
import { DeviceAuthorizationRequest, OAuth, isOAuthError } from "./oauth.cjs";
|
|
3
3
|
import { pollForToken } from "./poll-for-token.cjs";
|
|
4
|
-
import { inferScope
|
|
5
|
-
export { DeviceAuthorizationRequest, OAuth, getAuth, inferScope, isOAuthError, pollForToken,
|
|
4
|
+
import { inferScope } from "./project.cjs";
|
|
5
|
+
export { DeviceAuthorizationRequest, OAuth, getAuth, inferScope, isOAuthError, pollForToken, updateAuthConfig };
|
package/dist/auth/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getAuth, updateAuthConfig } from "./file.js";
|
|
2
2
|
import { DeviceAuthorizationRequest, OAuth, isOAuthError } from "./oauth.js";
|
|
3
3
|
import { pollForToken } from "./poll-for-token.js";
|
|
4
|
-
import { inferScope
|
|
5
|
-
export { DeviceAuthorizationRequest, OAuth, getAuth, inferScope, isOAuthError, pollForToken,
|
|
4
|
+
import { inferScope } from "./project.js";
|
|
5
|
+
export { DeviceAuthorizationRequest, OAuth, getAuth, inferScope, isOAuthError, pollForToken, updateAuthConfig };
|
package/dist/auth/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getAuth, updateAuthConfig } from "./file.js";
|
|
2
2
|
import { OAuth, isOAuthError } from "./oauth.js";
|
|
3
3
|
import { pollForToken } from "./poll-for-token.js";
|
|
4
|
-
import { inferScope
|
|
4
|
+
import { inferScope } from "./project.js";
|
|
5
5
|
|
|
6
|
-
export { OAuth, getAuth, inferScope, isOAuthError, pollForToken,
|
|
6
|
+
export { OAuth, getAuth, inferScope, isOAuthError, pollForToken, updateAuthConfig };
|
package/dist/auth/project.cjs
CHANGED
|
@@ -5,24 +5,47 @@ const require_linked_project = require('./linked-project.cjs');
|
|
|
5
5
|
let zod = require("zod");
|
|
6
6
|
|
|
7
7
|
//#region src/auth/project.ts
|
|
8
|
-
const
|
|
8
|
+
const UserSchema = zod.z.object({ user: zod.z.object({
|
|
9
|
+
defaultTeamId: zod.z.string().nullable(),
|
|
10
|
+
username: zod.z.string()
|
|
11
|
+
}) });
|
|
12
|
+
const TeamSchema = zod.z.object({
|
|
13
|
+
id: zod.z.string(),
|
|
14
|
+
slug: zod.z.string(),
|
|
15
|
+
updatedAt: zod.z.number(),
|
|
16
|
+
membership: zod.z.object({ role: zod.z.string() }),
|
|
17
|
+
billing: zod.z.object({ plan: zod.z.string() })
|
|
18
|
+
});
|
|
19
|
+
const TeamsSchema = zod.z.object({
|
|
20
|
+
teams: zod.z.array(TeamSchema),
|
|
21
|
+
pagination: zod.z.object({
|
|
22
|
+
count: zod.z.number(),
|
|
23
|
+
next: zod.z.number().nullable()
|
|
24
|
+
})
|
|
25
|
+
});
|
|
9
26
|
const DEFAULT_PROJECT_NAME = "vercel-sandbox-default-project";
|
|
27
|
+
/** Status codes that mean "this team can't be used, try the next one". */
|
|
28
|
+
function isSkippableTeamError(e) {
|
|
29
|
+
return e instanceof require_error.NotOk && (e.response.statusCode === 402 || e.response.statusCode === 403);
|
|
30
|
+
}
|
|
10
31
|
/**
|
|
11
32
|
* Resolves the team and project scope for sandbox operations.
|
|
12
33
|
*
|
|
13
34
|
* First checks for a locally linked project in `.vercel/project.json`.
|
|
14
35
|
* If found, uses the `projectId` and `orgId` from there.
|
|
15
36
|
*
|
|
16
|
-
* Otherwise, if `teamId` is not provided,
|
|
17
|
-
*
|
|
37
|
+
* Otherwise, if `teamId` is not provided, builds an ordered list of candidate
|
|
38
|
+
* teams to try: the user's `defaultTeamId` first (if set), then hobby-plan
|
|
39
|
+
* teams where the user has an OWNER role (preferring the personal team matching
|
|
40
|
+
* the username, then the most recently updated). Tries each candidate until one
|
|
41
|
+
* succeeds.
|
|
18
42
|
*
|
|
19
43
|
* @param opts.token - Vercel API authentication token.
|
|
20
|
-
* @param opts.teamId - Optional team slug. If omitted,
|
|
44
|
+
* @param opts.teamId - Optional team slug. If omitted, candidate teams are resolved automatically.
|
|
21
45
|
* @param opts.cwd - Optional directory to search for `.vercel/project.json`. Defaults to `process.cwd()`.
|
|
22
46
|
* @returns The resolved scope with `projectId`, `teamId`, and whether the project was `created`.
|
|
23
47
|
*
|
|
24
48
|
* @throws {NotOk} If the API returns an error other than 404 when checking the project.
|
|
25
|
-
* @throws {ZodError} If no teams exist for the account.
|
|
26
49
|
*
|
|
27
50
|
* @example
|
|
28
51
|
* ```ts
|
|
@@ -32,22 +55,89 @@ const DEFAULT_PROJECT_NAME = "vercel-sandbox-default-project";
|
|
|
32
55
|
*/
|
|
33
56
|
async function inferScope(opts) {
|
|
34
57
|
const linkedProject = await require_linked_project.readLinkedProject(opts.cwd ?? process.cwd());
|
|
35
|
-
if (linkedProject)
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
58
|
+
if (linkedProject) {
|
|
59
|
+
const slugs = await resolveLinkedProjectSlugs(opts.token, linkedProject.teamId, linkedProject.projectId);
|
|
60
|
+
return {
|
|
61
|
+
...linkedProject,
|
|
62
|
+
created: false,
|
|
63
|
+
...slugs
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
if (opts.teamId) return tryTeam(opts.token, opts.teamId);
|
|
67
|
+
const { defaultTeamId, username } = (await require_api.fetchApi({
|
|
68
|
+
token: opts.token,
|
|
69
|
+
endpoint: "/v2/user"
|
|
70
|
+
}).then(UserSchema.parse)).user;
|
|
71
|
+
if (defaultTeamId) try {
|
|
72
|
+
const result = await tryTeam(opts.token, defaultTeamId);
|
|
73
|
+
try {
|
|
74
|
+
const team = await require_api.fetchApi({
|
|
75
|
+
token: opts.token,
|
|
76
|
+
endpoint: `/v2/teams/${encodeURIComponent(defaultTeamId)}`
|
|
77
|
+
}).then(zod.z.object({ slug: zod.z.string() }).parse);
|
|
78
|
+
return {
|
|
79
|
+
...result,
|
|
80
|
+
teamSlug: team.slug
|
|
81
|
+
};
|
|
82
|
+
} catch {
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
85
|
+
} catch (e) {
|
|
86
|
+
if (!isSkippableTeamError(e)) throw e;
|
|
87
|
+
}
|
|
88
|
+
let next = null;
|
|
89
|
+
do {
|
|
90
|
+
const endpoint = next === null ? "/v2/teams?limit=20" : `/v2/teams?limit=20&until=${next}`;
|
|
91
|
+
const page = await require_api.fetchApi({
|
|
92
|
+
token: opts.token,
|
|
93
|
+
endpoint
|
|
94
|
+
}).then(TeamsSchema.parse);
|
|
95
|
+
next = page.pagination.next;
|
|
96
|
+
const hobbyOwnerTeams = page.teams.filter((t) => t.membership.role === "OWNER" && t.billing.plan === "hobby");
|
|
97
|
+
if (hobbyOwnerTeams.length === 0) continue;
|
|
98
|
+
const bestHobbyTeam = hobbyOwnerTeams.find((t) => t.slug === username) ?? hobbyOwnerTeams.sort((a, b) => b.updatedAt - a.updatedAt)[0];
|
|
99
|
+
if (bestHobbyTeam && bestHobbyTeam.id !== defaultTeamId) try {
|
|
100
|
+
return {
|
|
101
|
+
...await tryTeam(opts.token, bestHobbyTeam.id),
|
|
102
|
+
teamSlug: bestHobbyTeam.slug
|
|
103
|
+
};
|
|
104
|
+
} catch (e) {
|
|
105
|
+
if (!isSkippableTeamError(e)) throw e;
|
|
106
|
+
}
|
|
107
|
+
} while (next !== null);
|
|
108
|
+
try {
|
|
109
|
+
return {
|
|
110
|
+
...await tryTeam(opts.token, username),
|
|
111
|
+
teamSlug: username
|
|
112
|
+
};
|
|
113
|
+
} catch (e) {
|
|
114
|
+
if (!isSkippableTeamError(e)) throw e;
|
|
115
|
+
}
|
|
116
|
+
throw new require_error.NotOk({
|
|
117
|
+
statusCode: 403,
|
|
118
|
+
responseText: `Authenticated as "${username}" but none of the available teams allow sandbox creation. Specify a team explicitly with --scope <team-id-or-slug>.`
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Attempts to use a specific team for sandbox operations by checking for
|
|
123
|
+
* (or creating) the default project within that team.
|
|
124
|
+
*
|
|
125
|
+
* @returns The resolved scope if the team is usable.
|
|
126
|
+
* @throws {NotOk} On authorization or other API errors.
|
|
127
|
+
*/
|
|
128
|
+
async function tryTeam(token, teamId) {
|
|
129
|
+
const teamParam = teamId.startsWith("team_") ? `teamId=${encodeURIComponent(teamId)}` : `slug=${encodeURIComponent(teamId)}`;
|
|
40
130
|
let created = false;
|
|
41
131
|
try {
|
|
42
132
|
await require_api.fetchApi({
|
|
43
|
-
token
|
|
44
|
-
endpoint: `/v2/projects/${encodeURIComponent(DEFAULT_PROJECT_NAME)}
|
|
133
|
+
token,
|
|
134
|
+
endpoint: `/v2/projects/${encodeURIComponent(DEFAULT_PROJECT_NAME)}?${teamParam}`
|
|
45
135
|
});
|
|
46
136
|
} catch (e) {
|
|
47
137
|
if (!(e instanceof require_error.NotOk) || e.response.statusCode !== 404) throw e;
|
|
48
138
|
await require_api.fetchApi({
|
|
49
|
-
token
|
|
50
|
-
endpoint: `/v11/projects
|
|
139
|
+
token,
|
|
140
|
+
endpoint: `/v11/projects?${teamParam}`,
|
|
51
141
|
method: "POST",
|
|
52
142
|
body: JSON.stringify({ name: DEFAULT_PROJECT_NAME })
|
|
53
143
|
});
|
|
@@ -60,21 +150,29 @@ async function inferScope(opts) {
|
|
|
60
150
|
};
|
|
61
151
|
}
|
|
62
152
|
/**
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
* @param token - Authentication token used to call the Vercel API.
|
|
67
|
-
* @returns A promise that resolves to the first team's slug.
|
|
153
|
+
* Best-effort resolution of team slug and project name for a linked project.
|
|
154
|
+
* Both IDs may be opaque (e.g. `team_xxx`, `prj_xxx`), so we fetch the
|
|
155
|
+
* human-readable names from the API in parallel.
|
|
68
156
|
*/
|
|
69
|
-
async function
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
157
|
+
async function resolveLinkedProjectSlugs(token, teamId, projectId) {
|
|
158
|
+
try {
|
|
159
|
+
const teamParam = teamId.startsWith("team_") ? `teamId=${encodeURIComponent(teamId)}` : `slug=${encodeURIComponent(teamId)}`;
|
|
160
|
+
const [teamData, projectData] = await Promise.all([require_api.fetchApi({
|
|
161
|
+
token,
|
|
162
|
+
endpoint: `/v2/teams/${encodeURIComponent(teamId)}`
|
|
163
|
+
}).then(zod.z.object({ slug: zod.z.string() }).parse), require_api.fetchApi({
|
|
164
|
+
token,
|
|
165
|
+
endpoint: `/v2/projects/${encodeURIComponent(projectId)}?${teamParam}`
|
|
166
|
+
}).then(zod.z.object({ name: zod.z.string() }).parse)]);
|
|
167
|
+
return {
|
|
168
|
+
teamSlug: teamData.slug,
|
|
169
|
+
projectSlug: projectData.name
|
|
170
|
+
};
|
|
171
|
+
} catch {
|
|
172
|
+
return {};
|
|
173
|
+
}
|
|
75
174
|
}
|
|
76
175
|
|
|
77
176
|
//#endregion
|
|
78
177
|
exports.inferScope = inferScope;
|
|
79
|
-
exports.selectTeam = selectTeam;
|
|
80
178
|
//# sourceMappingURL=project.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project.cjs","names":["z","readLinkedProject","fetchApi","NotOk"],"sources":["../../src/auth/project.ts"],"sourcesContent":["import { z } from \"zod\";\nimport { fetchApi } from \"./api.js\";\nimport { NotOk } from \"./error.js\";\nimport { readLinkedProject } from \"./linked-project.js\";\n\nconst TeamsSchema = z.object({\n teams: z\n .array(\n z.object({\n slug: z.string(),\n }),\n )\n .min(1, `No teams found. Please create a team first.`),\n});\n\nconst DEFAULT_PROJECT_NAME = \"vercel-sandbox-default-project\";\n\n/**\n * Resolves the team and project scope for sandbox operations.\n *\n * First checks for a locally linked project in `.vercel/project.json`.\n * If found, uses the `projectId` and `orgId` from there.\n *\n * Otherwise, if `teamId` is not provided, selects the first available team for the account.\n * Ensures a default project exists within the team, creating it if necessary.\n *\n * @param opts.token - Vercel API authentication token.\n * @param opts.teamId - Optional team slug. If omitted, the first team is selected.\n * @param opts.cwd - Optional directory to search for `.vercel/project.json`. Defaults to `process.cwd()`.\n * @returns The resolved scope with `projectId`, `teamId`, and whether the project was `created`.\n *\n * @throws {NotOk} If the API returns an error other than 404 when checking the project.\n * @throws {ZodError} If no teams exist for the account.\n *\n * @example\n * ```ts\n * const scope = await inferScope({ token: \"vercel_...\" });\n * // => { projectId: \"vercel-sandbox-default-project\", teamId: \"my-team\", created: false }\n * ```\n */\nexport async function inferScope(opts: {\n token: string;\n teamId?: string;\n cwd?: string;\n}): Promise<{ projectId: string; teamId: string; created: boolean }> {\n const linkedProject = await readLinkedProject(opts.cwd ?? process.cwd());\n if (linkedProject) {\n return { ...linkedProject, created: false };\n }\n\n const teamId = opts.teamId ?? (await selectTeam(opts.token));\n\n let created = false;\n try {\n await fetchApi({\n token: opts.token,\n endpoint: `/v2/projects/${encodeURIComponent(DEFAULT_PROJECT_NAME)}?slug=${encodeURIComponent(teamId)}`,\n });\n } catch (e) {\n if (!(e instanceof NotOk) || e.response.statusCode !== 404) {\n throw e;\n }\n\n await fetchApi({\n token: opts.token,\n endpoint: `/v11/projects?slug=${encodeURIComponent(teamId)}`,\n method: \"POST\",\n body: JSON.stringify({\n name: DEFAULT_PROJECT_NAME,\n }),\n });\n created = true;\n }\n\n return { projectId: DEFAULT_PROJECT_NAME, teamId, created };\n}\n\n/**\n * Selects a team for the current token by querying the Teams API and\n * returning the slug of the first team in the result set.\n *\n * @param token - Authentication token used to call the Vercel API.\n * @returns A promise that resolves to the first team's slug.\n */\nexport async function selectTeam(token: string) {\n const {\n teams: [team],\n } = await fetchApi({ token, endpoint: \"/v2/teams?limit=1\" }).then(\n TeamsSchema.parse,\n );\n return team.slug;\n}\n"],"mappings":";;;;;;;AAKA,MAAM,cAAcA,MAAE,OAAO,EAC3B,OAAOA,MACJ,MACCA,MAAE,OAAO,EACP,MAAMA,MAAE,QAAQ,EACjB,CAAC,CACH,CACA,IAAI,GAAG,8CAA8C,EACzD,CAAC;AAEF,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;AAyB7B,eAAsB,WAAW,MAIoC;CACnE,MAAM,gBAAgB,MAAMC,yCAAkB,KAAK,OAAO,QAAQ,KAAK,CAAC;AACxE,KAAI,cACF,QAAO;EAAE,GAAG;EAAe,SAAS;EAAO;CAG7C,MAAM,SAAS,KAAK,UAAW,MAAM,WAAW,KAAK,MAAM;CAE3D,IAAI,UAAU;AACd,KAAI;AACF,QAAMC,qBAAS;GACb,OAAO,KAAK;GACZ,UAAU,gBAAgB,mBAAmB,qBAAqB,CAAC,QAAQ,mBAAmB,OAAO;GACtG,CAAC;UACK,GAAG;AACV,MAAI,EAAE,aAAaC,wBAAU,EAAE,SAAS,eAAe,IACrD,OAAM;AAGR,QAAMD,qBAAS;GACb,OAAO,KAAK;GACZ,UAAU,sBAAsB,mBAAmB,OAAO;GAC1D,QAAQ;GACR,MAAM,KAAK,UAAU,EACnB,MAAM,sBACP,CAAC;GACH,CAAC;AACF,YAAU;;AAGZ,QAAO;EAAE,WAAW;EAAsB;EAAQ;EAAS;;;;;;;;;AAU7D,eAAsB,WAAW,OAAe;CAC9C,MAAM,EACJ,OAAO,CAAC,UACN,MAAMA,qBAAS;EAAE;EAAO,UAAU;EAAqB,CAAC,CAAC,KAC3D,YAAY,MACb;AACD,QAAO,KAAK"}
|
|
1
|
+
{"version":3,"file":"project.cjs","names":["z","NotOk","readLinkedProject","fetchApi","next: number | null","endpoint: string"],"sources":["../../src/auth/project.ts"],"sourcesContent":["import { z } from \"zod\";\nimport { fetchApi } from \"./api.js\";\nimport { NotOk } from \"./error.js\";\nimport { readLinkedProject } from \"./linked-project.js\";\n\nconst UserSchema = z.object({\n user: z.object({\n defaultTeamId: z.string().nullable(),\n username: z.string(),\n }),\n});\n\nconst TeamSchema = z.object({\n id: z.string(),\n slug: z.string(),\n updatedAt: z.number(),\n membership: z.object({\n role: z.string(),\n }),\n billing: z.object({\n plan: z.string(),\n }),\n});\n\nconst TeamsSchema = z.object({\n teams: z.array(TeamSchema),\n pagination: z.object({\n count: z.number(),\n next: z.number().nullable(),\n }),\n});\n\nconst DEFAULT_PROJECT_NAME = \"vercel-sandbox-default-project\";\n\n/** Status codes that mean \"this team can't be used, try the next one\". */\nfunction isSkippableTeamError(e: unknown): boolean {\n return e instanceof NotOk && (e.response.statusCode === 402 || e.response.statusCode === 403);\n}\n\n/**\n * Resolves the team and project scope for sandbox operations.\n *\n * First checks for a locally linked project in `.vercel/project.json`.\n * If found, uses the `projectId` and `orgId` from there.\n *\n * Otherwise, if `teamId` is not provided, builds an ordered list of candidate\n * teams to try: the user's `defaultTeamId` first (if set), then hobby-plan\n * teams where the user has an OWNER role (preferring the personal team matching\n * the username, then the most recently updated). Tries each candidate until one\n * succeeds.\n *\n * @param opts.token - Vercel API authentication token.\n * @param opts.teamId - Optional team slug. If omitted, candidate teams are resolved automatically.\n * @param opts.cwd - Optional directory to search for `.vercel/project.json`. Defaults to `process.cwd()`.\n * @returns The resolved scope with `projectId`, `teamId`, and whether the project was `created`.\n *\n * @throws {NotOk} If the API returns an error other than 404 when checking the project.\n *\n * @example\n * ```ts\n * const scope = await inferScope({ token: \"vercel_...\" });\n * // => { projectId: \"vercel-sandbox-default-project\", teamId: \"my-team\", created: false }\n * ```\n */\nexport async function inferScope(opts: {\n token: string;\n teamId?: string;\n cwd?: string;\n}): Promise<{\n projectId: string;\n teamId: string;\n created: boolean;\n teamSlug?: string;\n projectSlug?: string;\n}> {\n const linkedProject = await readLinkedProject(opts.cwd ?? process.cwd());\n if (linkedProject) {\n const slugs = await resolveLinkedProjectSlugs(\n opts.token,\n linkedProject.teamId,\n linkedProject.projectId,\n );\n return { ...linkedProject, created: false, ...slugs };\n }\n\n if (opts.teamId) {\n return tryTeam(opts.token, opts.teamId);\n }\n\n const userData = await fetchApi({\n token: opts.token,\n endpoint: \"/v2/user\",\n }).then(UserSchema.parse);\n const { defaultTeamId, username } = userData.user;\n\n // 1. Try defaultTeamId first\n if (defaultTeamId) {\n try {\n const result = await tryTeam(opts.token, defaultTeamId);\n // Resolve team slug (best-effort)\n try {\n const team = await fetchApi({\n token: opts.token,\n endpoint: `/v2/teams/${encodeURIComponent(defaultTeamId)}`,\n }).then(z.object({ slug: z.string() }).parse);\n return { ...result, teamSlug: team.slug };\n } catch {\n return result;\n }\n } catch (e) {\n if (!isSkippableTeamError(e)) throw e;\n }\n }\n\n // 2. Paginate teams in pages of 20, try best hobby team per page\n let next: number | null = null;\n do {\n const endpoint: string =\n next === null\n ? \"/v2/teams?limit=20\"\n : `/v2/teams?limit=20&until=${next}`;\n const page = await fetchApi({ token: opts.token, endpoint }).then(\n TeamsSchema.parse,\n );\n\n next = page.pagination.next;\n\n const hobbyOwnerTeams = page.teams.filter(\n (t) => t.membership.role === \"OWNER\" && t.billing.plan === \"hobby\",\n );\n if (hobbyOwnerTeams.length === 0) {\n continue;\n }\n\n const bestHobbyTeam =\n hobbyOwnerTeams.find((t) => t.slug === username) ??\n hobbyOwnerTeams.sort((a, b) => b.updatedAt - a.updatedAt)[0];\n\n if (bestHobbyTeam && bestHobbyTeam.id !== defaultTeamId) {\n try {\n const result = await tryTeam(opts.token, bestHobbyTeam.id);\n return { ...result, teamSlug: bestHobbyTeam.slug };\n } catch (e) {\n if (!isSkippableTeamError(e)) throw e;\n }\n }\n } while (next !== null);\n\n // 3. Fall back to username as personal team\n try {\n const result = await tryTeam(opts.token, username);\n return { ...result, teamSlug: username };\n } catch (e) {\n if (!isSkippableTeamError(e)) throw e;\n }\n\n throw new NotOk({\n statusCode: 403,\n responseText: `Authenticated as \"${username}\" but none of the available teams allow sandbox creation. Specify a team explicitly with --scope <team-id-or-slug>.`,\n });\n}\n\n/**\n * Attempts to use a specific team for sandbox operations by checking for\n * (or creating) the default project within that team.\n *\n * @returns The resolved scope if the team is usable.\n * @throws {NotOk} On authorization or other API errors.\n */\nasync function tryTeam(\n token: string,\n teamId: string,\n): Promise<{ projectId: string; teamId: string; created: boolean }> {\n const teamParam = teamId.startsWith(\"team_\")\n ? `teamId=${encodeURIComponent(teamId)}`\n : `slug=${encodeURIComponent(teamId)}`;\n\n let created = false;\n try {\n await fetchApi({\n token,\n endpoint: `/v2/projects/${encodeURIComponent(DEFAULT_PROJECT_NAME)}?${teamParam}`,\n });\n } catch (e) {\n if (!(e instanceof NotOk) || e.response.statusCode !== 404) {\n throw e;\n }\n\n await fetchApi({\n token,\n endpoint: `/v11/projects?${teamParam}`,\n method: \"POST\",\n body: JSON.stringify({\n name: DEFAULT_PROJECT_NAME,\n }),\n });\n created = true;\n }\n\n return { projectId: DEFAULT_PROJECT_NAME, teamId, created };\n}\n\n/**\n * Best-effort resolution of team slug and project name for a linked project.\n * Both IDs may be opaque (e.g. `team_xxx`, `prj_xxx`), so we fetch the\n * human-readable names from the API in parallel.\n */\nasync function resolveLinkedProjectSlugs(\n token: string,\n teamId: string,\n projectId: string,\n): Promise<{ teamSlug?: string; projectSlug?: string }> {\n try {\n const teamParam = teamId.startsWith(\"team_\")\n ? `teamId=${encodeURIComponent(teamId)}`\n : `slug=${encodeURIComponent(teamId)}`;\n const [teamData, projectData] = await Promise.all([\n fetchApi({\n token,\n endpoint: `/v2/teams/${encodeURIComponent(teamId)}`,\n }).then(z.object({ slug: z.string() }).parse),\n fetchApi({\n token,\n endpoint: `/v2/projects/${encodeURIComponent(projectId)}?${teamParam}`,\n }).then(z.object({ name: z.string() }).parse),\n ]);\n return { teamSlug: teamData.slug, projectSlug: projectData.name };\n } catch {\n return {};\n }\n}\n"],"mappings":";;;;;;;AAKA,MAAM,aAAaA,MAAE,OAAO,EAC1B,MAAMA,MAAE,OAAO;CACb,eAAeA,MAAE,QAAQ,CAAC,UAAU;CACpC,UAAUA,MAAE,QAAQ;CACrB,CAAC,EACH,CAAC;AAEF,MAAM,aAAaA,MAAE,OAAO;CAC1B,IAAIA,MAAE,QAAQ;CACd,MAAMA,MAAE,QAAQ;CAChB,WAAWA,MAAE,QAAQ;CACrB,YAAYA,MAAE,OAAO,EACnB,MAAMA,MAAE,QAAQ,EACjB,CAAC;CACF,SAASA,MAAE,OAAO,EAChB,MAAMA,MAAE,QAAQ,EACjB,CAAC;CACH,CAAC;AAEF,MAAM,cAAcA,MAAE,OAAO;CAC3B,OAAOA,MAAE,MAAM,WAAW;CAC1B,YAAYA,MAAE,OAAO;EACnB,OAAOA,MAAE,QAAQ;EACjB,MAAMA,MAAE,QAAQ,CAAC,UAAU;EAC5B,CAAC;CACH,CAAC;AAEF,MAAM,uBAAuB;;AAG7B,SAAS,qBAAqB,GAAqB;AACjD,QAAO,aAAaC,wBAAU,EAAE,SAAS,eAAe,OAAO,EAAE,SAAS,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4B3F,eAAsB,WAAW,MAU9B;CACD,MAAM,gBAAgB,MAAMC,yCAAkB,KAAK,OAAO,QAAQ,KAAK,CAAC;AACxE,KAAI,eAAe;EACjB,MAAM,QAAQ,MAAM,0BAClB,KAAK,OACL,cAAc,QACd,cAAc,UACf;AACD,SAAO;GAAE,GAAG;GAAe,SAAS;GAAO,GAAG;GAAO;;AAGvD,KAAI,KAAK,OACP,QAAO,QAAQ,KAAK,OAAO,KAAK,OAAO;CAOzC,MAAM,EAAE,eAAe,cAJN,MAAMC,qBAAS;EAC9B,OAAO,KAAK;EACZ,UAAU;EACX,CAAC,CAAC,KAAK,WAAW,MAAM,EACoB;AAG7C,KAAI,cACF,KAAI;EACF,MAAM,SAAS,MAAM,QAAQ,KAAK,OAAO,cAAc;AAEvD,MAAI;GACF,MAAM,OAAO,MAAMA,qBAAS;IAC1B,OAAO,KAAK;IACZ,UAAU,aAAa,mBAAmB,cAAc;IACzD,CAAC,CAAC,KAAKH,MAAE,OAAO,EAAE,MAAMA,MAAE,QAAQ,EAAE,CAAC,CAAC,MAAM;AAC7C,UAAO;IAAE,GAAG;IAAQ,UAAU,KAAK;IAAM;UACnC;AACN,UAAO;;UAEF,GAAG;AACV,MAAI,CAAC,qBAAqB,EAAE,CAAE,OAAM;;CAKxC,IAAII,OAAsB;AAC1B,IAAG;EACD,MAAMC,WACJ,SAAS,OACL,uBACA,4BAA4B;EAClC,MAAM,OAAO,MAAMF,qBAAS;GAAE,OAAO,KAAK;GAAO;GAAU,CAAC,CAAC,KAC3D,YAAY,MACb;AAED,SAAO,KAAK,WAAW;EAEvB,MAAM,kBAAkB,KAAK,MAAM,QAChC,MAAM,EAAE,WAAW,SAAS,WAAW,EAAE,QAAQ,SAAS,QAC5D;AACD,MAAI,gBAAgB,WAAW,EAC7B;EAGF,MAAM,gBACJ,gBAAgB,MAAM,MAAM,EAAE,SAAS,SAAS,IAChD,gBAAgB,MAAM,GAAG,MAAM,EAAE,YAAY,EAAE,UAAU,CAAC;AAE5D,MAAI,iBAAiB,cAAc,OAAO,cACxC,KAAI;AAEF,UAAO;IAAE,GADM,MAAM,QAAQ,KAAK,OAAO,cAAc,GAAG;IACtC,UAAU,cAAc;IAAM;WAC3C,GAAG;AACV,OAAI,CAAC,qBAAqB,EAAE,CAAE,OAAM;;UAGjC,SAAS;AAGlB,KAAI;AAEF,SAAO;GAAE,GADM,MAAM,QAAQ,KAAK,OAAO,SAAS;GAC9B,UAAU;GAAU;UACjC,GAAG;AACV,MAAI,CAAC,qBAAqB,EAAE,CAAE,OAAM;;AAGtC,OAAM,IAAIF,oBAAM;EACd,YAAY;EACZ,cAAc,qBAAqB,SAAS;EAC7C,CAAC;;;;;;;;;AAUJ,eAAe,QACb,OACA,QACkE;CAClE,MAAM,YAAY,OAAO,WAAW,QAAQ,GACxC,UAAU,mBAAmB,OAAO,KACpC,QAAQ,mBAAmB,OAAO;CAEtC,IAAI,UAAU;AACd,KAAI;AACF,QAAME,qBAAS;GACb;GACA,UAAU,gBAAgB,mBAAmB,qBAAqB,CAAC,GAAG;GACvE,CAAC;UACK,GAAG;AACV,MAAI,EAAE,aAAaF,wBAAU,EAAE,SAAS,eAAe,IACrD,OAAM;AAGR,QAAME,qBAAS;GACb;GACA,UAAU,iBAAiB;GAC3B,QAAQ;GACR,MAAM,KAAK,UAAU,EACnB,MAAM,sBACP,CAAC;GACH,CAAC;AACF,YAAU;;AAGZ,QAAO;EAAE,WAAW;EAAsB;EAAQ;EAAS;;;;;;;AAQ7D,eAAe,0BACb,OACA,QACA,WACsD;AACtD,KAAI;EACF,MAAM,YAAY,OAAO,WAAW,QAAQ,GACxC,UAAU,mBAAmB,OAAO,KACpC,QAAQ,mBAAmB,OAAO;EACtC,MAAM,CAAC,UAAU,eAAe,MAAM,QAAQ,IAAI,CAChDA,qBAAS;GACP;GACA,UAAU,aAAa,mBAAmB,OAAO;GAClD,CAAC,CAAC,KAAKH,MAAE,OAAO,EAAE,MAAMA,MAAE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAC7CG,qBAAS;GACP;GACA,UAAU,gBAAgB,mBAAmB,UAAU,CAAC,GAAG;GAC5D,CAAC,CAAC,KAAKH,MAAE,OAAO,EAAE,MAAMA,MAAE,QAAQ,EAAE,CAAC,CAAC,MAAM,CAC9C,CAAC;AACF,SAAO;GAAE,UAAU,SAAS;GAAM,aAAa,YAAY;GAAM;SAC3D;AACN,SAAO,EAAE"}
|
package/dist/auth/project.d.cts
CHANGED
|
@@ -5,16 +5,18 @@
|
|
|
5
5
|
* First checks for a locally linked project in `.vercel/project.json`.
|
|
6
6
|
* If found, uses the `projectId` and `orgId` from there.
|
|
7
7
|
*
|
|
8
|
-
* Otherwise, if `teamId` is not provided,
|
|
9
|
-
*
|
|
8
|
+
* Otherwise, if `teamId` is not provided, builds an ordered list of candidate
|
|
9
|
+
* teams to try: the user's `defaultTeamId` first (if set), then hobby-plan
|
|
10
|
+
* teams where the user has an OWNER role (preferring the personal team matching
|
|
11
|
+
* the username, then the most recently updated). Tries each candidate until one
|
|
12
|
+
* succeeds.
|
|
10
13
|
*
|
|
11
14
|
* @param opts.token - Vercel API authentication token.
|
|
12
|
-
* @param opts.teamId - Optional team slug. If omitted,
|
|
15
|
+
* @param opts.teamId - Optional team slug. If omitted, candidate teams are resolved automatically.
|
|
13
16
|
* @param opts.cwd - Optional directory to search for `.vercel/project.json`. Defaults to `process.cwd()`.
|
|
14
17
|
* @returns The resolved scope with `projectId`, `teamId`, and whether the project was `created`.
|
|
15
18
|
*
|
|
16
19
|
* @throws {NotOk} If the API returns an error other than 404 when checking the project.
|
|
17
|
-
* @throws {ZodError} If no teams exist for the account.
|
|
18
20
|
*
|
|
19
21
|
* @example
|
|
20
22
|
* ```ts
|
|
@@ -30,15 +32,9 @@ declare function inferScope(opts: {
|
|
|
30
32
|
projectId: string;
|
|
31
33
|
teamId: string;
|
|
32
34
|
created: boolean;
|
|
35
|
+
teamSlug?: string;
|
|
36
|
+
projectSlug?: string;
|
|
33
37
|
}>;
|
|
34
|
-
/**
|
|
35
|
-
* Selects a team for the current token by querying the Teams API and
|
|
36
|
-
* returning the slug of the first team in the result set.
|
|
37
|
-
*
|
|
38
|
-
* @param token - Authentication token used to call the Vercel API.
|
|
39
|
-
* @returns A promise that resolves to the first team's slug.
|
|
40
|
-
*/
|
|
41
|
-
declare function selectTeam(token: string): Promise<string>;
|
|
42
38
|
//#endregion
|
|
43
|
-
export { inferScope
|
|
39
|
+
export { inferScope };
|
|
44
40
|
//# sourceMappingURL=project.d.cts.map
|
package/dist/auth/project.d.ts
CHANGED
|
@@ -5,16 +5,18 @@
|
|
|
5
5
|
* First checks for a locally linked project in `.vercel/project.json`.
|
|
6
6
|
* If found, uses the `projectId` and `orgId` from there.
|
|
7
7
|
*
|
|
8
|
-
* Otherwise, if `teamId` is not provided,
|
|
9
|
-
*
|
|
8
|
+
* Otherwise, if `teamId` is not provided, builds an ordered list of candidate
|
|
9
|
+
* teams to try: the user's `defaultTeamId` first (if set), then hobby-plan
|
|
10
|
+
* teams where the user has an OWNER role (preferring the personal team matching
|
|
11
|
+
* the username, then the most recently updated). Tries each candidate until one
|
|
12
|
+
* succeeds.
|
|
10
13
|
*
|
|
11
14
|
* @param opts.token - Vercel API authentication token.
|
|
12
|
-
* @param opts.teamId - Optional team slug. If omitted,
|
|
15
|
+
* @param opts.teamId - Optional team slug. If omitted, candidate teams are resolved automatically.
|
|
13
16
|
* @param opts.cwd - Optional directory to search for `.vercel/project.json`. Defaults to `process.cwd()`.
|
|
14
17
|
* @returns The resolved scope with `projectId`, `teamId`, and whether the project was `created`.
|
|
15
18
|
*
|
|
16
19
|
* @throws {NotOk} If the API returns an error other than 404 when checking the project.
|
|
17
|
-
* @throws {ZodError} If no teams exist for the account.
|
|
18
20
|
*
|
|
19
21
|
* @example
|
|
20
22
|
* ```ts
|
|
@@ -30,15 +32,9 @@ declare function inferScope(opts: {
|
|
|
30
32
|
projectId: string;
|
|
31
33
|
teamId: string;
|
|
32
34
|
created: boolean;
|
|
35
|
+
teamSlug?: string;
|
|
36
|
+
projectSlug?: string;
|
|
33
37
|
}>;
|
|
34
|
-
/**
|
|
35
|
-
* Selects a team for the current token by querying the Teams API and
|
|
36
|
-
* returning the slug of the first team in the result set.
|
|
37
|
-
*
|
|
38
|
-
* @param token - Authentication token used to call the Vercel API.
|
|
39
|
-
* @returns A promise that resolves to the first team's slug.
|
|
40
|
-
*/
|
|
41
|
-
declare function selectTeam(token: string): Promise<string>;
|
|
42
38
|
//#endregion
|
|
43
|
-
export { inferScope
|
|
39
|
+
export { inferScope };
|
|
44
40
|
//# sourceMappingURL=project.d.ts.map
|