@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.
- package/AGENTS.md +113 -0
- package/LICENSE +21 -0
- package/README.md +201 -0
- package/dist/cli/commands/doctor.js +336 -0
- package/dist/cli/commands/fix-targets.js +192 -0
- package/dist/cli/commands/fix.js +440 -0
- package/dist/cli/commands/setup-presets.js +281 -0
- package/dist/cli/commands/setup.js +501 -0
- package/dist/cli/generators/agent-rules.js +103 -0
- package/dist/cli/generators/badges.js +88 -0
- package/dist/cli/generators/build.js +216 -0
- package/dist/cli/generators/bun.js +25 -0
- package/dist/cli/generators/community-health.js +145 -0
- package/dist/cli/generators/docs-site.js +436 -0
- package/dist/cli/generators/git.js +164 -0
- package/dist/cli/generators/github-actions.js +35 -0
- package/dist/cli/generators/github-workflows.js +24 -0
- package/dist/cli/generators/gitlab-ci.js +10 -0
- package/dist/cli/generators/index.js +123 -0
- package/dist/cli/generators/linting.js +54 -0
- package/dist/cli/generators/misc.js +298 -0
- package/dist/cli/generators/nx.js +16 -0
- package/dist/cli/generators/package-json.js +317 -0
- package/dist/cli/generators/pnpm-workspace.js +126 -0
- package/dist/cli/generators/postcss.js +24 -0
- package/dist/cli/generators/readme.js +268 -0
- package/dist/cli/generators/security.js +156 -0
- package/dist/cli/generators/skills-install.js +70 -0
- package/dist/cli/generators/tailwind.js +34 -0
- package/dist/cli/generators/testing.js +88 -0
- package/dist/cli/generators/treeshake.js +148 -0
- package/dist/cli/generators/tsconfig.js +27 -0
- package/dist/cli/generators/turborepo.js +35 -0
- package/dist/cli/generators/typedoc.js +40 -0
- package/dist/cli/index.js +332 -0
- package/dist/cli/utils/copy-preset.js +98 -0
- package/dist/cli/utils/detect-language.js +22 -0
- package/dist/cli/utils/format.js +32 -0
- package/dist/cli/utils/install.js +28 -0
- package/dist/cli/utils/lockfile.js +84 -0
- package/dist/languages/js/checks.js +949 -0
- package/dist/languages/js/ci.js +251 -0
- package/dist/languages/js/fixers.js +735 -0
- package/dist/languages/registry.js +37 -0
- package/dist/languages/swift/checks.js +127 -0
- package/dist/languages/swift/ci.js +165 -0
- package/dist/languages/swift/fixers.js +102 -0
- package/dist/languages/swift/git-hooks.js +63 -0
- package/dist/languages/swift/gitignore.js +43 -0
- package/dist/languages/swift/scaffold.js +244 -0
- package/package.json +461 -0
- package/tooling/biome/README.md +90 -0
- package/tooling/biome/biome.json +63 -0
- package/tooling/bun/bunfig.toml +14 -0
- package/tooling/changesets/README.md +35 -0
- package/tooling/changesets/config.json +11 -0
- package/tooling/claude/repo-tooling.md +87 -0
- package/tooling/commitlint/commitlint.d.mts +4 -0
- package/tooling/commitlint/commitlint.mjs +40 -0
- package/tooling/cypress/cypress.config.d.mts +4 -0
- package/tooling/cypress/cypress.config.mjs +11 -0
- package/tooling/docusaurus/index.d.mts +17 -0
- package/tooling/docusaurus/index.mjs +38 -0
- package/tooling/docusaurus/sync-changelog.mjs +42 -0
- package/tooling/docusaurus/theme-tokens.css +79 -0
- package/tooling/docusaurus/theme.css +378 -0
- package/tooling/esbuild/index.d.mts +6 -0
- package/tooling/esbuild/index.mjs +102 -0
- package/tooling/eslint/base.d.mts +6 -0
- package/tooling/eslint/base.mjs +122 -0
- package/tooling/eslint/nextjs.d.mts +4 -0
- package/tooling/eslint/nextjs.mjs +22 -0
- package/tooling/eslint/types.d.ts +58 -0
- package/tooling/github-actions/workflows/cloudflare-pages.yml +42 -0
- package/tooling/github-actions/workflows/docker-publish.yml +44 -0
- package/tooling/github-actions/workflows/preview-deployments.yml +54 -0
- package/tooling/github-actions/workflows/vercel-deploy.yml +40 -0
- package/tooling/jest-presets/browser/jest-preset.d.mts +4 -0
- package/tooling/jest-presets/browser/jest-preset.mjs +14 -0
- package/tooling/jest-presets/node/jest-preset.d.mts +4 -0
- package/tooling/jest-presets/node/jest-preset.mjs +13 -0
- package/tooling/mcp/mcp.json.example +27 -0
- package/tooling/nx/nx.json +24 -0
- package/tooling/oxlint/README.md +25 -0
- package/tooling/oxlint/oxlintrc.json +28 -0
- package/tooling/playwright/playwright.config.d.mts +4 -0
- package/tooling/playwright/playwright.config.mjs +19 -0
- package/tooling/prettier/index.d.mts +4 -0
- package/tooling/prettier/index.mjs +36 -0
- package/tooling/release-please/.release-please-manifest.json +3 -0
- package/tooling/release-please/release-please-config.json +9 -0
- package/tooling/rolldown/rolldown.config.d.mts +18 -0
- package/tooling/rolldown/rolldown.config.mjs +59 -0
- package/tooling/rollup/rollup.config.d.mts +20 -0
- package/tooling/rollup/rollup.config.mjs +70 -0
- package/tooling/semantic-release/docker.d.mts +4 -0
- package/tooling/semantic-release/docker.mjs +59 -0
- package/tooling/semantic-release/github.d.mts +4 -0
- package/tooling/semantic-release/github.mjs +79 -0
- package/tooling/semantic-release/index.d.mts +4 -0
- package/tooling/semantic-release/index.mjs +80 -0
- package/tooling/swift/periphery.yml +4 -0
- package/tooling/swift/swiftlint.yml +23 -0
- package/tooling/tests/exports-resolution.d.mts +14 -0
- package/tooling/tests/exports-resolution.mjs +68 -0
- package/tooling/tests/ssr-safety.d.mts +14 -0
- package/tooling/tests/ssr-safety.mjs +53 -0
- package/tooling/tsup/index.d.mts +8 -0
- package/tooling/tsup/index.mjs +33 -0
- package/tooling/typedoc/typedoc.json +7 -0
- package/tooling/typescript/README.md +49 -0
- package/tooling/typescript/reset.d.ts +9 -0
- package/tooling/typescript/tsconfig.base.json +84 -0
- package/tooling/typescript/tsconfig.build.json +11 -0
- package/tooling/typescript/tsconfig.bun.json +9 -0
- package/tooling/typescript/tsconfig.express.json +9 -0
- package/tooling/typescript/tsconfig.next.json +20 -0
- package/tooling/typescript/tsconfig.node.json +9 -0
- package/tooling/typescript/tsconfig.react.json +15 -0
- package/tooling/typescript/tsconfig.test.json +8 -0
- package/tooling/typescript/v1/tsconfig.base.json +81 -0
- package/tooling/typescript/v1/tsconfig.express.json +9 -0
- package/tooling/typescript/v1/tsconfig.next.json +19 -0
- package/tooling/typescript/v1/tsconfig.node.json +9 -0
- package/tooling/typescript/v1/tsconfig.react.json +14 -0
- package/tooling/typescript/v1/tsconfig.test.json +8 -0
- package/tooling/vite/vite.config.d.mts +4 -0
- package/tooling/vite/vite.config.mjs +18 -0
- package/tooling/vitest/jsdom-shims.d.mts +1 -0
- package/tooling/vitest/jsdom-shims.mjs +58 -0
- package/tooling/vitest/vitest.config.d.mts +4 -0
- package/tooling/vitest/vitest.config.mjs +25 -0
- package/tooling/vitest/vitest.config.react.d.mts +4 -0
- package/tooling/vitest/vitest.config.react.mjs +27 -0
- package/tooling/vitest/vitest.setup.d.mts +1 -0
- package/tooling/vitest/vitest.setup.mjs +3 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import fs from 'fs-extra';
|
|
3
|
+
/**
|
|
4
|
+
* Marker files that identify a repo's language, checked in order — first match
|
|
5
|
+
* wins. One language per repo root; multi-language monorepos are out of scope
|
|
6
|
+
* for v1 (see #139). A dir with no marker → 'unknown' (base checks only).
|
|
7
|
+
*/
|
|
8
|
+
const MARKERS = [
|
|
9
|
+
['js', ['package.json']],
|
|
10
|
+
['swift', ['Package.swift']],
|
|
11
|
+
['perl', ['cpanfile', 'Makefile.PL', 'dist.ini']],
|
|
12
|
+
['python', ['pyproject.toml', 'setup.py']],
|
|
13
|
+
];
|
|
14
|
+
export async function detectLanguage(dir) {
|
|
15
|
+
for (const [language, candidates] of MARKERS) {
|
|
16
|
+
for (const candidate of candidates) {
|
|
17
|
+
if (await fs.pathExists(path.join(dir, candidate)))
|
|
18
|
+
return language;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return 'unknown';
|
|
22
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { spawn } from 'node:child_process';
|
|
3
|
+
function run(cmd, args, cwd) {
|
|
4
|
+
return new Promise((resolve) => {
|
|
5
|
+
const child = spawn(cmd, args, { cwd, stdio: 'inherit', shell: true });
|
|
6
|
+
child.on('close', (code) => resolve(code ?? 1));
|
|
7
|
+
child.on('error', () => resolve(1));
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Generated config files come from hand-built templates whose whitespace doesn't
|
|
12
|
+
* match the project's shipped formatter (biome collapses JSON arrays and uses
|
|
13
|
+
* tabs + trailing commas). Run the formatter once, post-install, so a fresh
|
|
14
|
+
* scaffold passes its own `pnpm check` / lint out of the box instead of failing
|
|
15
|
+
* on the consumer's first verify. Best-effort: never fails setup.
|
|
16
|
+
*/
|
|
17
|
+
export async function formatGeneratedFiles(config, targetDir) {
|
|
18
|
+
const usesBiome = config.linting.tool === 'biome' || config.linting.tool === 'both';
|
|
19
|
+
const usesEslint = config.linting.tool === 'eslint' || config.linting.tool === 'both';
|
|
20
|
+
if (usesBiome) {
|
|
21
|
+
await run('pnpm', ['exec', 'biome', 'check', '--write', '.'], targetDir);
|
|
22
|
+
}
|
|
23
|
+
if (config.formatting.tool === 'prettier') {
|
|
24
|
+
await run('pnpm', ['exec', 'prettier', '--write', '.'], targetDir);
|
|
25
|
+
}
|
|
26
|
+
if (usesEslint) {
|
|
27
|
+
await run('pnpm', ['exec', 'eslint', '.', '--fix'], targetDir);
|
|
28
|
+
}
|
|
29
|
+
if (usesBiome || usesEslint || config.formatting.tool === 'prettier') {
|
|
30
|
+
console.log(chalk.green('✨ Formatted generated files'));
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import fs from 'fs-extra';
|
|
3
|
+
import packageJson from '../../../package.json' with { type: 'json' };
|
|
4
|
+
import { validateProjectConfig } from '../commands/setup-presets.js';
|
|
5
|
+
export const LOCKFILE_NAME = '.repo-tooling.json';
|
|
6
|
+
// Name used before the js-tooling→repo-tooling rename (#272). Repos set up on an
|
|
7
|
+
// older version still have it: readLockfile falls back to it, and writeLockfile
|
|
8
|
+
// migrates to the new name (removing the old file) on the next write.
|
|
9
|
+
export const LEGACY_LOCKFILE_NAME = '.js-tooling.json';
|
|
10
|
+
// v2 added ProjectConfig.language (multi-language seam, #140). v1 files are
|
|
11
|
+
// migrated to v2 on read, defaulting language to 'js'.
|
|
12
|
+
export const LOCKFILE_VERSION = 2;
|
|
13
|
+
const LOCKFILE_SCHEMA_URL = 'https://rtorcato.github.io/repo-tooling/schemas/lockfile.json';
|
|
14
|
+
/**
|
|
15
|
+
* Upgrade an older lockfile in-memory. Only touches files older than the
|
|
16
|
+
* current version, so a newer-than-supported file is left as-is for
|
|
17
|
+
* checkLockfile to flag. The file is rewritten to v2 next time it's saved.
|
|
18
|
+
*/
|
|
19
|
+
function migrate(lock) {
|
|
20
|
+
if (lock.version >= LOCKFILE_VERSION)
|
|
21
|
+
return lock;
|
|
22
|
+
return {
|
|
23
|
+
...lock,
|
|
24
|
+
version: LOCKFILE_VERSION,
|
|
25
|
+
config: { language: 'js', ...lock.config },
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export async function readLockfile(dir) {
|
|
29
|
+
let filepath = path.join(dir, LOCKFILE_NAME);
|
|
30
|
+
if (!(await fs.pathExists(filepath))) {
|
|
31
|
+
// Fall back to the pre-rename name so existing repos keep working (#272).
|
|
32
|
+
const legacy = path.join(dir, LEGACY_LOCKFILE_NAME);
|
|
33
|
+
if (!(await fs.pathExists(legacy)))
|
|
34
|
+
return null;
|
|
35
|
+
filepath = legacy;
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
const raw = (await fs.readJson(filepath));
|
|
39
|
+
if (typeof raw !== 'object' || raw === null)
|
|
40
|
+
return null;
|
|
41
|
+
const obj = raw;
|
|
42
|
+
if (typeof obj.version !== 'number')
|
|
43
|
+
return null;
|
|
44
|
+
if (typeof obj.config !== 'object' || obj.config === null)
|
|
45
|
+
return null;
|
|
46
|
+
return migrate(obj);
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
export async function writeLockfile(dir, config) {
|
|
53
|
+
const { valid, errors } = validateProjectConfig(config);
|
|
54
|
+
if (!valid) {
|
|
55
|
+
throw new Error(`Refusing to write invalid lockfile:\n - ${errors.join('\n - ')}`);
|
|
56
|
+
}
|
|
57
|
+
const filepath = path.join(dir, LOCKFILE_NAME);
|
|
58
|
+
const lockfile = {
|
|
59
|
+
$schema: LOCKFILE_SCHEMA_URL,
|
|
60
|
+
version: LOCKFILE_VERSION,
|
|
61
|
+
config,
|
|
62
|
+
writtenBy: `@rtorcato/repo-tooling@${packageJson.version}`,
|
|
63
|
+
writtenAt: new Date().toISOString(),
|
|
64
|
+
};
|
|
65
|
+
await fs.writeJson(filepath, lockfile, { spaces: 2 });
|
|
66
|
+
// Migrate a pre-rename repo to the new name: now that the canonical file is
|
|
67
|
+
// written, drop the stale legacy lockfile so there's only one (#272).
|
|
68
|
+
const legacy = path.join(dir, LEGACY_LOCKFILE_NAME);
|
|
69
|
+
if (await fs.pathExists(legacy))
|
|
70
|
+
await fs.remove(legacy);
|
|
71
|
+
return filepath;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Patch a subset of a lockfile's config in place, preserving everything else.
|
|
75
|
+
* Returns true when the file was rewritten, false when no lockfile exists.
|
|
76
|
+
*/
|
|
77
|
+
export async function updateLockfileConfig(dir, patch) {
|
|
78
|
+
const existing = await readLockfile(dir);
|
|
79
|
+
if (!existing)
|
|
80
|
+
return false;
|
|
81
|
+
const merged = { ...existing.config, ...patch };
|
|
82
|
+
await writeLockfile(dir, merged);
|
|
83
|
+
return true;
|
|
84
|
+
}
|