@rtorcato/js-tooling 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/LICENSE +21 -0
- package/README.md +129 -0
- package/dist/cli/commands/setup.js +218 -0
- package/dist/cli/generators/build.js +90 -0
- package/dist/cli/generators/git.js +133 -0
- package/dist/cli/generators/github-actions.js +261 -0
- package/dist/cli/generators/index.js +53 -0
- package/dist/cli/generators/linting.js +43 -0
- package/dist/cli/generators/package-json.js +162 -0
- package/dist/cli/generators/readme.js +224 -0
- package/dist/cli/generators/testing.js +78 -0
- package/dist/cli/generators/tsconfig.js +28 -0
- package/dist/cli/index.js +53 -0
- package/dist/cli/utils/install.js +28 -0
- package/package.json +160 -0
- package/scripts/README.md +8 -0
- package/scripts/commitmessage.sh +44 -0
- package/scripts/helloworld.sh +5 -0
- package/tooling/biome/biome.jsonc +47 -0
- package/tooling/commitlint/commitlint.mjs +4 -0
- package/tooling/esbuild/build-sample.mjs +21 -0
- package/tooling/esbuild/index.mjs +102 -0
- package/tooling/eslint/README.md +3 -0
- package/tooling/eslint/base.mjs +122 -0
- package/tooling/eslint/nextjs.mjs +22 -0
- package/tooling/eslint/package.json +35 -0
- package/tooling/eslint/types.d.ts +58 -0
- package/tooling/jest-presets/browser/jest-preset.mjs +14 -0
- package/tooling/jest-presets/node/jest-preset.mjs +13 -0
- package/tooling/nextjs/next.config.js +4 -0
- package/tooling/oxc/.gitkeep +0 -0
- package/tooling/oxc/README.md +1 -0
- package/tooling/playwright/playwright.config.ts +0 -0
- package/tooling/prettier/index.mjs +36 -0
- package/tooling/rolldown/.gitkeep +0 -0
- package/tooling/rollup/.gitkeep +0 -0
- package/tooling/semantic-release/docker.mjs +59 -0
- package/tooling/semantic-release/github.mjs +74 -0
- package/tooling/semantic-release/index.mjs +75 -0
- package/tooling/tsdown/.gitkeep +0 -0
- package/tooling/tsup/index.ts +50 -0
- package/tooling/tsup/tsconfig.cjs.json +7 -0
- package/tooling/tsup/tsconfig.esm.json +9 -0
- package/tooling/tsup/tsconfig.json +11 -0
- package/tooling/tsup/tsconfig.types.json +9 -0
- package/tooling/typescript/README.md +52 -0
- package/tooling/typescript/reset.d.ts +9 -0
- package/tooling/typescript/tsconfig.base.json +78 -0
- package/tooling/typescript/tsconfig.build.json +11 -0
- package/tooling/typescript/tsconfig.express.json +9 -0
- package/tooling/typescript/tsconfig.next.json +19 -0
- package/tooling/typescript/tsconfig.node.json +9 -0
- package/tooling/typescript/tsconfig.react.json +14 -0
- package/tooling/typescript/tsconfig.test.json +8 -0
- package/tooling/vellite/.gitkeep +0 -0
- package/tooling/vite/.gitkeep +0 -0
- package/tooling/vitest/vitest.config.mjs +22 -0
- package/tooling/vitest/vitest.config.react.mjs +27 -0
- package/tooling/vitest/vitest.setup.mjs +3 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Richard Torcato
|
|
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
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# js-tooling
|
|
2
|
+
|
|
3
|
+
A comprehensive collection of JavaScript/TypeScript development tools and configurations for modern projects.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
Install the package globally or use it directly with npx:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
|
|
11
|
+
# Or use with npx
|
|
12
|
+
npx @rtorcato/js-tooling setup
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Getting started
|
|
16
|
+
|
|
17
|
+
Use the interactive CLI to set up tooling for your project:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npx @rtorcato/js-tooling setup
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Or import specific configurations:
|
|
24
|
+
|
|
25
|
+
```javascript
|
|
26
|
+
import '@rtorcato/js-tooling/typescript/base';
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Available Tools
|
|
30
|
+
|
|
31
|
+
This package includes configurations and presets for:
|
|
32
|
+
|
|
33
|
+
- **TypeScript** - Base configurations for different project types
|
|
34
|
+
- **ESLint** - Linting rules for JavaScript and TypeScript
|
|
35
|
+
- **Prettier** - Code formatting configuration
|
|
36
|
+
- **Biome** - Fast linter and formatter
|
|
37
|
+
- **Vitest** - Testing framework configuration
|
|
38
|
+
- **Jest** - Testing framework presets
|
|
39
|
+
- **Commitlint** - Commit message linting
|
|
40
|
+
- **Semantic Release** - Automated versioning and publishing
|
|
41
|
+
- **GitHub Actions** - CI/CD workflow templates
|
|
42
|
+
- **And more...**
|
|
43
|
+
|
|
44
|
+
## CI/CD Setup
|
|
45
|
+
|
|
46
|
+
The package includes GitHub Actions workflows and semantic-release configuration. For automated publishing, set these secrets in your GitHub repository:
|
|
47
|
+
|
|
48
|
+
1. **`NPM_TOKEN`** - npm authentication token for publishing packages
|
|
49
|
+
2. **`GITHUB_TOKEN`** - automatically provided by GitHub Actions
|
|
50
|
+
|
|
51
|
+
Repository settings: `https://github.com/your-username/your-repo/settings/secrets/actions`
|
|
52
|
+
|
|
53
|
+
## CLI Commands
|
|
54
|
+
|
|
55
|
+
The package provides several CLI commands:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# Interactive project setup wizard
|
|
59
|
+
npx @rtorcato/js-tooling setup
|
|
60
|
+
|
|
61
|
+
# Run commit message helper
|
|
62
|
+
npx @rtorcato/js-tooling commitmessage
|
|
63
|
+
|
|
64
|
+
# Hello world example
|
|
65
|
+
npx @rtorcato/js-tooling helloworld
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Using with Package Managers
|
|
69
|
+
|
|
70
|
+
### With pnpm
|
|
71
|
+
```bash
|
|
72
|
+
# Temporarily install and run
|
|
73
|
+
pnpm --package=@rtorcato/js-tooling dlx setup
|
|
74
|
+
|
|
75
|
+
# Or install globally
|
|
76
|
+
pnpm add -g @rtorcato/js-tooling
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### With npm
|
|
80
|
+
```bash
|
|
81
|
+
# Use directly
|
|
82
|
+
npx @rtorcato/js-tooling setup
|
|
83
|
+
|
|
84
|
+
# Or install globally
|
|
85
|
+
npm install -g @rtorcato/js-tooling
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Development
|
|
89
|
+
|
|
90
|
+
To work on this package locally:
|
|
91
|
+
|
|
92
|
+
1. Clone the repository:
|
|
93
|
+
```bash
|
|
94
|
+
git clone https://github.com/rtorcato/js-tooling.git
|
|
95
|
+
cd js-tooling
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
2. Install dependencies:
|
|
99
|
+
```bash
|
|
100
|
+
pnpm install
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
3. Build the CLI:
|
|
104
|
+
```bash
|
|
105
|
+
pnpm run build-cli
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
4. Link globally for testing:
|
|
109
|
+
```bash
|
|
110
|
+
pnpm link --global
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
For more details, refer to the [pnpm link documentation](https://pnpm.io/cli/link).
|
|
114
|
+
|
|
115
|
+
## Status
|
|
116
|
+
|
|
117
|
+
[](https://github.com/rtorcato/js-tooling/actions/workflows/ci.yml)
|
|
118
|
+
[](https://badge.fury.io/js/@rtorcato%2Fjs-tooling)
|
|
119
|
+
[](https://opensource.org/licenses/MIT)
|
|
120
|
+
[](https://github.com/rtorcato/js-tooling/releases)
|
|
121
|
+
[](https://github.com/rtorcato/js-tooling/issues)
|
|
122
|
+
|
|
123
|
+
## Contributing
|
|
124
|
+
|
|
125
|
+
Contributions are welcome! Please read our [contributing guidelines](CONTRIBUTING.md) and feel free to submit issues and pull requests.
|
|
126
|
+
|
|
127
|
+
## License
|
|
128
|
+
|
|
129
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import fs from 'fs-extra';
|
|
3
|
+
import inquirer from 'inquirer';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { generateConfigs } from '../generators/index.js';
|
|
6
|
+
import { installDependencies } from '../utils/install.js';
|
|
7
|
+
export async function setupProject(options) {
|
|
8
|
+
const targetDir = path.resolve(options.directory);
|
|
9
|
+
console.log(chalk.cyan('\n🛠️ Welcome to JS Tooling Setup!\n'));
|
|
10
|
+
console.log(chalk.gray(`Setting up tooling in: ${targetDir}\n`));
|
|
11
|
+
try {
|
|
12
|
+
// Check if directory exists and is writable
|
|
13
|
+
await fs.ensureDir(targetDir);
|
|
14
|
+
const config = await promptForConfig();
|
|
15
|
+
console.log(chalk.cyan('\n📝 Generating configuration files...\n'));
|
|
16
|
+
await generateConfigs(config, targetDir);
|
|
17
|
+
if (!options.skipInstall) {
|
|
18
|
+
console.log(chalk.cyan('\n📦 Installing dependencies...\n'));
|
|
19
|
+
await installDependencies(config, targetDir);
|
|
20
|
+
}
|
|
21
|
+
console.log(chalk.green('\n✅ Setup completed successfully!\n'));
|
|
22
|
+
// Show next steps
|
|
23
|
+
showNextSteps(config, targetDir);
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
console.error(chalk.red('\n❌ Setup failed:'), error);
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
async function promptForConfig() {
|
|
31
|
+
const answers = await inquirer.prompt([
|
|
32
|
+
{
|
|
33
|
+
type: 'input',
|
|
34
|
+
name: 'projectName',
|
|
35
|
+
message: '📦 What is your project name?',
|
|
36
|
+
default: path.basename(process.cwd()),
|
|
37
|
+
validate: (input) => input.trim().length > 0 || 'Project name is required',
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
type: 'list',
|
|
41
|
+
name: 'projectType',
|
|
42
|
+
message: '🏗️ What type of project are you building?',
|
|
43
|
+
choices: [
|
|
44
|
+
{ name: '📚 Library/Package', value: 'library' },
|
|
45
|
+
{ name: '🌐 Web Application', value: 'web-app' },
|
|
46
|
+
{ name: '🚀 Node.js API', value: 'node-api' },
|
|
47
|
+
{ name: '⚡ Next.js App', value: 'nextjs-app' },
|
|
48
|
+
{ name: '⚛️ React App', value: 'react-app' },
|
|
49
|
+
],
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
type: 'confirm',
|
|
53
|
+
name: 'useTypeScript',
|
|
54
|
+
message: '📘 Do you want to use TypeScript?',
|
|
55
|
+
default: true,
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
type: 'list',
|
|
59
|
+
name: 'tsConfig',
|
|
60
|
+
message: '⚙️ Which TypeScript configuration?',
|
|
61
|
+
choices: (answers) => {
|
|
62
|
+
const baseChoices = [
|
|
63
|
+
{ name: '🔧 Base (General purpose)', value: 'base' },
|
|
64
|
+
{ name: '🖥️ Node.js', value: 'node' },
|
|
65
|
+
];
|
|
66
|
+
if (answers.projectType === 'nextjs-app') {
|
|
67
|
+
return [{ name: '⚡ Next.js', value: 'next' }, ...baseChoices];
|
|
68
|
+
}
|
|
69
|
+
if (answers.projectType === 'react-app' || answers.projectType === 'web-app') {
|
|
70
|
+
return [{ name: '⚛️ React', value: 'react' }, ...baseChoices];
|
|
71
|
+
}
|
|
72
|
+
if (answers.projectType === 'node-api') {
|
|
73
|
+
return [
|
|
74
|
+
{ name: '🚀 Express/API', value: 'express' },
|
|
75
|
+
{ name: '🖥️ Node.js', value: 'node' },
|
|
76
|
+
];
|
|
77
|
+
}
|
|
78
|
+
return baseChoices;
|
|
79
|
+
},
|
|
80
|
+
when: (answers) => answers.useTypeScript,
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
type: 'list',
|
|
84
|
+
name: 'lintingTool',
|
|
85
|
+
message: '🔍 Which linting/formatting tool?',
|
|
86
|
+
choices: [
|
|
87
|
+
{ name: '⚡ Biome (Fast, all-in-one)', value: 'biome' },
|
|
88
|
+
{ name: '🔧 ESLint (Configurable)', value: 'eslint' },
|
|
89
|
+
{ name: '🔥 Both Biome + ESLint', value: 'both' },
|
|
90
|
+
{ name: '❌ None', value: 'none' },
|
|
91
|
+
],
|
|
92
|
+
default: 'biome',
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
type: 'list',
|
|
96
|
+
name: 'eslintConfig',
|
|
97
|
+
message: '🔧 Which ESLint configuration?',
|
|
98
|
+
choices: (answers) => {
|
|
99
|
+
const choices = [{ name: '🔧 Base configuration', value: 'base' }];
|
|
100
|
+
if (answers.projectType === 'nextjs-app') {
|
|
101
|
+
choices.unshift({ name: '⚡ Next.js configuration', value: 'nextjs' });
|
|
102
|
+
}
|
|
103
|
+
return choices;
|
|
104
|
+
},
|
|
105
|
+
when: (answers) => answers.lintingTool === 'eslint' || answers.lintingTool === 'both',
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
type: 'list',
|
|
109
|
+
name: 'testingFramework',
|
|
110
|
+
message: '🧪 Which testing framework?',
|
|
111
|
+
choices: [
|
|
112
|
+
{ name: '⚡ Vitest (Fast, Vite-powered)', value: 'vitest' },
|
|
113
|
+
{ name: '🃏 Jest (Traditional)', value: 'jest' },
|
|
114
|
+
{ name: '🎭 Playwright (E2E)', value: 'playwright' },
|
|
115
|
+
{ name: '❌ None', value: 'none' },
|
|
116
|
+
],
|
|
117
|
+
default: 'vitest',
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
type: 'list',
|
|
121
|
+
name: 'testEnvironment',
|
|
122
|
+
message: '🌍 Test environment?',
|
|
123
|
+
choices: [
|
|
124
|
+
{ name: '🖥️ Node.js', value: 'node' },
|
|
125
|
+
{ name: '🌐 Browser (DOM)', value: 'browser' },
|
|
126
|
+
{ name: '🔄 Both', value: 'both' },
|
|
127
|
+
],
|
|
128
|
+
when: (answers) => answers.testingFramework === 'jest',
|
|
129
|
+
default: 'node',
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
type: 'confirm',
|
|
133
|
+
name: 'gitHooks',
|
|
134
|
+
message: '🪝 Set up Git hooks (Husky + lint-staged)?',
|
|
135
|
+
default: true,
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
type: 'confirm',
|
|
139
|
+
name: 'commitLint',
|
|
140
|
+
message: '📝 Set up conventional commit linting?',
|
|
141
|
+
default: true,
|
|
142
|
+
when: (answers) => answers.gitHooks,
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
type: 'confirm',
|
|
146
|
+
name: 'semanticRelease',
|
|
147
|
+
message: '🚀 Set up semantic release for automated versioning?',
|
|
148
|
+
default: (answers) => answers.projectType === 'library',
|
|
149
|
+
when: (answers) => answers.projectType === 'library',
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
type: 'list',
|
|
153
|
+
name: 'bundler',
|
|
154
|
+
message: '📦 Which bundler/build tool?',
|
|
155
|
+
choices: (answers) => {
|
|
156
|
+
const choices = [
|
|
157
|
+
{ name: '📦 tsup (TypeScript packages)', value: 'tsup' },
|
|
158
|
+
{ name: '⚡ esbuild (Fast bundling)', value: 'esbuild' },
|
|
159
|
+
{ name: '❌ None', value: 'none' },
|
|
160
|
+
];
|
|
161
|
+
if (answers.projectType === 'web-app' || answers.projectType === 'react-app') {
|
|
162
|
+
choices.unshift({ name: '⚡ Vite (Modern web apps)', value: 'vite' });
|
|
163
|
+
}
|
|
164
|
+
return choices;
|
|
165
|
+
},
|
|
166
|
+
when: (answers) => answers.projectType !== 'nextjs-app', // Next.js has its own bundler
|
|
167
|
+
},
|
|
168
|
+
]);
|
|
169
|
+
return {
|
|
170
|
+
projectName: answers.projectName,
|
|
171
|
+
projectType: answers.projectType,
|
|
172
|
+
typescript: {
|
|
173
|
+
enabled: answers.useTypeScript || false,
|
|
174
|
+
config: answers.tsConfig || 'base',
|
|
175
|
+
},
|
|
176
|
+
linting: {
|
|
177
|
+
tool: answers.lintingTool || 'none',
|
|
178
|
+
eslintConfig: answers.eslintConfig,
|
|
179
|
+
},
|
|
180
|
+
formatting: {
|
|
181
|
+
tool: answers.lintingTool === 'biome' || answers.lintingTool === 'both'
|
|
182
|
+
? 'biome'
|
|
183
|
+
: answers.lintingTool === 'eslint'
|
|
184
|
+
? 'prettier'
|
|
185
|
+
: 'none',
|
|
186
|
+
},
|
|
187
|
+
testing: {
|
|
188
|
+
framework: answers.testingFramework || 'none',
|
|
189
|
+
environment: answers.testEnvironment,
|
|
190
|
+
},
|
|
191
|
+
gitHooks: answers.gitHooks || false,
|
|
192
|
+
commitLint: answers.commitLint || false,
|
|
193
|
+
semanticRelease: answers.semanticRelease || false,
|
|
194
|
+
bundler: answers.bundler || 'none',
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
function showNextSteps(config, _targetDir) {
|
|
198
|
+
console.log(chalk.bold('\n📋 Next Steps:\n'));
|
|
199
|
+
const steps = [];
|
|
200
|
+
if (config.typescript.enabled) {
|
|
201
|
+
steps.push('🔧 Customize your tsconfig.json as needed');
|
|
202
|
+
}
|
|
203
|
+
if (config.linting.tool !== 'none') {
|
|
204
|
+
steps.push(`🔍 Run linting with: ${config.linting.tool === 'biome' ? 'pnpm biome check .' : 'pnpm eslint .'}`);
|
|
205
|
+
}
|
|
206
|
+
if (config.testing.framework !== 'none') {
|
|
207
|
+
steps.push(`🧪 Run tests with: pnpm ${config.testing.framework}`);
|
|
208
|
+
}
|
|
209
|
+
if (config.gitHooks) {
|
|
210
|
+
steps.push('🪝 Commit your changes to test the git hooks');
|
|
211
|
+
}
|
|
212
|
+
steps.push('📖 Check the generated README.md for more details');
|
|
213
|
+
steps.forEach((step, index) => {
|
|
214
|
+
console.log(` ${index + 1}. ${step}`);
|
|
215
|
+
});
|
|
216
|
+
console.log(chalk.dim('\n💡 All configuration files have been generated in your project directory.'));
|
|
217
|
+
console.log(chalk.dim(' You can modify them to suit your specific needs.\n'));
|
|
218
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
export async function generateBuildConfigs(config, targetDir) {
|
|
4
|
+
if (config.bundler === 'tsup') {
|
|
5
|
+
await generateTsupConfig(targetDir);
|
|
6
|
+
}
|
|
7
|
+
else if (config.bundler === 'esbuild') {
|
|
8
|
+
await generateEsbuildConfig(targetDir);
|
|
9
|
+
}
|
|
10
|
+
else if (config.bundler === 'vite') {
|
|
11
|
+
await generateViteConfig(config, targetDir);
|
|
12
|
+
}
|
|
13
|
+
// Generate semantic-release config for GitHub
|
|
14
|
+
if (config.semanticRelease) {
|
|
15
|
+
await generateSemanticReleaseConfig(targetDir);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
async function generateTsupConfig(targetDir) {
|
|
19
|
+
const tsupConfigPath = path.join(targetDir, 'tsup.config.ts');
|
|
20
|
+
const tsupConfig = `import { getConfig } from '@rtorcato/js-tooling/tsup'
|
|
21
|
+
|
|
22
|
+
export default getConfig({
|
|
23
|
+
entry: ['src/index.ts'],
|
|
24
|
+
format: ['cjs', 'esm'],
|
|
25
|
+
dts: true,
|
|
26
|
+
clean: true,
|
|
27
|
+
splitting: false,
|
|
28
|
+
sourcemap: true,
|
|
29
|
+
}, process.env.NODE_ENV || 'development')
|
|
30
|
+
`;
|
|
31
|
+
await fs.writeFile(tsupConfigPath, tsupConfig);
|
|
32
|
+
}
|
|
33
|
+
async function generateEsbuildConfig(targetDir) {
|
|
34
|
+
const esbuildConfigPath = path.join(targetDir, 'build.mjs');
|
|
35
|
+
const esbuildConfig = `import { build } from 'esbuild'
|
|
36
|
+
import { nodeExternalsPlugin } from 'esbuild-node-externals'
|
|
37
|
+
|
|
38
|
+
const isProduction = process.env.NODE_ENV === 'production'
|
|
39
|
+
|
|
40
|
+
await build({
|
|
41
|
+
entryPoints: ['src/index.ts'],
|
|
42
|
+
bundle: true,
|
|
43
|
+
outdir: 'dist',
|
|
44
|
+
format: 'esm',
|
|
45
|
+
target: 'node18',
|
|
46
|
+
platform: 'node',
|
|
47
|
+
minify: isProduction,
|
|
48
|
+
sourcemap: !isProduction,
|
|
49
|
+
plugins: [nodeExternalsPlugin()],
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
console.log('Build completed!')
|
|
53
|
+
`;
|
|
54
|
+
await fs.writeFile(esbuildConfigPath, esbuildConfig);
|
|
55
|
+
}
|
|
56
|
+
async function generateViteConfig(config, targetDir) {
|
|
57
|
+
const viteConfigPath = path.join(targetDir, 'vite.config.ts');
|
|
58
|
+
let viteConfig = `import { defineConfig } from 'vite'
|
|
59
|
+
`;
|
|
60
|
+
if (config.projectType === 'react-app') {
|
|
61
|
+
viteConfig += `import react from '@vitejs/plugin-react'
|
|
62
|
+
`;
|
|
63
|
+
}
|
|
64
|
+
viteConfig += `
|
|
65
|
+
export default defineConfig({
|
|
66
|
+
plugins: [${config.projectType === 'react-app' ? 'react()' : ''}],
|
|
67
|
+
resolve: {
|
|
68
|
+
alias: {
|
|
69
|
+
'@': '/src',
|
|
70
|
+
'~': '/src'
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
build: {
|
|
74
|
+
outDir: 'dist',
|
|
75
|
+
sourcemap: true,
|
|
76
|
+
},
|
|
77
|
+
server: {
|
|
78
|
+
port: 3000,
|
|
79
|
+
open: true
|
|
80
|
+
}
|
|
81
|
+
})
|
|
82
|
+
`;
|
|
83
|
+
await fs.writeFile(viteConfigPath, viteConfig);
|
|
84
|
+
}
|
|
85
|
+
async function generateSemanticReleaseConfig(targetDir) {
|
|
86
|
+
const releaseConfigPath = path.join(targetDir, 'release.config.mjs');
|
|
87
|
+
const releaseConfig = `export { default } from '@rtorcato/js-tooling/semantic-release/github'
|
|
88
|
+
`;
|
|
89
|
+
await fs.writeFile(releaseConfigPath, releaseConfig);
|
|
90
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
export async function generateGitConfigs(config, targetDir) {
|
|
4
|
+
if (config.gitHooks) {
|
|
5
|
+
await generateHuskyConfig(config, targetDir);
|
|
6
|
+
}
|
|
7
|
+
if (config.commitLint) {
|
|
8
|
+
await generateCommitlintConfig(targetDir);
|
|
9
|
+
}
|
|
10
|
+
// Generate .gitignore
|
|
11
|
+
await generateGitignore(config, targetDir);
|
|
12
|
+
}
|
|
13
|
+
async function generateHuskyConfig(config, targetDir) {
|
|
14
|
+
const huskyDir = path.join(targetDir, '.husky');
|
|
15
|
+
await fs.ensureDir(huskyDir);
|
|
16
|
+
// Pre-commit hook
|
|
17
|
+
const preCommitPath = path.join(huskyDir, 'pre-commit');
|
|
18
|
+
const preCommitContent = `#!/usr/bin/env sh
|
|
19
|
+
. "$(dirname -- "$0")/_/husky.sh"
|
|
20
|
+
|
|
21
|
+
npx lint-staged
|
|
22
|
+
`;
|
|
23
|
+
await fs.writeFile(preCommitPath, preCommitContent);
|
|
24
|
+
await fs.chmod(preCommitPath, 0o755);
|
|
25
|
+
// Commit-msg hook (if commitlint is enabled)
|
|
26
|
+
if (config.commitLint) {
|
|
27
|
+
const commitMsgPath = path.join(huskyDir, 'commit-msg');
|
|
28
|
+
const commitMsgContent = `#!/usr/bin/env sh
|
|
29
|
+
. "$(dirname -- "$0")/_/husky.sh"
|
|
30
|
+
|
|
31
|
+
npx --no -- commitlint --edit $1
|
|
32
|
+
`;
|
|
33
|
+
await fs.writeFile(commitMsgPath, commitMsgContent);
|
|
34
|
+
await fs.chmod(commitMsgPath, 0o755);
|
|
35
|
+
}
|
|
36
|
+
// lint-staged configuration in package.json
|
|
37
|
+
const packageJsonPath = path.join(targetDir, 'package.json');
|
|
38
|
+
const packageJson = await fs.readJson(packageJsonPath);
|
|
39
|
+
packageJson['lint-staged'] = {
|
|
40
|
+
'*.{js,ts,jsx,tsx}': [
|
|
41
|
+
config.linting.tool === 'biome' || config.linting.tool === 'both'
|
|
42
|
+
? 'biome check --fix'
|
|
43
|
+
: 'eslint --fix',
|
|
44
|
+
'git add',
|
|
45
|
+
],
|
|
46
|
+
'*.{json,md,yml,yaml}': [
|
|
47
|
+
config.linting.tool === 'biome' || config.linting.tool === 'both'
|
|
48
|
+
? 'biome format --write'
|
|
49
|
+
: 'prettier --write',
|
|
50
|
+
'git add',
|
|
51
|
+
],
|
|
52
|
+
};
|
|
53
|
+
await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 });
|
|
54
|
+
}
|
|
55
|
+
async function generateCommitlintConfig(targetDir) {
|
|
56
|
+
const commitlintConfigPath = path.join(targetDir, 'commitlint.config.mjs');
|
|
57
|
+
const commitlintConfig = `export { default } from '@rtorcato/js-tooling/commitlint/config'
|
|
58
|
+
`;
|
|
59
|
+
await fs.writeFile(commitlintConfigPath, commitlintConfig);
|
|
60
|
+
}
|
|
61
|
+
async function generateGitignore(config, targetDir) {
|
|
62
|
+
const gitignorePath = path.join(targetDir, '.gitignore');
|
|
63
|
+
let gitignoreContent = `# Dependencies
|
|
64
|
+
node_modules/
|
|
65
|
+
.pnpm-store
|
|
66
|
+
|
|
67
|
+
# Build outputs
|
|
68
|
+
dist/
|
|
69
|
+
build/
|
|
70
|
+
out/
|
|
71
|
+
|
|
72
|
+
# Environment files
|
|
73
|
+
.env
|
|
74
|
+
.env.local
|
|
75
|
+
.env.development.local
|
|
76
|
+
.env.test.local
|
|
77
|
+
.env.production.local
|
|
78
|
+
|
|
79
|
+
# IDE
|
|
80
|
+
.vscode/
|
|
81
|
+
.idea/
|
|
82
|
+
*.swp
|
|
83
|
+
*.swo
|
|
84
|
+
|
|
85
|
+
# OS
|
|
86
|
+
.DS_Store
|
|
87
|
+
Thumbs.db
|
|
88
|
+
|
|
89
|
+
# Logs
|
|
90
|
+
logs
|
|
91
|
+
*.log
|
|
92
|
+
npm-debug.log*
|
|
93
|
+
yarn-debug.log*
|
|
94
|
+
yarn-error.log*
|
|
95
|
+
pnpm-debug.log*
|
|
96
|
+
|
|
97
|
+
# Runtime data
|
|
98
|
+
pids
|
|
99
|
+
*.pid
|
|
100
|
+
*.seed
|
|
101
|
+
*.pid.lock
|
|
102
|
+
|
|
103
|
+
# Coverage directory used by tools like istanbul
|
|
104
|
+
coverage/
|
|
105
|
+
*.lcov
|
|
106
|
+
|
|
107
|
+
# TypeScript
|
|
108
|
+
*.tsbuildinfo
|
|
109
|
+
`;
|
|
110
|
+
// Add framework-specific ignores
|
|
111
|
+
if (config.projectType === 'nextjs-app') {
|
|
112
|
+
gitignoreContent += `
|
|
113
|
+
# Next.js
|
|
114
|
+
.next/
|
|
115
|
+
.vercel
|
|
116
|
+
`;
|
|
117
|
+
}
|
|
118
|
+
if (config.bundler === 'vite') {
|
|
119
|
+
gitignoreContent += `
|
|
120
|
+
# Vite
|
|
121
|
+
.vite/
|
|
122
|
+
`;
|
|
123
|
+
}
|
|
124
|
+
if (config.testing.framework === 'playwright') {
|
|
125
|
+
gitignoreContent += `
|
|
126
|
+
# Playwright
|
|
127
|
+
/test-results/
|
|
128
|
+
/playwright-report/
|
|
129
|
+
/playwright/.cache/
|
|
130
|
+
`;
|
|
131
|
+
}
|
|
132
|
+
await fs.writeFile(gitignorePath, gitignoreContent);
|
|
133
|
+
}
|