fix(typebox): migrate to v1 with extension compat (#3474)
* fix(typebox): migrate to v1 with extension compat Replace AJV-based validation with TypeBox-native validation, keep legacy extension imports working (including @sinclair/typebox/compiler), and restore coercion for serialized/plain JSON schemas. This change closes #3112. * fix(typebox): use canonical imports and harden coercion Switch first-party code to canonical typebox imports while retaining legacy extension aliases in the loader. Remove obsolete runtime codegen guards, expand serialized JSON-schema coercion coverage, and update related tests and fixtures. Fixes #3112. --------- Co-authored-by: Mario Zechner <badlogicgames@gmail.com>
This commit is contained in:
@@ -18,7 +18,9 @@ import * as _bundledPiTui from "@mariozechner/pi-tui";
|
||||
// Static imports of packages that extensions may use.
|
||||
// These MUST be static so Bun bundles them into the compiled binary.
|
||||
// The virtualModules option then makes them available to extensions.
|
||||
import * as _bundledTypebox from "@sinclair/typebox";
|
||||
import * as _bundledTypebox from "typebox";
|
||||
import * as _bundledTypeboxCompile from "typebox/compile";
|
||||
import * as _bundledTypeboxValue from "typebox/value";
|
||||
import { getAgentDir, isBunBinary } from "../../config.js";
|
||||
// NOTE: This import works because loader.ts exports are NOT re-exported from index.ts,
|
||||
// avoiding a circular dependency. Extensions can import from @mariozechner/pi-coding-agent.
|
||||
@@ -27,6 +29,7 @@ import { createEventBus, type EventBus } from "../event-bus.js";
|
||||
import type { ExecOptions } from "../exec.js";
|
||||
import { execCommand } from "../exec.js";
|
||||
import { createSyntheticSourceInfo } from "../source-info.js";
|
||||
import * as _bundledTypeboxCompilerCompat from "./typebox-compiler-compat.js";
|
||||
import type {
|
||||
Extension,
|
||||
ExtensionAPI,
|
||||
@@ -41,7 +44,14 @@ import type {
|
||||
|
||||
/** Modules available to extensions via virtualModules (for compiled Bun binary) */
|
||||
const VIRTUAL_MODULES: Record<string, unknown> = {
|
||||
typebox: _bundledTypebox,
|
||||
"typebox/compile": _bundledTypeboxCompile,
|
||||
"typebox/value": _bundledTypeboxValue,
|
||||
"typebox/compiler": _bundledTypeboxCompilerCompat,
|
||||
"@sinclair/typebox": _bundledTypebox,
|
||||
"@sinclair/typebox/compile": _bundledTypeboxCompile,
|
||||
"@sinclair/typebox/value": _bundledTypeboxValue,
|
||||
"@sinclair/typebox/compiler": _bundledTypeboxCompilerCompat,
|
||||
"@mariozechner/pi-agent-core": _bundledPiAgentCore,
|
||||
"@mariozechner/pi-tui": _bundledPiTui,
|
||||
"@mariozechner/pi-ai": _bundledPiAi,
|
||||
@@ -56,14 +66,25 @@ const require = createRequire(import.meta.url);
|
||||
* In Bun binary mode, virtualModules is used instead.
|
||||
*/
|
||||
let _aliases: Record<string, string> | null = null;
|
||||
|
||||
function resolveTypeboxCompilerCompatPath(baseDir: string): string {
|
||||
const jsPath = path.resolve(baseDir, "typebox-compiler-compat.js");
|
||||
if (fs.existsSync(jsPath)) {
|
||||
return jsPath;
|
||||
}
|
||||
return path.resolve(baseDir, "typebox-compiler-compat.ts");
|
||||
}
|
||||
|
||||
function getAliases(): Record<string, string> {
|
||||
if (_aliases) return _aliases;
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const packageIndex = path.resolve(__dirname, "../..", "index.js");
|
||||
|
||||
const typeboxEntry = require.resolve("@sinclair/typebox");
|
||||
const typeboxRoot = typeboxEntry.replace(/[\\/]build[\\/]cjs[\\/]index\.js$/, "");
|
||||
const typeboxEntry = require.resolve("typebox");
|
||||
const typeboxCompileEntry = require.resolve("typebox/compile");
|
||||
const typeboxValueEntry = require.resolve("typebox/value");
|
||||
const typeboxCompilerCompat = resolveTypeboxCompilerCompatPath(__dirname);
|
||||
|
||||
const packagesRoot = path.resolve(__dirname, "../../../../");
|
||||
const resolveWorkspaceOrImport = (workspaceRelativePath: string, specifier: string): string => {
|
||||
@@ -80,7 +101,14 @@ function getAliases(): Record<string, string> {
|
||||
"@mariozechner/pi-tui": resolveWorkspaceOrImport("tui/dist/index.js", "@mariozechner/pi-tui"),
|
||||
"@mariozechner/pi-ai": resolveWorkspaceOrImport("ai/dist/index.js", "@mariozechner/pi-ai"),
|
||||
"@mariozechner/pi-ai/oauth": resolveWorkspaceOrImport("ai/dist/oauth.js", "@mariozechner/pi-ai/oauth"),
|
||||
"@sinclair/typebox": typeboxRoot,
|
||||
typebox: typeboxEntry,
|
||||
"typebox/compile": typeboxCompileEntry,
|
||||
"typebox/value": typeboxValueEntry,
|
||||
"typebox/compiler": typeboxCompilerCompat,
|
||||
"@sinclair/typebox": typeboxEntry,
|
||||
"@sinclair/typebox/compile": typeboxCompileEntry,
|
||||
"@sinclair/typebox/value": typeboxValueEntry,
|
||||
"@sinclair/typebox/compiler": typeboxCompilerCompat,
|
||||
};
|
||||
|
||||
return _aliases;
|
||||
|
||||
Reference in New Issue
Block a user