zile 0.0.0 → 0.0.1

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/package.json CHANGED
@@ -1,4 +1,60 @@
1
1
  {
2
2
  "name": "zile",
3
- "version": "0.0.0"
4
- }
3
+ "type": "module",
4
+ "version": "0.0.1",
5
+ "license": "MIT",
6
+ "bin": {
7
+ "zile": "./dist/Cli.js"
8
+ },
9
+ "scripts": {
10
+ "build": "bun src/Cli.ts",
11
+ "changeset:publish": "bun run build && changeset publish",
12
+ "changeset:version": "changeset version",
13
+ "check": "biome check --fix --unsafe",
14
+ "check:types": "tsc -b",
15
+ "test": "vitest --watch=false"
16
+ },
17
+ "files": [
18
+ "dist",
19
+ "src"
20
+ ],
21
+ "main": "./dist/index.js",
22
+ "packageManager": "bun@1.3",
23
+ "dependencies": {
24
+ "cac": "6.7.14",
25
+ "tsconfck": "3.1.6"
26
+ },
27
+ "peerDependencies": {
28
+ "@typescript/native-preview": ">=7.0.0",
29
+ "typescript": ">=5"
30
+ },
31
+ "peerDependenciesMeta": {
32
+ "@typescript/native-preview": {
33
+ "optional": true
34
+ },
35
+ "typescript": {
36
+ "optional": true
37
+ }
38
+ },
39
+ "devDependencies": {
40
+ "@arethetypeswrong/cli": "0.18.2",
41
+ "@biomejs/biome": "^2.2.5",
42
+ "@changesets/changelog-github": "^0.5.0",
43
+ "@changesets/cli": "^2.27.7",
44
+ "@types/node": "^24.7.1",
45
+ "publint": "0.3.14",
46
+ "type-fest": "^5.0.1",
47
+ "vitest": "^3.2.4"
48
+ },
49
+ "repository": "wevm/zile",
50
+ "sideEffects": false,
51
+ "module": "./dist/index.js",
52
+ "types": "./dist/index.d.ts",
53
+ "exports": {
54
+ ".": {
55
+ "src": "./src/index.ts",
56
+ "types": "./dist/index.d.ts",
57
+ "default": "./dist/index.js"
58
+ }
59
+ }
60
+ }
@@ -0,0 +1,81 @@
1
+ import { spawn } from 'node:child_process'
2
+ import * as fs from 'node:fs/promises'
3
+ import * as path from 'node:path'
4
+ import { setupRepos, tree } from '../test/utils.js'
5
+
6
+ const repos = () =>
7
+ setupRepos().then(({ repos }) => repos.filter(({ relative }) => !relative.includes('invalid-')))
8
+
9
+ describe.each(await repos())('$relative: Cli.run', ({ cwd }) => {
10
+ test('default', async () => {
11
+ if (cwd.includes('error-')) return
12
+
13
+ const result = spawn(
14
+ 'bun',
15
+ ['./Cli.ts', '--cwd', cwd, '--includes', '**,!**/error-*,!**/node_modules/**'],
16
+ { cwd: import.meta.dirname },
17
+ )
18
+
19
+ const promise = Promise.withResolvers<void>()
20
+ result.on('close', (code) =>
21
+ code === 0
22
+ ? promise.resolve()
23
+ : promise.reject(new Error(`Child process exited with code ${code}`)),
24
+ )
25
+ await promise.promise
26
+
27
+ const packageJsonString = await fs.readFile(path.resolve(cwd, 'package.json'), 'utf-8')
28
+ const packageJson = JSON.parse(packageJsonString)
29
+ expect([packageJsonString, await tree(cwd)].join('\n\n')).toMatchSnapshot('output')
30
+ expect(await fs.readFile(path.resolve(cwd, packageJson.main), 'utf-8')).toMatchSnapshot('main')
31
+ expect(await fs.readFile(path.resolve(cwd, packageJson.types), 'utf-8')).toMatchSnapshot(
32
+ 'types',
33
+ )
34
+ })
35
+
36
+ test('link', async () => {
37
+ if (cwd.includes('error-')) return
38
+
39
+ const result = spawn(
40
+ 'bun',
41
+ ['./Cli.ts', 'dev', '--cwd', cwd, '--includes', '**,!**/error-*,!**/node_modules/**'],
42
+ { cwd: import.meta.dirname },
43
+ )
44
+
45
+ const promise = Promise.withResolvers<void>()
46
+ result.on('close', (code) =>
47
+ code === 0
48
+ ? promise.resolve()
49
+ : promise.reject(new Error(`Child process exited with code ${code}`)),
50
+ )
51
+ await promise.promise
52
+
53
+ const packageJsonString = await fs.readFile(path.resolve(cwd, 'package.json'), 'utf-8')
54
+ const packageJson = JSON.parse(packageJsonString)
55
+ expect([packageJsonString, await tree(cwd)].join('\n\n')).toMatchSnapshot('output')
56
+
57
+ // Verify symlinks exist (check exports field for actual symlink locations)
58
+ const rootExport = packageJson.exports?.['.']
59
+ const defaultPath =
60
+ typeof rootExport === 'string'
61
+ ? rootExport
62
+ : typeof rootExport === 'object' && rootExport
63
+ ? rootExport.default
64
+ : null
65
+ const typesPath = typeof rootExport === 'object' && rootExport ? rootExport.types : null
66
+
67
+ if (defaultPath) {
68
+ const mainStats = await fs.lstat(path.resolve(cwd, defaultPath))
69
+ expect(mainStats.isSymbolicLink()).toBe(true)
70
+ const mainTarget = await fs.readlink(path.resolve(cwd, defaultPath))
71
+ expect(mainTarget).toMatchSnapshot('main-target')
72
+ }
73
+
74
+ if (typesPath) {
75
+ const typesStats = await fs.lstat(path.resolve(cwd, typesPath))
76
+ expect(typesStats.isSymbolicLink()).toBe(true)
77
+ const typesTarget = await fs.readlink(path.resolve(cwd, typesPath))
78
+ expect(typesTarget).toMatchSnapshot('types-target')
79
+ }
80
+ })
81
+ })
package/src/Cli.ts ADDED
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env bun
2
+ import { cac } from 'cac'
3
+ import * as commands from './internal/cli/commands.js'
4
+ import pkgJson from './internal/package.json' with { type: 'json' }
5
+
6
+ /**
7
+ * Runs the CLI with the given arguments.
8
+ *
9
+ * @param options - Options for running the CLI
10
+ * @returns Promise that resolves when the CLI completes
11
+ */
12
+ export async function run(options: run.Options): Promise<void> {
13
+ const { args } = options
14
+
15
+ const cli = cac(pkgJson.name)
16
+ cli.version(pkgJson.version)
17
+
18
+ commands.build(cli.command('[root]', ''))
19
+ commands.build(cli.command('build', 'Build package'))
20
+ commands.build(cli.command('dev', 'Resolve package exports to source for development'), {
21
+ link: true,
22
+ })
23
+
24
+ cli.help()
25
+ cli.parse(args)
26
+ }
27
+
28
+ export declare namespace run {
29
+ type Options = {
30
+ /** Command-line arguments to parse */
31
+ args: string[]
32
+ }
33
+ }
34
+
35
+ // Run the CLI if this module is executed directly
36
+ if (import.meta.url === `file://${process.argv[1]}`) {
37
+ run({ args: process.argv }).catch((error) => {
38
+ console.error(error)
39
+ process.exit(1)
40
+ })
41
+ }
@@ -0,0 +1,102 @@
1
+ import * as fs from 'node:fs/promises'
2
+ import path from 'node:path'
3
+ import { checkOutput, setupRepos, tree } from '../test/utils.js'
4
+ import * as Package from './Package.js'
5
+
6
+ const repos = () =>
7
+ setupRepos().then(({ repos }) => repos.filter(({ relative }) => !relative.includes('invalid-')))
8
+
9
+ describe.each(await repos())('$relative: Package.build', ({ cwd }) => {
10
+ test('default', async () => {
11
+ if (cwd.includes('error-')) {
12
+ await expect(Package.build({ cwd })).rejects.toMatchSnapshot('error')
13
+ return
14
+ }
15
+
16
+ {
17
+ const result = await Package.build({
18
+ cwd,
19
+ })
20
+ expect(result).toMatchSnapshot('result')
21
+ }
22
+
23
+ {
24
+ const result = await checkOutput({ cwd })
25
+ expect(result).toMatchSnapshot('check')
26
+ }
27
+
28
+ const packageJsonString = await fs.readFile(path.resolve(cwd, 'package.json'), 'utf-8')
29
+ const packageJson = JSON.parse(packageJsonString)
30
+ expect([packageJsonString, await tree(cwd)].join('\n\n')).toMatchSnapshot('output')
31
+ expect(await fs.readFile(path.resolve(cwd, packageJson.main), 'utf-8')).toMatchSnapshot('main')
32
+ expect(await fs.readFile(path.resolve(cwd, packageJson.types), 'utf-8')).toMatchSnapshot(
33
+ 'types',
34
+ )
35
+ })
36
+
37
+ test('link', async () => {
38
+ if (cwd.includes('error-')) return
39
+
40
+ const result = await Package.build({
41
+ cwd,
42
+ link: true,
43
+ })
44
+ expect(result).toMatchSnapshot('result')
45
+
46
+ const packageJsonString = await fs.readFile(path.resolve(cwd, 'package.json'), 'utf-8')
47
+ const packageJson = JSON.parse(packageJsonString)
48
+ expect([packageJsonString, await tree(cwd)].join('\n\n')).toMatchSnapshot('output')
49
+
50
+ // Verify symlinks exist (check exports field for actual symlink locations)
51
+ const rootExport = packageJson.exports?.['.']
52
+ const defaultPath =
53
+ typeof rootExport === 'string'
54
+ ? rootExport
55
+ : typeof rootExport === 'object' && rootExport
56
+ ? rootExport.default
57
+ : null
58
+ const typesPath = typeof rootExport === 'object' && rootExport ? rootExport.types : null
59
+
60
+ if (defaultPath) {
61
+ const mainStats = await fs.lstat(path.resolve(cwd, defaultPath))
62
+ expect(mainStats.isSymbolicLink()).toBe(true)
63
+ const mainTarget = await fs.readlink(path.resolve(cwd, defaultPath))
64
+ expect(mainTarget).toMatchSnapshot('main-target')
65
+ }
66
+
67
+ if (typesPath) {
68
+ const typesStats = await fs.lstat(path.resolve(cwd, typesPath))
69
+ expect(typesStats.isSymbolicLink()).toBe(true)
70
+ const typesTarget = await fs.readlink(path.resolve(cwd, typesPath))
71
+ expect(typesTarget).toMatchSnapshot('types-target')
72
+ }
73
+ })
74
+ })
75
+
76
+ describe('Package.getSourceDir', () => {
77
+ test('common', async () => {
78
+ {
79
+ const result = Package.getSourceDir({
80
+ entries: [
81
+ path.resolve(process.cwd(), 'src/index.ts'),
82
+ path.resolve(process.cwd(), 'src/foo.ts'),
83
+ path.resolve(process.cwd(), 'src/nested/dir/index.ts'),
84
+ path.resolve(process.cwd(), 'src/nested/dir/bar.ts'),
85
+ ],
86
+ })
87
+ expect(result).toBe(path.resolve(process.cwd(), 'src'))
88
+ }
89
+
90
+ {
91
+ const result = Package.getSourceDir({
92
+ entries: [
93
+ path.resolve(process.cwd(), 'src/index.ts'),
94
+ path.resolve(process.cwd(), 'foo.ts'),
95
+ path.resolve(process.cwd(), 'bar/nested/dir/index.ts'),
96
+ path.resolve(process.cwd(), 'src/nested/dir/bar.ts'),
97
+ ],
98
+ })
99
+ expect(result).toBe(process.cwd())
100
+ }
101
+ })
102
+ })