@tukuyomil032/bricklayer 1.0.42 → 1.0.44
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/LICENSE +21 -0
- package/README.md +3 -3
- package/dist/create/file-writer.js +26 -12
- package/dist/create/index.js +4 -4
- package/dist/create/installer.js +21 -9
- package/dist/create/package-versions.js +3 -0
- package/dist/create/prompts.js +23 -6
- package/dist/create/templates.js +156 -67
- package/dist/index.js +1 -1
- package/dist/sample.js +1 -1
- package/package.json +10 -22
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 tukuyomil032
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -52,9 +52,9 @@ $ brick create -d ~/Documents/dev/CLI/my-test-project
|
|
|
52
52
|
|
|
53
53
|
## Available Options
|
|
54
54
|
|
|
55
|
-
-
|
|
56
|
-
-
|
|
57
|
-
-
|
|
55
|
+
- `-h --help` - display help for command
|
|
56
|
+
- `-V --version` - output the version number
|
|
57
|
+
- `-d --destination` - Specify the project creation directory
|
|
58
58
|
- This option can be used either to manually select the directory path where the project will be created, or to specify a relative path by entering it directly after “-d”.
|
|
59
59
|
|
|
60
60
|
Follow the interactive prompts to configure your project:
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import cliProgress from 'cli-progress';
|
|
1
2
|
import fs from 'fs/promises';
|
|
2
3
|
import path from 'path';
|
|
3
|
-
import cliProgress from 'cli-progress';
|
|
4
4
|
import * as templates from './templates.js';
|
|
5
5
|
export async function writeProjectFiles(targetDir, answers, versions) {
|
|
6
|
+
const useBiome = answers.linterFormatter === 'biome';
|
|
6
7
|
const progressBar = new cliProgress.SingleBar({
|
|
7
8
|
format: 'Creating files |{bar}| {percentage}% | {value}/{total} files',
|
|
8
9
|
barCompleteChar: '\u2588',
|
|
@@ -16,13 +17,18 @@ export async function writeProjectFiles(targetDir, answers, versions) {
|
|
|
16
17
|
'src/commands/hello.ts',
|
|
17
18
|
'README.md',
|
|
18
19
|
'.gitignore',
|
|
19
|
-
'.prettierignore',
|
|
20
20
|
'.npmignore',
|
|
21
21
|
'.editorconfig',
|
|
22
22
|
'LICENSE',
|
|
23
23
|
];
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
if (useBiome) {
|
|
25
|
+
tasks.push('biome.json');
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
tasks.push('.prettierignore');
|
|
29
|
+
tasks.push('.prettierrc');
|
|
30
|
+
tasks.push('eslint.config.js');
|
|
31
|
+
}
|
|
26
32
|
// Add .npmrc when using pnpm
|
|
27
33
|
const shouldAddNpmrc = answers.packageManager === 'pnpm';
|
|
28
34
|
if (shouldAddNpmrc) {
|
|
@@ -54,13 +60,15 @@ export async function writeProjectFiles(targetDir, answers, versions) {
|
|
|
54
60
|
await fs.writeFile(path.join(targetDir, '.gitignore'), templates.generateGitignore());
|
|
55
61
|
progressBar.update(++completed);
|
|
56
62
|
if (answers.useHusky) {
|
|
57
|
-
await fs.writeFile(path.join(targetDir, '.husky', 'pre-commit'), templates.generatePreCommitHook());
|
|
63
|
+
await fs.writeFile(path.join(targetDir, '.husky', 'pre-commit'), templates.generatePreCommitHook(answers.packageManager));
|
|
58
64
|
progressBar.update(++completed);
|
|
59
|
-
await fs.writeFile(path.join(targetDir, '.husky', 'pre-push'), templates.generatePrePushHook());
|
|
65
|
+
await fs.writeFile(path.join(targetDir, '.husky', 'pre-push'), templates.generatePrePushHook(answers.packageManager, answers.linterFormatter));
|
|
66
|
+
progressBar.update(++completed);
|
|
67
|
+
}
|
|
68
|
+
if (!useBiome) {
|
|
69
|
+
await fs.writeFile(path.join(targetDir, '.prettierignore'), templates.generatePrettierIgnore());
|
|
60
70
|
progressBar.update(++completed);
|
|
61
71
|
}
|
|
62
|
-
await fs.writeFile(path.join(targetDir, '.prettierignore'), templates.generatePrettierIgnore());
|
|
63
|
-
progressBar.update(++completed);
|
|
64
72
|
await fs.writeFile(path.join(targetDir, '.npmignore'), templates.generateNpmIgnore());
|
|
65
73
|
progressBar.update(++completed);
|
|
66
74
|
if (shouldAddNpmrc) {
|
|
@@ -72,10 +80,16 @@ export async function writeProjectFiles(targetDir, answers, versions) {
|
|
|
72
80
|
const licenseText = await templates.generateLicenseText(answers.license, answers.author, new Date().getFullYear());
|
|
73
81
|
await fs.writeFile(path.join(targetDir, 'LICENSE'), licenseText);
|
|
74
82
|
progressBar.update(++completed);
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
83
|
+
if (useBiome) {
|
|
84
|
+
await fs.writeFile(path.join(targetDir, 'biome.json'), templates.generateBiomeConfig());
|
|
85
|
+
progressBar.update(++completed);
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
await fs.writeFile(path.join(targetDir, '.prettierrc'), templates.generatePrettierConfig());
|
|
89
|
+
progressBar.update(++completed);
|
|
90
|
+
await fs.writeFile(path.join(targetDir, 'eslint.config.js'), templates.generateEslintConfig());
|
|
91
|
+
progressBar.update(++completed);
|
|
92
|
+
}
|
|
79
93
|
progressBar.stop();
|
|
80
94
|
console.log('');
|
|
81
95
|
}
|
package/dist/create/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import path from 'path';
|
|
2
|
-
import os from 'os';
|
|
3
1
|
import chalk from 'chalk';
|
|
4
|
-
import ora from 'ora';
|
|
5
2
|
import { Command } from 'commander';
|
|
6
|
-
import
|
|
3
|
+
import ora from 'ora';
|
|
4
|
+
import os from 'os';
|
|
5
|
+
import path from 'path';
|
|
7
6
|
import { writeProjectFiles } from './file-writer.js';
|
|
8
7
|
import { installDependencies } from './installer.js';
|
|
9
8
|
import { getLatestVersions } from './package-versions.js';
|
|
9
|
+
import { promptProjectDetails } from './prompts.js';
|
|
10
10
|
export function createCommand() {
|
|
11
11
|
const cmd = new Command('create');
|
|
12
12
|
cmd
|
package/dist/create/installer.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { exec as execCb, spawn } from 'child_process';
|
|
2
|
-
import { promisify } from 'util';
|
|
3
|
-
import ora from 'ora';
|
|
4
2
|
import cliProgress from 'cli-progress';
|
|
3
|
+
import ora from 'ora';
|
|
4
|
+
import { promisify } from 'util';
|
|
5
5
|
const exec = promisify(execCb);
|
|
6
6
|
const INSTALL_COMMANDS = {
|
|
7
7
|
npm: 'npm install',
|
|
@@ -89,7 +89,9 @@ function runCommandWithProgress(command, cwd) {
|
|
|
89
89
|
try {
|
|
90
90
|
bar.update(floor);
|
|
91
91
|
}
|
|
92
|
-
catch {
|
|
92
|
+
catch {
|
|
93
|
+
// Ignore update errors during progress
|
|
94
|
+
}
|
|
93
95
|
}
|
|
94
96
|
}, tickInterval);
|
|
95
97
|
const child = spawn(parts[0], parts.slice(1), { cwd, stdio: ['ignore', 'pipe', 'pipe'] });
|
|
@@ -109,25 +111,31 @@ function runCommandWithProgress(command, cwd) {
|
|
|
109
111
|
try {
|
|
110
112
|
bar.update(floor);
|
|
111
113
|
}
|
|
112
|
-
catch {
|
|
114
|
+
catch {
|
|
115
|
+
// Ignore update errors
|
|
116
|
+
}
|
|
113
117
|
}
|
|
114
118
|
};
|
|
115
|
-
if (child.stdout)
|
|
119
|
+
if (child.stdout) {
|
|
116
120
|
child.stdout.on('data', (c) => {
|
|
117
121
|
stdoutChunks.push(Buffer.from(c));
|
|
118
122
|
onOutput();
|
|
119
123
|
});
|
|
120
|
-
|
|
124
|
+
}
|
|
125
|
+
if (child.stderr) {
|
|
121
126
|
child.stderr.on('data', (c) => {
|
|
122
127
|
stderrChunks.push(Buffer.from(c));
|
|
123
128
|
onOutput();
|
|
124
129
|
});
|
|
130
|
+
}
|
|
125
131
|
child.on('error', (err) => {
|
|
126
132
|
clearInterval(timer);
|
|
127
133
|
try {
|
|
128
134
|
bar.stop();
|
|
129
135
|
}
|
|
130
|
-
catch {
|
|
136
|
+
catch {
|
|
137
|
+
// Ignore stop errors
|
|
138
|
+
}
|
|
131
139
|
reject(err);
|
|
132
140
|
});
|
|
133
141
|
child.on('close', (code) => {
|
|
@@ -140,7 +148,9 @@ function runCommandWithProgress(command, cwd) {
|
|
|
140
148
|
bar.update(100);
|
|
141
149
|
bar.stop();
|
|
142
150
|
}
|
|
143
|
-
catch {
|
|
151
|
+
catch {
|
|
152
|
+
// Ignore final update errors
|
|
153
|
+
}
|
|
144
154
|
clearInterval(finishTimer);
|
|
145
155
|
if (code === 0) {
|
|
146
156
|
return resolve();
|
|
@@ -157,7 +167,9 @@ function runCommandWithProgress(command, cwd) {
|
|
|
157
167
|
try {
|
|
158
168
|
bar.update(floor);
|
|
159
169
|
}
|
|
160
|
-
catch {
|
|
170
|
+
catch {
|
|
171
|
+
// Ignore update errors
|
|
172
|
+
}
|
|
161
173
|
}
|
|
162
174
|
}, finishInterval);
|
|
163
175
|
});
|
|
@@ -25,6 +25,7 @@ export async function getLatestVersions() {
|
|
|
25
25
|
'ts-node',
|
|
26
26
|
'husky',
|
|
27
27
|
'@types/node',
|
|
28
|
+
'@types/cli-progress',
|
|
28
29
|
'eslint',
|
|
29
30
|
'eslint-config-prettier',
|
|
30
31
|
'eslint-plugin-prettier',
|
|
@@ -33,10 +34,12 @@ export async function getLatestVersions() {
|
|
|
33
34
|
'typescript-eslint',
|
|
34
35
|
'@eslint/json',
|
|
35
36
|
'prettier',
|
|
37
|
+
'@biomejs/biome',
|
|
36
38
|
'lint-staged',
|
|
37
39
|
'commander',
|
|
38
40
|
'inquirer',
|
|
39
41
|
'chalk',
|
|
42
|
+
'cli-progress',
|
|
40
43
|
'ora',
|
|
41
44
|
'yargs',
|
|
42
45
|
'pnpm',
|
package/dist/create/prompts.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import inquirer from 'inquirer';
|
|
2
|
-
import Enquirer from 'enquirer';
|
|
3
|
-
const Select = Enquirer.Select || Enquirer.default?.Select;
|
|
4
|
-
const Input = Enquirer.Input || Enquirer.default?.Input;
|
|
5
1
|
import chalk from 'chalk';
|
|
6
|
-
import
|
|
2
|
+
import Enquirer from 'enquirer';
|
|
7
3
|
import fs from 'fs';
|
|
4
|
+
import inquirer from 'inquirer';
|
|
8
5
|
import path from 'path';
|
|
6
|
+
import readline from 'readline';
|
|
7
|
+
const enquirerModule = Enquirer;
|
|
8
|
+
const Select = enquirerModule.Select || enquirerModule.default?.Select;
|
|
9
|
+
const Input = enquirerModule.Input || enquirerModule.default?.Input;
|
|
9
10
|
export async function promptProjectDetails(opts = {}) {
|
|
10
11
|
const questions = [
|
|
11
12
|
{
|
|
@@ -28,6 +29,16 @@ export async function promptProjectDetails(opts = {}) {
|
|
|
28
29
|
choices: ['npm', 'pnpm', 'yarn', 'bun'],
|
|
29
30
|
default: 'npm',
|
|
30
31
|
},
|
|
32
|
+
{
|
|
33
|
+
type: 'list',
|
|
34
|
+
name: 'linterFormatter',
|
|
35
|
+
message: 'Linter / formatter setup:',
|
|
36
|
+
choices: [
|
|
37
|
+
{ name: 'ESLint + Prettier', value: 'eslint+prettier' },
|
|
38
|
+
{ name: 'Biome', value: 'biome' },
|
|
39
|
+
],
|
|
40
|
+
default: 'eslint+prettier',
|
|
41
|
+
},
|
|
31
42
|
{
|
|
32
43
|
type: 'confirm',
|
|
33
44
|
name: 'autoInstall',
|
|
@@ -90,9 +101,12 @@ export async function promptProjectDetails(opts = {}) {
|
|
|
90
101
|
const answers = {};
|
|
91
102
|
console.log('');
|
|
92
103
|
const uiWith = inquirer;
|
|
104
|
+
const noop = () => {
|
|
105
|
+
// Intentionally no-op when BottomBar UI is unavailable.
|
|
106
|
+
};
|
|
93
107
|
const bottomBar = uiWith.ui && uiWith.ui.BottomBar
|
|
94
108
|
? new uiWith.ui.BottomBar()
|
|
95
|
-
: { updateBottomBar:
|
|
109
|
+
: { updateBottomBar: noop, close: noop };
|
|
96
110
|
const updateProgress = (n) => {
|
|
97
111
|
const progressLine = `Project Scaffolding Progress: [${n}/${totalQuestions}]`;
|
|
98
112
|
try {
|
|
@@ -134,6 +148,9 @@ export async function promptProjectDetails(opts = {}) {
|
|
|
134
148
|
choices.forEach((c) => {
|
|
135
149
|
c.display = `◯ ${c.display}`;
|
|
136
150
|
});
|
|
151
|
+
if (!Select || !Input) {
|
|
152
|
+
throw new Error('Enquirer Select/Input could not be resolved from the enquirer module.');
|
|
153
|
+
}
|
|
137
154
|
const select = new Select({
|
|
138
155
|
name: 'dir',
|
|
139
156
|
message: `destination: (navigate folders, Enter to choose)`,
|
package/dist/create/templates.js
CHANGED
|
@@ -153,14 +153,22 @@ const staticTemplates = {
|
|
|
153
153
|
],
|
|
154
154
|
};
|
|
155
155
|
const hooksTemplates = {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
'',
|
|
161
|
-
|
|
162
|
-
|
|
156
|
+
pnpm: {
|
|
157
|
+
'pre-commit': ['#!/bin/sh', '. "$(dirname "$0")/_/husky.sh"', '', 'pnpm run lint-staged'],
|
|
158
|
+
},
|
|
159
|
+
npm: {
|
|
160
|
+
'pre-commit': ['#!/bin/sh', '. "$(dirname "$0")/_/husky.sh"', '', 'npm run lint-staged'],
|
|
161
|
+
},
|
|
162
|
+
yarn: {
|
|
163
|
+
'pre-commit': ['#!/bin/sh', '. "$(dirname "$0")/_/husky.sh"', '', 'yarn lint-staged'],
|
|
164
|
+
},
|
|
165
|
+
bun: {
|
|
166
|
+
'pre-commit': ['#!/bin/sh', '. "$(dirname "$0")/_/husky.sh"', '', 'bun run lint-staged'],
|
|
167
|
+
},
|
|
163
168
|
};
|
|
169
|
+
function isBiomeSetup(answers) {
|
|
170
|
+
return answers.linterFormatter === 'biome';
|
|
171
|
+
}
|
|
164
172
|
// Generate scripts object with OS-specific postbuild handling
|
|
165
173
|
function generateScriptsWithPermissions(baseScripts) {
|
|
166
174
|
// Add postbuild script to handle file permissions across platforms
|
|
@@ -173,22 +181,28 @@ function generateScriptsWithPermissions(baseScripts) {
|
|
|
173
181
|
}
|
|
174
182
|
// license texts are provided from src/create/licenses.ts
|
|
175
183
|
export function generatePackageJson(answers, versions) {
|
|
184
|
+
const useBiome = isBiomeSetup(answers);
|
|
176
185
|
const devDeps = {
|
|
177
186
|
typescript: versions?.['typescript'] || '^5.7.2',
|
|
178
187
|
'ts-node': versions?.['ts-node'] || '^10.9.1',
|
|
179
188
|
'@types/node': versions?.['@types/node'] || '^22.10.5',
|
|
189
|
+
'@types/cli-progress': versions?.['@types/cli-progress'] || '^3.11.6',
|
|
180
190
|
'lint-staged': versions?.['lint-staged'] || '^15.2.11',
|
|
181
191
|
};
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
versions?.['
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
+
if (useBiome) {
|
|
193
|
+
devDeps['@biomejs/biome'] = versions?.['@biomejs/biome'] || '^1.9.4';
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
devDeps['eslint'] = versions?.['eslint'] || '^9.39.2';
|
|
197
|
+
devDeps['eslint-config-prettier'] = versions?.['eslint-config-prettier'] || '^10.1.8';
|
|
198
|
+
devDeps['eslint-plugin-prettier'] = versions?.['eslint-plugin-prettier'] || '^5.5.4';
|
|
199
|
+
devDeps['@typescript-eslint/parser'] = versions?.['@typescript-eslint/parser'] || '^8.52.0';
|
|
200
|
+
devDeps['@typescript-eslint/eslint-plugin'] =
|
|
201
|
+
versions?.['@typescript-eslint/eslint-plugin'] || '^8.52.0';
|
|
202
|
+
devDeps['typescript-eslint'] = versions?.['typescript-eslint'] || '^8.52.0';
|
|
203
|
+
devDeps['@eslint/json'] = versions?.['@eslint/json'] || '^0.1.1';
|
|
204
|
+
devDeps['prettier'] = versions?.['prettier'] || '^3.7.4';
|
|
205
|
+
}
|
|
192
206
|
// Husky should only be added when requested (useHusky)
|
|
193
207
|
if (answers.useHusky) {
|
|
194
208
|
devDeps['husky'] = versions?.['husky'] || '^9.1.7';
|
|
@@ -197,6 +211,7 @@ export function generatePackageJson(answers, versions) {
|
|
|
197
211
|
commander: versions?.['commander'] || '^11.1.0',
|
|
198
212
|
inquirer: versions?.['inquirer'] || '^9.0.0',
|
|
199
213
|
chalk: versions?.['chalk'] || '^5.3.0',
|
|
214
|
+
'cli-progress': versions?.['cli-progress'] || '^3.12.0',
|
|
200
215
|
ora: versions?.['ora'] || '^8.1.1',
|
|
201
216
|
yargs: versions?.['yargs'] || '^18.0.0',
|
|
202
217
|
};
|
|
@@ -208,20 +223,52 @@ export function generatePackageJson(answers, versions) {
|
|
|
208
223
|
bun: versions?.['bun'] || '1.3.6',
|
|
209
224
|
};
|
|
210
225
|
function exactVersion(v) {
|
|
211
|
-
if (!v)
|
|
226
|
+
if (!v) {
|
|
212
227
|
return v;
|
|
228
|
+
}
|
|
213
229
|
const m = v.match(/\d+\.\d+\.\d+/);
|
|
214
230
|
return m ? m[0] : v.replace(/^[^\d]*/, '');
|
|
215
231
|
}
|
|
216
232
|
function buildCmdForManager(m) {
|
|
217
|
-
if (m === 'yarn')
|
|
233
|
+
if (m === 'yarn') {
|
|
218
234
|
return 'yarn build';
|
|
219
|
-
|
|
235
|
+
}
|
|
236
|
+
if (m === 'bun') {
|
|
220
237
|
return 'bun run build';
|
|
238
|
+
}
|
|
221
239
|
return `${m} run build`;
|
|
222
240
|
}
|
|
223
241
|
// When Husky is enabled, keep prepare as just 'husky' (user requested).
|
|
224
242
|
const prepareScript = answers.useHusky ? 'husky' : buildCmdForManager(mgr);
|
|
243
|
+
const baseScripts = {
|
|
244
|
+
build: 'tsc -p tsconfig.json',
|
|
245
|
+
prepare: prepareScript,
|
|
246
|
+
prepublishOnly: buildCmdForManager(mgr),
|
|
247
|
+
dev: 'ts-node --esm src/index.ts',
|
|
248
|
+
start: 'node dist/index.js',
|
|
249
|
+
typecheck: 'tsc --noEmit',
|
|
250
|
+
'lint-staged': 'lint-staged',
|
|
251
|
+
};
|
|
252
|
+
const lintScripts = useBiome
|
|
253
|
+
? {
|
|
254
|
+
format: 'biome format --write .',
|
|
255
|
+
lint: 'biome lint --write .',
|
|
256
|
+
'biome:check': 'biome check .',
|
|
257
|
+
'biome:fix': 'biome check . --write',
|
|
258
|
+
}
|
|
259
|
+
: {
|
|
260
|
+
lint: 'eslint "src/**/*.ts"',
|
|
261
|
+
'lint:fix': 'eslint "src/**/*.ts" --fix',
|
|
262
|
+
format: 'prettier --write "src/**/*.ts"',
|
|
263
|
+
'format:check': 'prettier --check "src/**/*.ts"',
|
|
264
|
+
};
|
|
265
|
+
const lintStagedConfig = useBiome
|
|
266
|
+
? {
|
|
267
|
+
'*.{js,jsx,ts,tsx,json,jsonc,md}': ['biome check --write'],
|
|
268
|
+
}
|
|
269
|
+
: {
|
|
270
|
+
'*.ts': ['eslint --fix', 'prettier --write'],
|
|
271
|
+
};
|
|
225
272
|
return {
|
|
226
273
|
name: answers.npmPackageName || answers.name,
|
|
227
274
|
private: false,
|
|
@@ -234,19 +281,10 @@ export function generatePackageJson(answers, versions) {
|
|
|
234
281
|
[answers.name]: './dist/index.js',
|
|
235
282
|
},
|
|
236
283
|
files: ['dist', 'README.md'],
|
|
237
|
-
scripts: generateScriptsWithPermissions(
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
dev: 'ts-node --esm src/index.ts',
|
|
242
|
-
start: 'node dist/index.js',
|
|
243
|
-
typecheck: 'tsc --noEmit',
|
|
244
|
-
lint: 'eslint "src/**/*.ts"',
|
|
245
|
-
'lint:fix': 'eslint "src/**/*.ts" --fix',
|
|
246
|
-
'lint-staged': 'lint-staged',
|
|
247
|
-
format: 'prettier --write "src/**/*.ts"',
|
|
248
|
-
'format:check': 'prettier --check "src/**/*.ts"',
|
|
249
|
-
}, answers.useHusky ? {} : {})),
|
|
284
|
+
scripts: generateScriptsWithPermissions({
|
|
285
|
+
...baseScripts,
|
|
286
|
+
...lintScripts,
|
|
287
|
+
}),
|
|
250
288
|
keywords: ['cli', 'scaffold', 'typescript', 'generator'],
|
|
251
289
|
author: answers.author,
|
|
252
290
|
license: answers.license,
|
|
@@ -260,9 +298,7 @@ export function generatePackageJson(answers, versions) {
|
|
|
260
298
|
homepage: `https://github.com/${answers.gitOwner}/${answers.gitRepo}#readme`,
|
|
261
299
|
dependencies: deps,
|
|
262
300
|
devDependencies: devDeps,
|
|
263
|
-
'lint-staged':
|
|
264
|
-
'*.ts': ['eslint --fix', 'prettier --write'],
|
|
265
|
-
},
|
|
301
|
+
'lint-staged': lintStagedConfig,
|
|
266
302
|
packageManager: `${mgr}@${exactVersion(pkgManagerVersions[mgr] || '10.27.0')}`,
|
|
267
303
|
};
|
|
268
304
|
}
|
|
@@ -321,14 +357,29 @@ export function generateGitignore() {
|
|
|
321
357
|
? staticTemplates.gitignore.join('\n')
|
|
322
358
|
: staticTemplates.gitignore;
|
|
323
359
|
}
|
|
324
|
-
|
|
325
|
-
const
|
|
326
|
-
|
|
360
|
+
function pickManagerKey(mgr) {
|
|
361
|
+
const m = (mgr || 'pnpm').toLowerCase();
|
|
362
|
+
if (m === 'npm' || m === 'yarn' || m === 'bun' || m === 'pnpm')
|
|
363
|
+
return m;
|
|
364
|
+
return 'pnpm';
|
|
327
365
|
}
|
|
328
|
-
export function
|
|
329
|
-
const
|
|
366
|
+
export function generatePreCommitHook(packageManager) {
|
|
367
|
+
const key = pickManagerKey(packageManager);
|
|
368
|
+
const hook = hooksTemplates[key]['pre-commit'];
|
|
330
369
|
return Array.isArray(hook) ? hook.join('\n') : hook;
|
|
331
370
|
}
|
|
371
|
+
export function generatePrePushHook(packageManager, linterFormatter = 'eslint+prettier') {
|
|
372
|
+
const key = pickManagerKey(packageManager);
|
|
373
|
+
const runScript = key === 'yarn'
|
|
374
|
+
? (script) => `yarn ${script}`
|
|
375
|
+
: key === 'bun'
|
|
376
|
+
? (script) => `bun run ${script}`
|
|
377
|
+
: (script) => `${key} run ${script}`;
|
|
378
|
+
const checkCommand = linterFormatter === 'biome'
|
|
379
|
+
? 'pnpm run biome:check'
|
|
380
|
+
: `${runScript('lint')} && ${runScript('format:check')}`;
|
|
381
|
+
return ['#!/bin/sh', '. "$(dirname "$0")/_/husky.sh"', '', checkCommand].join('\n');
|
|
382
|
+
}
|
|
332
383
|
export function generatePrettierConfig() {
|
|
333
384
|
return `{
|
|
334
385
|
"semi": true,
|
|
@@ -363,47 +414,84 @@ export function generateEditorConfig() {
|
|
|
363
414
|
: staticTemplates.editorconfig;
|
|
364
415
|
}
|
|
365
416
|
export function generateEslintConfig() {
|
|
366
|
-
return `import
|
|
367
|
-
import
|
|
368
|
-
import
|
|
369
|
-
import
|
|
417
|
+
return `import eslint from '@eslint/js';
|
|
418
|
+
import tseslint from '@typescript-eslint/eslint-plugin';
|
|
419
|
+
import tsparser from '@typescript-eslint/parser';
|
|
420
|
+
import prettier from 'eslint-plugin-prettier';
|
|
421
|
+
import prettierConfig from 'eslint-config-prettier';
|
|
370
422
|
|
|
371
423
|
export default [
|
|
424
|
+
eslint.configs.recommended,
|
|
372
425
|
{
|
|
373
|
-
|
|
374
|
-
},
|
|
375
|
-
|
|
376
|
-
{
|
|
377
|
-
files: ['**/*.{js,mjs,cjs}'],
|
|
378
|
-
languageOptions: {
|
|
379
|
-
globals: globals.node,
|
|
380
|
-
},
|
|
381
|
-
...js.configs.recommended,
|
|
382
|
-
},
|
|
383
|
-
|
|
384
|
-
{
|
|
385
|
-
files: ['**/*.{ts,mts,cts}'],
|
|
426
|
+
files: ['src/**/*.ts'],
|
|
386
427
|
languageOptions: {
|
|
387
|
-
|
|
388
|
-
|
|
428
|
+
parser: tsparser,
|
|
429
|
+
parserOptions: {
|
|
430
|
+
ecmaVersion: 'latest',
|
|
431
|
+
sourceType: 'module',
|
|
432
|
+
project: './tsconfig.json',
|
|
433
|
+
},
|
|
434
|
+
globals: {
|
|
435
|
+
console: 'readonly',
|
|
436
|
+
process: 'readonly',
|
|
437
|
+
Buffer: 'readonly',
|
|
438
|
+
__dirname: 'readonly',
|
|
439
|
+
__filename: 'readonly',
|
|
440
|
+
},
|
|
389
441
|
},
|
|
390
442
|
plugins: {
|
|
391
|
-
'@typescript-eslint': tseslint
|
|
443
|
+
'@typescript-eslint': tseslint,
|
|
444
|
+
prettier: prettier,
|
|
392
445
|
},
|
|
393
446
|
rules: {
|
|
394
447
|
...tseslint.configs.recommended.rules,
|
|
448
|
+
...prettierConfig.rules,
|
|
449
|
+
'prettier/prettier': 'error',
|
|
450
|
+
'@typescript-eslint/no-unused-vars': [
|
|
451
|
+
'error',
|
|
452
|
+
{
|
|
453
|
+
argsIgnorePattern: '^_',
|
|
454
|
+
varsIgnorePattern: '^_',
|
|
455
|
+
},
|
|
456
|
+
],
|
|
457
|
+
'@typescript-eslint/explicit-function-return-type': 'off',
|
|
458
|
+
'@typescript-eslint/no-explicit-any': 'warn',
|
|
459
|
+
'no-console': 'off',
|
|
395
460
|
},
|
|
396
461
|
},
|
|
397
|
-
|
|
398
462
|
{
|
|
399
|
-
|
|
400
|
-
language: 'json/json',
|
|
401
|
-
plugins: { json },
|
|
402
|
-
...json.configs.recommended,
|
|
463
|
+
ignores: ['dist/**', 'node_modules/**', '*.js'],
|
|
403
464
|
},
|
|
404
465
|
];
|
|
405
466
|
`;
|
|
406
467
|
}
|
|
468
|
+
export function generateBiomeConfig() {
|
|
469
|
+
const config = {
|
|
470
|
+
$schema: 'https://biomejs.dev/schemas/1.9.4/schema.json',
|
|
471
|
+
formatter: {
|
|
472
|
+
enabled: true,
|
|
473
|
+
indentStyle: 'space',
|
|
474
|
+
indentWidth: 2,
|
|
475
|
+
lineWidth: 100,
|
|
476
|
+
},
|
|
477
|
+
linter: {
|
|
478
|
+
enabled: true,
|
|
479
|
+
rules: {
|
|
480
|
+
recommended: true,
|
|
481
|
+
},
|
|
482
|
+
},
|
|
483
|
+
javascript: {
|
|
484
|
+
formatter: {
|
|
485
|
+
semicolons: 'always',
|
|
486
|
+
quoteStyle: 'single',
|
|
487
|
+
},
|
|
488
|
+
},
|
|
489
|
+
files: {
|
|
490
|
+
ignore: ['dist', 'node_modules'],
|
|
491
|
+
},
|
|
492
|
+
};
|
|
493
|
+
return `${JSON.stringify(config, null, 2)}\n`;
|
|
494
|
+
}
|
|
407
495
|
export async function generateLicenseText(license, author, year) {
|
|
408
496
|
// Try reading per-license text files (more readable than JSON storage)
|
|
409
497
|
const keyMap = {
|
|
@@ -417,8 +505,9 @@ export async function generateLicenseText(license, author, year) {
|
|
|
417
505
|
};
|
|
418
506
|
const key = keyMap[license] || 'MIT';
|
|
419
507
|
const textTemplate = (LICENSE_TEXTS && LICENSE_TEXTS[key]) || '';
|
|
420
|
-
if (!textTemplate)
|
|
508
|
+
if (!textTemplate) {
|
|
421
509
|
return `MIT License\n\nCopyright (c) ${year} ${author}`;
|
|
510
|
+
}
|
|
422
511
|
// Common placeholder patterns to replace in license text files.
|
|
423
512
|
// Support multiple variants users may paste: [year], <YEAR>, {{year}}, {yyyy}, etc.
|
|
424
513
|
const yearRegex = /\[year\]|\{yyyy\}|<year>|\{\{year\}\}|\[YEAR\]|<YEAR>|\{YEAR\}/gi;
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ const program = new Command();
|
|
|
5
5
|
program
|
|
6
6
|
.name('brick')
|
|
7
7
|
.description('Interactive CLI to scaffold TypeScript CLI projects')
|
|
8
|
-
.version('1.0.
|
|
8
|
+
.version('1.0.6');
|
|
9
9
|
program.addCommand(createCommand());
|
|
10
10
|
program.addCommand(sampleCommand());
|
|
11
11
|
program.parseAsync(process.argv).catch((err) => {
|
package/dist/sample.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tukuyomil032/bricklayer",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.44",
|
|
5
5
|
"description": "Interactive TypeScript CLI project scaffolder",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./dist/index.js",
|
|
@@ -18,14 +18,12 @@
|
|
|
18
18
|
"postbuild": "node -e \"require('fs').chmodSync('dist/index.js', 0o755)\"",
|
|
19
19
|
"prepare": "husky",
|
|
20
20
|
"prepublishOnly": "pnpm run build",
|
|
21
|
-
"dev": "
|
|
22
|
-
"start": "node dist/index.js",
|
|
21
|
+
"dev": "node dist/index.js",
|
|
23
22
|
"typecheck": "tsc --noEmit",
|
|
24
|
-
"
|
|
25
|
-
"lint
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"format:check": "prettier --check \"src/**/*.ts\""
|
|
23
|
+
"format": "biome format --write",
|
|
24
|
+
"lint": "biome lint --write",
|
|
25
|
+
"biome:check": "biome check",
|
|
26
|
+
"lint-staged": "lint-staged"
|
|
29
27
|
},
|
|
30
28
|
"keywords": [
|
|
31
29
|
"cli",
|
|
@@ -47,36 +45,26 @@
|
|
|
47
45
|
"chalk": "^5.3.0",
|
|
48
46
|
"cli-progress": "^3.12.0",
|
|
49
47
|
"commander": "^11.1.0",
|
|
50
|
-
"consola": "^3.4.2",
|
|
51
48
|
"enquirer": "^2.4.1",
|
|
52
49
|
"inquirer": "^9.2.11",
|
|
53
|
-
"ora": "^8.1.1"
|
|
54
|
-
"yargs": "^18.0.0"
|
|
50
|
+
"ora": "^8.1.1"
|
|
55
51
|
},
|
|
56
52
|
"devDependencies": {
|
|
57
|
-
"@
|
|
58
|
-
"@eslint/json": "^0.14.0",
|
|
53
|
+
"@biomejs/biome": "2.4.9",
|
|
59
54
|
"@types/cli-progress": "^3.11.6",
|
|
60
55
|
"@types/inquirer": "^9.0.9",
|
|
61
56
|
"@types/node": "^22.10.5",
|
|
62
|
-
"@types/yargs": "^17.0.35",
|
|
63
|
-
"@typescript-eslint/eslint-plugin": "^8.52.0",
|
|
64
|
-
"@typescript-eslint/parser": "^8.52.0",
|
|
65
|
-
"eslint": "^9.39.2",
|
|
66
|
-
"eslint-config-prettier": "^10.1.8",
|
|
67
|
-
"eslint-plugin-prettier": "^5.5.4",
|
|
68
57
|
"globals": "^17.1.0",
|
|
69
58
|
"husky": "^9.1.7",
|
|
70
59
|
"lint-staged": "^16.2.7",
|
|
71
|
-
"prettier": "^3.7.4",
|
|
72
60
|
"ts-node": "^10.9.1",
|
|
73
61
|
"typescript": "^5.7.2",
|
|
74
62
|
"typescript-eslint": "^8.53.1"
|
|
75
63
|
},
|
|
76
64
|
"lint-staged": {
|
|
77
65
|
"*.ts": [
|
|
78
|
-
"
|
|
79
|
-
"
|
|
66
|
+
"biome format --write",
|
|
67
|
+
"biome lint --write"
|
|
80
68
|
]
|
|
81
69
|
},
|
|
82
70
|
"packageManager": "pnpm@10.27.0"
|