Skip to content
Merged
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
77 changes: 77 additions & 0 deletions apps/server/src/provider/jsoncParserPack.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// @effect-diagnostics nodeBuiltinImport:off - The packaging regression must execute the emitted module from a disposable filesystem fixture.
import { assert, it } from "@effect/vitest";
import { build } from "vite-plus/pack";
import * as NodeChildProcess from "node:child_process";
import * as NodeFSP from "node:fs/promises";
import * as NodeOS from "node:os";
import * as NodePath from "node:path";
import * as NodeURL from "node:url";

import { jsoncParserPackInputOptions } from "../../vite.config.ts";

it("starts a bundled JSONC parser and preserves comment/trailing-comma parsing", async () => {
const workDir = await NodeFSP.mkdtemp(NodePath.join(NodeOS.tmpdir(), "t3-jsonc-pack-"));
const entry = NodePath.join(workDir, "entry.mjs");
const outDir = NodePath.join(workDir, "out");

try {
await NodeFSP.writeFile(
entry,
`import { parse as parseJsonc } from "jsonc-parser";
const errors = [];
const parsed = parseJsonc('{ /* comment */ "provider": "codex", "args": ["--flag",], }', errors, { allowTrailingComma: true });
if (errors.length !== 0 || parsed.provider !== "codex" || parsed.args[0] !== "--flag") {
throw new Error(JSON.stringify({ errors, parsed }));
}
const malformedErrors = [];
parseJsonc('{ "provider": }', malformedErrors);
if (malformedErrors.length === 0) throw new Error("Malformed JSONC was accepted");
export const jsoncBundleProbe = {
provider: parsed.provider,
argument: parsed.args[0],
malformedErrorCount: malformedErrors.length,
moduleUrl: import.meta.url,
};
console.log("JSONC_BUNDLE_OK", parsed.provider, parsed.args[0], malformedErrors.length);
`,
);

const result = await build({
cwd: process.cwd(),
entry,
outDir,
format: "esm",
deps: { alwaysBundle: ["jsonc-parser"] },
inputOptions: jsoncParserPackInputOptions,
});
const entryChunk = result.bundles.flatMap((bundle) => bundle.chunks)[0];
assert(entryChunk, "The JSONC fixture should produce an entry bundle");
const bundlePath = NodePath.join(outDir, entryChunk.fileName);
const bundleSource = await NodeFSP.readFile(bundlePath, "utf8");

assert(!bundleSource.includes('require("./impl/format")'));
// Run the artifact with Node itself so the packaging regression exercises
// the emitted module, not a transformed or mocked source import.
const execution = NodeChildProcess.spawnSync(process.execPath, [bundlePath], {
encoding: "utf8",
timeout: 10_000,
});
const spawnError = execution.error as NodeJS.ErrnoException | undefined;
if (spawnError?.code === "EPERM") {
// The managed test sandbox may prohibit child processes. Load the emitted
// .mjs directly there; CI still gets the independent Node process above.
const emittedModule = await import(NodeURL.pathToFileURL(bundlePath).href);
assert.deepEqual(emittedModule.jsoncBundleProbe, {
provider: "codex",
argument: "--flag",
malformedErrorCount: 1,
moduleUrl: NodeURL.pathToFileURL(bundlePath).href,
});
} else {
assert.equal(execution.status, 0, execution.stderr ?? execution.error?.message);
assert(execution.stdout.includes("JSONC_BUNDLE_OK codex --flag 1"));
}
} finally {
await NodeFSP.rm(workDir, { recursive: true, force: true });
}
});
14 changes: 14 additions & 0 deletions apps/server/vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import "vite-plus/test/config";
import { defineConfig, mergeConfig } from "vite-plus";
import * as NodeModule from "node:module";

import baseConfig from "../../vite.config.ts";
import { loadRepoEnv } from "../../scripts/lib/public-config.ts";
Expand All @@ -20,6 +21,18 @@ import {

export { shouldBundleCliDependency };

// jsonc-parser's package `main` is its UMD build, which leaves relative
// CommonJS requires in a single-file SEA. Point only this package at its ESM
// entry so Rolldown bundles the parser's implementation modules.
const nodeRequire = NodeModule.createRequire(import.meta.url);
export const jsoncParserPackInputOptions = {
resolve: {
alias: {
"jsonc-parser$": nodeRequire.resolve("jsonc-parser/lib/esm/main.js"),
},
},
};

const repoEnv = loadRepoEnv();
const cliBuildChannel = /^[^-+]+-(?:nightly|preview)\./.test(packageJson.version)
? "nightly"
Expand Down Expand Up @@ -106,6 +119,7 @@ export default mergeConfig(
neverBundle: (id: string) => isExternalCliDependency(id),
onlyBundle: false,
},
inputOptions: jsoncParserPackInputOptions,
banner: {
js: "#!/usr/bin/env node\n",
},
Expand Down
Loading