create-bunli 0.1.0

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.
Files changed (96) hide show
  1. package/README.md +302 -0
  2. package/dist/cli.d.ts +2 -0
  3. package/dist/cli.js +310 -0
  4. package/dist/create-project.d.ts +13 -0
  5. package/dist/create.d.ts +13 -0
  6. package/dist/index.d.ts +4 -0
  7. package/dist/index.js +217 -0
  8. package/dist/template-engine.d.ts +27 -0
  9. package/dist/templates/advanced/README.md +114 -0
  10. package/dist/templates/advanced/package.json +36 -0
  11. package/dist/templates/advanced/src/commands/config.ts +145 -0
  12. package/dist/templates/advanced/src/commands/init.ts +153 -0
  13. package/dist/templates/advanced/src/commands/serve.ts +176 -0
  14. package/dist/templates/advanced/src/commands/validate.ts +116 -0
  15. package/dist/templates/advanced/src/index.ts +44 -0
  16. package/dist/templates/advanced/src/utils/config.ts +83 -0
  17. package/dist/templates/advanced/src/utils/constants.ts +12 -0
  18. package/dist/templates/advanced/src/utils/glob.ts +49 -0
  19. package/dist/templates/advanced/src/utils/validator.ts +131 -0
  20. package/dist/templates/advanced/template.json +37 -0
  21. package/dist/templates/advanced/test/commands.test.ts +34 -0
  22. package/dist/templates/advanced/tsconfig.json +23 -0
  23. package/dist/templates/basic/README.md +41 -0
  24. package/dist/templates/basic/package.json +29 -0
  25. package/dist/templates/basic/src/commands/hello.ts +29 -0
  26. package/dist/templates/basic/src/index.ts +13 -0
  27. package/dist/templates/basic/template.json +31 -0
  28. package/dist/templates/basic/test/hello.test.ts +26 -0
  29. package/dist/templates/basic/tsconfig.json +19 -0
  30. package/dist/templates/monorepo/README.md +74 -0
  31. package/dist/templates/monorepo/package.json +28 -0
  32. package/dist/templates/monorepo/packages/cli/package.json +34 -0
  33. package/dist/templates/monorepo/packages/cli/src/index.ts +22 -0
  34. package/dist/templates/monorepo/packages/cli/tsconfig.json +15 -0
  35. package/dist/templates/monorepo/packages/core/package.json +32 -0
  36. package/dist/templates/monorepo/packages/core/scripts/build.ts +18 -0
  37. package/dist/templates/monorepo/packages/core/src/commands/analyze.ts +84 -0
  38. package/dist/templates/monorepo/packages/core/src/commands/process.ts +64 -0
  39. package/dist/templates/monorepo/packages/core/src/index.ts +3 -0
  40. package/dist/templates/monorepo/packages/core/src/types.ts +21 -0
  41. package/dist/templates/monorepo/packages/core/tsconfig.json +15 -0
  42. package/dist/templates/monorepo/packages/utils/package.json +26 -0
  43. package/dist/templates/monorepo/packages/utils/scripts/build.ts +17 -0
  44. package/dist/templates/monorepo/packages/utils/src/format.ts +27 -0
  45. package/dist/templates/monorepo/packages/utils/src/index.ts +3 -0
  46. package/dist/templates/monorepo/packages/utils/src/json.ts +11 -0
  47. package/dist/templates/monorepo/packages/utils/src/logger.ts +19 -0
  48. package/dist/templates/monorepo/packages/utils/tsconfig.json +12 -0
  49. package/dist/templates/monorepo/template.json +24 -0
  50. package/dist/templates/monorepo/tsconfig.json +14 -0
  51. package/dist/templates/monorepo/turbo.json +28 -0
  52. package/dist/types.d.ts +48 -0
  53. package/package.json +57 -0
  54. package/templates/advanced/README.md +114 -0
  55. package/templates/advanced/package.json +36 -0
  56. package/templates/advanced/src/commands/config.ts +145 -0
  57. package/templates/advanced/src/commands/init.ts +153 -0
  58. package/templates/advanced/src/commands/serve.ts +176 -0
  59. package/templates/advanced/src/commands/validate.ts +116 -0
  60. package/templates/advanced/src/index.ts +44 -0
  61. package/templates/advanced/src/utils/config.ts +83 -0
  62. package/templates/advanced/src/utils/constants.ts +12 -0
  63. package/templates/advanced/src/utils/glob.ts +49 -0
  64. package/templates/advanced/src/utils/validator.ts +131 -0
  65. package/templates/advanced/template.json +37 -0
  66. package/templates/advanced/test/commands.test.ts +34 -0
  67. package/templates/advanced/tsconfig.json +23 -0
  68. package/templates/basic/README.md +41 -0
  69. package/templates/basic/package.json +29 -0
  70. package/templates/basic/src/commands/hello.ts +29 -0
  71. package/templates/basic/src/index.ts +13 -0
  72. package/templates/basic/template.json +31 -0
  73. package/templates/basic/test/hello.test.ts +26 -0
  74. package/templates/basic/tsconfig.json +19 -0
  75. package/templates/monorepo/README.md +74 -0
  76. package/templates/monorepo/package.json +28 -0
  77. package/templates/monorepo/packages/cli/package.json +34 -0
  78. package/templates/monorepo/packages/cli/src/index.ts +22 -0
  79. package/templates/monorepo/packages/cli/tsconfig.json +15 -0
  80. package/templates/monorepo/packages/core/package.json +32 -0
  81. package/templates/monorepo/packages/core/scripts/build.ts +18 -0
  82. package/templates/monorepo/packages/core/src/commands/analyze.ts +84 -0
  83. package/templates/monorepo/packages/core/src/commands/process.ts +64 -0
  84. package/templates/monorepo/packages/core/src/index.ts +3 -0
  85. package/templates/monorepo/packages/core/src/types.ts +21 -0
  86. package/templates/monorepo/packages/core/tsconfig.json +15 -0
  87. package/templates/monorepo/packages/utils/package.json +26 -0
  88. package/templates/monorepo/packages/utils/scripts/build.ts +17 -0
  89. package/templates/monorepo/packages/utils/src/format.ts +27 -0
  90. package/templates/monorepo/packages/utils/src/index.ts +3 -0
  91. package/templates/monorepo/packages/utils/src/json.ts +11 -0
  92. package/templates/monorepo/packages/utils/src/logger.ts +19 -0
  93. package/templates/monorepo/packages/utils/tsconfig.json +12 -0
  94. package/templates/monorepo/template.json +24 -0
  95. package/templates/monorepo/tsconfig.json +14 -0
  96. package/templates/monorepo/turbo.json +28 -0
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env bun
2
+ import { $ } from 'bun'
3
+
4
+ // Clean dist directory
5
+ await $`rm -rf dist`
6
+ await $`mkdir -p dist`
7
+
8
+ // Build TypeScript files
9
+ await Bun.build({
10
+ entrypoints: ['./src/index.ts'],
11
+ outdir: './dist',
12
+ target: 'bun',
13
+ format: 'esm',
14
+ minify: false
15
+ })
16
+
17
+ console.log('✅ @{{projectName}}/utils built successfully')
@@ -0,0 +1,27 @@
1
+ export function formatTable(data: Record<string, any>[]): string {
2
+ if (data.length === 0) return ''
3
+
4
+ const headers = Object.keys(data[0])
5
+ const rows = data.map(item => headers.map(h => String(item[h] ?? '')))
6
+
7
+ // Calculate column widths
8
+ const widths = headers.map((h, i) => {
9
+ const headerWidth = h.length
10
+ const maxDataWidth = Math.max(...rows.map(r => r[i].length))
11
+ return Math.max(headerWidth, maxDataWidth)
12
+ })
13
+
14
+ // Build table
15
+ const lines: string[] = []
16
+
17
+ // Header
18
+ lines.push(headers.map((h, i) => h.padEnd(widths[i])).join(' '))
19
+ lines.push(widths.map(w => '-'.repeat(w)).join(' '))
20
+
21
+ // Rows
22
+ for (const row of rows) {
23
+ lines.push(row.map((cell, i) => cell.padEnd(widths[i])).join(' '))
24
+ }
25
+
26
+ return lines.join('\\n')
27
+ }
@@ -0,0 +1,3 @@
1
+ export { logger } from './logger.js'
2
+ export { formatTable } from './format.js'
3
+ export { parseJSON, stringifyJSON } from './json.js'
@@ -0,0 +1,11 @@
1
+ export function parseJSON<T = any>(text: string): T {
2
+ try {
3
+ return JSON.parse(text)
4
+ } catch (error) {
5
+ throw new Error(`Invalid JSON: ${error}`)
6
+ }
7
+ }
8
+
9
+ export function stringifyJSON(data: any, pretty = false): string {
10
+ return JSON.stringify(data, null, pretty ? 2 : 0)
11
+ }
@@ -0,0 +1,19 @@
1
+ export const logger = {
2
+ debug: (...args: any[]) => {
3
+ if (process.env.DEBUG) {
4
+ console.log('[DEBUG]', ...args)
5
+ }
6
+ },
7
+
8
+ info: (...args: any[]) => {
9
+ console.log('[INFO]', ...args)
10
+ },
11
+
12
+ warn: (...args: any[]) => {
13
+ console.warn('[WARN]', ...args)
14
+ },
15
+
16
+ error: (...args: any[]) => {
17
+ console.error('[ERROR]', ...args)
18
+ }
19
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "./dist",
5
+ "rootDir": "./src",
6
+ "declaration": true,
7
+ "declarationMap": true,
8
+ "composite": true
9
+ },
10
+ "include": ["src/**/*"],
11
+ "exclude": ["node_modules", "dist", "test/**/*"]
12
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "bunli-monorepo",
3
+ "description": "Monorepo template for multi-package Bunli projects",
4
+ "variables": [
5
+ {
6
+ "name": "projectName",
7
+ "message": "Project name",
8
+ "type": "string",
9
+ "default": "my-bunli-monorepo"
10
+ },
11
+ {
12
+ "name": "description",
13
+ "message": "Project description",
14
+ "type": "string",
15
+ "default": "A monorepo CLI project built with Bunli"
16
+ },
17
+ {
18
+ "name": "author",
19
+ "message": "Author name",
20
+ "type": "string",
21
+ "default": ""
22
+ }
23
+ ]
24
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "strict": true,
7
+ "esModuleInterop": true,
8
+ "skipLibCheck": true,
9
+ "forceConsistentCasingInFileNames": true,
10
+ "resolveJsonModule": true,
11
+ "types": ["bun-types"]
12
+ },
13
+ "exclude": ["node_modules", "dist", "build", ".turbo"]
14
+ }
@@ -0,0 +1,28 @@
1
+ {
2
+ "$schema": "https://turbo.build/schema.json",
3
+ "globalDependencies": ["**/.env.*local"],
4
+ "pipeline": {
5
+ "build": {
6
+ "dependsOn": ["^build"],
7
+ "outputs": ["dist/**", ".next/**", "!.next/cache/**"]
8
+ },
9
+ "test": {
10
+ "dependsOn": ["build"],
11
+ "outputs": ["coverage/**"],
12
+ "cache": false
13
+ },
14
+ "lint": {
15
+ "dependsOn": ["^build"]
16
+ },
17
+ "type-check": {
18
+ "dependsOn": ["^build"]
19
+ },
20
+ "dev": {
21
+ "cache": false,
22
+ "persistent": true
23
+ },
24
+ "clean": {
25
+ "cache": false
26
+ }
27
+ }
28
+ }
@@ -0,0 +1,48 @@
1
+ export interface CreateOptions {
2
+ template?: string;
3
+ packageManager?: PackageManager;
4
+ install?: boolean;
5
+ git?: boolean;
6
+ offline?: boolean;
7
+ }
8
+ export type PackageManager = 'bun' | 'npm' | 'yarn' | 'pnpm';
9
+ export interface ProjectConfig {
10
+ name: string;
11
+ template: string;
12
+ packageManager: PackageManager;
13
+ install: boolean;
14
+ git: boolean;
15
+ offline?: boolean;
16
+ }
17
+ export interface TemplateManifest {
18
+ name?: string;
19
+ description?: string;
20
+ variables?: TemplateVariable[];
21
+ files?: {
22
+ include?: string[];
23
+ exclude?: string[];
24
+ };
25
+ hooks?: {
26
+ postInstall?: string[];
27
+ };
28
+ requirements?: {
29
+ node?: string;
30
+ bun?: string;
31
+ };
32
+ }
33
+ export interface TemplateVariable {
34
+ name: string;
35
+ message: string;
36
+ type?: 'string' | 'boolean' | 'number' | 'select';
37
+ default?: any;
38
+ choices?: Array<{
39
+ label: string;
40
+ value: any;
41
+ }>;
42
+ validate?: (value: any) => boolean | string;
43
+ }
44
+ export interface Template {
45
+ name: string;
46
+ description: string;
47
+ files: Record<string, string>;
48
+ }
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "create-bunli",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "description": "Scaffold new Bunli CLI projects",
6
+ "bin": {
7
+ "create-bunli": "./dist/cli.js"
8
+ },
9
+ "module": "./dist/index.js",
10
+ "types": "./dist/index.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "import": "./dist/index.js",
14
+ "types": "./dist/index.d.ts"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist",
19
+ "templates"
20
+ ],
21
+ "author": "Arya Labs, Inc.",
22
+ "license": "MIT",
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "https://github.com/AryaLabsHQ/bunli.git",
26
+ "directory": "packages/create-bunli"
27
+ },
28
+ "bugs": {
29
+ "url": "https://github.com/AryaLabsHQ/bunli/issues"
30
+ },
31
+ "homepage": "https://github.com/AryaLabsHQ/bunli#readme",
32
+ "keywords": [
33
+ "bunli",
34
+ "create",
35
+ "scaffold",
36
+ "cli",
37
+ "starter",
38
+ "template",
39
+ "bun",
40
+ "typescript"
41
+ ],
42
+ "scripts": {
43
+ "dev": "bun run src/cli.ts",
44
+ "build": "bun scripts/build.ts && bun run tsc",
45
+ "test": "bun test",
46
+ "type-check": "tsc --noEmit"
47
+ },
48
+ "dependencies": {
49
+ "@bunli/core": "0.1.0",
50
+ "@bunli/utils": "0.1.0",
51
+ "giget": "^2.0.0"
52
+ },
53
+ "devDependencies": {
54
+ "@types/bun": "latest",
55
+ "typescript": "^5.8.0"
56
+ }
57
+ }
@@ -0,0 +1,114 @@
1
+ # {{projectName}}
2
+
3
+ {{description}}
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ # Install globally
9
+ bun add -g {{projectName}}
10
+
11
+ # Or use directly with bunx
12
+ bunx {{projectName}} [command]
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ ```bash
18
+ {{projectName}} <command> [options]
19
+ ```
20
+
21
+ ### Commands
22
+
23
+ #### `init`
24
+ Initialize a new configuration file in the current directory.
25
+
26
+ ```bash
27
+ {{projectName}} init [options]
28
+
29
+ Options:
30
+ -f, --force Overwrite existing config
31
+ -t, --template Config template to use
32
+ ```
33
+
34
+ #### `validate`
35
+ Validate files against defined rules.
36
+
37
+ ```bash
38
+ {{projectName}} validate <files...> [options]
39
+
40
+ Options:
41
+ -c, --config Path to config file
42
+ -f, --fix Auto-fix issues
43
+ --no-cache Disable caching
44
+ ```
45
+
46
+ #### `serve`
47
+ Start a development server.
48
+
49
+ ```bash
50
+ {{projectName}} serve [options]
51
+
52
+ Options:
53
+ -p, --port Port to listen on (default: 3000)
54
+ -h, --host Host to bind to (default: localhost)
55
+ --no-open Don't open browser
56
+ ```
57
+
58
+ #### `config`
59
+ Manage configuration settings.
60
+
61
+ ```bash
62
+ {{projectName}} config <action> [key] [value]
63
+
64
+ Actions:
65
+ get <key> Get a config value
66
+ set <key> <value> Set a config value
67
+ list List all config values
68
+ reset Reset to defaults
69
+ ```
70
+
71
+ ### Global Options
72
+
73
+ - `-v, --version` - Show version
74
+ - `-h, --help` - Show help
75
+ - `--verbose` - Enable verbose output
76
+ - `--quiet` - Suppress output
77
+ - `--no-color` - Disable colored output
78
+
79
+ ## Configuration
80
+
81
+ Create a `{{projectName}}.config.js` file in your project root:
82
+
83
+ ```javascript
84
+ export default {
85
+ // Configuration options
86
+ rules: {
87
+ // Define your rules
88
+ },
89
+ server: {
90
+ port: 3000,
91
+ host: 'localhost'
92
+ }
93
+ }
94
+ ```
95
+
96
+ ## Development
97
+
98
+ ```bash
99
+ # Install dependencies
100
+ bun install
101
+
102
+ # Run in development
103
+ bun dev
104
+
105
+ # Run tests
106
+ bun test
107
+
108
+ # Build for production
109
+ bun run build
110
+ ```
111
+
112
+ ## License
113
+
114
+ {{license}}
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "{{projectName}}",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "description": "{{description}}",
6
+ "author": "{{author}}",
7
+ "license": "{{license}}",
8
+ "bin": {
9
+ "{{projectName}}": "./dist/index.js"
10
+ },
11
+ "scripts": {
12
+ "dev": "bun run src/index.ts",
13
+ "build": "bunli build",
14
+ "test": "bun test",
15
+ "test:watch": "bun test --watch",
16
+ "type-check": "tsc --noEmit",
17
+ "lint": "tsc --noEmit",
18
+ "prepare": "bun run build"
19
+ },
20
+ "dependencies": {
21
+ "@bunli/core": "latest",
22
+ "@bunli/utils": "latest",
23
+ "zod": "^3.22.0"
24
+ },
25
+ "devDependencies": {
26
+ "@bunli/test": "latest",
27
+ "@types/bun": "latest",
28
+ "bunli": "latest",
29
+ "typescript": "^5.0.0"
30
+ },
31
+ "bunli": {
32
+ "entry": "./src/index.ts",
33
+ "outDir": "./dist",
34
+ "external": ["@bunli/core", "@bunli/utils", "zod"]
35
+ }
36
+ }
@@ -0,0 +1,145 @@
1
+ import { defineCommand, option } from '@bunli/core'
2
+ import { z } from 'zod'
3
+ import { loadConfig, saveConfig, getConfigPath } from '../utils/config.js'
4
+
5
+ export const configCommand = defineCommand({
6
+ name: 'config',
7
+ description: 'Manage configuration',
8
+ subcommands: [
9
+ defineCommand({
10
+ name: 'get',
11
+ description: 'Get a config value',
12
+ args: z.tuple([z.string()]).describe('Config key to get'),
13
+ handler: async ({ args, colors }) => {
14
+ const [key] = args
15
+
16
+ try {
17
+ const config = await loadConfig()
18
+ const value = getNestedValue(config, key)
19
+
20
+ if (value === undefined) {
21
+ console.log(colors.yellow(`Config key '${key}' not found`))
22
+ } else {
23
+ console.log(JSON.stringify(value, null, 2))
24
+ }
25
+ } catch (error) {
26
+ console.error(colors.red(`Failed to load config: ${error}`))
27
+ process.exit(1)
28
+ }
29
+ }
30
+ }),
31
+
32
+ defineCommand({
33
+ name: 'set',
34
+ description: 'Set a config value',
35
+ args: z.tuple([z.string(), z.string()]).describe('Config key and value'),
36
+ handler: async ({ args, colors, spinner }) => {
37
+ const [key, value] = args
38
+
39
+ const spin = spinner('Updating config...')
40
+ spin.start()
41
+
42
+ try {
43
+ const config = await loadConfig()
44
+ setNestedValue(config, key, JSON.parse(value))
45
+ await saveConfig(config)
46
+
47
+ spin.succeed(`Config '${key}' updated`)
48
+ } catch (error) {
49
+ spin.fail('Failed to update config')
50
+ console.error(colors.red(String(error)))
51
+ process.exit(1)
52
+ }
53
+ }
54
+ }),
55
+
56
+ defineCommand({
57
+ name: 'list',
58
+ description: 'List all config values',
59
+ handler: async ({ colors }) => {
60
+ try {
61
+ const config = await loadConfig()
62
+ const configPath = await getConfigPath()
63
+
64
+ console.log(colors.bold('Configuration:'))
65
+ console.log(colors.dim(` File: ${configPath}`))
66
+ console.log()
67
+ console.log(JSON.stringify(config, null, 2))
68
+ } catch (error) {
69
+ console.error(colors.red(`Failed to load config: ${error}`))
70
+ process.exit(1)
71
+ }
72
+ }
73
+ }),
74
+
75
+ defineCommand({
76
+ name: 'reset',
77
+ description: 'Reset config to defaults',
78
+ options: {
79
+ force: option(
80
+ z.boolean().default(false),
81
+ {
82
+ short: 'f',
83
+ description: 'Skip confirmation'
84
+ }
85
+ )
86
+ },
87
+ handler: async ({ flags, colors, prompt, spinner }) => {
88
+ if (!flags.force) {
89
+ const confirmed = await prompt.confirm(
90
+ 'This will reset all config to defaults. Continue?',
91
+ { default: false }
92
+ )
93
+
94
+ if (!confirmed) {
95
+ console.log(colors.yellow('Reset cancelled'))
96
+ return
97
+ }
98
+ }
99
+
100
+ const spin = spinner('Resetting config...')
101
+ spin.start()
102
+
103
+ try {
104
+ const { DEFAULT_CONFIG } = await import('../utils/constants.js')
105
+ await saveConfig(DEFAULT_CONFIG)
106
+
107
+ spin.succeed('Config reset to defaults')
108
+ } catch (error) {
109
+ spin.fail('Failed to reset config')
110
+ console.error(colors.red(String(error)))
111
+ process.exit(1)
112
+ }
113
+ }
114
+ })
115
+ ]
116
+ })
117
+
118
+ function getNestedValue(obj: any, path: string): any {
119
+ const keys = path.split('.')
120
+ let current = obj
121
+
122
+ for (const key of keys) {
123
+ if (current === null || current === undefined) {
124
+ return undefined
125
+ }
126
+ current = current[key]
127
+ }
128
+
129
+ return current
130
+ }
131
+
132
+ function setNestedValue(obj: any, path: string, value: any): void {
133
+ const keys = path.split('.')
134
+ const lastKey = keys.pop()!
135
+ let current = obj
136
+
137
+ for (const key of keys) {
138
+ if (!(key in current) || typeof current[key] !== 'object') {
139
+ current[key] = {}
140
+ }
141
+ current = current[key]
142
+ }
143
+
144
+ current[lastKey] = value
145
+ }