@rtorcato/repo-tooling 2.59.0

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 (136) hide show
  1. package/AGENTS.md +113 -0
  2. package/LICENSE +21 -0
  3. package/README.md +201 -0
  4. package/dist/cli/commands/doctor.js +336 -0
  5. package/dist/cli/commands/fix-targets.js +192 -0
  6. package/dist/cli/commands/fix.js +440 -0
  7. package/dist/cli/commands/setup-presets.js +281 -0
  8. package/dist/cli/commands/setup.js +501 -0
  9. package/dist/cli/generators/agent-rules.js +103 -0
  10. package/dist/cli/generators/badges.js +88 -0
  11. package/dist/cli/generators/build.js +216 -0
  12. package/dist/cli/generators/bun.js +25 -0
  13. package/dist/cli/generators/community-health.js +145 -0
  14. package/dist/cli/generators/docs-site.js +436 -0
  15. package/dist/cli/generators/git.js +164 -0
  16. package/dist/cli/generators/github-actions.js +35 -0
  17. package/dist/cli/generators/github-workflows.js +24 -0
  18. package/dist/cli/generators/gitlab-ci.js +10 -0
  19. package/dist/cli/generators/index.js +123 -0
  20. package/dist/cli/generators/linting.js +54 -0
  21. package/dist/cli/generators/misc.js +298 -0
  22. package/dist/cli/generators/nx.js +16 -0
  23. package/dist/cli/generators/package-json.js +317 -0
  24. package/dist/cli/generators/pnpm-workspace.js +126 -0
  25. package/dist/cli/generators/postcss.js +24 -0
  26. package/dist/cli/generators/readme.js +268 -0
  27. package/dist/cli/generators/security.js +156 -0
  28. package/dist/cli/generators/skills-install.js +70 -0
  29. package/dist/cli/generators/tailwind.js +34 -0
  30. package/dist/cli/generators/testing.js +88 -0
  31. package/dist/cli/generators/treeshake.js +148 -0
  32. package/dist/cli/generators/tsconfig.js +27 -0
  33. package/dist/cli/generators/turborepo.js +35 -0
  34. package/dist/cli/generators/typedoc.js +40 -0
  35. package/dist/cli/index.js +332 -0
  36. package/dist/cli/utils/copy-preset.js +98 -0
  37. package/dist/cli/utils/detect-language.js +22 -0
  38. package/dist/cli/utils/format.js +32 -0
  39. package/dist/cli/utils/install.js +28 -0
  40. package/dist/cli/utils/lockfile.js +84 -0
  41. package/dist/languages/js/checks.js +949 -0
  42. package/dist/languages/js/ci.js +251 -0
  43. package/dist/languages/js/fixers.js +735 -0
  44. package/dist/languages/registry.js +37 -0
  45. package/dist/languages/swift/checks.js +127 -0
  46. package/dist/languages/swift/ci.js +165 -0
  47. package/dist/languages/swift/fixers.js +102 -0
  48. package/dist/languages/swift/git-hooks.js +63 -0
  49. package/dist/languages/swift/gitignore.js +43 -0
  50. package/dist/languages/swift/scaffold.js +244 -0
  51. package/package.json +461 -0
  52. package/tooling/biome/README.md +90 -0
  53. package/tooling/biome/biome.json +63 -0
  54. package/tooling/bun/bunfig.toml +14 -0
  55. package/tooling/changesets/README.md +35 -0
  56. package/tooling/changesets/config.json +11 -0
  57. package/tooling/claude/repo-tooling.md +87 -0
  58. package/tooling/commitlint/commitlint.d.mts +4 -0
  59. package/tooling/commitlint/commitlint.mjs +40 -0
  60. package/tooling/cypress/cypress.config.d.mts +4 -0
  61. package/tooling/cypress/cypress.config.mjs +11 -0
  62. package/tooling/docusaurus/index.d.mts +17 -0
  63. package/tooling/docusaurus/index.mjs +38 -0
  64. package/tooling/docusaurus/sync-changelog.mjs +42 -0
  65. package/tooling/docusaurus/theme-tokens.css +79 -0
  66. package/tooling/docusaurus/theme.css +378 -0
  67. package/tooling/esbuild/index.d.mts +6 -0
  68. package/tooling/esbuild/index.mjs +102 -0
  69. package/tooling/eslint/base.d.mts +6 -0
  70. package/tooling/eslint/base.mjs +122 -0
  71. package/tooling/eslint/nextjs.d.mts +4 -0
  72. package/tooling/eslint/nextjs.mjs +22 -0
  73. package/tooling/eslint/types.d.ts +58 -0
  74. package/tooling/github-actions/workflows/cloudflare-pages.yml +42 -0
  75. package/tooling/github-actions/workflows/docker-publish.yml +44 -0
  76. package/tooling/github-actions/workflows/preview-deployments.yml +54 -0
  77. package/tooling/github-actions/workflows/vercel-deploy.yml +40 -0
  78. package/tooling/jest-presets/browser/jest-preset.d.mts +4 -0
  79. package/tooling/jest-presets/browser/jest-preset.mjs +14 -0
  80. package/tooling/jest-presets/node/jest-preset.d.mts +4 -0
  81. package/tooling/jest-presets/node/jest-preset.mjs +13 -0
  82. package/tooling/mcp/mcp.json.example +27 -0
  83. package/tooling/nx/nx.json +24 -0
  84. package/tooling/oxlint/README.md +25 -0
  85. package/tooling/oxlint/oxlintrc.json +28 -0
  86. package/tooling/playwright/playwright.config.d.mts +4 -0
  87. package/tooling/playwright/playwright.config.mjs +19 -0
  88. package/tooling/prettier/index.d.mts +4 -0
  89. package/tooling/prettier/index.mjs +36 -0
  90. package/tooling/release-please/.release-please-manifest.json +3 -0
  91. package/tooling/release-please/release-please-config.json +9 -0
  92. package/tooling/rolldown/rolldown.config.d.mts +18 -0
  93. package/tooling/rolldown/rolldown.config.mjs +59 -0
  94. package/tooling/rollup/rollup.config.d.mts +20 -0
  95. package/tooling/rollup/rollup.config.mjs +70 -0
  96. package/tooling/semantic-release/docker.d.mts +4 -0
  97. package/tooling/semantic-release/docker.mjs +59 -0
  98. package/tooling/semantic-release/github.d.mts +4 -0
  99. package/tooling/semantic-release/github.mjs +79 -0
  100. package/tooling/semantic-release/index.d.mts +4 -0
  101. package/tooling/semantic-release/index.mjs +80 -0
  102. package/tooling/swift/periphery.yml +4 -0
  103. package/tooling/swift/swiftlint.yml +23 -0
  104. package/tooling/tests/exports-resolution.d.mts +14 -0
  105. package/tooling/tests/exports-resolution.mjs +68 -0
  106. package/tooling/tests/ssr-safety.d.mts +14 -0
  107. package/tooling/tests/ssr-safety.mjs +53 -0
  108. package/tooling/tsup/index.d.mts +8 -0
  109. package/tooling/tsup/index.mjs +33 -0
  110. package/tooling/typedoc/typedoc.json +7 -0
  111. package/tooling/typescript/README.md +49 -0
  112. package/tooling/typescript/reset.d.ts +9 -0
  113. package/tooling/typescript/tsconfig.base.json +84 -0
  114. package/tooling/typescript/tsconfig.build.json +11 -0
  115. package/tooling/typescript/tsconfig.bun.json +9 -0
  116. package/tooling/typescript/tsconfig.express.json +9 -0
  117. package/tooling/typescript/tsconfig.next.json +20 -0
  118. package/tooling/typescript/tsconfig.node.json +9 -0
  119. package/tooling/typescript/tsconfig.react.json +15 -0
  120. package/tooling/typescript/tsconfig.test.json +8 -0
  121. package/tooling/typescript/v1/tsconfig.base.json +81 -0
  122. package/tooling/typescript/v1/tsconfig.express.json +9 -0
  123. package/tooling/typescript/v1/tsconfig.next.json +19 -0
  124. package/tooling/typescript/v1/tsconfig.node.json +9 -0
  125. package/tooling/typescript/v1/tsconfig.react.json +14 -0
  126. package/tooling/typescript/v1/tsconfig.test.json +8 -0
  127. package/tooling/vite/vite.config.d.mts +4 -0
  128. package/tooling/vite/vite.config.mjs +18 -0
  129. package/tooling/vitest/jsdom-shims.d.mts +1 -0
  130. package/tooling/vitest/jsdom-shims.mjs +58 -0
  131. package/tooling/vitest/vitest.config.d.mts +4 -0
  132. package/tooling/vitest/vitest.config.mjs +25 -0
  133. package/tooling/vitest/vitest.config.react.d.mts +4 -0
  134. package/tooling/vitest/vitest.config.react.mjs +27 -0
  135. package/tooling/vitest/vitest.setup.d.mts +1 -0
  136. package/tooling/vitest/vitest.setup.mjs +3 -0
@@ -0,0 +1,281 @@
1
+ import { swiftFileList } from '../../languages/swift/scaffold.js';
2
+ export const PRESET_NAMES = [
3
+ 'library',
4
+ 'web-app',
5
+ 'node-api',
6
+ 'nextjs-app',
7
+ 'react-app',
8
+ 'swift-library',
9
+ ];
10
+ const BASE = {
11
+ language: 'js',
12
+ linting: { tool: 'biome' },
13
+ formatting: { tool: 'biome' },
14
+ testing: { framework: 'vitest', environment: 'node' },
15
+ gitHooks: true,
16
+ commitLint: true,
17
+ semanticRelease: false,
18
+ securityAutomation: true,
19
+ badges: true,
20
+ aiSetup: true,
21
+ };
22
+ export function buildPresetConfig(name, projectName) {
23
+ switch (name) {
24
+ case 'library':
25
+ return {
26
+ ...BASE,
27
+ projectName,
28
+ projectType: 'library',
29
+ typescript: { enabled: true, config: 'base' },
30
+ semanticRelease: true,
31
+ bundler: 'tsup',
32
+ publint: true,
33
+ };
34
+ case 'web-app':
35
+ return {
36
+ ...BASE,
37
+ projectName,
38
+ projectType: 'web-app',
39
+ typescript: { enabled: true, config: 'base' },
40
+ testing: { framework: 'vitest', environment: 'browser' },
41
+ bundler: 'vite',
42
+ };
43
+ case 'node-api':
44
+ return {
45
+ ...BASE,
46
+ projectName,
47
+ projectType: 'node-api',
48
+ typescript: { enabled: true, config: 'node' },
49
+ bundler: 'esbuild',
50
+ };
51
+ case 'nextjs-app':
52
+ return {
53
+ ...BASE,
54
+ projectName,
55
+ projectType: 'nextjs-app',
56
+ typescript: { enabled: true, config: 'next' },
57
+ linting: { tool: 'eslint', eslintConfig: 'nextjs' },
58
+ formatting: { tool: 'prettier' },
59
+ bundler: 'none',
60
+ };
61
+ case 'react-app':
62
+ return {
63
+ ...BASE,
64
+ projectName,
65
+ projectType: 'react-app',
66
+ typescript: { enabled: true, config: 'react' },
67
+ testing: { framework: 'vitest', environment: 'browser' },
68
+ bundler: 'vite',
69
+ };
70
+ // A SwiftPM library (#288). Deliberately not spread from BASE: every one
71
+ // of its tool choices names a JS tool. The JS-shaped fields below are all
72
+ // "no JS tool", which is not the same as "no tooling" — SwiftLint,
73
+ // Periphery and `swift test` are wired unconditionally by the Swift
74
+ // scaffolder, because unlike the JS path there's nothing to choose
75
+ // between. They're set explicitly because ProjectConfig requires them and
76
+ // the lockfile records them.
77
+ case 'swift-library':
78
+ return {
79
+ projectName,
80
+ language: 'swift',
81
+ projectType: 'library',
82
+ typescript: { enabled: false, config: 'base' },
83
+ linting: { tool: 'none' },
84
+ formatting: { tool: 'none' },
85
+ testing: { framework: 'none' },
86
+ // Husky is an npm package, but git hooks aren't (#309): the Swift path
87
+ // commits `.githooks/` and points git at it with `core.hooksPath`.
88
+ gitHooks: true,
89
+ // commitlint *is* an npm package and needs node on PATH to run, so
90
+ // the Swift hooks deliberately wire no commit-msg hook.
91
+ commitLint: false,
92
+ // semantic-release publishes to npm. SwiftPM consumes git tags.
93
+ semanticRelease: false,
94
+ securityAutomation: true,
95
+ bundler: 'none',
96
+ // Every badge URL is derived from package.json (name + repository),
97
+ // so on a Swift repo the block would always render empty.
98
+ badges: false,
99
+ aiSetup: true,
100
+ };
101
+ }
102
+ }
103
+ export const CONFIG_SCHEMA = {
104
+ $schema: 'https://json-schema.org/draft/2020-12/schema',
105
+ $id: 'https://rtorcato.github.io/repo-tooling/schemas/project-config.json',
106
+ title: 'ProjectConfig',
107
+ description: '@rtorcato/repo-tooling setup configuration',
108
+ type: 'object',
109
+ additionalProperties: false,
110
+ required: [
111
+ 'projectName',
112
+ 'projectType',
113
+ 'typescript',
114
+ 'linting',
115
+ 'formatting',
116
+ 'testing',
117
+ 'gitHooks',
118
+ 'commitLint',
119
+ 'semanticRelease',
120
+ 'securityAutomation',
121
+ 'bundler',
122
+ ],
123
+ properties: {
124
+ projectName: { type: 'string', minLength: 1 },
125
+ language: { type: 'string', enum: ['js', 'swift', 'perl', 'python'] },
126
+ projectType: {
127
+ type: 'string',
128
+ enum: ['library', 'web-app', 'node-api', 'nextjs-app', 'react-app'],
129
+ },
130
+ typescript: {
131
+ type: 'object',
132
+ additionalProperties: false,
133
+ required: ['enabled', 'config'],
134
+ properties: {
135
+ enabled: { type: 'boolean' },
136
+ config: { type: 'string', enum: ['base', 'react', 'next', 'node', 'express'] },
137
+ },
138
+ },
139
+ linting: {
140
+ type: 'object',
141
+ additionalProperties: false,
142
+ required: ['tool'],
143
+ properties: {
144
+ tool: { type: 'string', enum: ['biome', 'eslint', 'both', 'none'] },
145
+ eslintConfig: { type: 'string', enum: ['base', 'nextjs'] },
146
+ },
147
+ },
148
+ formatting: {
149
+ type: 'object',
150
+ additionalProperties: false,
151
+ required: ['tool'],
152
+ properties: { tool: { type: 'string', enum: ['biome', 'prettier', 'none'] } },
153
+ },
154
+ testing: {
155
+ type: 'object',
156
+ additionalProperties: false,
157
+ required: ['framework'],
158
+ properties: {
159
+ framework: { type: 'string', enum: ['vitest', 'jest', 'playwright', 'cypress', 'none'] },
160
+ environment: { type: 'string', enum: ['node', 'browser', 'both'] },
161
+ },
162
+ },
163
+ gitHooks: { type: 'boolean' },
164
+ commitLint: { type: 'boolean' },
165
+ semanticRelease: { type: 'boolean' },
166
+ changesets: { type: 'boolean' },
167
+ releasePlease: { type: 'boolean' },
168
+ oxlint: { type: 'boolean' },
169
+ securityAutomation: { type: 'boolean' },
170
+ bundler: { type: 'string', enum: ['tsup', 'esbuild', 'rollup', 'rolldown', 'vite', 'none'] },
171
+ treeshakeCheck: { type: 'boolean' },
172
+ publint: { type: 'boolean' },
173
+ badges: { type: 'boolean' },
174
+ aiSetup: { type: 'boolean' },
175
+ turborepo: { type: 'boolean' },
176
+ nx: { type: 'boolean' },
177
+ tailwind: { type: 'boolean' },
178
+ bun: { type: 'boolean' },
179
+ },
180
+ };
181
+ const ALLOWED_KEYS = new Set([
182
+ ...CONFIG_SCHEMA.required,
183
+ ...Object.keys(CONFIG_SCHEMA.properties),
184
+ ]);
185
+ export function validateProjectConfig(input) {
186
+ const errors = [];
187
+ if (typeof input !== 'object' || input === null || Array.isArray(input)) {
188
+ return { valid: false, errors: ['Config must be a JSON object'] };
189
+ }
190
+ const obj = input;
191
+ for (const key of Object.keys(obj)) {
192
+ if (!ALLOWED_KEYS.has(key))
193
+ errors.push(`Unknown field: ${key}`);
194
+ }
195
+ for (const required of CONFIG_SCHEMA.required) {
196
+ if (!(required in obj))
197
+ errors.push(`Missing required field: ${required}`);
198
+ }
199
+ return { valid: errors.length === 0, errors };
200
+ }
201
+ export function computeFileList(config) {
202
+ // Swift shares the language-agnostic files but none of the package.json-rooted
203
+ // ones, so its list is built by the Swift scaffolder rather than filtered out
204
+ // of this one condition by condition.
205
+ if (config.language === 'swift')
206
+ return swiftFileList(config);
207
+ const files = ['package.json', '.repo-tooling.json'];
208
+ files.push('.editorconfig', '.nvmrc', 'knip.json', '.vscode/extensions.json');
209
+ if (config.typescript.enabled) {
210
+ files.push('tsconfig.json', 'reset.d.ts');
211
+ }
212
+ if (config.linting.tool === 'biome' || config.linting.tool === 'both') {
213
+ files.push('biome.jsonc');
214
+ }
215
+ if (config.linting.tool === 'eslint' || config.linting.tool === 'both') {
216
+ files.push('eslint.config.mjs');
217
+ }
218
+ if (config.linting.tool === 'eslint') {
219
+ files.push('prettier.config.mjs');
220
+ }
221
+ if (config.testing.framework === 'vitest') {
222
+ files.push('vitest.config.ts', 'vitest.setup.ts', 'codecov.yml');
223
+ }
224
+ if (config.testing.framework === 'jest') {
225
+ files.push('jest.config.mjs');
226
+ }
227
+ if (config.testing.framework === 'playwright') {
228
+ files.push('playwright.config.ts');
229
+ }
230
+ if (config.testing.framework === 'cypress') {
231
+ files.push('cypress.config.ts', 'cypress/support/e2e.ts', 'cypress/support/commands.ts', 'tests/e2e/example.cy.ts');
232
+ }
233
+ if (config.gitHooks) {
234
+ files.push('.husky/pre-commit', '.gitignore');
235
+ }
236
+ if (config.commitLint) {
237
+ files.push('.husky/commit-msg', 'commitlint.config.mjs');
238
+ }
239
+ files.push('.github/workflows/ci.yml');
240
+ if (config.securityAutomation) {
241
+ files.push('.github/dependabot.yml', '.github/workflows/dependabot-automerge.yml', '.github/workflows/codeql.yml');
242
+ }
243
+ if (config.bundler === 'tsup')
244
+ files.push('tsup.config.ts');
245
+ else if (config.bundler === 'esbuild')
246
+ files.push('build.mjs');
247
+ else if (config.bundler === 'rollup')
248
+ files.push('rollup.config.mjs');
249
+ else if (config.bundler === 'rolldown')
250
+ files.push('rolldown.config.mjs');
251
+ else if (config.bundler === 'vite')
252
+ files.push('vite.config.ts');
253
+ if (config.semanticRelease)
254
+ files.push('release.config.mjs');
255
+ if (config.changesets)
256
+ files.push('.changeset/config.json');
257
+ if (config.releasePlease)
258
+ files.push('release-please-config.json', '.release-please-manifest.json', '.github/workflows/release-please.yml');
259
+ if (config.oxlint)
260
+ files.push('.oxlintrc.json');
261
+ if (config.treeshakeCheck && config.projectType === 'library') {
262
+ files.push('apps/treeshake-check/package.json', 'apps/treeshake-check/check.mjs', 'apps/treeshake-check/src/entry.ts');
263
+ }
264
+ // pnpm-workspace.yaml carries the family-wide pnpm settings (#314) plus, where
265
+ // they apply, build-script approvals and the treeshake path's apps/* glob —
266
+ // so it's written for every JS scaffold.
267
+ files.push('pnpm-workspace.yaml');
268
+ if (config.aiSetup) {
269
+ files.push('AGENTS.md', 'CLAUDE.md', '.cursor/rules/repo-tooling.mdc', '.github/copilot-instructions.md', '.claude/skills/repo-tooling.md', '.mcp.json.example');
270
+ }
271
+ if (config.turborepo)
272
+ files.push('turbo.json');
273
+ if (config.nx)
274
+ files.push('nx.json');
275
+ if (config.tailwind)
276
+ files.push('postcss.config.mjs', 'src/styles/globals.css');
277
+ if (config.bun)
278
+ files.push('bunfig.toml');
279
+ files.push('README.md');
280
+ return files;
281
+ }