dappbooster 0.3.4 ā 2.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/.nvmrc +1 -0
- package/README.md +30 -3
- package/import/config.js +17 -0
- package/import/git.js +56 -0
- package/import/install.js +199 -0
- package/import/user-prompts.js +145 -0
- package/index.js +22 -147
- package/package.json +8 -8
package/.nvmrc
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
20
|
package/README.md
CHANGED
|
@@ -1,9 +1,36 @@
|
|
|
1
1
|
# dAppBooster starter
|
|
2
2
|
|
|
3
|
-
A script to clone dAppBooster and cleanup the history to freshly start your new project
|
|
3
|
+
A script to clone dAppBooster and cleanup the history to freshly start your new project.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Clones the latest tag from https://github.com/BootNodeDev/dAppBooster (so you might not see the last changes in `main`).
|
|
6
|
+
|
|
7
|
+
## Usage
|
|
8
|
+
|
|
9
|
+
```shell
|
|
10
|
+
$ pnpm dlx dappbooster <projectName>
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Development
|
|
14
|
+
|
|
15
|
+
Move into the script's folder and then
|
|
6
16
|
|
|
7
17
|
```shell
|
|
8
|
-
|
|
18
|
+
# Clone the repo
|
|
19
|
+
git clone git@github.com:BootNodeDev/dAppBooster-starter.git
|
|
20
|
+
|
|
21
|
+
# Install dependencies
|
|
22
|
+
pnpm i
|
|
23
|
+
|
|
24
|
+
# Move into the script's folder
|
|
25
|
+
cd dAppBooster-starter
|
|
9
26
|
```
|
|
27
|
+
|
|
28
|
+
The common loop for testing the script looks something like
|
|
29
|
+
|
|
30
|
+
```shell
|
|
31
|
+
# Test the script, creates a folder called test
|
|
32
|
+
$ node index.js test
|
|
33
|
+
|
|
34
|
+
# Remove the test directory (ignored in .gitignore)
|
|
35
|
+
$ rm -rf test
|
|
36
|
+
```
|
package/import/config.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export const repoUrl = 'https://github.com/BootNodeDev/dAppBooster.git'
|
|
2
|
+
export const homeFolder = '/src/components/pageComponents/home'
|
|
3
|
+
|
|
4
|
+
export const defaultExecOptions = {
|
|
5
|
+
stdio: 'pipe',
|
|
6
|
+
shell: true,
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const fileExecOptions = {
|
|
10
|
+
recursive: true,
|
|
11
|
+
force: true,
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const installPackageExecOptions = {
|
|
15
|
+
stdio: 'inherit',
|
|
16
|
+
shell: true,
|
|
17
|
+
}
|
package/import/git.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { execSync } from 'node:child_process'
|
|
2
|
+
import { rmSync } from 'node:fs'
|
|
3
|
+
import os from 'node:os'
|
|
4
|
+
import { join } from 'node:path'
|
|
5
|
+
import chalk from 'chalk'
|
|
6
|
+
import { defaultExecOptions, fileExecOptions, repoUrl } from './config.js'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @description Get the latest tag from the repository
|
|
10
|
+
* @returns {string} The latest tag
|
|
11
|
+
*/
|
|
12
|
+
function getLatestTag() {
|
|
13
|
+
const commandSilencer = os.platform() === 'win32' ? '> nul 2>&1' : '> /dev/null 2>&1'
|
|
14
|
+
|
|
15
|
+
execSync(`git fetch --tags ${commandSilencer}`, defaultExecOptions)
|
|
16
|
+
|
|
17
|
+
const tags = execSync('git tag -l --sort=-v:refname').toString().trim().split('\n')
|
|
18
|
+
|
|
19
|
+
return tags[0]
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @description Clone the repository
|
|
24
|
+
*/
|
|
25
|
+
export function cloneRepo(projectName) {
|
|
26
|
+
const projectDir = join(process.cwd(), projectName)
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
console.log(`Cloning dAppBooster in ${chalk.bold(`${projectName}`)}`)
|
|
30
|
+
execSync(`git clone --depth 1 --no-checkout "${repoUrl}" "${projectDir}"`, defaultExecOptions)
|
|
31
|
+
|
|
32
|
+
process.chdir(projectDir)
|
|
33
|
+
|
|
34
|
+
const latestTag = getLatestTag(defaultExecOptions)
|
|
35
|
+
|
|
36
|
+
if (latestTag) {
|
|
37
|
+
console.log(`Checking out latest tag`)
|
|
38
|
+
execSync(`git checkout "${latestTag}"`, defaultExecOptions)
|
|
39
|
+
} else {
|
|
40
|
+
console.log(`No tags found, checking out ${chalk.bold('main')} branch...`)
|
|
41
|
+
execSync('git checkout main', defaultExecOptions)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Remove .git, and initialize the repo
|
|
45
|
+
rmSync(join(projectDir, '.git'), fileExecOptions)
|
|
46
|
+
execSync('git init', defaultExecOptions)
|
|
47
|
+
|
|
48
|
+
console.log(`Repository cloned in ${chalk.bold(projectDir)}`)
|
|
49
|
+
console.log(`Version: ${latestTag ? chalk.bold(latestTag) : chalk.bold('main')}`)
|
|
50
|
+
} catch (error) {
|
|
51
|
+
console.error(`${chalk.bold.red('An error occurred:')}`, error.message)
|
|
52
|
+
process.exit(1)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
console.log('\n---\n')
|
|
56
|
+
}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { execSync } from 'node:child_process'
|
|
2
|
+
import { existsSync, readFileSync, rmSync, writeFileSync } from 'node:fs'
|
|
3
|
+
import { join } from 'node:path'
|
|
4
|
+
import chalk from 'chalk'
|
|
5
|
+
import { defaultExecOptions, fileExecOptions, homeFolder, installPackageExecOptions } from './config.js'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @description Create the .env.local file
|
|
9
|
+
*/
|
|
10
|
+
export function createEnvFile() {
|
|
11
|
+
const envFilePath = join(process.cwd(), '.env.local')
|
|
12
|
+
const exampleFilePath = join(process.cwd(), '.env.example')
|
|
13
|
+
|
|
14
|
+
execSync(`cp ${exampleFilePath} ${envFilePath}`, defaultExecOptions)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @description Install project packages, remove unwanted ones.
|
|
19
|
+
*/
|
|
20
|
+
export function installPackages(
|
|
21
|
+
demoSupport,
|
|
22
|
+
subgraphSupport,
|
|
23
|
+
typedocSupport,
|
|
24
|
+
vocsSupport,
|
|
25
|
+
huskySupport,
|
|
26
|
+
) {
|
|
27
|
+
const subgraphPackages = !subgraphSupport
|
|
28
|
+
? [
|
|
29
|
+
'@bootnodedev/db-subgraph',
|
|
30
|
+
'graphql graphql-request',
|
|
31
|
+
'@graphql-codegen/cli',
|
|
32
|
+
'@graphql-typed-document-node/core',
|
|
33
|
+
]
|
|
34
|
+
: []
|
|
35
|
+
const typedocPackages = !typedocSupport
|
|
36
|
+
? [
|
|
37
|
+
'typedoc',
|
|
38
|
+
'typedoc-github-theme',
|
|
39
|
+
'typedoc-plugin-inline-sources',
|
|
40
|
+
'typedoc-plugin-missing-exports',
|
|
41
|
+
'typedoc-plugin-rename-defaults',
|
|
42
|
+
]
|
|
43
|
+
: []
|
|
44
|
+
const vocsPackages = !vocsSupport ? ['vocs'] : []
|
|
45
|
+
const huskyPackages = !huskySupport
|
|
46
|
+
? ['husky', 'lint-staged', '@commitlint/cli', '@commitlint/config-conventional']
|
|
47
|
+
: []
|
|
48
|
+
|
|
49
|
+
const packagesToRemove = [
|
|
50
|
+
...subgraphPackages,
|
|
51
|
+
...typedocPackages,
|
|
52
|
+
...vocsPackages,
|
|
53
|
+
...huskyPackages,
|
|
54
|
+
]
|
|
55
|
+
|
|
56
|
+
console.log('\n---\n')
|
|
57
|
+
console.log(`Installing packages...`)
|
|
58
|
+
|
|
59
|
+
// Remove demo files
|
|
60
|
+
if (!demoSupport) {
|
|
61
|
+
demoFilesCleanup()
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
console.log('\n---\n')
|
|
65
|
+
|
|
66
|
+
if (!packagesToRemove.length) {
|
|
67
|
+
execSync('pnpm install --loglevel warn', installPackageExecOptions)
|
|
68
|
+
console.log('\n---\n')
|
|
69
|
+
} else {
|
|
70
|
+
// pnpm remove will install the necessary packages while uninstalling the unwanted ones...
|
|
71
|
+
execSync(`pnpm remove ${packagesToRemove.join(' ')} --loglevel warn`, installPackageExecOptions)
|
|
72
|
+
// ... but it won't run the post-install script, so we run it manually
|
|
73
|
+
execSync(`pnpm run postinstall`, installPackageExecOptions)
|
|
74
|
+
console.log('\n---\n')
|
|
75
|
+
|
|
76
|
+
// Remove package-related files and scripts
|
|
77
|
+
packageFilesCleanup(subgraphSupport, typedocSupport, vocsSupport, huskySupport)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Remove installer files
|
|
81
|
+
installFilesCleanup()
|
|
82
|
+
console.log('\n---\n')
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* @description Removes demo-related folders and files
|
|
87
|
+
*/
|
|
88
|
+
function demoFilesCleanup() {
|
|
89
|
+
const absoluteHomeFolder = join(process.cwd(), homeFolder)
|
|
90
|
+
|
|
91
|
+
console.log(`${chalk.bold.red('Removing')} demo list`)
|
|
92
|
+
|
|
93
|
+
rmSync(absoluteHomeFolder, fileExecOptions)
|
|
94
|
+
|
|
95
|
+
execSync(`mkdir -p ${absoluteHomeFolder}`, defaultExecOptions)
|
|
96
|
+
execSync(
|
|
97
|
+
`cp ${join(process.cwd(), '.install-files/home/index.tsx')} ${absoluteHomeFolder}`,
|
|
98
|
+
defaultExecOptions,
|
|
99
|
+
)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* @description Removes:
|
|
104
|
+
* - Subgraphs folder
|
|
105
|
+
* - Subgraph demos and references to them in the demos list
|
|
106
|
+
*/
|
|
107
|
+
function subgraphCleanup() {
|
|
108
|
+
const demoListFile = join(process.cwd(), `${homeFolder}/Examples/index.tsx`)
|
|
109
|
+
|
|
110
|
+
// Remove the root subgraphs folder
|
|
111
|
+
rmSync(join(process.cwd(), '/src/subgraphs'), fileExecOptions)
|
|
112
|
+
|
|
113
|
+
// Only remove the subgraph demos if the user kept the demo list
|
|
114
|
+
if (existsSync(demoListFile)) {
|
|
115
|
+
// Remove the subgraph demos
|
|
116
|
+
rmSync(join(process.cwd(), `${homeFolder}/Examples/demos/subgraphs`), fileExecOptions)
|
|
117
|
+
|
|
118
|
+
// Remove the list...
|
|
119
|
+
rmSync(demoListFile, { force: true })
|
|
120
|
+
|
|
121
|
+
// ... and replace it by the list with no subgraph demos
|
|
122
|
+
execSync(
|
|
123
|
+
`cp ${join(process.cwd(), `.install-files/home/Examples/index.tsx`)} ${demoListFile}`,
|
|
124
|
+
defaultExecOptions,
|
|
125
|
+
)
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* @description Removes typedoc files
|
|
131
|
+
*/
|
|
132
|
+
function typedocCleanup() {
|
|
133
|
+
rmSync(join(process.cwd(), 'typedoc.json'), fileExecOptions)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* @description Removes Vocs files
|
|
138
|
+
*/
|
|
139
|
+
function vocsCleanup() {
|
|
140
|
+
rmSync(join(process.cwd(), 'vocs.config.ts'), fileExecOptions)
|
|
141
|
+
rmSync(join(process.cwd(), 'docs'), fileExecOptions)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* @description Removes Husky files
|
|
146
|
+
*/
|
|
147
|
+
function huskyCleanup() {
|
|
148
|
+
rmSync(join(process.cwd(), '.lintstagedrc.mjs'), fileExecOptions)
|
|
149
|
+
rmSync(join(process.cwd(), 'commitlint.config.js'), fileExecOptions)
|
|
150
|
+
rmSync(join(process.cwd(), '.husky'), fileExecOptions)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* @description Removes the .install-files folder
|
|
155
|
+
*/
|
|
156
|
+
function installFilesCleanup() {
|
|
157
|
+
console.log(`${chalk.bold.red('Removing')} installer files`)
|
|
158
|
+
rmSync(join(process.cwd(), '.install-files'), fileExecOptions)
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* @description Cleans up the files associated with removed packages
|
|
163
|
+
*/
|
|
164
|
+
function packageFilesCleanup(subgraphSupport, typedocSupport, vocsSupport, huskySupport) {
|
|
165
|
+
const pkgPath = join(process.cwd(), 'package.json')
|
|
166
|
+
const pkgJson = JSON.parse(readFileSync(pkgPath, 'utf8'))
|
|
167
|
+
|
|
168
|
+
console.log(
|
|
169
|
+
`${chalk.bold.red('Removing')} files and scripts associated with uninstalled packages`,
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
// Remove everything subgraph-related
|
|
173
|
+
if (!subgraphSupport) {
|
|
174
|
+
subgraphCleanup()
|
|
175
|
+
pkgJson.scripts['subgraph-codegen'] = undefined
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Remove everything typedoc-related
|
|
179
|
+
if (!typedocSupport) {
|
|
180
|
+
typedocCleanup()
|
|
181
|
+
pkgJson.scripts['typedoc:build'] = undefined
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Remove everything vocs-related
|
|
185
|
+
if (!vocsSupport) {
|
|
186
|
+
vocsCleanup()
|
|
187
|
+
pkgJson.scripts['docs:build'] = undefined
|
|
188
|
+
pkgJson.scripts['docs:dev'] = undefined
|
|
189
|
+
pkgJson.scripts['docs:preview'] = undefined
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Remove everything husky-related
|
|
193
|
+
if (!huskySupport) {
|
|
194
|
+
huskyCleanup()
|
|
195
|
+
pkgJson.scripts['prepare'] = undefined
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
writeFileSync(pkgPath, `${JSON.stringify(pkgJson, null, 2)}\n`)
|
|
199
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { join } from 'node:path'
|
|
2
|
+
import readline from 'node:readline'
|
|
3
|
+
import chalk from 'chalk'
|
|
4
|
+
import { homeFolder } from './config.js'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @description Check if the project name is valid
|
|
8
|
+
*/
|
|
9
|
+
export function checkProjectName(name) {
|
|
10
|
+
const error = !name
|
|
11
|
+
? `
|
|
12
|
+
#################################################
|
|
13
|
+
# A directory name is mandatory. #
|
|
14
|
+
# #
|
|
15
|
+
# Letters (aāz, AāZ), numbers (0ā9), #
|
|
16
|
+
# hyphens (-), and underscores (_) are allowed. #
|
|
17
|
+
#################################################`
|
|
18
|
+
: !/^[a-zA-Z0-9-_]+$/.test(name)
|
|
19
|
+
? `
|
|
20
|
+
#################################################
|
|
21
|
+
# Invalid project name. #
|
|
22
|
+
# #
|
|
23
|
+
# Letters (aāz, AāZ), numbers (0ā9), #
|
|
24
|
+
# hyphens (-), and underscores (_) are allowed. #
|
|
25
|
+
#################################################`
|
|
26
|
+
: ''
|
|
27
|
+
|
|
28
|
+
if (error) {
|
|
29
|
+
console.error(`${chalk.red.bold(error.trim())}`)
|
|
30
|
+
process.exit(1)
|
|
31
|
+
} else {
|
|
32
|
+
return name.replace(/[^a-zA-Z0-9-_]/g, '-')
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @description Asks a question to the user
|
|
38
|
+
*/
|
|
39
|
+
function askQuestion(query) {
|
|
40
|
+
const rl = readline.createInterface({
|
|
41
|
+
input: process.stdin,
|
|
42
|
+
output: process.stdout,
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
return new Promise((resolve) => {
|
|
46
|
+
rl.question(query, (answer) => {
|
|
47
|
+
rl.close()
|
|
48
|
+
resolve(answer)
|
|
49
|
+
})
|
|
50
|
+
})
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* @description Asks the user for setup options
|
|
55
|
+
* @returns {Promise<{demoSupport: boolean, subgraphSupport: boolean, typedocSupport: boolean, vocsSupport: boolean, commitHookPackagesSupport: boolean}>}
|
|
56
|
+
*/
|
|
57
|
+
export async function installationSetup() {
|
|
58
|
+
const demoSupport =
|
|
59
|
+
(await askQuestion(`Keep the ${chalk.bold('home page demos')}? (Y/n) `)).toLowerCase() !== 'n'
|
|
60
|
+
|
|
61
|
+
const subgraphSupport =
|
|
62
|
+
(await askQuestion(`Keep ${chalk.bold('subgraph')} support? (Y/n) `)).toLowerCase() !== 'n'
|
|
63
|
+
|
|
64
|
+
const typedocSupport =
|
|
65
|
+
(
|
|
66
|
+
await askQuestion(
|
|
67
|
+
`Keep ${chalk.bold('Typedoc')} (converts TypeScript comments to HTML documentation) support? (Y/n) `,
|
|
68
|
+
)
|
|
69
|
+
).toLowerCase() !== 'n'
|
|
70
|
+
|
|
71
|
+
const vocsSupport =
|
|
72
|
+
(
|
|
73
|
+
await askQuestion(
|
|
74
|
+
`Keep ${chalk.bold('Vocs')} (static markdown documentation generation) support? (Y/n) `,
|
|
75
|
+
)
|
|
76
|
+
).toLowerCase() !== 'n'
|
|
77
|
+
|
|
78
|
+
const huskySupport =
|
|
79
|
+
(
|
|
80
|
+
await askQuestion(
|
|
81
|
+
`Keep ${chalk.bold('Husky')} (Git hooks) support? Note: removing this will also remove ${chalk.bold('lint-staged')} and ${chalk.bold('commitlint')} (Y/n) `,
|
|
82
|
+
)
|
|
83
|
+
).toLowerCase() !== 'n'
|
|
84
|
+
|
|
85
|
+
return {
|
|
86
|
+
demoSupport,
|
|
87
|
+
subgraphSupport,
|
|
88
|
+
typedocSupport,
|
|
89
|
+
vocsSupport,
|
|
90
|
+
huskySupport,
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* @description Prints instructions for subgraph support
|
|
96
|
+
*/
|
|
97
|
+
function subgraphInstructions() {
|
|
98
|
+
console.log(
|
|
99
|
+
`${chalk.yellow.bold('##################################################################################')}`,
|
|
100
|
+
)
|
|
101
|
+
console.log(
|
|
102
|
+
`${chalk.yellow.bold('# WARNING: Your project support subgraphs, before you continue you MUST: #')}`,
|
|
103
|
+
)
|
|
104
|
+
console.log(
|
|
105
|
+
`${chalk.yellow.bold('##################################################################################')}`,
|
|
106
|
+
)
|
|
107
|
+
console.log('')
|
|
108
|
+
console.log(
|
|
109
|
+
`1- Provide your own API key for the var ${chalk.bold('PUBLIC_SUBGRAPHS_API_KEY')} in ${chalk.italic('.env.local')}`,
|
|
110
|
+
)
|
|
111
|
+
console.log(
|
|
112
|
+
` You can get one at ${chalk.bold.underline('https://thegraph.com/studio/apikeys/')}`,
|
|
113
|
+
)
|
|
114
|
+
console.log(
|
|
115
|
+
`2- Run ${chalk.bold('pnpm subgraph-codegen')} in your console from the project's folder`,
|
|
116
|
+
)
|
|
117
|
+
console.log('')
|
|
118
|
+
console.log('Only after you followed these steps you may proceed.')
|
|
119
|
+
console.log('\n---\n')
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* @description Prints post-install instructions
|
|
124
|
+
*/
|
|
125
|
+
export function postInstallInstructions(subgraphSupport, projectName) {
|
|
126
|
+
console.log('To start development on your project:')
|
|
127
|
+
console.log('')
|
|
128
|
+
console.log('1- Move into the project directory')
|
|
129
|
+
console.log(chalk.cyan(`$ cd ${projectName}`))
|
|
130
|
+
console.log('')
|
|
131
|
+
console.log('2- Start the development server')
|
|
132
|
+
console.log(chalk.cyan('$ pnpm dev'))
|
|
133
|
+
console.log('')
|
|
134
|
+
console.log(
|
|
135
|
+
`You can edit the home page in ${chalk.bold(`${join(process.cwd(), homeFolder)}/index.tsx`)}`,
|
|
136
|
+
)
|
|
137
|
+
console.log('\n---\n')
|
|
138
|
+
console.log(`Check out ${chalk.bold('.env.local')} for more project configurations.`)
|
|
139
|
+
console.log(`Check out the docs at ${chalk.bold.underline('https://docs.dappbooster.dev/')}`)
|
|
140
|
+
console.log('\n---\n')
|
|
141
|
+
|
|
142
|
+
if (subgraphSupport) {
|
|
143
|
+
subgraphInstructions()
|
|
144
|
+
}
|
|
145
|
+
}
|
package/index.js
CHANGED
|
@@ -1,158 +1,33 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
import { createEnvFile, installPackages } from './import/install.js'
|
|
4
|
+
import { cloneRepo } from './import/git.js'
|
|
5
|
+
import {
|
|
6
|
+
checkProjectName,
|
|
7
|
+
installationSetup,
|
|
8
|
+
postInstallInstructions,
|
|
9
|
+
} from './import/user-prompts.js'
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const repoUrls = {
|
|
13
|
-
barebones: "https://github.com/BootNodeDev/dAppBooster.git",
|
|
14
|
-
example: "https://github.com/BootNodeDev/dAppBoosterLandingPage.git",
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
const projectName = process.argv[2];
|
|
18
|
-
|
|
19
|
-
// Check if the project name is valid
|
|
20
|
-
if (!projectName || !/^[a-zA-Z0-9-_]+$/.test(projectName)) {
|
|
21
|
-
console.error(`${chalk.red.bold("Invalid directory name. Please enter a valid project name.")}`);
|
|
22
|
-
process.exit(1);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// Prompt the user to select the repository type
|
|
26
|
-
promptUserForRepoType()
|
|
27
|
-
.then((repoType) => {
|
|
28
|
-
const repoUrl = repoUrls[repoType];
|
|
29
|
-
cloneRepo(projectName, repoUrl);
|
|
30
|
-
})
|
|
31
|
-
.catch((error) => {
|
|
32
|
-
console.error(chalk.red.bold("Error:"), error.message);
|
|
33
|
-
process.exit(1);
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* @description Prompt the user to select the repository type
|
|
38
|
-
* @returns {Promise<string>} The selected repository type
|
|
39
|
-
*/
|
|
40
|
-
function promptUserForRepoType() {
|
|
41
|
-
return new Promise((resolve, reject) => {
|
|
42
|
-
const rl = readline.createInterface({
|
|
43
|
-
input: process.stdin,
|
|
44
|
-
output: process.stdout,
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
rl.question(
|
|
48
|
-
`You can choose to start with a ${chalk.green.bold('Barebones')} project or a project with ${chalk.green.bold('Examples')} and demo code (B/e):`,
|
|
49
|
-
(answer) => {
|
|
50
|
-
rl.close();
|
|
51
|
-
const selection = answer.trim().toUpperCase();
|
|
52
|
-
if (selection === "B" || selection === "") {
|
|
53
|
-
resolve("barebones");
|
|
54
|
-
} else if (selection === "E") {
|
|
55
|
-
resolve("example");
|
|
56
|
-
} else {
|
|
57
|
-
reject(new Error("Invalid selection. Please choose B or E."));
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
);
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* @description Get the latest tag in the repository
|
|
66
|
-
* @param {Object} execOptions The options to pass to the exec
|
|
67
|
-
* @returns {string} The latest tag in the repository
|
|
68
|
-
*/
|
|
69
|
-
function getLatestTag(execOptions) {
|
|
70
|
-
// Fetch all tags
|
|
71
|
-
execSync(`git fetch --tags ${commandSilencer}`, execOptions);
|
|
72
|
-
|
|
73
|
-
// Get all tags, sorted by version
|
|
74
|
-
const tags = execSync("git tag -l --sort=-v:refname")
|
|
75
|
-
.toString()
|
|
76
|
-
.trim()
|
|
77
|
-
.split("\n");
|
|
78
|
-
|
|
79
|
-
// Return the first (latest) tag
|
|
80
|
-
return tags[0];
|
|
81
|
-
}
|
|
11
|
+
main().then(() => console.log('\nš»\n'))
|
|
82
12
|
|
|
83
13
|
/**
|
|
84
|
-
* @description
|
|
85
|
-
* @param {string} projectName The name of the project
|
|
86
|
-
* @param {string} repoUrl The URL of the repository
|
|
87
|
-
* @returns {void}
|
|
14
|
+
* @description Main entry point
|
|
88
15
|
*/
|
|
89
|
-
function
|
|
90
|
-
|
|
91
|
-
const
|
|
92
|
-
const execOptions = {
|
|
93
|
-
stdio: "pipe",
|
|
94
|
-
shell: true,
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
try {
|
|
98
|
-
console.log(`\nCloning dAppBooster...`);
|
|
99
|
-
|
|
100
|
-
// Clone the repository
|
|
101
|
-
execSync(
|
|
102
|
-
`git clone --depth 1 --no-checkout "${repoUrl}" "${projectDir}"`,
|
|
103
|
-
execOptions
|
|
104
|
-
);
|
|
105
|
-
|
|
106
|
-
// Change to the project directory
|
|
107
|
-
process.chdir(projectDir);
|
|
108
|
-
|
|
109
|
-
// Get the latest tag
|
|
110
|
-
const latestTag = getLatestTag();
|
|
111
|
-
|
|
112
|
-
if (latestTag) {
|
|
113
|
-
console.log(`Checking out latest tag: ${latestTag}`);
|
|
114
|
-
execSync(`git checkout "${latestTag}"`, execOptions);
|
|
115
|
-
} else {
|
|
116
|
-
console.log(`No tags found, checking out ${chalk.bold('main')} branch...`);
|
|
117
|
-
execSync("git checkout main", execOptions);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// Remove the .git directory
|
|
121
|
-
rmSync(join(projectDir, ".git"), { recursive: true, force: true });
|
|
122
|
-
|
|
123
|
-
// Initialize a new git repository
|
|
124
|
-
execSync("git init", execOptions);
|
|
125
|
-
|
|
126
|
-
// Success
|
|
127
|
-
console.log(`\ndAppBooster repository cloned in ${chalk.bold(projectDir)}`);
|
|
128
|
-
if (latestTag) {
|
|
129
|
-
console.log(`Latest version: ${chalk.bold(latestTag)}`);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
console.log(`\n---\n`);
|
|
133
|
-
// Some extra instructions for the user
|
|
134
|
-
console.log(`
|
|
135
|
-
${chalk.blue.bold("You can now start your project with the following commands:")}
|
|
136
|
-
|
|
137
|
-
${chalk.gray.italic("# Change to the project directory")}
|
|
138
|
-
$ ${chalk.cyan(`cd ${sanitizedProjectName}`)}
|
|
139
|
-
|
|
140
|
-
${chalk.gray.italic("# Install dependencies")}
|
|
141
|
-
$ ${chalk.cyan("pnpm install")}
|
|
142
|
-
|
|
143
|
-
${chalk.gray.italic("# Copy the example environment file")}
|
|
144
|
-
$ ${chalk.cyan("cp .env.example .env.local")}
|
|
16
|
+
async function main() {
|
|
17
|
+
// Check if the project name is valid
|
|
18
|
+
const projectName = checkProjectName(process.argv[2])
|
|
145
19
|
|
|
146
|
-
|
|
147
|
-
|
|
20
|
+
// Clone, create .env.local file
|
|
21
|
+
cloneRepo(projectName)
|
|
22
|
+
createEnvFile(projectName)
|
|
148
23
|
|
|
149
|
-
|
|
24
|
+
// Ask setup questions
|
|
25
|
+
const { demoSupport, subgraphSupport, typedocSupport, vocsSupport, huskySupport } =
|
|
26
|
+
await installationSetup()
|
|
150
27
|
|
|
151
|
-
|
|
28
|
+
// Install the required packages
|
|
29
|
+
installPackages(demoSupport, subgraphSupport, typedocSupport, vocsSupport, huskySupport)
|
|
152
30
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
console.error(`${chalk.bold.red("An error occurred:")}`, error.message);
|
|
156
|
-
process.exit(1);
|
|
157
|
-
}
|
|
31
|
+
// Tell the user what to do after installation is finished
|
|
32
|
+
postInstallInstructions(subgraphSupport, projectName)
|
|
158
33
|
}
|
package/package.json
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dappbooster",
|
|
3
|
-
"
|
|
3
|
+
"author": "bootnodedev",
|
|
4
|
+
"version": "2.0.1",
|
|
4
5
|
"description": "Script to easily start your project with dAppBooster",
|
|
5
6
|
"main": "index.js",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"engines": {
|
|
9
|
+
"node": ">=20.0.0"
|
|
10
|
+
},
|
|
6
11
|
"bin": {
|
|
7
12
|
"dappbooster": "index.js"
|
|
8
13
|
},
|
|
9
14
|
"type": "module",
|
|
10
|
-
"scripts": {
|
|
11
|
-
"test": "echo \"Error: no test specified\" && exit 1"
|
|
12
|
-
},
|
|
13
15
|
"dependencies": {
|
|
14
16
|
"chalk": "^5.3.0"
|
|
15
17
|
},
|
|
@@ -20,9 +22,7 @@
|
|
|
20
22
|
"installer",
|
|
21
23
|
"dapp"
|
|
22
24
|
],
|
|
23
|
-
"
|
|
24
|
-
|
|
25
|
-
"engines": {
|
|
26
|
-
"node": ">=20.0.0"
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"prettier": "^3.5.3"
|
|
27
27
|
}
|
|
28
28
|
}
|