diff --git a/scripts/addRuleToExportIndex.js b/scripts/addRuleToExportIndex.ts similarity index 85% rename from scripts/addRuleToExportIndex.js rename to scripts/addRuleToExportIndex.ts index c917f2c..5fe2c75 100644 --- a/scripts/addRuleToExportIndex.js +++ b/scripts/addRuleToExportIndex.ts @@ -4,7 +4,15 @@ import fs from "fs"; import { kebabToCamelCase } from "./utils/kebabToKamelCase"; -function transformer(file, api, options) { +// @ts-ignore: No types for jscodeshift +import { FileInfo, API, Options } from "jscodeshift"; + +interface TransformerOptions { + ruleName: string; + exportIndexFilePath: string; +} + +export function transformer(file: FileInfo, api: API, options: TransformerOptions): string { const j = api.jscodeshift; const { ruleName, exportIndexFilePath } = options; @@ -45,14 +53,15 @@ function transformer(file, api, options) { // Manually sort the export statements alphabetically const sortedExports = updatedExportStatements .nodes() - .map(node => { + + .map((node: any) => { if (node.specifiers && node.specifiers[0] && node.specifiers[0].exported) { return node; } return null; // Ignore nodes without valid specifiers }) - .filter(node => node !== null) // Remove nulls - .sort((a, b) => { + .filter((node: any) => node !== null) // Remove nulls + .sort((a: any, b: any) => { const aName = a.specifiers[0].exported.name; const bName = b.specifiers[0].exported.name; return aName.localeCompare(bName); @@ -63,7 +72,7 @@ function transformer(file, api, options) { // Now insert the sorted export statements back into the AST const body = exportIndexSource.get().node.program.body; - sortedExports.forEach(exportNode => { + sortedExports.forEach((exportNode: any) => { body.push(exportNode); // Insert each export statement at the end of the body }); } @@ -74,4 +83,4 @@ function transformer(file, api, options) { // Return the original file source (this is for the main file passed in) return file.source; } -module.exports = transformer; + diff --git a/scripts/addRuleToIndex.js b/scripts/addRuleToIndex.ts similarity index 78% rename from scripts/addRuleToIndex.js rename to scripts/addRuleToIndex.ts index 9fa56fe..2e64ca9 100644 --- a/scripts/addRuleToIndex.js +++ b/scripts/addRuleToIndex.ts @@ -4,25 +4,29 @@ import { kebabToCamelCase } from "./utils/kebabToKamelCase"; // Sort function to keep rules and config sorted alphabetically -const nameSort = (a, b) => { +const nameSort = (a: any, b: any) => { const aName = a.key.type === "Literal" ? a.key.value : a.key.name; - const bName = a.key.type === "Literal" ? b.key.value : b.key.name; + const bName = b.key.type === "Literal" ? b.key.value : b.key.name; if (aName < bName) return -1; if (aName > bName) return 1; return 0; }; -const transformer = (file, api, options) => { +interface TransformerOptions { + ruleName: string; +} + +export const transformer = (file: any, api: any, options: any): string | null => { const j = api.jscodeshift; const root = j(file.source); - const { ruleName } = options; // No need for rulePath in this case + const { ruleName } = options; let changesMade = 0; // Step 1: Add rule to the `rules` object (without parentheses) root.find(j.Property, { key: { name: "rules" } }) .at(0) - .forEach(path => { + .forEach((path: any) => { const properties = path.value.value.properties; properties.unshift( j.property("init", j.literal(ruleName), j.memberExpression(j.identifier("rules"), j.identifier(kebabToCamelCase(ruleName)))) @@ -32,11 +36,11 @@ const transformer = (file, api, options) => { }); // Step 2: Find and modify `configs.recommended.rules` - root.find(j.Property, { key: { name: "configs" } }).forEach(configPath => { - const recommendedConfig = configPath.value.value.properties.find(prop => prop.key.name === "recommended"); + root.find(j.Property, { key: { name: "configs" } }).forEach((configPath: any) => { + const recommendedConfig = configPath.value.value.properties.find((prop: any) => prop.key.name === "recommended"); if (recommendedConfig) { - const recommendedRules = recommendedConfig.value.properties.find(prop => prop.key.name === "rules"); + const recommendedRules = recommendedConfig.value.properties.find((prop: any) => prop.key.name === "rules"); if (recommendedRules) { const rulesProps = recommendedRules.value.properties; @@ -53,4 +57,4 @@ const transformer = (file, api, options) => { return root.toSource({ quote: "double", trailingComma: false }); }; -module.exports = transformer; + diff --git a/scripts/boilerplate/doc.js b/scripts/boilerplate/doc.ts similarity index 59% rename from scripts/boilerplate/doc.js rename to scripts/boilerplate/doc.ts index ad1ffde..041c295 100644 --- a/scripts/boilerplate/doc.js +++ b/scripts/boilerplate/doc.ts @@ -1,7 +1,10 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -const docBoilerplateGenerator = (name, description) => `# ${description} (@microsoft/fluentui-jsx-a11y/${name}) +export const docBoilerplateGenerator = ( + name: string, + description: string +): string => `# ${description} (@microsoft/fluentui-jsx-a11y/${name}) Write a useful explanation here! @@ -19,4 +22,4 @@ Write more details here! ## Further Reading `; -module.exports = docBoilerplateGenerator; + diff --git a/scripts/boilerplate/rule.js b/scripts/boilerplate/rule.ts similarity index 91% rename from scripts/boilerplate/rule.js rename to scripts/boilerplate/rule.ts index 3dbd687..a85f099 100644 --- a/scripts/boilerplate/rule.js +++ b/scripts/boilerplate/rule.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -const ruleBoilerplate = (name, description) => `// Copyright (c) Microsoft Corporation. +export const ruleBoilerplateGenerator = (name: string, description: string): string => `// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. import { ESLintUtils, TSESTree } from "@typescript-eslint/utils"; @@ -42,4 +42,4 @@ const rule = createRule({ export default rule; `; -module.exports = ruleBoilerplate; + diff --git a/scripts/boilerplate/test.js b/scripts/boilerplate/test.ts similarity index 83% rename from scripts/boilerplate/test.js rename to scripts/boilerplate/test.ts index 996f3ba..aed79eb 100644 --- a/scripts/boilerplate/test.js +++ b/scripts/boilerplate/test.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -const testBoilerplate = name => `// Copyright (c) Microsoft Corporation. +export const testBoilerplateGenerator = (name: string): string => `// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. import { Rule } from "eslint"; @@ -21,4 +21,4 @@ ruleTester.run("${name}", rule as unknown as Rule.RuleModule, { ] }); `; -module.exports = testBoilerplate; + diff --git a/scripts/create-rule.js b/scripts/create-rule.ts similarity index 83% rename from scripts/create-rule.js rename to scripts/create-rule.ts index 215171e..4984672 100644 --- a/scripts/create-rule.js +++ b/scripts/create-rule.ts @@ -2,14 +2,14 @@ // Licensed under the MIT License. /* eslint-disable no-console */ -const { resolve } = require("path"); -const { existsSync, writeFileSync } = require("fs"); -const { exec } = require("child_process"); -const yargs = require("yargs/yargs"); // Use yargs/yargs for modules -const { hideBin } = require("yargs/helpers"); // To handle CLI arguments -const ruleBoilerplateGenerator = require("./boilerplate/rule"); -const testBoilerplateGenerator = require("./boilerplate/test"); -const docBoilerplateGenerator = require("./boilerplate/doc"); +import { resolve } from "path"; +import { existsSync, writeFileSync } from "fs"; +import { exec } from "child_process"; +import yargs from "yargs/yargs"; +import { hideBin } from "yargs/helpers"; +import {ruleBoilerplateGenerator} from "./boilerplate/rule"; +import {testBoilerplateGenerator} from "./boilerplate/test"; +import {docBoilerplateGenerator} from "./boilerplate/doc"; // Define the yargs configuration const argv = yargs(hideBin(process.argv)) @@ -27,11 +27,11 @@ const argv = yargs(hideBin(process.argv)) default: "$DESCRIPTION" // Provide default value } }) - .demandCommand(1, "You must provide the rule name.").argv; // Make the rule name (positional) + .demandCommand(1, "You must provide the rule name.").argv as any; // Type assertion for yargs -const ruleName = argv._[0]; -const author = argv.author || "$AUTHOR"; -const description = argv.description || "$DESCRIPTION"; +const ruleName: string = argv._[0]; +const author: string = argv.author || "$AUTHOR"; +const description: string = argv.description || "$DESCRIPTION"; const rulePath = resolve(`lib/rules/${ruleName}.ts`); const testPath = resolve(`tests/lib/rules/${ruleName}-test.ts`); @@ -106,3 +106,4 @@ exec(commandForMainIndex, (error, stdout, stderr) => { console.log(`stdout: ${stdout}`); }); }); + diff --git a/scripts/utils/kebabToKamelCase.js b/scripts/utils/kebabToKamelCase.ts similarity index 76% rename from scripts/utils/kebabToKamelCase.js rename to scripts/utils/kebabToKamelCase.ts index ab796fb..64c8567 100644 --- a/scripts/utils/kebabToKamelCase.js +++ b/scripts/utils/kebabToKamelCase.ts @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -export const kebabToCamelCase = str => { +export const kebabToCamelCase = (str: string): string => { return str.replace(/[-_](.)/g, (_, char) => char.toUpperCase()).replace(/^(.)/, (_, char) => char.toLowerCase()); }; +