diff --git a/package.json b/package.json index 8c12f1a8483..f872fa271bd 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "build-storybook": "pnpm --filter @paperclipai/ui build-storybook", "build": "pnpm run preflight:workspace-links && pnpm -r build", "typecheck": "pnpm run preflight:workspace-links && pnpm -r typecheck", - "typecheck:build-gaps": "pnpm run preflight:workspace-links && pnpm --filter @paperclipai/plugin-sdk build && pnpm --filter paperclipai typecheck && pnpm --filter @paperclipai/plugin-authoring-smoke-example typecheck", + "typecheck:build-gaps": "pnpm run preflight:workspace-links && node scripts/run-typecheck-build-gaps.mjs", "test": "pnpm run test:run", "test:watch": "pnpm run preflight:workspace-links && vitest", "test:run": "pnpm run preflight:workspace-links && node scripts/run-vitest-stable.mjs", diff --git a/scripts/run-typecheck-build-gaps.mjs b/scripts/run-typecheck-build-gaps.mjs new file mode 100644 index 00000000000..8ab72ea0284 --- /dev/null +++ b/scripts/run-typecheck-build-gaps.mjs @@ -0,0 +1,73 @@ +#!/usr/bin/env node +import { readFileSync } from "node:fs"; +import path from "node:path"; +import { spawnSync } from "node:child_process"; + +const repoRoot = process.cwd(); + +function fail(message) { + console.error(`[typecheck:build-gaps] ${message}`); + process.exit(1); +} + +function run(command, args) { + const result = spawnSync(command, args, { + cwd: repoRoot, + stdio: "inherit", + }); + + if (result.status !== 0) { + process.exit(result.status ?? 1); + } +} + +function readJson(filePath) { + return JSON.parse(readFileSync(filePath, "utf8")); +} + +function listWorkspacePackages() { + const result = spawnSync("pnpm", ["ls", "-r", "--depth", "-1", "--json"], { + cwd: repoRoot, + encoding: "utf8", + }); + + if (result.status !== 0) { + fail("Unable to list pnpm workspace packages."); + } + + return JSON.parse(result.stdout); +} + +function buildSkipsTypeScript(pkg) { + const buildScript = pkg.scripts?.build; + const typecheckScript = pkg.scripts?.typecheck; + if (typeof buildScript !== "string" || typeof typecheckScript !== "string") { + return false; + } + + return !/\btsc\b/.test(buildScript); +} + +const workspacePackages = listWorkspacePackages(); +const buildGapPackages = workspacePackages + .filter((workspacePkg) => workspacePkg.path !== repoRoot) + .map((workspacePkg) => ({ + name: workspacePkg.name, + path: workspacePkg.path, + pkg: readJson(path.join(workspacePkg.path, "package.json")), + })) + .filter(({ pkg }) => buildSkipsTypeScript(pkg)); + +console.log( + `[typecheck:build-gaps] typechecking ${buildGapPackages.length} workspace(s): ${buildGapPackages.map(({ name }) => name).join(", ") || "(none)"}`, +); + +if (buildGapPackages.length === 0) { + process.exit(0); +} + +run("pnpm", ["--filter", "@paperclipai/plugin-sdk", "build"]); + +for (const workspacePkg of buildGapPackages) { + run("pnpm", ["--filter", workspacePkg.name, "typecheck"]); +} diff --git a/scripts/run-vitest-stable.mjs b/scripts/run-vitest-stable.mjs index 49fb61caea7..398e7e9858c 100644 --- a/scripts/run-vitest-stable.mjs +++ b/scripts/run-vitest-stable.mjs @@ -87,7 +87,7 @@ function fail(message) { function readOptionValue(argv, index, argName) { const value = argv[index + 1]; - if (!value) { + if (value === undefined) { fail(`Missing value for ${argName}`); }