Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/gold-flowers-clean.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@vercel/sandbox": patch
---

Build and publish both ESM and CJS outputs for the SDK package.
22 changes: 20 additions & 2 deletions packages/vercel-sandbox/package.json
Original file line number Diff line number Diff line change
@@ -1,17 +1,34 @@
{
"name": "@vercel/sandbox",
"type": "module",
"version": "1.8.0",
"description": "Software Development Kit for Vercel Sandbox",
"main": "dist/index.js",
"main": "dist/index.cjs",
"module": "dist/index.js",
"types": "dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"require": "./dist/index.cjs",
"default": "./dist/index.cjs"
},
"./dist/*.js": {
"import": "./dist/*.js",
"require": "./dist/*.cjs",
"default": "./dist/*.cjs"
},
"./dist/*": "./dist/*",
"./package.json": "./package.json"
},
"files": [
"dist",
"README.md",
"LICENSE"
],
"scripts": {
"clean": "rm -rf node_modules dist",
"build": "tsc",
"build": "tsdown",
"test": "vitest run",
"typedoc": "typedoc",
"typecheck": "tsc --noEmit",
Expand Down Expand Up @@ -49,6 +66,7 @@
"dotenv": "16.5.0",
"factoree": "^0.1.2",
"typedoc": "0.28.5",
"tsdown": "catalog:",
"typescript": "5.8.3",
"vitest": "catalog:"
}
Expand Down
6 changes: 3 additions & 3 deletions packages/vercel-sandbox/src/api-client/api-client.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
import { APIClient } from "./api-client";
import { APIError, StreamError } from "./api-error";
import { createNdjsonStream } from "../../test-utils/mock-response";
import { APIClient } from "./api-client.js";
import { APIError, StreamError } from "./api-error.js";
import { createNdjsonStream } from "../../test-utils/mock-response.js";

describe("APIClient", () => {
describe("getLogs", () => {
Expand Down
22 changes: 11 additions & 11 deletions packages/vercel-sandbox/src/api-client/api-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
parseOrThrow,
type Parsed,
type RequestParams,
} from "./base-client";
} from "./base-client.js";
import {
CommandFinishedData,
SandboxAndRoutesResponse,
Expand All @@ -21,21 +21,21 @@ CommandFinishedData,
SnapshotResponse,
CreateSnapshotResponse,
type CommandData,
} from "./validators";
import { APIError, StreamError } from "./api-error";
import { FileWriter } from "./file-writer";
import { VERSION } from "../version";
import { consumeReadable } from "../utils/consume-readable";
} from "./validators.js";
import { APIError, StreamError } from "./api-error.js";
import { FileWriter } from "./file-writer.js";
import { VERSION } from "../version.js";
import { consumeReadable } from "../utils/consume-readable.js";
import { z } from "zod";
import jsonlines from "jsonlines";
import os from "os";
import { Readable } from "stream";
import { normalizePath } from "../utils/normalizePath";
import { normalizePath } from "../utils/normalizePath.js";
import { getVercelOidcToken } from "@vercel/oidc";
import { NetworkPolicy } from "../network-policy";
import { toAPINetworkPolicy, fromAPINetworkPolicy } from "../utils/network-policy";
import { getPrivateParams, WithPrivate } from "../utils/types";
import { RUNTIMES } from "../constants";
import { NetworkPolicy } from "../network-policy.js";
import { toAPINetworkPolicy, fromAPINetworkPolicy } from "../utils/network-policy.js";
import { getPrivateParams, WithPrivate } from "../utils/types.js";
import { RUNTIMES } from "../constants.js";
import { setTimeout } from "node:timers/promises";

interface Claims {
Expand Down
6 changes: 3 additions & 3 deletions packages/vercel-sandbox/src/api-client/base-client.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type { Options as RetryOptions } from "async-retry";
import { APIError } from "./api-error";
import { APIError } from "./api-error.js";
import { ZodType } from "zod";
import { array } from "../utils/array";
import { withRetry, type RequestOptions } from "./with-retry";
import { array } from "../utils/array.js";
import { withRetry, type RequestOptions } from "./with-retry.js";
import { Agent } from "undici";

export interface RequestParams extends RequestInit {
Expand Down
4 changes: 2 additions & 2 deletions packages/vercel-sandbox/src/api-client/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export { APIClient } from "./api-client";
export * from "./validators";
export { APIClient } from "./api-client.js";
export * from "./validators.js";
2 changes: 1 addition & 1 deletion packages/vercel-sandbox/src/api-client/with-retry.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Options as RetryOptions } from "async-retry";
import { APIError } from "./api-error";
import { APIError } from "./api-error.js";
import { setTimeout } from "node:timers/promises";
import retry from "async-retry";

Expand Down
2 changes: 1 addition & 1 deletion packages/vercel-sandbox/src/auth/api.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { NotOk } from "./error";
import { NotOk } from "./error.js";

export async function fetchApi(opts: {
token: string;
Expand Down
2 changes: 1 addition & 1 deletion packages/vercel-sandbox/src/auth/file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import fs from "node:fs";
import { homedir } from "node:os";
import XDGAppPaths from "xdg-app-paths";
import { z } from "zod";
import { json } from "./zod";
import { json } from "./zod.js";

const ZodDate = z.number().transform((seconds) => new Date(seconds * 1000));

Expand Down
12 changes: 6 additions & 6 deletions packages/vercel-sandbox/src/auth/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// This file can also be imported as `@vercel/sandbox/dist/auth`, which is completely fine.
// The only valid importer of this would be the CLI as we share the same codebase.

export * from "./file";
export type * from "./file";
export * from "./oauth";
export type * from "./oauth";
export { pollForToken } from "./poll-for-token";
export { inferScope, selectTeam } from "./project";
export * from "./file.js";
export type * from "./file.js";
export * from "./oauth.js";
export type * from "./oauth.js";
export { pollForToken } from "./poll-for-token.js";
export { inferScope, selectTeam } from "./project.js";
6 changes: 3 additions & 3 deletions packages/vercel-sandbox/src/auth/infer-scope.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { inferScope, selectTeam } from "./project";
import { inferScope, selectTeam } from "./project.js";
import {
beforeEach,
describe,
Expand All @@ -8,8 +8,8 @@ import {
expect,
onTestFinished,
} from "vitest";
import { fetchApi } from "./api";
import { NotOk } from "./error";
import { fetchApi } from "./api.js";
import { NotOk } from "./error.js";
import * as fs from "node:fs/promises";
import * as path from "node:path";
import * as os from "node:os";
Expand Down
2 changes: 1 addition & 1 deletion packages/vercel-sandbox/src/auth/linked-project.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { readLinkedProject } from "./linked-project";
import { readLinkedProject } from "./linked-project.js";
import { describe, test, expect } from "vitest";
import * as fs from "node:fs/promises";
import * as path from "node:path";
Expand Down
2 changes: 1 addition & 1 deletion packages/vercel-sandbox/src/auth/linked-project.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { z } from "zod";
import * as fs from "node:fs/promises";
import * as path from "node:path";
import { json } from "./zod";
import { json } from "./zod.js";

const LinkedProjectSchema = json.pipe(
z.object({
Expand Down
2 changes: 1 addition & 1 deletion packages/vercel-sandbox/src/auth/oauth.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import os from "os";
import { z } from "zod";
import { VERSION } from "../version";
import { VERSION } from "../version.js";

const USER_AGENT = `${os.hostname()} @ vercel/sandbox/${VERSION} node-${
process.version
Expand Down
4 changes: 2 additions & 2 deletions packages/vercel-sandbox/src/auth/poll-for-token.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { setTimeout } from "node:timers/promises";
import { updateAuthConfig } from "./file";
import { DeviceAuthorizationRequest, isOAuthError, OAuth } from "./oauth";
import { updateAuthConfig } from "./file.js";
import { DeviceAuthorizationRequest, isOAuthError, OAuth } from "./oauth.js";

export type PollTokenItem =
| { _tag: "Timeout"; newInterval: number }
Expand Down
6 changes: 3 additions & 3 deletions packages/vercel-sandbox/src/auth/project.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { z } from "zod";
import { fetchApi } from "./api";
import { NotOk } from "./error";
import { readLinkedProject } from "./linked-project";
import { fetchApi } from "./api.js";
import { NotOk } from "./error.js";
import { readLinkedProject } from "./linked-project.js";

const TeamsSchema = z.object({
teams: z
Expand Down
2 changes: 1 addition & 1 deletion packages/vercel-sandbox/src/command.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { expect, it, vi, beforeEach, afterEach, describe } from "vitest";
import { Sandbox } from "./sandbox";
import { Sandbox } from "./sandbox.js";

describe.skipIf(process.env.RUN_INTEGRATION_TESTS !== "1")("Command", () => {
let sandbox: Sandbox;
Expand Down
4 changes: 2 additions & 2 deletions packages/vercel-sandbox/src/command.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { APIClient, type CommandData } from "./api-client";
import { Signal, resolveSignal } from "./utils/resolveSignal";
import { APIClient, type CommandData } from "./api-client/index.js";
import { Signal, resolveSignal } from "./utils/resolveSignal.js";

/**
* A command executed in a Sandbox.
Expand Down
10 changes: 5 additions & 5 deletions packages/vercel-sandbox/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ export {
type NetworkPolicy,
type NetworkPolicyRule,
type NetworkTransformer,
} from "./sandbox";
export { Snapshot } from "./snapshot";
export { Command, CommandFinished } from "./command";
export { StreamError } from "./api-client/api-error";
export { APIError } from "./api-client/api-error";
} from "./sandbox.js";
export { Snapshot } from "./snapshot.js";
export { Command, CommandFinished } from "./command.js";
export { StreamError } from "./api-client/api-error.js";
export { APIError } from "./api-client/api-error.js";
70 changes: 70 additions & 0 deletions packages/vercel-sandbox/src/package-exports.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { expect, it } from "vitest";
import { execFileSync } from "node:child_process";
import { readFileSync } from "node:fs";
import { resolve } from "node:path";
import { fileURLToPath } from "node:url";

it("defines import/require export targets", () => {
const packageJsonPath = resolve(__dirname, "..", "package.json");
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8"));

expect(packageJson.exports?.["."]?.import).toBe("./dist/index.js");
expect(packageJson.exports?.["."]?.require).toBe("./dist/index.cjs");
expect(packageJson.exports?.["."]?.types).toBe("./dist/index.d.ts");
expect(packageJson.exports?.["./dist/*.js"]?.import).toBe("./dist/*.js");
expect(packageJson.exports?.["./dist/*.js"]?.require).toBe("./dist/*.cjs");
expect(packageJson.exports?.["./dist/*"]).toBe("./dist/*");
});

it("resolves import and require to different entrypoints", () => {
const packageRoot = resolve(__dirname, "..");

const cjsResolution = execFileSync(
process.execPath,
["-e", "console.log(require.resolve('@vercel/sandbox'))"],
{ cwd: packageRoot, encoding: "utf8" },
).trim();

const esmResolutionUrl = execFileSync(
process.execPath,
[
"--input-type=module",
"-e",
"console.log(await import.meta.resolve('@vercel/sandbox'))",
],
{ cwd: packageRoot, encoding: "utf8" },
).trim();

const esmResolution = fileURLToPath(esmResolutionUrl);

expect(cjsResolution).toBe(resolve(packageRoot, "dist/index.cjs"));
expect(esmResolution).toBe(resolve(packageRoot, "dist/index.js"));
});

it("resolves deep dist imports with format-appropriate files", () => {
const packageRoot = resolve(__dirname, "..");

const cjsResolution = execFileSync(
process.execPath,
[
"-e",
"console.log(require.resolve('@vercel/sandbox/dist/auth/index.js'))",
],
{ cwd: packageRoot, encoding: "utf8" },
).trim();

const esmResolutionUrl = execFileSync(
process.execPath,
[
"--input-type=module",
"-e",
"console.log(await import.meta.resolve('@vercel/sandbox/dist/auth/index.js'))",
],
{ cwd: packageRoot, encoding: "utf8" },
).trim();

const esmResolution = fileURLToPath(esmResolutionUrl);

expect(cjsResolution).toBe(resolve(packageRoot, "dist/auth/index.cjs"));
expect(esmResolution).toBe(resolve(packageRoot, "dist/auth/index.js"));
});
6 changes: 3 additions & 3 deletions packages/vercel-sandbox/src/sandbox.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { it, beforeEach, afterEach, expect, describe } from "vitest";
import { consumeReadable } from "./utils/consume-readable";
import { Sandbox } from "./sandbox";
import { APIError } from "./api-client/api-error";
import { consumeReadable } from "./utils/consume-readable.js";
import { Sandbox } from "./sandbox.js";
import { APIError } from "./api-client/api-error.js";
import { mkdtemp, readFile, rm } from "fs/promises";
import { tmpdir } from "os";
import { join, resolve } from "path";
Expand Down
Loading