@tscircuit/cli 0.1.21 → 0.1.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bun.lock +2260 -0
- package/cli/init/register.ts +80 -3
- package/cli/main.ts +2 -0
- package/cli/push/register.ts +199 -0
- package/dist/main.js +214 -13
- package/example-dir/snippet2-large-led-matrix.tsx +1 -1
- package/example-dir/tsconfig.json +17 -0
- package/example-dir/types.d.ts +20 -0
- package/lib/registry-api/get-ky.ts +1 -1
- package/package.json +5 -3
- package/tests/cli/init/init.test.ts +34 -0
- package/tests/fake-snippets-api.d.ts +3 -0
- package/tests/fixtures/get-test-server.ts +54 -0
- package/tests/test4-push-api.test.ts +85 -0
- package/bun.lockb +0 -0
|
@@ -104,7 +104,7 @@ export default () => {
|
|
|
104
104
|
ySpacing: 5,
|
|
105
105
|
offsetX: 3 - 122,
|
|
106
106
|
offsetY: -32 / 2 - 7.5,
|
|
107
|
-
}).map(({ center, index
|
|
107
|
+
}).map(({ center, index }) => {
|
|
108
108
|
const ledName = `LED${index + 1}`
|
|
109
109
|
const prevLedName = index > 0 ? `LED${index}` : null
|
|
110
110
|
const capName = `C_${ledName}`
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES6",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"jsx": "react-jsx",
|
|
6
|
+
"outDir": "dist",
|
|
7
|
+
"strict": true,
|
|
8
|
+
"esModuleInterop": true,
|
|
9
|
+
"moduleResolution": "node",
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"forceConsistentCasingInFileNames": true,
|
|
12
|
+
"resolveJsonModule": true,
|
|
13
|
+
"sourceMap": true,
|
|
14
|
+
"allowSyntheticDefaultImports": true,
|
|
15
|
+
"experimentalDecorators": true
|
|
16
|
+
}
|
|
17
|
+
}
|
package/example-dir/types.d.ts
CHANGED
|
@@ -9,3 +9,23 @@ declare module "@tsci/seveibar.push-button" {
|
|
|
9
9
|
declare module "@tsci/seveibar.smd-usb-c" {
|
|
10
10
|
export function useUsbC(name: string): any
|
|
11
11
|
}
|
|
12
|
+
|
|
13
|
+
declare module "@tsci/seveibar.PICO_W" {
|
|
14
|
+
export function usePICO_W(name: string): any
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
declare module "@tsci/seveibar.HS91L02W2C01" {
|
|
18
|
+
export function useHS91L02W2C01(name: string): any
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
declare module "@tsci/seveibar.WS2812B_2020" {
|
|
22
|
+
interface WS2812B_2020Props {
|
|
23
|
+
schX: number
|
|
24
|
+
schY: number
|
|
25
|
+
name: string
|
|
26
|
+
pcbX: number
|
|
27
|
+
pcbY: number
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export const WS2812B_2020: React.FC<WS2812B_2020Props>
|
|
31
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { getRegistryApiUrl } from "lib/cli-config"
|
|
2
2
|
import ky, { type AfterResponseHook } from "ky"
|
|
3
3
|
|
|
4
|
-
const prettyResponseErrorHook: AfterResponseHook = async (
|
|
4
|
+
export const prettyResponseErrorHook: AfterResponseHook = async (
|
|
5
5
|
_request,
|
|
6
6
|
_options,
|
|
7
7
|
response,
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@tscircuit/cli",
|
|
3
3
|
"main": "dist/main.js",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"version": "0.1.
|
|
5
|
+
"version": "0.1.23",
|
|
6
6
|
"bin": {
|
|
7
7
|
"tsci": "./dist/main.js"
|
|
8
8
|
},
|
|
@@ -17,9 +17,10 @@
|
|
|
17
17
|
"devDependencies": {
|
|
18
18
|
"@biomejs/biome": "^1.9.4",
|
|
19
19
|
"@tscircuit/core": "^0.0.249",
|
|
20
|
+
"@tscircuit/fake-snippets": "^0.0.5",
|
|
20
21
|
"@types/bun": "^1.1.15",
|
|
21
22
|
"@types/configstore": "^6.0.2",
|
|
22
|
-
"@types/react": "^19.0.
|
|
23
|
+
"@types/react": "^19.0.8",
|
|
23
24
|
"@types/semver": "^7.5.8",
|
|
24
25
|
"get-port": "^7.1.0",
|
|
25
26
|
"tempy": "^3.1.0",
|
|
@@ -32,7 +33,7 @@
|
|
|
32
33
|
"dependencies": {
|
|
33
34
|
"@tscircuit/file-server": "^0.0.13",
|
|
34
35
|
"@tscircuit/runframe": "^0.0.47",
|
|
35
|
-
"chokidar": "
|
|
36
|
+
"chokidar": "4.0.1",
|
|
36
37
|
"commander": "^12.1.0",
|
|
37
38
|
"configstore": "^7.0.0",
|
|
38
39
|
"cosmiconfig": "^9.0.0",
|
|
@@ -41,6 +42,7 @@
|
|
|
41
42
|
"ky": "^1.7.4",
|
|
42
43
|
"make-vfs": "^1.0.15",
|
|
43
44
|
"perfect-cli": "^1.0.20",
|
|
45
|
+
"redaxios": "^0.5.1",
|
|
44
46
|
"semver": "^7.6.3"
|
|
45
47
|
}
|
|
46
48
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { getCliTestFixture } from "../../fixtures/get-cli-test-fixture"
|
|
2
|
+
import { test, expect } from "bun:test"
|
|
3
|
+
import { join } from "node:path"
|
|
4
|
+
import { execSync } from "node:child_process"
|
|
5
|
+
|
|
6
|
+
test("init command installs @types/react and passes type-checking", async () => {
|
|
7
|
+
const { tmpDir, runCommand } = await getCliTestFixture()
|
|
8
|
+
|
|
9
|
+
const { stdout } = await runCommand("tsci init")
|
|
10
|
+
console.log(stdout)
|
|
11
|
+
|
|
12
|
+
const pkgJsonPath = join(tmpDir, "package.json")
|
|
13
|
+
const pkgJson = JSON.parse(await Bun.file(pkgJsonPath).text())
|
|
14
|
+
expect(pkgJson.devDependencies["@types/react"]).toBeDefined()
|
|
15
|
+
expect(pkgJson.devDependencies["@tscircuit/core"]).toBeDefined()
|
|
16
|
+
|
|
17
|
+
const npmrcPath = join(tmpDir, ".npmrc")
|
|
18
|
+
const npmrcContent = await Bun.file(npmrcPath).text()
|
|
19
|
+
expect(npmrcContent).toContain("@tsci:registry=https://npm.tscircuit.com")
|
|
20
|
+
|
|
21
|
+
const tsconfigPath = join(tmpDir, "tsconfig.json")
|
|
22
|
+
const tsconfigExists = await Bun.file(tsconfigPath).exists()
|
|
23
|
+
expect(tsconfigExists).toBeTrue()
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
const typeCheckResult = execSync("npx tsc --noEmit", {
|
|
27
|
+
cwd: tmpDir,
|
|
28
|
+
stdio: "pipe",
|
|
29
|
+
})
|
|
30
|
+
console.log(typeCheckResult.toString())
|
|
31
|
+
} catch (error) {
|
|
32
|
+
throw new Error("Type-checking failed")
|
|
33
|
+
}
|
|
34
|
+
})
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { afterAll } from "bun:test"
|
|
2
|
+
import { startServer } from "@tscircuit/fake-snippets/bun-tests/fake-snippets-api/fixtures/start-server"
|
|
3
|
+
import { DbClient } from "@tscircuit/fake-snippets/fake-snippets-api/lib/db/db-client"
|
|
4
|
+
import ky from "ky"
|
|
5
|
+
import { prettyResponseErrorHook } from "lib/registry-api/get-ky"
|
|
6
|
+
import { cliConfig } from "lib/cli-config"
|
|
7
|
+
import { seed as seedDB } from "@tscircuit/fake-snippets/fake-snippets-api/lib/db/seed"
|
|
8
|
+
|
|
9
|
+
interface TestFixture {
|
|
10
|
+
url: string
|
|
11
|
+
server: any
|
|
12
|
+
ky: typeof ky
|
|
13
|
+
db: DbClient
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const getTestSnippetsServer = async (): Promise<TestFixture> => {
|
|
17
|
+
const port = 3789
|
|
18
|
+
const testInstanceId = Math.random().toString(36).substring(2, 15)
|
|
19
|
+
const testDbName = `testdb${testInstanceId}`
|
|
20
|
+
|
|
21
|
+
const { server, db } = await startServer({
|
|
22
|
+
port,
|
|
23
|
+
testDbName,
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
const url = `http://localhost:${port}/api`
|
|
27
|
+
seedDB(db)
|
|
28
|
+
const kyInstance = ky.create({
|
|
29
|
+
prefixUrl: url,
|
|
30
|
+
hooks: {
|
|
31
|
+
afterResponse: [prettyResponseErrorHook],
|
|
32
|
+
},
|
|
33
|
+
headers: {
|
|
34
|
+
Authorization: `Bearer ${db.accounts[0].account_id}`,
|
|
35
|
+
},
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
cliConfig.set("sessionToken", db.accounts[0].account_id)
|
|
39
|
+
cliConfig.set("registryApiUrl", url)
|
|
40
|
+
|
|
41
|
+
afterAll(async () => {
|
|
42
|
+
if (server && typeof server.stop === "function") {
|
|
43
|
+
await server.stop()
|
|
44
|
+
}
|
|
45
|
+
cliConfig.clear()
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
url,
|
|
50
|
+
server,
|
|
51
|
+
ky: kyInstance,
|
|
52
|
+
db,
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { test, expect, beforeEach, afterEach } from "bun:test"
|
|
2
|
+
import { getTestSnippetsServer } from "./fixtures/get-test-server"
|
|
3
|
+
import { getCliTestFixture } from "./fixtures/get-cli-test-fixture"
|
|
4
|
+
import * as fs from "node:fs"
|
|
5
|
+
import * as path from "node:path"
|
|
6
|
+
|
|
7
|
+
const { ky } = await getTestSnippetsServer()
|
|
8
|
+
const { tmpDir, runCommand } = await getCliTestFixture()
|
|
9
|
+
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
fs.rmSync(tmpDir, { recursive: true, force: true })
|
|
12
|
+
fs.mkdirSync(tmpDir, { recursive: true })
|
|
13
|
+
fs.writeFileSync(
|
|
14
|
+
path.join(tmpDir, "package.json"),
|
|
15
|
+
JSON.stringify({
|
|
16
|
+
name: "test-package",
|
|
17
|
+
version: "1.0.0",
|
|
18
|
+
}),
|
|
19
|
+
)
|
|
20
|
+
})
|
|
21
|
+
afterEach(() => {
|
|
22
|
+
fs.rmSync(tmpDir, { recursive: true, force: true })
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
test("should fail if no entrypoint file is found", async () => {
|
|
26
|
+
await runCommand("tsci push").catch((e) => {
|
|
27
|
+
expect(e.message).toInclude(
|
|
28
|
+
"No entrypoint found. Run 'tsci init' to bootstrap a basic project.",
|
|
29
|
+
)
|
|
30
|
+
})
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
test("should use default entrypoint if no file is provided", async () => {
|
|
34
|
+
const defaultEntrypoint = path.resolve(tmpDir, "index.tsx")
|
|
35
|
+
fs.writeFileSync(defaultEntrypoint, "// Default entrypoint!")
|
|
36
|
+
const { stdout } = await runCommand(`tsci push`)
|
|
37
|
+
expect(stdout).toContain(
|
|
38
|
+
"No file provided. Using 'index.tsx' as the entrypoint.",
|
|
39
|
+
)
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
test("should fail if package.json is missing or invalid", async () => {
|
|
43
|
+
const snippetFilePath = path.resolve(tmpDir, "snippet.tsx")
|
|
44
|
+
fs.writeFileSync(snippetFilePath, "// Snippet content")
|
|
45
|
+
|
|
46
|
+
try {
|
|
47
|
+
await runCommand(`tsci push ${snippetFilePath}`)
|
|
48
|
+
} catch (error) {
|
|
49
|
+
expect(console.error).toHaveBeenCalledWith(
|
|
50
|
+
"Failed to retrieve package version.",
|
|
51
|
+
)
|
|
52
|
+
}
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
test("should create package if it does not exist", async () => {
|
|
56
|
+
const snippetFilePath = path.resolve(tmpDir, "snippet.tsx")
|
|
57
|
+
|
|
58
|
+
fs.writeFileSync(snippetFilePath, "// Snippet content")
|
|
59
|
+
|
|
60
|
+
const { stdout } = await runCommand(`tsci push ${snippetFilePath}`)
|
|
61
|
+
expect(stdout).toContain("Successfully pushed package")
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
test("should bump version if release already exists", async () => {
|
|
65
|
+
const snippetFilePath = path.resolve(tmpDir, "snippet.tsx")
|
|
66
|
+
const packageJsonPath = path.resolve(tmpDir, "package.json")
|
|
67
|
+
|
|
68
|
+
fs.writeFileSync(snippetFilePath, "// Snippet content")
|
|
69
|
+
fs.writeFileSync(
|
|
70
|
+
packageJsonPath,
|
|
71
|
+
JSON.stringify({ name: "test-package", version: "1.0.0" }),
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
const { stdout } = await runCommand(`tsci push ${snippetFilePath}`)
|
|
75
|
+
expect(stdout).toContain("Incrementing Package Version 1.0.0 -> 1.0.1")
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
test("should upload files to the registry", async () => {
|
|
79
|
+
const snippetFilePath = path.resolve(tmpDir, "snippet.tsx")
|
|
80
|
+
|
|
81
|
+
fs.writeFileSync(snippetFilePath, "// Snippet content")
|
|
82
|
+
|
|
83
|
+
const { stdout } = await runCommand(`tsci push ${snippetFilePath}`)
|
|
84
|
+
expect(stdout).toContain("Uploaded file snippet.tsx to the registry.")
|
|
85
|
+
})
|
package/bun.lockb
DELETED
|
Binary file
|