@ardly/bunext 1.0.5 → 1.0.6
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/bin/cli.mjs +78 -85
- package/package.json +1 -1
- package/bin/utils.mjs +0 -32
package/bin/cli.mjs
CHANGED
|
@@ -2,26 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
import { execSync } from 'child_process'
|
|
4
4
|
import readline from 'readline'
|
|
5
|
-
import { createSpinner } from './utils.mjs'
|
|
6
|
-
|
|
7
|
-
// ANSI color codes for terminal output
|
|
8
|
-
const colors = {
|
|
9
|
-
reset: '\x1b[0m',
|
|
10
|
-
cyan: '\x1b[36m',
|
|
11
|
-
green: '\x1b[32m',
|
|
12
|
-
yellow: '\x1b[33m',
|
|
13
|
-
red: '\x1b[31m',
|
|
14
|
-
bold: '\x1b[1m',
|
|
15
|
-
dim: '\x1b[2m',
|
|
16
|
-
}
|
|
17
5
|
|
|
18
6
|
const runCommand = (command) => {
|
|
19
7
|
try {
|
|
20
8
|
execSync(`${command}`, { stdio: 'inherit' })
|
|
21
|
-
return true
|
|
22
9
|
} catch (error) {
|
|
10
|
+
console.error(`Failed to run command: ${command}`, error)
|
|
23
11
|
return false
|
|
24
12
|
}
|
|
13
|
+
return true
|
|
25
14
|
}
|
|
26
15
|
|
|
27
16
|
const rl = readline.createInterface({
|
|
@@ -29,50 +18,52 @@ const rl = readline.createInterface({
|
|
|
29
18
|
output: process.stdout,
|
|
30
19
|
})
|
|
31
20
|
|
|
32
|
-
const question = (query) =>
|
|
33
|
-
new Promise((resolve) => rl.question(query, resolve))
|
|
34
|
-
|
|
35
21
|
let repoName = process.argv[2]
|
|
36
22
|
const args = process.argv.slice(2)
|
|
37
23
|
const useVSCode = args.includes('--vs')
|
|
38
24
|
const useCursor = args.includes('--cursor')
|
|
39
25
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
26
|
+
const validateRepoName = (name) => {
|
|
27
|
+
const validNameRegex = /^[a-z0-9-]+$/
|
|
28
|
+
return validNameRegex.test(name)
|
|
29
|
+
}
|
|
44
30
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
31
|
+
const promptForValidRepoName = (callback) => {
|
|
32
|
+
rl.question(
|
|
33
|
+
'Please enter a name for your project (lowercase letters, numbers and hyphens only): ',
|
|
34
|
+
(answer) => {
|
|
35
|
+
if (validateRepoName(answer)) {
|
|
36
|
+
repoName = answer
|
|
37
|
+
callback()
|
|
38
|
+
} else {
|
|
39
|
+
console.error(
|
|
40
|
+
'Invalid project name. Please use only lowercase letters, numbers and hyphens.'
|
|
41
|
+
)
|
|
42
|
+
promptForValidRepoName(callback)
|
|
43
|
+
}
|
|
50
44
|
}
|
|
51
|
-
|
|
45
|
+
)
|
|
46
|
+
}
|
|
52
47
|
|
|
53
|
-
|
|
48
|
+
if (!repoName || repoName.startsWith('--')) {
|
|
49
|
+
promptForValidRepoName(initializeProject)
|
|
50
|
+
} else if (!validateRepoName(repoName)) {
|
|
51
|
+
console.error(
|
|
52
|
+
'Invalid project name. Please use only lowercase letters, numbers and hyphens.'
|
|
53
|
+
)
|
|
54
|
+
promptForValidRepoName(initializeProject)
|
|
55
|
+
} else {
|
|
56
|
+
initializeProject()
|
|
57
|
+
}
|
|
54
58
|
|
|
55
|
-
|
|
56
|
-
spinner.start('Creating project template')
|
|
59
|
+
function initializeProject() {
|
|
57
60
|
const gitCheckout = `git clone --depth 1 https://github.com/DarkidOP/Bunext.git ${repoName}`
|
|
58
|
-
const checkedOut = runCommand(gitCheckout)
|
|
59
|
-
if (!checkedOut) {
|
|
60
|
-
spinner.fail('Failed to clone template repository')
|
|
61
|
-
process.exit(1)
|
|
62
|
-
}
|
|
63
|
-
spinner.succeed(`Project template created in ./${repoName}`)
|
|
64
|
-
|
|
65
|
-
// Remove git
|
|
66
|
-
spinner.start('Removing Git history')
|
|
67
61
|
const removeGit = `cd ${repoName} && rm -rf .git`
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
process.exit(1)
|
|
72
|
-
}
|
|
73
|
-
spinner.succeed('Git history removed')
|
|
62
|
+
const initGit = `cd ${repoName} && git init && git add . && git commit -m "Initial commit"`
|
|
63
|
+
const openVSCode = `cd ${repoName} && code .`
|
|
64
|
+
const openCursor = `cd ${repoName} && cursor .`
|
|
74
65
|
|
|
75
|
-
//
|
|
66
|
+
// Determine package manager based on how script was executed
|
|
76
67
|
let packageManager = 'npm'
|
|
77
68
|
if (process.env.npm_execpath?.includes('pnpm')) {
|
|
78
69
|
packageManager = 'pnpm'
|
|
@@ -82,52 +73,54 @@ async function initializeProject() {
|
|
|
82
73
|
packageManager = 'bun'
|
|
83
74
|
}
|
|
84
75
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
76
|
+
const installDeps = `cd ${repoName} && ${packageManager}${packageManager === 'npm' ? ' install --legacy-peer-deps' : ' install'}`
|
|
77
|
+
|
|
78
|
+
console.log(`Creating project template in ./${repoName}`)
|
|
79
|
+
const checkedOut = runCommand(gitCheckout)
|
|
80
|
+
if (!checkedOut) {
|
|
81
|
+
console.error(
|
|
82
|
+
'Failed to clone template repository "https://github.com/DarkidOP/Bunext.git"'
|
|
83
|
+
)
|
|
93
84
|
process.exit(1)
|
|
94
85
|
}
|
|
95
|
-
spinner.succeed('Dependencies installed')
|
|
96
86
|
|
|
97
|
-
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
spinner.start('Initializing Git repository')
|
|
103
|
-
const gitInit = `cd ${repoName} && git init && git add . && git commit -m "Initial commit"`
|
|
104
|
-
const initializedGit = runCommand(gitInit)
|
|
105
|
-
if (!initializedGit) {
|
|
106
|
-
spinner.fail('Failed to initialize Git repository')
|
|
107
|
-
process.exit(1)
|
|
108
|
-
}
|
|
109
|
-
spinner.succeed('Git repository initialized')
|
|
87
|
+
console.log('Removing Git history...')
|
|
88
|
+
const removedGit = runCommand(removeGit)
|
|
89
|
+
if (!removedGit) {
|
|
90
|
+
console.error('Failed to remove Git history')
|
|
91
|
+
process.exit(1)
|
|
110
92
|
}
|
|
111
93
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
console.
|
|
116
|
-
|
|
117
|
-
runCommand(`cd ${repoName} && cursor .`)
|
|
118
|
-
console.log(`${colors.dim}Opening in Cursor...${colors.reset}`)
|
|
94
|
+
console.log('Installing dependencies...')
|
|
95
|
+
const installedDeps = runCommand(installDeps)
|
|
96
|
+
if (!installedDeps) {
|
|
97
|
+
console.error('Failed to install dependencies')
|
|
98
|
+
process.exit(1)
|
|
119
99
|
}
|
|
120
100
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
101
|
+
rl.question(
|
|
102
|
+
'Would you like to initialize a new git repository? (y/n) ',
|
|
103
|
+
(answer) => {
|
|
104
|
+
if (answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes') {
|
|
105
|
+
console.log('Initializing Git repository...')
|
|
106
|
+
const initializedGit = runCommand(initGit)
|
|
107
|
+
if (!initializedGit) {
|
|
108
|
+
console.error('Failed to initialize Git repository')
|
|
109
|
+
process.exit(1)
|
|
110
|
+
}
|
|
111
|
+
console.log('Git repository initialized successfully!')
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (useVSCode) {
|
|
115
|
+
console.log('Opening in Visual Studio Code...')
|
|
116
|
+
runCommand(openVSCode)
|
|
117
|
+
} else if (useCursor) {
|
|
118
|
+
console.log('Opening in Cursor...')
|
|
119
|
+
runCommand(openCursor)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
console.log('\nHappy coding! 🎉')
|
|
123
|
+
rl.close()
|
|
124
|
+
}
|
|
128
125
|
)
|
|
129
|
-
|
|
130
|
-
rl.close()
|
|
131
126
|
}
|
|
132
|
-
|
|
133
|
-
// Create utils.mjs for the spinner
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@ardly/bunext",
|
|
3
3
|
"description": "Bunext - A Next.js 15 template with Tailwind CSS, shadcn ui and Bun with some utilities built in",
|
|
4
4
|
"author": "Ard Astroid <ardastroid@gmail.com>",
|
|
5
|
-
"version": "1.0.
|
|
5
|
+
"version": "1.0.6",
|
|
6
6
|
"bin": "./bin/cli.mjs",
|
|
7
7
|
"keywords": [
|
|
8
8
|
"next.js",
|
package/bin/utils.mjs
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
const spinner = {
|
|
2
|
-
frames: ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'],
|
|
3
|
-
interval: 80,
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
export function createSpinner() {
|
|
7
|
-
let currentFrame = 0
|
|
8
|
-
let intervalId
|
|
9
|
-
let text = ''
|
|
10
|
-
|
|
11
|
-
return {
|
|
12
|
-
start(message) {
|
|
13
|
-
text = message
|
|
14
|
-
process.stdout.write('\x1b[?25l') // Hide cursor
|
|
15
|
-
intervalId = setInterval(() => {
|
|
16
|
-
const frame = spinner.frames[currentFrame]
|
|
17
|
-
process.stdout.write(`\r${frame} ${text}`)
|
|
18
|
-
currentFrame = (currentFrame + 1) % spinner.frames.length
|
|
19
|
-
}, spinner.interval)
|
|
20
|
-
},
|
|
21
|
-
succeed(message) {
|
|
22
|
-
clearInterval(intervalId)
|
|
23
|
-
process.stdout.write('\r✓ ' + (message || text) + '\n')
|
|
24
|
-
process.stdout.write('\x1b[?25h') // Show cursor
|
|
25
|
-
},
|
|
26
|
-
fail(message) {
|
|
27
|
-
clearInterval(intervalId)
|
|
28
|
-
process.stdout.write('\r✖ ' + (message || text) + '\n')
|
|
29
|
-
process.stdout.write('\x1b[?25h') // Show cursor
|
|
30
|
-
},
|
|
31
|
-
}
|
|
32
|
-
}
|