diff --git a/AGENTS.md b/AGENTS.md index a7894f2a2..23f670c1b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -80,3 +80,13 @@ Test fixture provides: ## Runtime The CLI entrypoint (`cli/entrypoint.js`) selects between Bun and tsx as the TypeScript runner, preferring Bun when available. This allows hot-reload during development while maintaining Node.js compatibility. +# bump 1778256007 +# bump 1778299207 +# bump 1778342407 +# bump 1778385607 +# bump 1778515208 +# bump 1778558407 +# bump 1778601608 +# bump 1778644807 +# bump 1778688008 +# bump 1778731207 diff --git a/bun.lock b/bun.lock index 24cbd21dd..308ac296a 100644 --- a/bun.lock +++ b/bun.lock @@ -9,13 +9,13 @@ "@biomejs/biome": "^1.9.4", "@tscircuit/circuit-json-placement-analysis": "^0.0.6", "@tscircuit/circuit-json-routing-analysis": "^0.0.1", - "@tscircuit/circuit-json-schematic-placement-analysis": "github:tscircuit/circuit-json-schematic-placement-analysis#d09c8d74f3085b29744bb0f1c9864c1154c69436", + "@tscircuit/circuit-json-schematic-placement-analysis": "github:tscircuit/circuit-json-schematic-placement-analysis#8e3b4dc434d342f6b9833777107fc66515d1480b", "@tscircuit/fake-snippets": "^0.0.182", "@tscircuit/file-server": "^0.0.32", "@tscircuit/image-utils": "^0.0.3", "@tscircuit/math-utils": "0.0.36", "@tscircuit/props": "^0.0.496", - "@tscircuit/runframe": "^0.0.1882", + "@tscircuit/runframe": "^0.0.1938", "@tscircuit/schematic-match-adapt": "^0.0.22", "@types/bun": "^1.2.2", "@types/configstore": "^6.0.2", @@ -29,8 +29,8 @@ "chokidar": "4.0.1", "circuit-json": "^0.0.403", "circuit-json-to-bom-csv": "^0.0.7", - "circuit-json-to-gerber": "^0.0.49", - "circuit-json-to-kicad": "^0.0.114", + "circuit-json-to-gerber": "^0.0.51", + "circuit-json-to-kicad": "^0.0.125", "circuit-json-to-pnp-csv": "^0.0.7", "circuit-json-to-readable-netlist": "^0.0.15", "circuit-json-to-spice": "^0.0.10", @@ -301,7 +301,7 @@ "@tscircuit/circuit-json-routing-analysis": ["@tscircuit/circuit-json-routing-analysis@0.0.1", "", { "dependencies": { "flatbush": "^4.5.1" }, "peerDependencies": { "typescript": "^5" } }, "sha512-vxXM5Vo92R4GjqYSuGrgRTU8jh3An8tUt4yvBvBALwkAswMWSXJIJFnA/n7wlV9S0uzv9uOvIwizKtbyUgNBpA=="], - "@tscircuit/circuit-json-schematic-placement-analysis": ["@tscircuit/circuit-json-schematic-placement-analysis@github:tscircuit/circuit-json-schematic-placement-analysis#d09c8d7", { "dependencies": { "@tscircuit/circuit-json-util": "^0.0.94" }, "peerDependencies": { "circuit-json": "*", "typescript": "^5" } }, "tscircuit-circuit-json-schematic-placement-analysis-d09c8d7", "sha512-eMmF0Qw8LDa+cgsneknNkPugRmsB6eRhOTL5C/NKE+dnMVsX7Lsw2J6bPVZAQBe3D3i+dt9fGSvAE+KXiRrogw=="], + "@tscircuit/circuit-json-schematic-placement-analysis": ["@tscircuit/circuit-json-schematic-placement-analysis@github:tscircuit/circuit-json-schematic-placement-analysis#8e3b4dc", { "dependencies": { "@tscircuit/circuit-json-util": "^0.0.94" }, "peerDependencies": { "circuit-json": "*", "typescript": "^5" } }, "tscircuit-circuit-json-schematic-placement-analysis-8e3b4dc", "sha512-dWY8v4Nlz7+DUa7CA21AMpXKzU50V6wUIW+mWaepAy64gZGRtCtxvVqNp2bpd7HDtVwerjh4AER6CngDvWsP1w=="], "@tscircuit/circuit-json-util": ["@tscircuit/circuit-json-util@0.0.94", "", { "dependencies": { "parsel-js": "^1.1.2" }, "peerDependencies": { "circuit-json": "*", "transformation-matrix": "*", "zod": "3" } }, "sha512-kEYV6LzcZbRuw43IxsZ1cZL2pUx4nF07MYAHHhY9s90UzKYaIYfZ1q11s+F2wNwKecCcSyTUoAwWeqazLQEyVQ=="], @@ -309,7 +309,7 @@ "@tscircuit/core": ["@tscircuit/core@0.0.1128", "", { "dependencies": { "@flatten-js/core": "^1.6.2", "@lume/kiwi": "^0.4.3", "calculate-packing": "0.0.68", "css-select": "5.1.0", "format-si-unit": "^0.0.3", "nanoid": "^5.0.7", "performance-now": "^2.1.0", "react-reconciler": "^0.32.0", "svg-path-commander": "^2.1.11", "transformation-matrix": "^2.16.1", "zod": "^3.25.67" }, "peerDependencies": { "@tscircuit/capacity-autorouter": "*", "@tscircuit/checks": "*", "@tscircuit/circuit-json-util": "*", "@tscircuit/footprinter": "*", "@tscircuit/infgrid-ijump-astar": "*", "@tscircuit/matchpack": "*", "@tscircuit/math-utils": "*", "@tscircuit/props": "*", "@tscircuit/schematic-match-adapt": "*", "bpc-graph": "*", "circuit-json": "*", "circuit-json-to-bpc": "*", "circuit-json-to-connectivity-map": "*", "schematic-symbols": "*", "typescript": "^5.0.0" } }, "sha512-nYngZ32siHzLzoxdE+q/MAMlXwqkNc11RlA1Yc7sw5y6dtUHzVkTFCSP2w7hNi/2KG4GXEG/HdCrO5jPIqcXOQ=="], - "@tscircuit/eval": ["@tscircuit/eval@0.0.792", "", { "peerDependencies": { "@tscircuit/core": "*", "circuit-json": "*", "typescript": "^5.0.0", "zod": "3" } }, "sha512-LF4s3lIisOXsWlNik8ivpFMDes6MS1yJA7PysBft+YdeIpDlJa/mqZnPrM4G9r59dXbea94UZukUvaOd6fdw0w=="], + "@tscircuit/eval": ["@tscircuit/eval@0.0.828", "", { "peerDependencies": { "@tscircuit/core": "*", "circuit-json": "*", "typescript": "^5.0.0", "zod": "3" } }, "sha512-WTzl7ia2mTZPG6fiCssmTtdLX3WtD7coTbgRqbMMWAzUUuI4PMbFaqSC7agZcXJ8QKPOPwHFkDmjYwWvgNdAew=="], "@tscircuit/fake-snippets": ["@tscircuit/fake-snippets@0.0.182", "", {}, "sha512-DHGb1aAUm9KUKhUEiULZbbsUi3xeFnH0w11srz0boV2+Ceu0h8yn2oGvnpsAjlMFq/pmPg3HJayldHHGnw/n4A=="], @@ -337,7 +337,7 @@ "@tscircuit/props": ["@tscircuit/props@0.0.496", "", { "peerDependencies": { "circuit-json": "*", "react": "*", "zod": "*" } }, "sha512-HV1kXzLEXO2/QPBdoXwjd5nYvADntQzsIjmt7YhSNt0TEu+LgQp6pQgontiQLv6A7SppQB69uUURMJm7ZTm+hw=="], - "@tscircuit/runframe": ["@tscircuit/runframe@0.0.1882", "", { "dependencies": { "@tscircuit/eval": "^0.0.792", "@tscircuit/solver-utils": "^0.0.7" } }, "sha512-rirTC2KYUM0l2q7PvxvuDP/iRWcIw+I2+o2UtBzg5bM2vfXdLbO/kmGBWm81fxlpJOUogaEpfwNro2c4iQr1yw=="], + "@tscircuit/runframe": ["@tscircuit/runframe@0.0.1938", "", { "dependencies": { "@tscircuit/eval": "^0.0.828", "@tscircuit/solver-utils": "^0.0.7" } }, "sha512-Xm0Fsoe/IXG10pf08Y4pc3AQUacAeodd7nuD1SRWz1ONDy/yNwR4pMfANEAHZsCp1Jg76RAhj65lF2I3F8mlZQ=="], "@tscircuit/schematic-corpus": ["@tscircuit/schematic-corpus@0.0.114", "", { "peerDependencies": { "typescript": "^5" } }, "sha512-jDQX+XDXP6PklB39X8AwUSuiqGRdn78esy1wD/qG8U3cCXkT5rtE3ousDVaKRxclCeED8FxJlD+ZvRtAe8mw8w=="], @@ -469,11 +469,11 @@ "circuit-json-to-connectivity-map": ["circuit-json-to-connectivity-map@0.0.23", "", { "dependencies": { "@tscircuit/math-utils": "^0.0.9" }, "peerDependencies": { "typescript": "^5.9.3" } }, "sha512-DSOiXaXOTvjU+7et8ITXb2LjgKto6cQzLv3hReYdXuUNtLw2GVnpOly1G83VcIBcSQ4hRVHI4VMKRyZB3XVzdg=="], - "circuit-json-to-gerber": ["circuit-json-to-gerber@0.0.49", "", { "dependencies": { "@tscircuit/alphabet": "^0.0.25", "fast-json-stable-stringify": "^2.1.0", "transformation-matrix": "^3.0.0" }, "peerDependencies": { "circuit-json": "*", "tscircuit": "*", "typescript": "^5.0.0" }, "bin": { "circuit-to-gerber": "dist/cli.js" } }, "sha512-+IMXSj5YdwsFx8Xk8JYuDl+Zf3y/Ig8O7uBkw2/bUMGO6rMpJseSObs7YUEwArF+JG0e+Viroa1a8EyIlzVExQ=="], + "circuit-json-to-gerber": ["circuit-json-to-gerber@0.0.51", "", { "dependencies": { "@tscircuit/alphabet": "^0.0.25", "fast-json-stable-stringify": "^2.1.0", "transformation-matrix": "^3.0.0" }, "peerDependencies": { "circuit-json": "*", "tscircuit": "*", "typescript": "^5.0.0" }, "bin": { "circuit-to-gerber": "dist/cli.js" } }, "sha512-wcVsSJ5coWbbOb+fdkYPX8x4urtOJi4tbuDcUvCDUxY6DM7nqM3rvi7p1XjGVlhJIrDRcL7rdepbVeT5fIuOwA=="], "circuit-json-to-gltf": ["circuit-json-to-gltf@0.0.91", "", { "dependencies": { "@jscad/modeling": "^2.12.6", "earcut": "^3.0.2", "jscad-electronics": "^0.0.120", "jscad-to-gltf": "^0.0.5", "occt-import-js": "^0.0.23" }, "peerDependencies": { "@resvg/resvg-js": "2", "@resvg/resvg-wasm": "2", "@tscircuit/circuit-json-util": "*", "circuit-json": "*", "circuit-to-svg": "*", "typescript": "^5" }, "optionalPeers": ["@resvg/resvg-js", "@resvg/resvg-wasm"] }, "sha512-7QzJ0WF88WmVMgWtt+2ogfvFCDEr4EKWRMy/oMgCVnsr3vI6wkfQjqE8RwgFRtitZzMh9msfM8Vvcu2lZ2I/rA=="], - "circuit-json-to-kicad": ["circuit-json-to-kicad@0.0.114", "", { "peerDependencies": { "typescript": "^5" } }, "sha512-3VhF6ekiiDzmid0fUfF7NWKvl5UDfTRBkPHhRUaIcTgcZZKDNoyhdYAJYTuHwHXQbj9jmC8iNnwjoX5BZY6KaA=="], + "circuit-json-to-kicad": ["circuit-json-to-kicad@0.0.125", "", { "peerDependencies": { "typescript": "^5" } }, "sha512-WN/DcclxV1/of0HrqS8Xf2prtzUPNSP3U4w69waD5THMqDXzNBtMd0RWwbBdX1nrAuTqN+4cQfA1d9KUbohJMw=="], "circuit-json-to-pnp-csv": ["circuit-json-to-pnp-csv@0.0.7", "", { "dependencies": { "papaparse": "^5.4.1" }, "peerDependencies": { "@tscircuit/soup-util": "*", "typescript": "^5.0.0" } }, "sha512-WAdNRHtaPhQM8X5NN/43WMBKDCEKQSLShg/mHIZxMUzJviymnfbq6rJj/2WvDqm/bogey34PyTEHwF3mC7zxlQ=="], diff --git a/cli/build/register.ts b/cli/build/register.ts index ffc7b8397..436abbf44 100644 --- a/cli/build/register.ts +++ b/cli/build/register.ts @@ -732,7 +732,16 @@ export const registerBuild = (program: Command) => { const entryFile = fileArgIsDirectFile ? resolvedFileArgPath : transpileEntrypoint - if (!entryFile) { + const isRealTsEntrypoint = Boolean( + entryFile && + (entryFile.endsWith(".ts") || entryFile.endsWith(".tsx")), + ) + if ( + !entryFile || + (hasConfiguredIncludeBoardFiles && + !transpileExplicitlyRequested && + !isRealTsEntrypoint) + ) { if ( hasConfiguredIncludeBoardFiles && !transpileExplicitlyRequested diff --git a/cli/check/routing/register.ts b/cli/check/routing/register.ts deleted file mode 100644 index e0517ea9e..000000000 --- a/cli/check/routing/register.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { Command } from "commander" - -export const registerCheckRouting = (program: Command) => { - program.commands - .find((c) => c.name() === "check")! - .command("routing") - .description("Partially build and validate the routing") - .action(() => { - throw new Error("Not implemented") - }) -} diff --git a/cli/main.ts b/cli/main.ts index 9cb0a7d0b..a03780bdd 100644 --- a/cli/main.ts +++ b/cli/main.ts @@ -17,7 +17,6 @@ import { registerCheckPinSpecification } from "./check/pin-specification/registe import { registerCheckPlacement } from "./check/placement/register" import { registerCheck } from "./check/register" import { registerCheckRoutingDifficulty } from "./check/routing-difficulty/register" -import { registerCheckRouting } from "./check/routing/register" import { registerCheckSchematicPlacement } from "./check/schematic-placement/register" import { registerCheckTraceLength } from "./check/trace-length/register" import { registerClone } from "./clone/register" @@ -85,7 +84,6 @@ registerCheckNetlist(program) registerCheckPinSpecification(program) registerCheckPlacement(program) registerCheckRoutingDifficulty(program) -registerCheckRouting(program) registerCheckSchematicPlacement(program) registerCheckTraceLength(program) diff --git a/lib/shared/get-entrypoint.ts b/lib/shared/get-entrypoint.ts index c2858b38d..770cce979 100644 --- a/lib/shared/get-entrypoint.ts +++ b/lib/shared/get-entrypoint.ts @@ -1,5 +1,6 @@ import * as fs from "node:fs" import * as path from "node:path" +import { globbySync } from "globby" import { loadProjectConfig } from "lib/project-config" import kleur from "kleur" @@ -202,6 +203,27 @@ export const getEntrypoint = async ({ } } + // No entrypoint found - check for circuit.json files as implicit entrypoints + // This allows `tsci push` to work the same as `tsci dev` which supports circuit.json files + const circuitJsonFiles = globbySync( + ["**/*.circuit.json", "**/circuit.json"], + { + cwd: validatedProjectDir, + ignore: ["**/node_modules/**", "**/dist/**"], + }, + ) + .map((f) => path.resolve(validatedProjectDir, f)) + .filter( + (f) => fs.existsSync(f) && isValidDirectory(f, validatedProjectDir), + ) + .sort() + + if (circuitJsonFiles.length > 0) { + const chosenFile = path.relative(validatedProjectDir, circuitJsonFiles[0]) + onSuccess(`Using circuit.json as implicit entrypoint: '${chosenFile}'`) + return circuitJsonFiles[0] + } + onError( kleur.red( "No entrypoint found. Run 'tsci init' to bootstrap a basic project or specify a file with 'tsci push '", diff --git a/lib/shared/push-snippet.ts b/lib/shared/push-snippet.ts index 75bc61dea..158f0abbd 100644 --- a/lib/shared/push-snippet.ts +++ b/lib/shared/push-snippet.ts @@ -30,6 +30,55 @@ type PushOptions = { const debug = Debug("tsci:push-snippet") +const findPushProject = async ({ + filePath, + onError, +}: { + filePath?: string + onError: (message: string) => void +}): Promise<{ + snippetFilePath?: string + packageJsonPath?: string + projectDir: string +} | null> => { + if (filePath) { + const snippetFilePath = await getEntrypoint({ + filePath, + onSuccess: () => {}, + onError, + }) + + if (!snippetFilePath) { + return null + } + + const packageJsonPath = [ + path.resolve(path.join(path.dirname(snippetFilePath), "package.json")), + path.resolve(path.join(process.cwd(), "package.json")), + ].find((candidatePath) => fs.existsSync(candidatePath)) + const projectDir = packageJsonPath + ? path.dirname(packageJsonPath) + : path.dirname(snippetFilePath) + + return { snippetFilePath, packageJsonPath, projectDir } + } + + const projectDir = process.cwd() + const packageJsonPath = path.resolve(path.join(projectDir, "package.json")) + if (!fs.existsSync(packageJsonPath)) { + return { projectDir } + } + + const snippetFilePath = + (await getEntrypoint({ + projectDir, + onSuccess: () => {}, + onError: () => {}, + })) ?? undefined + + return { snippetFilePath, packageJsonPath, projectDir } +} + const getArchivePayload = async ( filePaths: string[], projectDir: string, @@ -74,24 +123,16 @@ export const pushSnippet = async ({ return onExit(1) } - // Detect the entrypoint file - const snippetFilePath = await getEntrypoint({ + const pushProject = await findPushProject({ filePath, - onSuccess: () => {}, onError, }) - if (!snippetFilePath) { + if (!pushProject) { return onExit(1) } - const packageJsonPath = [ - path.resolve(path.join(path.dirname(snippetFilePath), "package.json")), - path.resolve(path.join(process.cwd(), "package.json")), - ].find((path) => fs.existsSync(path)) - const projectDir = packageJsonPath - ? path.dirname(packageJsonPath) - : path.dirname(snippetFilePath) + const { snippetFilePath, packageJsonPath, projectDir } = pushProject if (!packageJsonPath) { onError( @@ -110,7 +151,7 @@ export const pushSnippet = async ({ } } - if (!fs.existsSync(snippetFilePath)) { + if (snippetFilePath && !fs.existsSync(snippetFilePath)) { onError(`File not found: ${snippetFilePath}`) return onExit(1) } diff --git a/package.json b/package.json index d46a4f183..9f3f7a08a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@tscircuit/cli", - "version": "0.1.1296", + "version": "0.1.1357", "main": "dist/cli/main.js", "exports": { ".": "./dist/cli/main.js", @@ -11,13 +11,13 @@ "@biomejs/biome": "^1.9.4", "@tscircuit/circuit-json-placement-analysis": "^0.0.6", "@tscircuit/circuit-json-routing-analysis": "^0.0.1", - "@tscircuit/circuit-json-schematic-placement-analysis": "github:tscircuit/circuit-json-schematic-placement-analysis#d09c8d74f3085b29744bb0f1c9864c1154c69436", + "@tscircuit/circuit-json-schematic-placement-analysis": "github:tscircuit/circuit-json-schematic-placement-analysis#8e3b4dc434d342f6b9833777107fc66515d1480b", "@tscircuit/fake-snippets": "^0.0.182", "@tscircuit/file-server": "^0.0.32", "@tscircuit/image-utils": "^0.0.3", "@tscircuit/math-utils": "0.0.36", "@tscircuit/props": "^0.0.496", - "@tscircuit/runframe": "^0.0.1882", + "@tscircuit/runframe": "^0.0.1938", "@tscircuit/schematic-match-adapt": "^0.0.22", "@types/bun": "^1.2.2", "@types/configstore": "^6.0.2", @@ -31,8 +31,8 @@ "chokidar": "4.0.1", "circuit-json": "^0.0.403", "circuit-json-to-bom-csv": "^0.0.7", - "circuit-json-to-gerber": "^0.0.49", - "circuit-json-to-kicad": "^0.0.114", + "circuit-json-to-gerber": "^0.0.51", + "circuit-json-to-kicad": "^0.0.125", "circuit-json-to-pnp-csv": "^0.0.7", "circuit-json-to-readable-netlist": "^0.0.15", "circuit-json-to-spice": "^0.0.10", diff --git a/tests/cli/push/push1-no-entrypoint.test.ts b/tests/cli/push/push1-no-entrypoint.test.ts index 9df0ecb31..1bbd13295 100644 --- a/tests/cli/push/push1-no-entrypoint.test.ts +++ b/tests/cli/push/push1-no-entrypoint.test.ts @@ -1,17 +1,42 @@ import { test, expect } from "bun:test" import { getCliTestFixture } from "../../fixtures/get-cli-test-fixture" +import * as fs from "node:fs" +import * as path from "node:path" -test("should fail if no entrypoint file is found", async () => { - const { runCommand } = await getCliTestFixture() - try { - await runCommand("tsci push") - } catch (e) { - if (e instanceof Error) { - expect(e.message).toContain( - "No entrypoint found. Run 'tsci init' to bootstrap a basic project.", - ) - } else { - throw e - } - } +test("should fail if no package.json is found", async () => { + const { runCommand } = await getCliTestFixture({ loggedIn: true }) + const { stderr, exitCode } = await runCommand("tsci push") + + expect(exitCode).toBe(1) + expect(stderr).toBe( + "No package.json found, try running 'tsci init' to bootstrap the project\n", + ) }) + +test("should push a package without an entrypoint", async () => { + const { tmpDir, runCommand } = await getCliTestFixture({ + loggedIn: true, + }) + + fs.writeFileSync( + path.resolve(tmpDir, "package.json"), + JSON.stringify({ name: "@tsci/test-user.test-package", version: "1.0.0" }), + ) + fs.writeFileSync( + path.resolve(tmpDir, "tscircuit.config.json"), + JSON.stringify({ includeBoardFiles: ["**/*.circuit.json"] }), + ) + fs.writeFileSync( + path.resolve(tmpDir, "prebuilt.circuit.json"), + JSON.stringify([{ type: "source_component", name: "U1" }]), + ) + + const { stdout, stderr, exitCode } = await runCommand("tsci push") + + expect(exitCode).toBe(0) + expect(stderr).toBe("") + expect(stdout).toContain("⬆︎ package.json") + expect(stdout).toContain("⬆︎ prebuilt.circuit.json") + expect(stdout).toContain("⬆︎ tscircuit.config.json") + expect(stdout).toContain('"@tsci/test-user.test-package@1.0.0" published!') +}, 30_000) diff --git a/tests/get-entrypoint.test.ts b/tests/get-entrypoint.test.ts index 28ee40c54..ff30ef7de 100644 --- a/tests/get-entrypoint.test.ts +++ b/tests/get-entrypoint.test.ts @@ -519,3 +519,49 @@ test("getEntrypoint warns when multiple common locations exist", async () => { expect(warnings[0]).toContain("Choosing 'index.tsx'") expect(warnings[0]).toContain("'src/index.tsx'") }) + +test("getEntrypoint returns circuit.json as implicit entrypoint when no tsx/ts files exist", async () => { + const { tmpDir } = await getCliTestFixture() + + // Create only a circuit.json file, no tsx/ts entrypoints + await fs.writeFile( + path.join(tmpDir, "prebuilt.circuit.json"), + JSON.stringify([{ type: "source_component", name: "U1" }]), + ) + + let onSuccessMessage = "" + const entrypoint = await getEntrypoint({ + projectDir: tmpDir, + onSuccess: (msg) => { + onSuccessMessage = msg + }, + }) + + expect(entrypoint).not.toBeNull() + expect(entrypoint).toBe(path.join(tmpDir, "prebuilt.circuit.json")) + expect(onSuccessMessage).toContain( + "Using circuit.json as implicit entrypoint", + ) +}) + +test("getEntrypoint prefers tsx entrypoint over circuit.json", async () => { + const { tmpDir } = await getCliTestFixture() + + // Create both a circuit.json and an index.tsx + await fs.writeFile( + path.join(tmpDir, "prebuilt.circuit.json"), + JSON.stringify([{ type: "source_component", name: "U1" }]), + ) + await fs.writeFile( + path.join(tmpDir, "index.tsx"), + 'export default () => ', + ) + + const entrypoint = await getEntrypoint({ + projectDir: tmpDir, + }) + + // Should prefer the tsx file since it comes first in ALLOWED_ENTRYPOINT_NAMES + expect(entrypoint).not.toBeNull() + expect(entrypoint).toBe(path.join(tmpDir, "index.tsx")) +})