From dc0f64c1ea97c87dc1a9949284a2b83c8c56a124 Mon Sep 17 00:00:00 2001 From: Chris Tate Date: Tue, 18 Aug 2026 08:59:46 -0500 Subject: [PATCH] fix(ts-core): resolve installed compiler and SQLite modules (#389) - Resolve scriptc through npm package resolution so nested, hoisted, and global sibling installs work. - Generate a complete SQLite SDK module family and validate library imports against their actual directory. - Cover global compiler lookup, documented event imports, and generated-core loading with regressions. --- build.zig | 5 +- build/app.zig | 66 ++++++------------- .../scripts/run_external_core_compiler.mjs | 28 +++++--- .../scripts/run_external_service_compiler.mjs | 25 ++++--- packages/core/src/modules.ts | 8 ++- packages/core/src/sqlite_cli.ts | 24 ++++++- .../core/test/external_core_compiler.test.ts | 53 +++++++++++++++ packages/core/test/services.test.ts | 6 +- packages/core/test/sqlite_codegen.test.ts | 39 +++++++++++ src/tooling/ts_core.zig | 18 +++-- 10 files changed, 196 insertions(+), 76 deletions(-) diff --git a/build.zig b/build.zig index 823fce52..3cb61b17 100644 --- a/build.zig +++ b/build.zig @@ -859,7 +859,10 @@ pub fn build(b: *std.Build) void { .{ .path = "packages/core/scripts/embed_markup_c.mjs", .pattern = "const unsigned char native_sdk_app_markup[]" }, .{ .path = "build/app.zig", .pattern = "node_modules\", \"scriptc\", \"dist\", \"bootstrap.js\"" }, .{ .path = "build/app.zig", .pattern = "setEnvironmentVariable(\"SCRIPTC_TIMING\", \"1\")" }, - .{ .path = "build/app.zig", .pattern = "node_modules\", \".bin\", if (builtin.os.tag == .windows) \"scriptc.cmd\" else \"scriptc\"" }, + .{ .path = "build/app.zig", .pattern = "service_compile.addArg(\"--compiler-package-origin\")" }, + .{ .path = "build/app.zig", .pattern = "compile.addArg(\"--compiler-package-origin\")" }, + .{ .path = "packages/core/scripts/run_external_core_compiler.mjs", .pattern = "publishedScriptcArgv(args[\"compiler-package-origin\"])" }, + .{ .path = "packages/core/scripts/run_external_service_compiler.mjs", .pattern = "publishedScriptcArgv(args[\"compiler-package-origin\"])" }, .{ .path = "build/app.zig", .pattern = "addFileInput(dep.path(\"packages/core/scripts/compiler_command.mjs\"))" }, .{ .path = "packages/core/scripts/run_external_core_compiler.mjs", .pattern = "compilerArgv(args.compiler)" }, .{ .path = "packages/core/scripts/run_external_service_compiler.mjs", .pattern = "compilerArgv(args.compiler)" }, diff --git a/build/app.zig b/build/app.zig index a548a55d..7590a9e0 100644 --- a/build/app.zig +++ b/build/app.zig @@ -708,48 +708,6 @@ fn tsParseQuotedManifestValue(manifest_json: []const u8, comptime key: []const u return suffix; } -/// The external compiler's published `scriptc` binary entrypoint, -/// resolved by node's ancestor node_modules walk from the SDK's -/// packages/core — the same origin the frontend toolchain resolves from -/// (tsAliasedCompilerVersion's walk, kept in lockstep). Repo checkouts -/// install it there with `npm ci`; the npm-installed CLI carries the -/// compiler as a regular dependency, nested under the package on global -/// prefixes and hoisted to the project root on local ones. -fn tsExternalCompilerBin(b: *std.Build, dep: *std.Build.Dependency) ?[]const u8 { - const io = b.graph.io; - const sdk_root = tsSdkRoot(b.allocator, io, dep); - var dir: []const u8 = b.pathJoin(&.{ sdk_root, "packages", "core" }); - while (true) { - if (!std.mem.eql(u8, std.fs.path.basename(dir), "node_modules")) { - const candidate = b.pathJoin(&.{ dir, "node_modules", ".bin", if (builtin.os.tag == .windows) "scriptc.cmd" else "scriptc" }); - found: { - std.Io.Dir.cwd().access(io, candidate, .{}) catch break :found; - return candidate; - } - } - dir = std.fs.path.dirname(dir) orelse return null; - } -} - -fn requireTsExternalCompilerBin(b: *std.Build, dep: *std.Build.Dependency) []const u8 { - return tsExternalCompilerBin(b, dep) orelse { - const sdk_root = tsSdkRoot(dep.builder.allocator, dep.builder.graph.io, dep); - std.debug.print( - \\ - \\error: the external TypeScript compiler is not installed (cores and services - \\compile through it). It ships as an exact-pinned dependency of the SDK's - \\packages/core — install it once with: - \\ cd {s}/packages/core && npm ci - \\(or point NATIVE_SDK_CORE_COMPILER at the pinned release's command; an - \\npm-installed @native-sdk/cli carries the compiler automatically — if it is - \\missing there, the install is broken: reinstall @native-sdk/cli). - \\ - \\ - , .{sdk_root}); - std.process.exit(1); - }; -} - /// PR 166 adds both the published compile-cache bootstrap and the optional /// library-profile optimization field. The installed bootstrap is therefore /// the capability marker: keep older exact pins byte-for-byte compatible; @@ -934,6 +892,16 @@ fn tsCoreStage( sqlite_check.addFileArg(dep.path("packages/core/compile-surface/core.ts")); sqlite_check.addArg("--sdk-out"); checked_sdk_core = sqlite_check.addOutputFileArg("core.ts"); + sqlite_check.addArg("--sdk-events-out"); + _ = sqlite_check.addOutputFileArg("events.ts"); + sqlite_check.addArg("--sdk-text-out"); + _ = sqlite_check.addOutputFileArg("text.ts"); + sqlite_check.addArg("--sdk-bytes-text-methods-out"); + _ = sqlite_check.addOutputFileArg("bytes_text_methods.d.ts"); + sqlite_check.addArg("--sdk-events-dts-out"); + _ = sqlite_check.addOutputFileArg("events.d.ts"); + sqlite_check.addArg("--sdk-text-dts-out"); + _ = sqlite_check.addOutputFileArg("text.d.ts"); sqlite_check.addArg("--static-out"); checked_static_core = sqlite_check.addOutputFileArg("core_static.ts"); sqlite_check.addArg("--zig-out"); @@ -946,6 +914,9 @@ fn tsCoreStage( } sqlite_check.addFileInput(dep.path("packages/core/src/sqlite_codegen.ts")); sqlite_check.addFileInput(dep.path("packages/core/src/sqlite_runtime_policy.ts")); + for ([_][]const u8{ "events.ts", "text.ts", "bytes_text_methods.d.ts", "events.d.ts", "text.d.ts" }) |source| { + sqlite_check.addFileInput(dep.path(b.fmt("packages/core/sdk/{s}", .{source}))); + } addAppSqlDirInputs(b, sqlite_check, appPath(b, app_root, "src")); } @@ -1119,8 +1090,11 @@ fn tsCoreStage( if (b.graph.environ_map.get("NATIVE_SDK_CORE_COMPILER")) |override| { service_compile.addArgs(&.{ "--compiler", override }); } else { - const compiler_bin = requireTsExternalCompilerBin(b, dep); - service_compile.addArgs(&.{ "--compiler", compiler_bin }); + // Let Node resolve the dependency from the SDK package origin: + // this is npm's own nested/hoisted/global-sibling walk, and the + // driver follows scriptc's published `bin` declaration. + service_compile.addArg("--compiler-package-origin"); + service_compile.addFileArg(dep.path("packages/core/package.json")); } } @@ -1190,8 +1164,8 @@ fn tsCoreStage( // driver still refuses a release other than the SDK's pin. compile.addArgs(&.{ "--compiler", override }); } else { - const compiler_bin = requireTsExternalCompilerBin(b, dep); - compile.addArgs(&.{ "--compiler", compiler_bin }); + compile.addArg("--compiler-package-origin"); + compile.addFileArg(dep.path("packages/core/package.json")); } // The mirror, generated from the archive's OWN co-emitted contract. diff --git a/packages/core/scripts/run_external_core_compiler.mjs b/packages/core/scripts/run_external_core_compiler.mjs index b7425bc2..aa6dcfc0 100644 --- a/packages/core/scripts/run_external_core_compiler.mjs +++ b/packages/core/scripts/run_external_core_compiler.mjs @@ -14,13 +14,14 @@ // --out-sidecar // [--host-platform --target-platform // --zig-exe ] [--android-ndk ] -// (--compiler | --compiler-js ) +// (--compiler | --compiler-js | +// --compiler-package-origin ) import { spawnSync } from "node:child_process"; import fs from "node:fs"; import os from "node:os"; import path from "node:path"; -import { compilerArgv } from "./compiler_command.mjs"; +import { compilerArgv, publishedScriptcArgv } from "./compiler_command.mjs"; function parseArgs(argv) { const args = {}; @@ -28,7 +29,7 @@ function parseArgs(argv) { const key = argv[i]; const value = argv[i + 1]; if (!key.startsWith("--") || value === undefined) { - console.error("usage: run_external_core_compiler.mjs --stage --name --manifest --frontend-sidecar --out-archive --out-sidecar [--host-platform --target-platform --zig-exe ] (--compiler | --compiler-js )"); + console.error("usage: run_external_core_compiler.mjs --stage --name --manifest --frontend-sidecar --out-archive --out-sidecar [--host-platform --target-platform --zig-exe ] (--compiler | --compiler-js | --compiler-package-origin )"); process.exit(2); } args[key.slice(2)] = value; @@ -39,8 +40,9 @@ function parseArgs(argv) { process.exit(2); } } - if (!args.compiler && !args["compiler-js"]) { - console.error("run_external_core_compiler.mjs: supply --compiler or --compiler-js "); + const compilerModes = [args.compiler, args["compiler-js"], args["compiler-package-origin"]].filter(Boolean); + if (compilerModes.length !== 1) { + console.error("run_external_core_compiler.mjs: supply exactly one of --compiler , --compiler-js , or --compiler-package-origin "); process.exit(2); } if (Boolean(args["host-platform"]) !== Boolean(args["target-platform"])) { @@ -53,15 +55,23 @@ function parseArgs(argv) { const args = parseArgs(process.argv); // Every path argument resolves against the INVOCATION's cwd up front: // the compile itself runs from a scratch directory. -for (const key of ["stage", "manifest", "frontend-sidecar", "out-archive", "out-sidecar", "compiler-js", "zig-exe", "android-ndk"]) { +for (const key of ["stage", "manifest", "frontend-sidecar", "out-archive", "out-sidecar", "compiler-js", "compiler-package-origin", "zig-exe", "android-ndk"]) { if (key in args) args[key] = path.resolve(args[key]); } // --compiler is a COMMAND: a bare executable path (possibly containing // spaces) or an interpreter plus script ("node .../main.js"). The shared // resolver also unwraps npm's Windows .cmd shim to its declared JS bin. -const argv0 = args.compiler - ? compilerArgv(args.compiler) - : [process.execPath, args["compiler-js"]]; +let argv0; +try { + argv0 = args.compiler + ? compilerArgv(args.compiler) + : args["compiler-js"] + ? [process.execPath, args["compiler-js"]] + : publishedScriptcArgv(args["compiler-package-origin"]); +} catch (error) { + console.error(`the external TypeScript compiler is not installed or has no valid published bin: ${error instanceof Error ? error.message : String(error)} — reinstall @native-sdk/cli, or point NATIVE_SDK_CORE_COMPILER at the pinned release's command`); + process.exit(2); +} // App and fixture build graphs state the host and target explicitly. A // differing target must compile the core archive through the same ScriptC diff --git a/packages/core/scripts/run_external_service_compiler.mjs b/packages/core/scripts/run_external_service_compiler.mjs index e08bce46..7b5ee2c1 100644 --- a/packages/core/scripts/run_external_service_compiler.mjs +++ b/packages/core/scripts/run_external_service_compiler.mjs @@ -17,7 +17,7 @@ import { spawnSync } from "node:child_process"; import fs from "node:fs"; import os from "node:os"; import path from "node:path"; -import { compilerArgv } from "./compiler_command.mjs"; +import { compilerArgv, publishedScriptcArgv } from "./compiler_command.mjs"; function parseArgs(argv) { const args = {}; @@ -25,7 +25,7 @@ function parseArgs(argv) { const key = argv[i]; const value = argv[i + 1]; if (!key?.startsWith("--") || value === undefined) { - console.error("usage: run_external_service_compiler.mjs --stage --manifest --contract (--out-exe | --out-archive ) --host-platform --target-platform [--zig-exe ] [--android-ndk ] (--compiler | --compiler-js )"); + console.error("usage: run_external_service_compiler.mjs --stage --manifest --contract (--out-exe | --out-archive ) --host-platform --target-platform [--zig-exe ] [--android-ndk ] (--compiler | --compiler-js | --compiler-package-origin )"); process.exit(2); } args[key.slice(2)] = value; @@ -40,8 +40,9 @@ function parseArgs(argv) { console.error("run_external_service_compiler.mjs: supply --out-exe, --out-archive, or both"); process.exit(2); } - if (!args.compiler && !args["compiler-js"]) { - console.error("run_external_service_compiler.mjs: supply --compiler or --compiler-js"); + const compilerModes = [args.compiler, args["compiler-js"], args["compiler-package-origin"]].filter(Boolean); + if (compilerModes.length !== 1) { + console.error("run_external_service_compiler.mjs: supply exactly one of --compiler, --compiler-js, or --compiler-package-origin"); process.exit(2); } return args; @@ -140,12 +141,20 @@ if (args["out-archive"]) { process.exit(2); } } -for (const key of ["stage", "manifest", "contract", "out-exe", "out-archive", "compiler-js", "zig-exe", "android-ndk"]) { +for (const key of ["stage", "manifest", "contract", "out-exe", "out-archive", "compiler-js", "compiler-package-origin", "zig-exe", "android-ndk"]) { if (args[key]) args[key] = path.resolve(args[key]); } -const argv0 = args.compiler - ? compilerArgv(args.compiler) - : [process.execPath, args["compiler-js"]]; +let argv0; +try { + argv0 = args.compiler + ? compilerArgv(args.compiler) + : args["compiler-js"] + ? [process.execPath, args["compiler-js"]] + : publishedScriptcArgv(args["compiler-package-origin"]); +} catch (error) { + console.error(`the external TypeScript compiler is not installed or has no valid published bin: ${error instanceof Error ? error.message : String(error)} — reinstall @native-sdk/cli, or point NATIVE_SDK_CORE_COMPILER at the pinned release's command`); + process.exit(2); +} // Cross compiles hand the compiler its zig-cc lane: the target triple as // SCRIPTC_TARGET (the compiler's own mobile spellings for iOS/Android), and diff --git a/packages/core/src/modules.ts b/packages/core/src/modules.ts index 373a6f5c..d40f46fc 100644 --- a/packages/core/src/modules.ts +++ b/packages/core/src/modules.ts @@ -83,7 +83,6 @@ export function resolveModuleGraph( const entryPath = path.resolve(entry); const boundary = path.dirname(entryPath); const servicesBoundary = path.join(boundary, "services"); - const sdkBoundary = path.dirname(coreModulePath); const diagnostics: SubsetDiagnostic[] = []; const files: string[] = []; const coreFiles: string[] = []; @@ -133,7 +132,12 @@ export function resolveModuleGraph( const text = fs.readFileSync(filePath, "utf8"); const parsed = ts.createSourceFile(filePath, text, ts.ScriptTarget.ESNext, true); const isSdk = sdkFiles.has(filePath); - const root = isSdk ? sdkBoundary : boundary; + // A generated relational core may live under .native/cache while the + // published library modules still resolve from the SDK package. Fence a + // library module against its own module directory, not the generated + // intrinsic core's directory; otherwise events.ts's valid ./text.ts + // re-export is falsely diagnosed as escaping the SDK. + const root = isSdk ? path.dirname(filePath) : boundary; for (const edge of edgesOf(parsed)) { const spec = edge.specifier; diff --git a/packages/core/src/sqlite_cli.ts b/packages/core/src/sqlite_cli.ts index 24fa4050..f0262af6 100644 --- a/packages/core/src/sqlite_cli.ts +++ b/packages/core/src/sqlite_cli.ts @@ -21,15 +21,25 @@ try { const sdkIn = args.get("sdk-in"); const staticIn = args.get("static-in"); const sdkOut = args.get("sdk-out"); + const sdkEventsOut = args.get("sdk-events-out"); + const sdkTextOut = args.get("sdk-text-out"); + const sdkBytesTextMethodsOut = args.get("sdk-bytes-text-methods-out"); + const sdkEventsDtsOut = args.get("sdk-events-dts-out"); + const sdkTextDtsOut = args.get("sdk-text-dts-out"); const staticOut = args.get("static-out"); const zigOut = args.get("zig-out"); const metadataOut = args.get("metadata-out"); const dtsOut = args.get("dts-out"); const state = args.get("state"); if (!zigOut) throw new Error("usage: sqlite_cli.ts --src --zig-out [--sdk-in --static-in --sdk-out --static-out --metadata-out ] [--state ]"); - const surfaceArgs = [sdkIn, staticIn, sdkOut, staticOut]; + const surfaceArgs = [ + sdkIn, staticIn, sdkOut, staticOut, + sdkEventsOut, sdkTextOut, sdkBytesTextMethodsOut, sdkEventsDtsOut, sdkTextDtsOut, + ]; const emitsSurface = surfaceArgs.every((value) => value !== undefined); - if (!emitsSurface && surfaceArgs.some((value) => value !== undefined)) throw new Error("SQLite SDK generation requires --sdk-in, --static-in, --sdk-out, and --static-out together"); + if (!emitsSurface && surfaceArgs.some((value) => value !== undefined)) { + throw new Error("SQLite SDK generation requires its core, static, and SDK sibling outputs together"); + } const analysis = analyzeSqlite(src); const diagnostics = [...analysis.diagnostics, ...(state ? checkMigrationState(analysis, state) : [])]; for (const diagnostic of [...diagnostics, ...analysis.warnings]) console.error(formatSqliteDiagnostic(diagnostic)); @@ -37,6 +47,16 @@ try { if (emitsSurface) { const sdkSource = generateCoreSurface(fs.readFileSync(sdkIn!, "utf8"), analysis); fs.writeFileSync(sdkOut!, sdkSource); + const sdkDir = path.dirname(sdkIn!); + for (const [source, destination] of [ + ["events.ts", sdkEventsOut!], + ["text.ts", sdkTextOut!], + ["bytes_text_methods.d.ts", sdkBytesTextMethodsOut!], + ["events.d.ts", sdkEventsDtsOut!], + ["text.d.ts", sdkTextDtsOut!], + ] as const) { + fs.copyFileSync(path.join(sdkDir, source), destination); + } if (dtsOut) { const compilerOptions: ts.CompilerOptions = { strict: true, diff --git a/packages/core/test/external_core_compiler.test.ts b/packages/core/test/external_core_compiler.test.ts index 32fb9aa8..7ec3929d 100644 --- a/packages/core/test/external_core_compiler.test.ts +++ b/packages/core/test/external_core_compiler.test.ts @@ -7,6 +7,59 @@ import { test } from "node:test"; import { fileURLToPath } from "node:url"; import { scriptcPin } from "./helpers.ts"; +test("the external core compile lane resolves a global-sibling scriptc package", () => { + const root = fs.mkdtempSync(path.join(os.tmpdir(), "native-core-global-scriptc-")); + try { + const globalModules = path.join(root, "lib", "node_modules"); + const sdkCore = path.join(globalModules, "@native-sdk", "cli", "packages", "core"); + const scriptcRoot = path.join(globalModules, "scriptc"); + const compiler = path.join(scriptcRoot, "dist", "bootstrap.js"); + const stage = path.join(root, "stage"); + fs.mkdirSync(sdkCore, { recursive: true }); + fs.mkdirSync(path.dirname(compiler), { recursive: true }); + fs.mkdirSync(stage); + fs.writeFileSync(path.join(stage, "profile.json"), "{}\n"); + const manifest = path.join(sdkCore, "package.json"); + fs.writeFileSync(manifest, JSON.stringify({ dependencies: { scriptc: scriptcPin } })); + fs.writeFileSync(path.join(scriptcRoot, "package.json"), JSON.stringify({ + name: "scriptc", + version: scriptcPin, + type: "module", + bin: { scriptc: "dist/bootstrap.js" }, + })); + fs.writeFileSync(compiler, ` +import fs from "node:fs"; +if (process.argv.includes("-v")) { console.log(${JSON.stringify(scriptcPin)}); process.exit(0); } +const output = process.argv[process.argv.indexOf("-o") + 1]; +fs.writeFileSync(output + ".lib.a", "global sibling archive"); +fs.writeFileSync("core.contract.json", JSON.stringify({ build_id: "global-sibling", model_unbound: [], msg: { unbound: [] } })); +`); + const frontendSidecar = path.join(root, "frontend.contract.json"); + fs.writeFileSync(frontendSidecar, JSON.stringify({ + model_fingerprint: "0123456789abcdef", + has_migrate: false, + model_unbound: [], + msg: { unbound: [] }, + })); + const script = path.join(path.dirname(fileURLToPath(import.meta.url)), "..", "scripts", "run_external_core_compiler.mjs"); + const archive = path.join(root, "libfixture_core.a"); + const result = spawnSync(process.execPath, [ + script, + "--stage", stage, + "--name", "fixture_core", + "--manifest", manifest, + "--frontend-sidecar", frontendSidecar, + "--out-archive", archive, + "--out-sidecar", path.join(root, "compiled.contract.json"), + "--compiler-package-origin", manifest, + ], { encoding: "utf8" }); + assert.equal(result.status, 0, `${result.stdout}${result.stderr}`); + assert.equal(fs.readFileSync(archive, "utf8"), "global sibling archive"); + } finally { + fs.rmSync(root, { recursive: true, force: true }); + } +}); + test("the external core compile lane uses the target-aware zig-cc environment", () => { const root = fs.mkdtempSync(path.join(os.tmpdir(), "native-core-cross-")); try { diff --git a/packages/core/test/services.test.ts b/packages/core/test/services.test.ts index 0a16a9a6..cbab3f43 100644 --- a/packages/core/test/services.test.ts +++ b/packages/core/test/services.test.ts @@ -61,7 +61,11 @@ test("a generated SQLite SDK surface and typed services share one checked progra try { fs.cpSync(path.join(packageDir, "sdk"), generatedDir, { recursive: true }); const result = checkFiles({ - "core.ts": serviceCore, + "core.ts": ` +import type { WindowDescriptor } from "@native-sdk/core/events"; +${serviceCore} +export function windows(_model: Model): readonly WindowDescriptor[] { return []; } +`, "services/feeds.ts": `export function parse(bytes: Uint8Array): Uint8Array { return bytes; }`, }, { contractEntry: "src/core.ts", diff --git a/packages/core/test/sqlite_codegen.test.ts b/packages/core/test/sqlite_codegen.test.ts index d71c8f81..50e21701 100644 --- a/packages/core/test/sqlite_codegen.test.ts +++ b/packages/core/test/sqlite_codegen.test.ts @@ -3,6 +3,8 @@ import fs from "node:fs"; import os from "node:os"; import path from "node:path"; import test from "node:test"; +import { spawnSync } from "node:child_process"; +import { pathToFileURL, fileURLToPath } from "node:url"; import { analyzeSqlite, checkMigrationState, generateCoreSurface, generateMigrationsZig } from "../src/sqlite_codegen.ts"; import { inspectRelationalSql } from "../src/sqlite_runtime_policy.ts"; @@ -22,6 +24,43 @@ UPDATE note SET folder_id = :to WHERE id = :id; return root; } +test("the SQLite CLI emits a complete loadable SDK module directory", async () => { + const src = fixture(); + const out = fs.mkdtempSync(path.join(os.tmpdir(), "native-sqlite-sdk-")); + const packageDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), ".."); + try { + const args = [ + path.join(packageDir, "src", "sqlite_cli.ts"), + "--src", src, + "--sdk-in", path.join(packageDir, "sdk", "core.ts"), + "--static-in", path.join(packageDir, "compile-surface", "core.ts"), + "--sdk-out", path.join(out, "core.ts"), + "--dts-out", path.join(out, "core.d.ts"), + "--static-out", path.join(out, "core_static.ts"), + "--sdk-events-out", path.join(out, "events.ts"), + "--sdk-text-out", path.join(out, "text.ts"), + "--sdk-bytes-text-methods-out", path.join(out, "bytes_text_methods.d.ts"), + "--sdk-events-dts-out", path.join(out, "events.d.ts"), + "--sdk-text-dts-out", path.join(out, "text.d.ts"), + "--zig-out", path.join(out, "migrations.zig"), + "--metadata-out", path.join(out, "metadata.json"), + ]; + const run = spawnSync(process.execPath, args, { encoding: "utf8" }); + assert.equal(run.status, 0, `${run.stdout}${run.stderr}`); + for (const file of [ + "core.ts", "core.d.ts", "core_static.ts", "events.ts", "text.ts", + "bytes_text_methods.d.ts", "events.d.ts", "text.d.ts", "migrations.zig", "metadata.json", + ]) { + assert.equal(fs.existsSync(path.join(out, file)), true, `${file} was not generated`); + } + const generated = await import(`${pathToFileURL(path.join(out, "core.ts")).href}?test=${Date.now()}`); + assert.equal(typeof generated.windowDescriptor, "function"); + } finally { + fs.rmSync(src, { recursive: true, force: true }); + fs.rmSync(out, { recursive: true, force: true }); + } +}); + test("real SQLite validates migrations and emits typed query/live constructors", () => { const root = fixture(); try { diff --git a/src/tooling/ts_core.zig b/src/tooling/ts_core.zig index f0ff35c5..13366497 100644 --- a/src/tooling/ts_core.zig +++ b/src/tooling/ts_core.zig @@ -480,13 +480,17 @@ pub fn generateSqliteSurface( errdefer allocator.free(sdk_out); var child = std.process.spawn(io, .{ .argv = &.{ - "node", runner, sqlite_cli, - "--src", "src", "--sdk-in", - sdk_in, "--static-in", static_in, - "--sdk-out", sdk_out, "--dts-out", - ".native/cache/sqlite/core.d.ts", "--static-out", ".native/cache/sqlite/core_static.ts", - "--zig-out", ".native/cache/sqlite/migrations.zig", "--metadata-out", - ".native/cache/sqlite/metadata.json", "--state", "src/schema/migrations.lock.json", + "node", runner, sqlite_cli, + "--src", "src", "--sdk-in", + sdk_in, "--static-in", static_in, + "--sdk-out", sdk_out, "--dts-out", + ".native/cache/sqlite/core.d.ts", "--static-out", ".native/cache/sqlite/core_static.ts", + "--sdk-events-out", ".native/cache/sqlite/events.ts", "--sdk-text-out", + ".native/cache/sqlite/text.ts", "--sdk-bytes-text-methods-out", ".native/cache/sqlite/bytes_text_methods.d.ts", + "--sdk-events-dts-out", ".native/cache/sqlite/events.d.ts", "--sdk-text-dts-out", + ".native/cache/sqlite/text.d.ts", "--zig-out", ".native/cache/sqlite/migrations.zig", + "--metadata-out", ".native/cache/sqlite/metadata.json", "--state", + "src/schema/migrations.lock.json", }, .stdin = .ignore, .stdout = .inherit,