diff --git a/package.json b/package.json index 54c3eb1..1219a65 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "@clack/prompts": "^1.2.0", "@microsoft/api-extractor": "^7.58.7", "@rslib/core": "0.21.3", - "@rslint/core": "^0.5.0", + "@rslint/core": "^0.5.1", "@rstest/core": "0.9.9", "@types/fs-extra": "^11.0.4", "@types/minimist": "^1.2.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e23be90..3095c30 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -18,8 +18,8 @@ importers: specifier: 0.21.3 version: 0.21.3(@microsoft/api-extractor@7.58.7(@types/node@24.12.2))(core-js@3.47.0)(typescript@6.0.3) '@rslint/core': - specifier: ^0.5.0 - version: 0.5.0 + specifier: ^0.5.1 + version: 0.5.1 '@rstest/core': specifier: 0.9.9 version: 0.9.9(core-js@3.47.0) @@ -184,8 +184,8 @@ packages: typescript: optional: true - '@rslint/core@0.5.0': - resolution: {integrity: sha512-RkP/xqWx+Nvj7awvALIpbGnc5ECv8/AjPXqQDixhms4bu4dW5UbNNZ9XbrvJ4JoToUC/Ac5CrwW+nOj7JItSFQ==} + '@rslint/core@0.5.1': + resolution: {integrity: sha512-UGcalhkpNvm4zN7E2DiQsuwM10LMi3CazOiANVevf5hn+NB7WKEMWYKn3bFySptg7Ll042IKMUlIXaFQjWs9lQ==} hasBin: true peerDependencies: jiti: ^2.0.0 @@ -193,33 +193,33 @@ packages: jiti: optional: true - '@rslint/darwin-arm64@0.5.0': - resolution: {integrity: sha512-AgsyJBnmXBuTnXAB5YUr6fhgfxvCl+iNRFlCjNN4WiClKEQyRLkU8KAmqVoZWOMyNszDUl9k/KT5P5KrBEJCJQ==} + '@rslint/darwin-arm64@0.5.1': + resolution: {integrity: sha512-grbPKhrRv0BTKvdByIIlS5avc4ttF9vylaStJh/TTYS96cTkjCcTv7RAUv/ZI3VSaSZdRBcW4f6wW9pPWpt41w==} cpu: [arm64] os: [darwin] - '@rslint/darwin-x64@0.5.0': - resolution: {integrity: sha512-4vxDu0DFzJVsGGxmmGmtSqKOPPfVcJvqxZP7XXDf9isFPg3L9jF+2DW3QL3KL7LO3Q+3zVG9eL+MQslMUf9NSw==} + '@rslint/darwin-x64@0.5.1': + resolution: {integrity: sha512-v7P5AYWzm4Xrly5nl5yXSAyHn6j9pwZyFFUTD9UCOodZMEVmBxW3WxdL9iq8PfnG5n8GXHqTqBSYwWfG1WWD0g==} cpu: [x64] os: [darwin] - '@rslint/linux-arm64@0.5.0': - resolution: {integrity: sha512-sNdDT7Omf6GttaJOql1915t/6txHlo0mEulLNhuDK4KVD9EnSltQ1uIDeqhNVvsKSnqIuTp3qCWmo1qYv5xKTA==} + '@rslint/linux-arm64@0.5.1': + resolution: {integrity: sha512-czDNVvgea0LpTlqaRvZHulJn8RmmDso2DufIWedxIA9yfK+nEK4H0tANNVQL4NBTHiv/6cqQw8NveP3KD5I93g==} cpu: [arm64] os: [linux] - '@rslint/linux-x64@0.5.0': - resolution: {integrity: sha512-Er/feorEUqOjee1ueE02fHIaPB1haxoGdh3uNqNrm3CUyrBp+Amjb8HL3MRzIYQuYoZWBAw9fU67YG8FxcWUsA==} + '@rslint/linux-x64@0.5.1': + resolution: {integrity: sha512-D0isbtok26OSjSQkWDDfTWPLQDqrufbTbiihMFxkDlIRKDGcU9HvnfTlEmgnwzkxt6Jm7CBZZiXdFtyhPgnWEg==} cpu: [x64] os: [linux] - '@rslint/win32-arm64@0.5.0': - resolution: {integrity: sha512-Y895KBuDVfoprZqr1BKX4YwP4kA2cqUuQr1B50+W8yjSRznyotNa09pRqUi+FrgJ5z6x07JjmW3Ggv8t5z9wwg==} + '@rslint/win32-arm64@0.5.1': + resolution: {integrity: sha512-XnU369fuTR9EqFhRMmbg+rHO3T/gwC+VV2AC1HAvZ62/pgNjFQmlK6IEsU293sgXHOUnRIQ6IsC9J0imyrCMXQ==} cpu: [arm64] os: [win32] - '@rslint/win32-x64@0.5.0': - resolution: {integrity: sha512-pTvCNr99DQg+22XQ5QkHySOLD4ap3wJ6yuwoW2r/4dW4MbmyDF9FfQGfhH1ZsQA3h20H8/3ANGdKuCbZnjkSrg==} + '@rslint/win32-x64@0.5.1': + resolution: {integrity: sha512-7++ELodvfVPFDSYEMVWb7OA+BD2JeONXtwXP/vmbrcawBTff7E/6VREB8dGPYCNh/ypBuSQ2WYXUtYAxQxwSiQ==} cpu: [x64] os: [win32] @@ -425,6 +425,15 @@ packages: fast-wrap-ansi@0.1.6: resolution: {integrity: sha512-HlUwET7a5gqjURj70D5jl7aC3Zmy4weA1SHUfM0JFI0Ptq987NH2TwbBFLoERhfwk+E+eaq4EK3jXoT+R3yp3w==} + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + fs-extra@11.3.4: resolution: {integrity: sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==} engines: {node: '>=14.14'} @@ -570,6 +579,10 @@ packages: resolution: {integrity: sha512-VKS/ZaQhhkKFMANmAOhhXVoIfBXblQxGX1myCQ2faQrfmobMftXeJPcZGp0gS07ocvGJWDLZGyOZDadDBqYIJg==} engines: {node: '>=18'} + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + engines: {node: '>=12.0.0'} + tinypool@2.1.0: resolution: {integrity: sha512-Pugqs6M0m7Lv1I7FtxN4aoyToKg1C4tu+/381vH35y8oENM/Ai7f7C4StcoK4/+BSw9ebcS8jRiVrORFKCALLw==} engines: {node: ^20.0.0 || >=22.0.0} @@ -726,33 +739,34 @@ snapshots: - '@typescript/native-preview' - core-js - '@rslint/core@0.5.0': + '@rslint/core@0.5.1': dependencies: picomatch: 4.0.4 + tinyglobby: 0.2.15 optionalDependencies: - '@rslint/darwin-arm64': 0.5.0 - '@rslint/darwin-x64': 0.5.0 - '@rslint/linux-arm64': 0.5.0 - '@rslint/linux-x64': 0.5.0 - '@rslint/win32-arm64': 0.5.0 - '@rslint/win32-x64': 0.5.0 - - '@rslint/darwin-arm64@0.5.0': + '@rslint/darwin-arm64': 0.5.1 + '@rslint/darwin-x64': 0.5.1 + '@rslint/linux-arm64': 0.5.1 + '@rslint/linux-x64': 0.5.1 + '@rslint/win32-arm64': 0.5.1 + '@rslint/win32-x64': 0.5.1 + + '@rslint/darwin-arm64@0.5.1': optional: true - '@rslint/darwin-x64@0.5.0': + '@rslint/darwin-x64@0.5.1': optional: true - '@rslint/linux-arm64@0.5.0': + '@rslint/linux-arm64@0.5.1': optional: true - '@rslint/linux-x64@0.5.0': + '@rslint/linux-x64@0.5.1': optional: true - '@rslint/win32-arm64@0.5.0': + '@rslint/win32-arm64@0.5.1': optional: true - '@rslint/win32-x64@0.5.0': + '@rslint/win32-x64@0.5.1': optional: true '@rspack/binding-darwin-arm64@2.0.0': @@ -939,6 +953,10 @@ snapshots: dependencies: fast-string-width: 1.1.0 + fdir@6.5.0(picomatch@4.0.4): + optionalDependencies: + picomatch: 4.0.4 + fs-extra@11.3.4: dependencies: graceful-fs: 4.2.11 @@ -1047,6 +1065,11 @@ snapshots: tinyexec@1.1.1: {} + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 + tinypool@2.1.0: {} tslib@2.8.1: {} diff --git a/src/index.ts b/src/index.ts index 4685d35..c6d2e2a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -333,6 +333,12 @@ export type ESLintTemplateName = | 'svelte-js' | 'svelte-ts'; +export type RslintTemplateName = + | 'vanilla-js' + | 'vanilla-ts' + | 'react-js' + | 'react-ts'; + const readJSON = async (path: string) => JSON.parse(await fs.promises.readFile(path, 'utf-8')); @@ -533,6 +539,7 @@ export async function create({ skipFiles, getTemplateName, mapESLintTemplate, + mapRslintTemplate, version, noteInformation, extraTools, @@ -552,6 +559,14 @@ export async function create({ templateName: string, context: { distFolder: string }, ) => ESLintTemplateName | null; + /** + * Map the template name to the Rslint template name. + * If not provided, reuses mapESLintTemplate and falls back to 'vanilla-ts'. + */ + mapRslintTemplate?: ( + templateName: string, + context: { distFolder: string }, + ) => RslintTemplateName | null; version?: Record | string; noteInformation?: string[]; /** @@ -771,6 +786,30 @@ export async function create({ continue; } + if (tool === 'rslint') { + const rslintTemplateName = mapRslintTemplate + ? mapRslintTemplate(templateName, { distFolder }) + : 'vanilla-ts'; + + if (!rslintTemplateName) { + continue; + } + + const subFolder = path.join(toolFolder, rslintTemplateName); + copyFolder({ + from: subFolder, + to: distFolder, + version, + skipFiles, + templateParameters, + isMergePackageJson: true, + }); + + agentsMdSearchDirs.push(toolFolder); + agentsMdSearchDirs.push(subFolder); + continue; + } + copyFolder({ from: toolFolder, to: distFolder, diff --git a/template-rslint/package.json b/template-rslint/react-js/package.json similarity index 66% rename from template-rslint/package.json rename to template-rslint/react-js/package.json index 725ad77..2572187 100644 --- a/template-rslint/package.json +++ b/template-rslint/react-js/package.json @@ -1,11 +1,11 @@ { - "name": "rslint", + "name": "rslint-react-js", "private": true, "version": "1.0.0", "scripts": { "lint": "rslint" }, "devDependencies": { - "@rslint/core": "^0.5.0" + "@rslint/core": "^0.5.1" } } diff --git a/template-rslint/react-js/rslint.config.ts b/template-rslint/react-js/rslint.config.ts new file mode 100644 index 0000000..ffb56c3 --- /dev/null +++ b/template-rslint/react-js/rslint.config.ts @@ -0,0 +1,7 @@ +import { defineConfig, js, reactHooksPlugin, reactPlugin } from '@rslint/core'; + +export default defineConfig([ + js.configs.recommended, + reactPlugin.configs.recommended, + reactHooksPlugin.configs.recommended, +]); diff --git a/template-rslint/react-ts/package.json b/template-rslint/react-ts/package.json new file mode 100644 index 0000000..4825bae --- /dev/null +++ b/template-rslint/react-ts/package.json @@ -0,0 +1,11 @@ +{ + "name": "rslint-react-ts", + "private": true, + "version": "1.0.0", + "scripts": { + "lint": "rslint" + }, + "devDependencies": { + "@rslint/core": "^0.5.1" + } +} diff --git a/template-rslint/react-ts/rslint.config.ts b/template-rslint/react-ts/rslint.config.ts new file mode 100644 index 0000000..951771a --- /dev/null +++ b/template-rslint/react-ts/rslint.config.ts @@ -0,0 +1,14 @@ +import { + defineConfig, + js, + ts, + reactPlugin, + reactHooksPlugin, +} from '@rslint/core'; + +export default defineConfig([ + js.configs.recommended, + ts.configs.recommended, + reactPlugin.configs.recommended, + reactHooksPlugin.configs.recommended, +]); diff --git a/template-rslint/rslint.config.ts b/template-rslint/rslint.config.ts deleted file mode 100644 index 5055b09..0000000 --- a/template-rslint/rslint.config.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { defineConfig, ts } from '@rslint/core'; - -export default defineConfig([ts.configs.recommended]); diff --git a/template-rslint/vanilla-js/package.json b/template-rslint/vanilla-js/package.json new file mode 100644 index 0000000..576313d --- /dev/null +++ b/template-rslint/vanilla-js/package.json @@ -0,0 +1,11 @@ +{ + "name": "rslint-vanilla-js", + "private": true, + "version": "1.0.0", + "scripts": { + "lint": "rslint" + }, + "devDependencies": { + "@rslint/core": "^0.5.1" + } +} diff --git a/template-rslint/vanilla-js/rslint.config.ts b/template-rslint/vanilla-js/rslint.config.ts new file mode 100644 index 0000000..3b3fad6 --- /dev/null +++ b/template-rslint/vanilla-js/rslint.config.ts @@ -0,0 +1,3 @@ +import { defineConfig, js } from '@rslint/core'; + +export default defineConfig([js.configs.recommended]); diff --git a/template-rslint/vanilla-ts/package.json b/template-rslint/vanilla-ts/package.json new file mode 100644 index 0000000..2a44e02 --- /dev/null +++ b/template-rslint/vanilla-ts/package.json @@ -0,0 +1,11 @@ +{ + "name": "rslint-vanilla-ts", + "private": true, + "version": "1.0.0", + "scripts": { + "lint": "rslint" + }, + "devDependencies": { + "@rslint/core": "^0.5.1" + } +} diff --git a/template-rslint/vanilla-ts/rslint.config.ts b/template-rslint/vanilla-ts/rslint.config.ts new file mode 100644 index 0000000..4269a7e --- /dev/null +++ b/template-rslint/vanilla-ts/rslint.config.ts @@ -0,0 +1,3 @@ +import { defineConfig, js, ts } from '@rslint/core'; + +export default defineConfig([js.configs.recommended, ts.configs.recommended]); diff --git a/test/cli.test.ts b/test/cli.test.ts index 32050fd..f032799 100644 --- a/test/cli.test.ts +++ b/test/cli.test.ts @@ -79,6 +79,37 @@ test('should scaffold rslint tool files', async () => { expect(packageJson.devDependencies['@rslint/core']).toBeTruthy(); }); +test('should scaffold mapped rslint tool template', async () => { + const projectDir = path.join(testDir, 'mapped-rslint-tool'); + + await create({ + name: 'test', + root: fixturesDir, + templates: ['vanilla'], + getTemplateName: async () => 'vanilla', + mapRslintTemplate: () => 'react-ts', + argv: [ + 'node', + 'test', + '--dir', + projectDir, + '--template', + 'vanilla', + '--tools', + 'rslint', + ], + }); + + const config = fs.readFileSync( + path.join(projectDir, 'rslint.config.ts'), + 'utf-8', + ); + + expect(config).toContain('reactPlugin.configs.recommended'); + expect(config).toContain('ts.configs.recommended'); + expect(fs.existsSync(path.join(projectDir, 'react-ts'))).toBe(false); +}); + test('should skip tools selection', async () => { const projectDir = path.join(testDir, 'comma-separated-tools');