@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.
Files changed (59) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +129 -0
  3. package/dist/cli/commands/setup.js +218 -0
  4. package/dist/cli/generators/build.js +90 -0
  5. package/dist/cli/generators/git.js +133 -0
  6. package/dist/cli/generators/github-actions.js +261 -0
  7. package/dist/cli/generators/index.js +53 -0
  8. package/dist/cli/generators/linting.js +43 -0
  9. package/dist/cli/generators/package-json.js +162 -0
  10. package/dist/cli/generators/readme.js +224 -0
  11. package/dist/cli/generators/testing.js +78 -0
  12. package/dist/cli/generators/tsconfig.js +28 -0
  13. package/dist/cli/index.js +53 -0
  14. package/dist/cli/utils/install.js +28 -0
  15. package/package.json +160 -0
  16. package/scripts/README.md +8 -0
  17. package/scripts/commitmessage.sh +44 -0
  18. package/scripts/helloworld.sh +5 -0
  19. package/tooling/biome/biome.jsonc +47 -0
  20. package/tooling/commitlint/commitlint.mjs +4 -0
  21. package/tooling/esbuild/build-sample.mjs +21 -0
  22. package/tooling/esbuild/index.mjs +102 -0
  23. package/tooling/eslint/README.md +3 -0
  24. package/tooling/eslint/base.mjs +122 -0
  25. package/tooling/eslint/nextjs.mjs +22 -0
  26. package/tooling/eslint/package.json +35 -0
  27. package/tooling/eslint/types.d.ts +58 -0
  28. package/tooling/jest-presets/browser/jest-preset.mjs +14 -0
  29. package/tooling/jest-presets/node/jest-preset.mjs +13 -0
  30. package/tooling/nextjs/next.config.js +4 -0
  31. package/tooling/oxc/.gitkeep +0 -0
  32. package/tooling/oxc/README.md +1 -0
  33. package/tooling/playwright/playwright.config.ts +0 -0
  34. package/tooling/prettier/index.mjs +36 -0
  35. package/tooling/rolldown/.gitkeep +0 -0
  36. package/tooling/rollup/.gitkeep +0 -0
  37. package/tooling/semantic-release/docker.mjs +59 -0
  38. package/tooling/semantic-release/github.mjs +74 -0
  39. package/tooling/semantic-release/index.mjs +75 -0
  40. package/tooling/tsdown/.gitkeep +0 -0
  41. package/tooling/tsup/index.ts +50 -0
  42. package/tooling/tsup/tsconfig.cjs.json +7 -0
  43. package/tooling/tsup/tsconfig.esm.json +9 -0
  44. package/tooling/tsup/tsconfig.json +11 -0
  45. package/tooling/tsup/tsconfig.types.json +9 -0
  46. package/tooling/typescript/README.md +52 -0
  47. package/tooling/typescript/reset.d.ts +9 -0
  48. package/tooling/typescript/tsconfig.base.json +78 -0
  49. package/tooling/typescript/tsconfig.build.json +11 -0
  50. package/tooling/typescript/tsconfig.express.json +9 -0
  51. package/tooling/typescript/tsconfig.next.json +19 -0
  52. package/tooling/typescript/tsconfig.node.json +9 -0
  53. package/tooling/typescript/tsconfig.react.json +14 -0
  54. package/tooling/typescript/tsconfig.test.json +8 -0
  55. package/tooling/vellite/.gitkeep +0 -0
  56. package/tooling/vite/.gitkeep +0 -0
  57. package/tooling/vitest/vitest.config.mjs +22 -0
  58. package/tooling/vitest/vitest.config.react.mjs +27 -0
  59. package/tooling/vitest/vitest.setup.mjs +3 -0
@@ -0,0 +1,224 @@
1
+ import fs from 'fs-extra';
2
+ import path from 'node:path';
3
+ export async function generateReadme(config, targetDir) {
4
+ const readmePath = path.join(targetDir, 'README.md');
5
+ const readme = `# ${config.projectName}
6
+
7
+ > Generated with [@rtorcato/js-tooling](https://www.npmjs.com/package/@rtorcato/js-tooling)
8
+
9
+ ## Description
10
+
11
+ Your project description here.
12
+
13
+ ## Installation
14
+
15
+ \`\`\`bash
16
+ # Using pnpm (recommended)
17
+ pnpm install
18
+
19
+ # Using npm
20
+ npm install
21
+
22
+ # Using yarn
23
+ yarn install
24
+ \`\`\`
25
+
26
+ ## Development
27
+
28
+ ${generateDevelopmentSection(config)}
29
+
30
+ ## Testing
31
+
32
+ ${generateTestingSection(config)}
33
+
34
+ ## Building
35
+
36
+ ${generateBuildingSection(config)}
37
+
38
+ ## Scripts
39
+
40
+ ${generateScriptsSection(config)}
41
+
42
+ ## Project Structure
43
+
44
+ \`\`\`
45
+ ${config.projectName}/
46
+ ├── src/ # Source code
47
+ ${config.typescript.enabled ? '├── reset.d.ts # TypeScript reset types' : ''}
48
+ ${config.testing.framework !== 'none' ? '├── tests/ # Test files' : ''}
49
+ ├── dist/ # Build output${config.projectType === 'library' ? ' (library)' : ''}
50
+ ├── package.json
51
+ ${config.typescript.enabled ? '├── tsconfig.json # TypeScript configuration' : ''}
52
+ ${config.linting.tool === 'biome' || config.linting.tool === 'both' ? '├── biome.jsonc # Biome configuration' : ''}
53
+ ${config.linting.tool === 'eslint' || config.linting.tool === 'both' ? '├── eslint.config.mjs # ESLint configuration' : ''}
54
+ ${config.linting.tool === 'eslint' ? '├── prettier.config.mjs # Prettier configuration' : ''}
55
+ ${config.testing.framework === 'vitest' ? '├── vitest.config.ts # Vitest configuration' : ''}
56
+ ${config.testing.framework === 'jest' ? '├── jest.config.mjs # Jest configuration' : ''}
57
+ ${config.testing.framework === 'playwright' ? '├── playwright.config.ts # Playwright configuration' : ''}
58
+ ${config.bundler === 'tsup' ? '├── tsup.config.ts # tsup configuration' : ''}
59
+ ${config.bundler === 'esbuild' ? '├── build.mjs # esbuild configuration' : ''}
60
+ ${config.bundler === 'vite' ? '├── vite.config.ts # Vite configuration' : ''}
61
+ ${config.commitLint ? '├── commitlint.config.mjs # Commitlint configuration' : ''}
62
+ ${config.gitHooks ? '├── .husky/ # Git hooks' : ''}
63
+ └── README.md
64
+ \`\`\`
65
+
66
+ ## Tooling
67
+
68
+ This project uses:
69
+
70
+ ${generateToolingList(config)}
71
+
72
+ ## Contributing
73
+
74
+ 1. Fork the repository
75
+ 2. Create your feature branch (\`git checkout -b feature/amazing-feature\`)
76
+ 3. Commit your changes (\`git commit -m 'feat: add amazing feature'\`)
77
+ 4. Push to the branch (\`git push origin feature/amazing-feature\`)
78
+ 5. Open a Pull Request
79
+
80
+ ${config.commitLint
81
+ ? `
82
+ ### Commit Convention
83
+
84
+ This project follows [Conventional Commits](https://conventionalcommits.org/):
85
+
86
+ - \`feat:\` new features
87
+ - \`fix:\` bug fixes
88
+ - \`docs:\` documentation changes
89
+ - \`style:\` formatting changes
90
+ - \`refactor:\` code refactoring
91
+ - \`test:\` adding or updating tests
92
+ - \`chore:\` maintenance tasks
93
+ `
94
+ : ''}
95
+
96
+ ## License
97
+
98
+ [Add your license here]
99
+ `;
100
+ await fs.writeFile(readmePath, readme);
101
+ }
102
+ function generateDevelopmentSection(config) {
103
+ const sections = [];
104
+ if (config.bundler === 'vite') {
105
+ sections.push('```bash\npnpm dev\n```');
106
+ }
107
+ else {
108
+ sections.push('Start development by running your preferred development server.');
109
+ }
110
+ if (config.linting.tool !== 'none') {
111
+ const lintCommand = config.linting.tool === 'biome' || config.linting.tool === 'both'
112
+ ? 'pnpm check:fix'
113
+ : 'pnpm lint:fix';
114
+ sections.push(`\n### Linting & Formatting\n\n\`\`\`bash\n${lintCommand}\n\`\`\``);
115
+ }
116
+ if (config.typescript.enabled) {
117
+ sections.push('\n### Type Checking\n\n```bash\npnpm typecheck\n```');
118
+ }
119
+ return sections.length > 0 ? sections.join('\n') : 'No specific development commands configured.';
120
+ }
121
+ function generateTestingSection(config) {
122
+ if (config.testing.framework === 'none') {
123
+ return 'No testing framework configured.';
124
+ }
125
+ const commands = [];
126
+ if (config.testing.framework === 'vitest') {
127
+ commands.push('pnpm test # Run tests');
128
+ commands.push('pnpm test:watch # Run tests in watch mode');
129
+ commands.push('pnpm test:ui # Run tests with UI');
130
+ commands.push('pnpm coverage # Generate coverage report');
131
+ }
132
+ else if (config.testing.framework === 'jest') {
133
+ commands.push('pnpm test # Run tests');
134
+ commands.push('pnpm test:watch # Run tests in watch mode');
135
+ commands.push('pnpm coverage # Generate coverage report');
136
+ }
137
+ else if (config.testing.framework === 'playwright') {
138
+ commands.push('pnpm test:e2e # Run E2E tests');
139
+ commands.push('pnpm test:e2e:ui # Run E2E tests with UI');
140
+ }
141
+ return `\`\`\`bash\n${commands.join('\n')}\n\`\`\``;
142
+ }
143
+ function generateBuildingSection(config) {
144
+ if (config.bundler === 'none') {
145
+ return 'No build configuration set up.';
146
+ }
147
+ return '```bash\npnpm build\n```';
148
+ }
149
+ function generateScriptsSection(config) {
150
+ const scripts = [];
151
+ scripts.push('- `pnpm install` - Install dependencies');
152
+ if (config.typescript.enabled) {
153
+ scripts.push('- `pnpm typecheck` - Type check TypeScript');
154
+ }
155
+ if (config.linting.tool !== 'none') {
156
+ if (config.linting.tool === 'biome' || config.linting.tool === 'both') {
157
+ scripts.push('- `pnpm lint` - Lint code with Biome');
158
+ scripts.push('- `pnpm format` - Format code with Biome');
159
+ scripts.push('- `pnpm check:fix` - Lint and format with Biome');
160
+ }
161
+ if (config.linting.tool === 'eslint' || config.linting.tool === 'both') {
162
+ scripts.push('- `pnpm lint` - Lint code with ESLint');
163
+ scripts.push('- `pnpm lint:fix` - Fix ESLint issues');
164
+ scripts.push('- `pnpm format` - Format code with Prettier');
165
+ }
166
+ }
167
+ if (config.testing.framework !== 'none') {
168
+ scripts.push('- `pnpm test` - Run tests');
169
+ if (config.testing.framework === 'vitest') {
170
+ scripts.push('- `pnpm test:watch` - Run tests in watch mode');
171
+ scripts.push('- `pnpm coverage` - Generate test coverage');
172
+ }
173
+ }
174
+ if (config.bundler !== 'none') {
175
+ scripts.push('- `pnpm build` - Build for production');
176
+ }
177
+ return scripts.join('\n');
178
+ }
179
+ function generateToolingList(config) {
180
+ const tools = [];
181
+ if (config.typescript.enabled) {
182
+ tools.push('- **TypeScript** - Type-safe JavaScript');
183
+ }
184
+ if (config.linting.tool === 'biome') {
185
+ tools.push('- **Biome** - Fast formatter and linter');
186
+ }
187
+ else if (config.linting.tool === 'eslint') {
188
+ tools.push('- **ESLint** - Linting utility');
189
+ tools.push('- **Prettier** - Code formatter');
190
+ }
191
+ else if (config.linting.tool === 'both') {
192
+ tools.push('- **Biome** - Fast formatter and linter');
193
+ tools.push('- **ESLint** - Additional linting rules');
194
+ }
195
+ if (config.testing.framework === 'vitest') {
196
+ tools.push('- **Vitest** - Fast testing framework');
197
+ }
198
+ else if (config.testing.framework === 'jest') {
199
+ tools.push('- **Jest** - Testing framework');
200
+ }
201
+ else if (config.testing.framework === 'playwright') {
202
+ tools.push('- **Playwright** - End-to-end testing');
203
+ }
204
+ if (config.bundler === 'tsup') {
205
+ tools.push('- **tsup** - TypeScript bundler');
206
+ }
207
+ else if (config.bundler === 'esbuild') {
208
+ tools.push('- **esbuild** - Fast JavaScript bundler');
209
+ }
210
+ else if (config.bundler === 'vite') {
211
+ tools.push('- **Vite** - Fast build tool');
212
+ }
213
+ if (config.gitHooks) {
214
+ tools.push('- **Husky** - Git hooks');
215
+ tools.push('- **lint-staged** - Run linters on staged files');
216
+ }
217
+ if (config.commitLint) {
218
+ tools.push('- **Commitlint** - Conventional commit linting');
219
+ }
220
+ if (config.semanticRelease) {
221
+ tools.push('- **Semantic Release** - Automated versioning and publishing');
222
+ }
223
+ return tools.join('\n');
224
+ }
@@ -0,0 +1,78 @@
1
+ import fs from 'fs-extra';
2
+ import path from 'node:path';
3
+ export async function generateTestingConfigs(config, targetDir) {
4
+ if (config.testing.framework === 'vitest') {
5
+ await generateVitestConfig(config, targetDir);
6
+ }
7
+ else if (config.testing.framework === 'jest') {
8
+ await generateJestConfig(config, targetDir);
9
+ }
10
+ else if (config.testing.framework === 'playwright') {
11
+ await generatePlaywrightConfig(targetDir);
12
+ }
13
+ }
14
+ async function generateVitestConfig(config, targetDir) {
15
+ const vitestConfigPath = path.join(targetDir, 'vitest.config.ts');
16
+ const vitestConfig = `import { defineConfig } from 'vitest/config'
17
+
18
+ export default defineConfig({
19
+ test: {
20
+ globals: true,
21
+ environment: '${config.testing.environment === 'browser' ? 'jsdom' : 'node'}',
22
+ setupFiles: ['./vitest.setup.ts']
23
+ }
24
+ })
25
+ `;
26
+ await fs.writeFile(vitestConfigPath, vitestConfig);
27
+ // Create setup file
28
+ const setupPath = path.join(targetDir, 'vitest.setup.ts');
29
+ const setupContent = `// Vitest setup file
30
+ // Add global test setup here
31
+ `;
32
+ await fs.writeFile(setupPath, setupContent);
33
+ }
34
+ async function generateJestConfig(config, targetDir) {
35
+ const jestConfigPath = path.join(targetDir, 'jest.config.mjs');
36
+ const environment = config.testing.environment === 'browser' ? 'browser' : 'node';
37
+ const jestConfig = `export { default } from '@rtorcato/js-tooling/jest-presets/${environment}/jest-preset'
38
+ `;
39
+ await fs.writeFile(jestConfigPath, jestConfig);
40
+ }
41
+ async function generatePlaywrightConfig(targetDir) {
42
+ const playwrightConfigPath = path.join(targetDir, 'playwright.config.ts');
43
+ const playwrightConfig = `import { defineConfig } from '@playwright/test'
44
+
45
+ export default defineConfig({
46
+ testDir: './tests/e2e',
47
+ fullyParallel: true,
48
+ forbidOnly: !!process.env.CI,
49
+ retries: process.env.CI ? 2 : 0,
50
+ workers: process.env.CI ? 1 : undefined,
51
+ reporter: 'html',
52
+ use: {
53
+ baseURL: 'http://localhost:3000',
54
+ trace: 'on-first-retry',
55
+ },
56
+ projects: [
57
+ {
58
+ name: 'chromium',
59
+ use: { ...devices['Desktop Chrome'] },
60
+ },
61
+ {
62
+ name: 'firefox',
63
+ use: { ...devices['Desktop Firefox'] },
64
+ },
65
+ {
66
+ name: 'webkit',
67
+ use: { ...devices['Desktop Safari'] },
68
+ },
69
+ ],
70
+ webServer: {
71
+ command: 'npm run dev',
72
+ url: 'http://localhost:3000',
73
+ reuseExistingServer: !process.env.CI,
74
+ },
75
+ })
76
+ `;
77
+ await fs.writeFile(playwrightConfigPath, playwrightConfig);
78
+ }
@@ -0,0 +1,28 @@
1
+ import fs from 'fs-extra';
2
+ import path from 'node:path';
3
+ export async function generateTSConfig(config, targetDir) {
4
+ const tsconfigPath = path.join(targetDir, 'tsconfig.json');
5
+ // Base configuration extends our tooling
6
+ const tsconfig = {
7
+ extends: `@rtorcato/js-tooling/typescript/${config.typescript.config}`,
8
+ compilerOptions: {
9
+ baseUrl: '.',
10
+ paths: {
11
+ '@/*': ['./src/*'],
12
+ '~/*': ['./src/*'],
13
+ },
14
+ },
15
+ include: ['src/**/*', 'reset.d.ts'],
16
+ exclude: ['node_modules', 'dist', 'build'],
17
+ };
18
+ // Adjust for project type
19
+ if (config.projectType === 'library') {
20
+ tsconfig.compilerOptions.outDir = './dist';
21
+ tsconfig.compilerOptions.rootDir = './src';
22
+ }
23
+ if (config.projectType === 'nextjs-app') {
24
+ tsconfig.include = ['next-env.d.ts', 'src', 'app', 'pages', 'components', 'reset.d.ts'];
25
+ tsconfig.exclude.push('.next');
26
+ }
27
+ await fs.writeJson(tsconfigPath, tsconfig, { spaces: 2 });
28
+ }
@@ -0,0 +1,53 @@
1
+ #!/usr/bin/env node
2
+ import chalk from 'chalk';
3
+ import { Command } from 'commander';
4
+ import packageJson from '../../package.json' with { type: 'json' };
5
+ import { setupProject } from './commands/setup.js';
6
+ const program = new Command();
7
+ program
8
+ .name('@rtorcato/js-tooling')
9
+ .description('🛠️ JavaScript and TypeScript tooling setup for modern projects')
10
+ .version(packageJson.version);
11
+ program
12
+ .command('setup')
13
+ .alias('init')
14
+ .description('🚀 Setup tooling for a new or existing project')
15
+ .option('-d, --directory <path>', 'Target directory for setup', process.cwd())
16
+ .option('--skip-install', 'Skip installing dependencies')
17
+ .action(setupProject);
18
+ program
19
+ .command('list')
20
+ .alias('ls')
21
+ .description('📋 List all available tooling configurations')
22
+ .action(() => {
23
+ console.log(chalk.cyan('\n🛠️ Available tooling configurations:\n'));
24
+ const configs = [
25
+ { name: 'TypeScript', desc: 'Base, React, Next.js, Node.js, Express configurations' },
26
+ { name: 'ESLint', desc: 'Base and Next.js ESLint configurations' },
27
+ { name: 'Biome', desc: 'Fast formatter and linter configuration' },
28
+ { name: 'Prettier', desc: 'Code formatter configuration' },
29
+ { name: 'Vitest', desc: 'Testing framework configuration' },
30
+ { name: 'Jest', desc: 'Testing framework presets for browser and Node.js' },
31
+ { name: 'Playwright', desc: 'End-to-end testing configuration' },
32
+ { name: 'Commitlint', desc: 'Conventional commit linting' },
33
+ { name: 'Husky', desc: 'Git hooks for pre-commit validation' },
34
+ { name: 'Semantic Release', desc: 'Automated versioning and publishing' },
35
+ { name: 'tsup', desc: 'TypeScript bundler configuration' },
36
+ { name: 'esbuild', desc: 'Fast JavaScript bundler configuration' },
37
+ ];
38
+ configs.forEach(({ name, desc }) => {
39
+ console.log(` ${chalk.green('●')} ${chalk.bold(name)}: ${chalk.gray(desc)}`);
40
+ });
41
+ console.log(chalk.dim('\n💡 Run "js-tooling setup" to configure your project\n'));
42
+ });
43
+ // Handle unknown commands
44
+ program.on('command:*', () => {
45
+ console.error(chalk.red(`\n❌ Unknown command: ${program.args.join(' ')}`));
46
+ console.log(chalk.gray('See --help for a list of available commands.\n'));
47
+ process.exit(1);
48
+ });
49
+ // Show help if no arguments
50
+ if (!process.argv.slice(2).length) {
51
+ program.outputHelp();
52
+ }
53
+ program.parse();
@@ -0,0 +1,28 @@
1
+ import chalk from 'chalk';
2
+ import { spawn } from 'node:child_process';
3
+ export async function installDependencies(_config, targetDir) {
4
+ return new Promise((resolve) => {
5
+ console.log(chalk.blue('📦 Installing dependencies with pnpm...'));
6
+ const child = spawn('pnpm', ['install'], {
7
+ cwd: targetDir,
8
+ stdio: 'inherit',
9
+ shell: true,
10
+ });
11
+ child.on('close', (code) => {
12
+ if (code === 0) {
13
+ console.log(chalk.green('✅ Dependencies installed successfully!'));
14
+ resolve();
15
+ }
16
+ else {
17
+ console.error(chalk.red(`❌ pnpm install failed with code ${code}`));
18
+ console.log(chalk.yellow('💡 You can install dependencies manually with: pnpm install'));
19
+ resolve(); // Don't reject, just warn
20
+ }
21
+ });
22
+ child.on('error', (error) => {
23
+ console.error(chalk.red('❌ Error running pnpm install:'), error.message);
24
+ console.log(chalk.yellow('💡 You can install dependencies manually with: pnpm install'));
25
+ resolve(); // Don't reject, just warn
26
+ });
27
+ });
28
+ }
package/package.json ADDED
@@ -0,0 +1,160 @@
1
+ {
2
+ "name": "@rtorcato/js-tooling",
3
+ "version": "1.0.6",
4
+ "description": "JavaScript and TypeScript tooling for Node.js, React, Next.js, and Vitest.",
5
+ "type": "module",
6
+ "keywords": [
7
+ "tooling",
8
+ "typescript",
9
+ "eslint"
10
+ ],
11
+ "author": "Richard Torcato",
12
+ "sideEffects": false,
13
+ "license": "MIT",
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "https://github.com/rtorcato/js-tooling.git"
17
+ },
18
+ "homepage": "https://github.com/rtorcato/js-tooling#readme",
19
+ "bugs": {
20
+ "url": "https://github.com/rtorcato/js-tooling/issues"
21
+ },
22
+ "scripts": {
23
+ "build-dev": "rimraf ./dist && cross-env NODE_ENV=development node build.mjs && tsc --emitDeclarationOnly --project tsconfig.build.json && pnpm build-cli",
24
+ "build-prod": "rimraf ./dist && cross-env NODE_ENV=production node build.mjs && tsc --emitDeclarationOnly --project tsconfig.build.json && pnpm build-cli",
25
+ "build-cli": "rimraf ./dist/cli && tsc --project src/cli/tsconfig.json",
26
+ "prepublishOnly": "./scripts/fix-bins.sh",
27
+ "==================== Common ====================": "",
28
+ "lint": "pnpm exec biome lint .",
29
+ "format": "pnpm exec biome format .",
30
+ "check:fix": "pnpm exec biome check --fix",
31
+ "check": "pnpm exec biome check .",
32
+ "prepare": "is-ci || husky",
33
+ "typecheck1": "tsc --noEmit",
34
+ "test": "vitest",
35
+ "test:watch": "vitest --watch",
36
+ "coverage": "vitest run --coverage",
37
+ "commit": "cz",
38
+ "================================================": ""
39
+ },
40
+ "files": [
41
+ "dist/cli/**/*.js",
42
+ "tooling/*",
43
+ "tooling/commitlint/commitlint.config.mjs",
44
+ "tooling/esbuild/index.mjs",
45
+ "tooling/eslint/*.mjs",
46
+ "tooling/jest-presets/**",
47
+ "tooling/prettier/index.mjs",
48
+ "tooling/typescript/*.json",
49
+ "tooling/typescript/reset.d.ts",
50
+ "tooling/vitest/vitest.config.mjs",
51
+ "tooling/tsup/index.ts",
52
+ "tooling/biome/biome.json",
53
+ "tooling/semantic-release/*.mjs",
54
+ "README.md"
55
+ ],
56
+ "exports": {
57
+ "./commitlint/config": {
58
+ "import": "./tooling/commitlint/commitlint.mjs"
59
+ },
60
+ "./esbuild": "./tooling/esbuild/index.mjs",
61
+ "./eslint/base": "./tooling/eslint/base.mjs",
62
+ "./eslint/nextjs": "./tooling/eslint/nextjs.mjs",
63
+ "./jest-presets/browser/jest-preset": "./tooling/jest-presets/browser/jest-preset.mjs",
64
+ "./jest-presets/node/jest-preset": "./tooling/jest-presets/node/jest-preset.mjs",
65
+ "./prettier": "./tooling/prettier/index.mjs",
66
+ "./typescript/base": "./tooling/typescript/tsconfig.base.json",
67
+ "./typescript/next": "./tooling/typescript/tsconfig.next.json",
68
+ "./typescript/express": "./tooling/typescript/tsconfig.express.json",
69
+ "./typescript/node": "./tooling/typescript/tsconfig.node.json",
70
+ "./typescript/react": "./tooling/typescript/tsconfig.react.json",
71
+ "./typescript/test": "./tooling/typescript/tsconfig.test.json",
72
+ "./typescript/reset": "./tooling/typescript/reset.d.ts",
73
+ "./vitest/config": "./tooling/vitest/vitest.config.mjs",
74
+ "./tsup": "./tooling/tsup/index.ts",
75
+ "./biome": "./tooling/biome/biome.json",
76
+ "./semantic-release": "./tooling/semantic-release/index.mjs",
77
+ "./semantic-release/github": "./tooling/semantic-release/github.mjs",
78
+ "./semantic-release/docker": "./tooling/semantic-release/docker.mjs"
79
+ },
80
+ "dependencies": {
81
+ "@biomejs/biome": "^2.3.0",
82
+ "@commitlint/cli": "^20.1.0",
83
+ "@commitlint/config-conventional": "^20.0.0",
84
+ "@playwright/test": "^1.56.1",
85
+ "@semantic-release/commit-analyzer": "^13.0.1",
86
+ "@semantic-release/exec": "^7.1.0",
87
+ "@semantic-release/git": "^10.0.1",
88
+ "@semantic-release/npm": "^13.1.1",
89
+ "@semantic-release/release-notes-generator": "^14.1.0",
90
+ "@total-typescript/ts-reset": "0.6.1",
91
+ "@types/node": "^24.9.1",
92
+ "@typescript-eslint/eslint-plugin": "^8.46.2",
93
+ "@typescript-eslint/parser": "^8.46.2",
94
+ "@vitejs/plugin-react": "^5.1.0",
95
+ "chalk": "^5.6.2",
96
+ "commander": "^14.0.1",
97
+ "commitizen": "^4.3.1",
98
+ "conventional-changelog-conventionalcommits": "^9.1.0",
99
+ "cz-conventional-changelog": "^3.3.0",
100
+ "esbuild": "^0.25.11",
101
+ "esbuild-node-externals": "^1.18.0",
102
+ "fs-extra": "^11.3.2",
103
+ "husky": "^9.1.7",
104
+ "inquirer": "^12.10.0",
105
+ "lint-staged": "^16.2.6",
106
+ "semantic-release": "^25.0.1",
107
+ "typescript": "^5.9.3",
108
+ "typescript-eslint": "latest",
109
+ "vitest": "4.0.2"
110
+ },
111
+ "devDependencies": {
112
+ "@next/eslint-plugin-next": "^16.0.0",
113
+ "@semantic-release/changelog": "^6.0.3",
114
+ "@semantic-release/github": "^12.0.0",
115
+ "@types/fs-extra": "^11.0.4",
116
+ "@types/inquirer": "^9.0.9",
117
+ "cross-env": "^10.1.0",
118
+ "eslint": "9.38.0",
119
+ "eslint-config-airbnb": "^19.0.4",
120
+ "eslint-config-prettier": "10.1.8",
121
+ "eslint-config-turbo": "^2.5.8",
122
+ "eslint-plugin-import": "^2.32.0",
123
+ "eslint-plugin-jest": "29.0.1",
124
+ "eslint-plugin-jsx-a11y": "^6.10.2",
125
+ "eslint-plugin-react": "^7.37.5",
126
+ "eslint-plugin-react-hooks": "^7.0.0",
127
+ "eslint-plugin-vitest": "0.5.4",
128
+ "is-ci": "^4.1.0",
129
+ "prettier": "^3.6.2",
130
+ "prettier-plugin-tailwindcss": "^0.7.1",
131
+ "rimraf": "6.0.1",
132
+ "ts-jest": "^29.4.5",
133
+ "tsup": "8.5.0"
134
+ },
135
+ "lint-staged": {
136
+ "*.{js,ts,json,md}": [
137
+ "pnpm exec biome lint",
138
+ "pnpm exec biome format",
139
+ "git add"
140
+ ]
141
+ },
142
+ "husky": {
143
+ "hooks": {
144
+ "pre-commit": "lint-staged"
145
+ }
146
+ },
147
+ "bin": {
148
+ "js-tooling": "./dist/cli/index.js",
149
+ "commitmessage": "scripts/commitmessage.sh",
150
+ "helloworld": "scripts/helloworld.sh"
151
+ },
152
+ "config": {
153
+ "commitizen": {
154
+ "path": "cz-conventional-changelog"
155
+ }
156
+ },
157
+ "publishConfig": {
158
+ "access": "public"
159
+ }
160
+ }
@@ -0,0 +1,8 @@
1
+ pnpx js-tooling commitmessage
2
+ pnpx js-tooling version-bump
3
+ pnpx js-tooling genpassword
4
+
5
+ <!-- run before publish -->
6
+ pnpm exec ./scripts/fix-bins.sh
7
+
8
+ pnpm link --global
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # chmod +x scripts/commitmessage.sh
4
+ set -e
5
+
6
+ echo "Select commit type by number:"
7
+ select type in "feat" "fix" "perf" "ci" "WIP" "chore" "docs" "test" "style" "refactor" "build" "BREAKING CHANGE" "revert"; do
8
+ if [ -n "$type" ]; then
9
+ break
10
+ else
11
+ echo "❌ Invalid selection. Try again."
12
+ fi
13
+ done
14
+
15
+ if [[ "$type" =~ ^(feat|fix|perf)$ ]]; then
16
+ echo "Select semantic version by number:"
17
+ select semantic_version in "none" "patch" "minor" "major"; do
18
+ [ -n "$semantic_version" ] && break
19
+ done
20
+ else
21
+ semantic_version="none"
22
+ fi
23
+
24
+ read -p "Enter commit description: " description
25
+ read -p "Skip CI? (y/n) [n]: " skip_ci
26
+ skip_ci=${skip_ci:-n}
27
+
28
+ msg="$type"
29
+ [ "$semantic_version" != "none" ] && msg="$msg($semantic_version)"
30
+ msg="$msg: $description"
31
+ [ "$skip_ci" = "y" ] && msg="$msg [skip ci]"
32
+
33
+ echo ""
34
+ echo "🔍 Commit preview:"
35
+ echo "$msg"
36
+ read -p "Is this okay? (y/n): " confirm
37
+ [ "$confirm" != "y" ] && echo "❌ Commit aborted." && exit 1
38
+
39
+ git add -A
40
+ git commit -m "$msg"
41
+
42
+ echo ""
43
+ read -p "Do you want to push the commit? (y/n): " push_confirm
44
+ [ "$push_confirm" = "y" ] && git push || echo "🚫 Commit not pushed."
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # chmod +x scripts/helloworld.sh
4
+
5
+ echo "👋 Hello, world from js-tooling!"
@@ -0,0 +1,47 @@
1
+ {
2
+ "root": false,
3
+ "$schema": "https://biomejs.dev/schemas/2.3.0/schema.json",
4
+ "vcs": {
5
+ "enabled": false,
6
+ "clientKind": "git",
7
+ "useIgnoreFile": true
8
+ },
9
+ "files": {
10
+ "ignoreUnknown": false,
11
+ "includes": [
12
+ "**",
13
+ "!**/node_modules",
14
+ "!**/package.json",
15
+ "!**/tsconfig*.json",
16
+ "!**/dist",
17
+ "!**/coverage",
18
+ "!**/.git",
19
+ "!**/.github",
20
+ "!**/.vscode"
21
+ ]
22
+ },
23
+ "formatter": {
24
+ "enabled": true,
25
+ "indentStyle": "tab",
26
+ "lineWidth": 100
27
+ },
28
+ "assist": { "actions": { "source": { "organizeImports": "on" } } },
29
+ "linter": {
30
+ "enabled": true,
31
+ "rules": {
32
+ "recommended": true,
33
+ "style": {
34
+ "noInferrableTypes": "off"
35
+ }
36
+ // "noUnusedVariables": "error", ❌ Not supported yet
37
+ // "noExplicitAny": "warn" ❌ Not supported yet
38
+ }
39
+ },
40
+ "javascript": {
41
+ "formatter": {
42
+ "quoteStyle": "single",
43
+ "trailingCommas": "es5",
44
+ "semicolons": "asNeeded"
45
+ }
46
+ }
47
+ }