Skip to content

Commit

Permalink
Merge branch 'tscircuit:main' into patch-79
Browse files Browse the repository at this point in the history
  • Loading branch information
ArnavK-09 authored Jan 26, 2025
2 parents 29a21d5 + 0ff1ae1 commit 7b78ddf
Show file tree
Hide file tree
Showing 10 changed files with 335 additions and 1 deletion.
14 changes: 14 additions & 0 deletions cli/auth/print-token/register.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import type { Command } from "commander"
import { cliConfig } from "lib/cli-config"

export const registerAuthPrintToken = (program: Command) => {
program.commands
.find((c) => c.name() === "auth")!
.command("print-token")
.description("Prints your auth token")
.action(() => {
const token = cliConfig.get("sessionToken")
if (!token) return console.log("You need to log in to access this.")
console.log("Your Token:\n", token)
})
}
25 changes: 25 additions & 0 deletions cli/auth/set-token/register.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import type { Command } from "commander"
import { cliConfig } from "lib/cli-config"

function validateJWTLength(token: string) {
const parts = token.split(".")

if (parts.length === 3 && parts.every((part) => part.length > 0)) {
return true
} else {
return false
}
}
export const registerAuthSetToken = (program: Command) => {
program.commands
.find((c) => c.name() === "auth")!
.command("set-token")
.description("Explicitly set your auth token")
.argument("<token>", "New token to manually configure")
.action((token) => {
if (!validateJWTLength(token))
return console.log("Invalid token provided")
cliConfig.set("sessionToken", token)
console.log("Token manually updated.")
})
}
3 changes: 3 additions & 0 deletions cli/clone/register.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ export const registerClone = (program: Command) => {
fs.writeFileSync(fullPath, fileContent.package_file.content_text)
}

const npmrcPath = path.join(dirPath, ".npmrc")
fs.writeFileSync(npmrcPath, "@tsci:registry=https://npm.tscircuit.com")

console.log(`Successfully cloned to ./${author}.${snippetName}/`)
} catch (error) {
if (error instanceof Error) {
Expand Down
4 changes: 4 additions & 0 deletions cli/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import { perfectCli } from "perfect-cli"
import pkg from "../package.json"
import semver from "semver"
import { registerExport } from "./export/register"
import { registerAuthPrintToken } from "./auth/print-token/register"
import { registerAuthSetToken } from "./auth/set-token/register"

const program = new Command()

Expand All @@ -30,6 +32,8 @@ registerClone(program)
registerAuth(program)
registerAuthLogin(program)
registerAuthLogout(program)
registerAuthPrintToken(program)
registerAuthSetToken(program)

registerConfig(program)
registerConfigPrint(program)
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "@tscircuit/cli",
"main": "dist/main.js",
"type": "module",
"version": "0.1.13",
"version": "0.1.16",
"bin": {
"tsci": "./dist/main.js"
},
Expand Down
30 changes: 30 additions & 0 deletions tests/cli/add/add.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { getCliTestFixture } from "../../fixtures/get-cli-test-fixture"
import { test, expect } from "bun:test"
import { join } from "node:path"

test.skip("add command installs package and updates .npmrc", async () => {
const { tmpDir, runCommand } = await getCliTestFixture()

// Create initial package.json using Bun
await Bun.write(
join(tmpDir, "package.json"),
JSON.stringify({
name: "test-project",
dependencies: {},
}),
)

// Run add command
const { stdout } = await runCommand("tsci add @tsci/example-package")
expect(stdout).toContain("Added @tsci/example-package")

// Verify package.json was updated
const pkgJson = JSON.parse(
await Bun.file(join(tmpDir, "package.json")).text(),
)
expect(pkgJson.dependencies["@tsci/example-package"]).toBeDefined()

// Verify .npmrc was created/updated
const npmrc = await Bun.file(join(tmpDir, ".npmrc")).text()
expect(npmrc).toContain("@tsci:registry=https://npm.tscircuit.com")
})
130 changes: 130 additions & 0 deletions tests/cli/push/push.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import { getCliTestFixture } from "../../fixtures/get-cli-test-fixture"
import { test, expect } from "bun:test"
import { join } from "node:path"

test.skip("push command bundles and uploads to registry", async () => {
const { tmpDir, runCommand } = await getCliTestFixture()

// Create package files
await Bun.write(
join(tmpDir, "package.json"),
JSON.stringify({
name: "@tsci/test-component",
version: "0.1.0",
main: "dist/index.js",
module: "dist/index.mjs",
types: "dist/index.d.ts",
}),
)

await Bun.write(
join(tmpDir, "circuit.tsx"),
`
export const Circuit = () => (
<board width="10mm" height="10mm">
<resistor name="R1" resistance="10k" footprint="0402" />
</board>
)
`,
)

// Run push command
const { stdout } = await runCommand("tsci push")

// Verify bundle files were generated
const distFiles = {
esm: await Bun.file(join(tmpDir, "dist/index.mjs")).exists(),
cjs: await Bun.file(join(tmpDir, "dist/index.js")).exists(),
dts: await Bun.file(join(tmpDir, "dist/index.d.ts")).exists(),
circuitJson: await Bun.file(join(tmpDir, "dist/circuit.json")).exists(),
}

expect(distFiles.esm).toBe(true)
expect(distFiles.cjs).toBe(true)
expect(distFiles.dts).toBe(true)
expect(distFiles.circuitJson).toBe(true)

// Verify bundle contents
const esmContent = await Bun.file(join(tmpDir, "dist/index.mjs")).text()
expect(esmContent).toContain("export const Circuit")

const cjsContent = await Bun.file(join(tmpDir, "dist/index.js")).text()
expect(cjsContent).toContain("exports.Circuit")

const dtsContent = await Bun.file(join(tmpDir, "dist/index.d.ts")).text()
expect(dtsContent).toContain("export declare const Circuit")

// Verify circuit JSON was generated correctly
const circuitJson = JSON.parse(
await Bun.file(join(tmpDir, "dist/circuit.json")).text(),
)
expect(circuitJson).toMatchObject({
components: expect.arrayContaining([
expect.objectContaining({
type: "source_component",
name: "R1",
resistance: 10000,
}),
]),
})

// Verify command output
expect(stdout).toContain("Successfully pushed to registry")
expect(stdout).toContain("Generated Circuit JSON")
expect(stdout).toContain("ESM bundle size:")
expect(stdout).toContain("CJS bundle size:")
})

test.skip("push command with force flag bypasses bundle validation", async () => {
const { tmpDir, runCommand } = await getCliTestFixture()

// Create invalid package
await Bun.write(
join(tmpDir, "package.json"),
JSON.stringify({
name: "@tsci/test-component",
version: "0.1.0",
}),
)

await Bun.write(
join(tmpDir, "circuit.tsx"),
`
export const Circuit = () => (
// Invalid JSX
<board>
<broken-component />
)
`,
)

// Push should succeed with -f flag despite invalid code
const { stdout } = await runCommand("tsci push -f")
expect(stdout).toContain("Forced push successful")
expect(stdout).toContain("Warning: Bundle validation skipped")
})

test.skip("push command fails on invalid typescript", async () => {
const { tmpDir, runCommand } = await getCliTestFixture()

await Bun.write(
join(tmpDir, "package.json"),
JSON.stringify({
name: "@tsci/test-component",
version: "0.1.0",
}),
)

await Bun.write(
join(tmpDir, "circuit.tsx"),
`
export const Circuit = () => {
const x: number = "string" // Type error
return <board />
}
`,
)

// Push should fail due to TypeScript error
await expect(runCommand("tsci push")).rejects.toThrow()
})
37 changes: 37 additions & 0 deletions tests/cli/release/release.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { getCliTestFixture } from "../../fixtures/get-cli-test-fixture"
import { test, expect } from "bun:test"
import { join } from "node:path"

test.skip("release command increments version and pushes to registry", async () => {
const { tmpDir, runCommand } = await getCliTestFixture()

// Create test files using Bun
await Bun.write(
join(tmpDir, "package.json"),
JSON.stringify({
name: "@tsci/test-package",
version: "0.1.0",
}),
)

await Bun.write(
join(tmpDir, "circuit.tsx"),
`
export const Circuit = () => (
<board width="10mm" height="10mm">
<chip name="U1" footprint="soic8" />
</board>
)
`,
)

// Run release command
const { stdout } = await runCommand("tsci release --patch")
expect(stdout).toContain("Released version 0.1.1")

// Verify package.json was updated
const pkgJson = JSON.parse(
await Bun.file(join(tmpDir, "package.json")).text(),
)
expect(pkgJson.version).toBe("0.1.1")
})
50 changes: 50 additions & 0 deletions tests/cli/snapshot/snapshot.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { getCliTestFixture } from "../../fixtures/get-cli-test-fixture"
import { test, expect } from "bun:test"
import { join } from "node:path"

test.skip("snapshot command creates SVG snapshots", async () => {
const { tmpDir, runCommand } = await getCliTestFixture()

// Create test files using Bun
await Bun.write(
join(tmpDir, "circuit.example.tsx"),
`
export const SimpleCircuit = () => (
<board width="10mm" height="10mm">
<chip name="U1" footprint="soic8" />
</board>
)
`,
)

await Bun.write(
join(tmpDir, "main.tsx"),
`
export const MainCircuit = () => (
<board width="20mm" height="20mm">
<resistor value="10k" />
</board>
)
`,
)

// Run snapshot update command
const { stdout: updateStdout } = await runCommand("tsci snapshot --update")
expect(updateStdout).toContain("Created snapshots")

// Verify snapshots were created
const snapshotDir = join(tmpDir, "__snapshots__")
const circuitSnapshot = await Bun.file(
join(snapshotDir, "circuit.example.snap.svg"),
).exists()
const mainSnapshot = await Bun.file(
join(snapshotDir, "main.snap.svg"),
).exists()

expect(circuitSnapshot).toBe(true)
expect(mainSnapshot).toBe(true)

// Run snapshot test command
const { stdout: testStdout } = await runCommand("tsci snapshot")
expect(testStdout).toContain("All snapshots match")
})
41 changes: 41 additions & 0 deletions tests/cli/token/token.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { getCliTestFixture } from "../../fixtures/get-cli-test-fixture"
import { test, expect } from "bun:test"

const demoJwtToken =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"

test("print and set token explicitly", async () => {
const { runCommand } = await getCliTestFixture()

// Test printing token without authentication
const { stdout: invalidTokenPrintStdout, stderr: invalidTokenPrintStderr } =
await runCommand("tsci auth print-token")
expect(invalidTokenPrintStdout).toContain(
"You need to log in to access this.",
)
expect(invalidTokenPrintStderr).toBeFalsy()

// Test setting an invalid token
const { stdout: invalidTokenSetStdout, stderr: invalidTokenSetStderr } =
await runCommand("tsci auth set-token invalid-token-example")
expect(invalidTokenSetStdout).toContain("Invalid token provided")
expect(invalidTokenSetStderr).toBeFalsy()

// Test setting a valid token
const { stdout: validTokenSetStdout, stderr: validTokenSetStderr } =
await runCommand(`tsci auth set-token ${demoJwtToken}`)
expect(validTokenSetStdout).toContain("Token manually updated.")
expect(validTokenSetStderr).toBeFalsy()

// Test printing the valid token
const { stdout: validTokenPrintStdout, stderr: validTokenPrintStderr } =
await runCommand("tsci auth print-token")
expect(validTokenPrintStdout).toContain(demoJwtToken)
expect(validTokenPrintStderr).toBeFalsy()

// Verify token is correctly stored and can be reused
const { stdout: reprintTokenStdout } = await runCommand(
"tsci auth print-token",
)
expect(reprintTokenStdout).toContain(demoJwtToken)
})

0 comments on commit 7b78ddf

Please sign in to comment.