Skip to content

Commit

Permalink
Merge pull request #9 from OpenAlly/typescript-config-v1
Browse files Browse the repository at this point in the history
feat: implement typescript configs V1.0
  • Loading branch information
fraxken authored Aug 12, 2024
2 parents 60e4e74 + 395e4a1 commit f24f461
Show file tree
Hide file tree
Showing 21 changed files with 318 additions and 183 deletions.
71 changes: 71 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions src/eslint/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<p align="center"><h1 align="center">
Eslint Config
</h1>
<p align="center">
<h1 align="center">Eslint Config</h1>
</p>

<div align="center">OpenAlly Node.js Eslint configuration (Work for both JavaScript and TypeScript projects).</div>

Expand Down
5 changes: 4 additions & 1 deletion src/eslint/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@
"name": "@openally/config.eslint",
"version": "1.0.0",
"description": "OpenAlly ESLint configuration for Node.js and TypeScript",
"type": "module",
"main": "./dist/index.js",
"scripts": {
"build": "tsc",
"prepublishOnly": "npm run build",
"test-only": "tsx --test ./test/test.ts",
"test": "c8 --all --src ./src -r html npm run test-only",
"lint": "cross-env eslint src/**/*.ts",
"sync": "npx tsx ./tools/sync.ts"
"sync": "npx tsx ./scripts/sync.ts"
},
"files": [
"dist"
Expand All @@ -29,6 +30,8 @@
"typescript-eslint": "^8.1.0"
},
"devDependencies": {
"@myunisoft/httpie": "^5.0.0",
"@types/jsdom": "^21.1.7",
"@typescript-eslint/types": "^8.1.0",
"jsdom": "^24.1.1"
}
Expand Down
86 changes: 86 additions & 0 deletions src/eslint/scripts/sync.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// Import Third-party Dependencies
import { request } from "@myunisoft/httpie";
import { JSDOM } from "jsdom";

// Import Internal Dependencies
import { rulesWithTS } from "../src/rules/index.js";

// CONSTANTS
const kEslintRulesReferenceUrl = "https://eslint.org/docs/latest/rules/";
const kStylisticRulesUrl = "https://eslint.style/rules";
const kLocalRules = new Set(Object.keys(rulesWithTS));

const [eslintResult, stylisticResult] = await Promise.all([
request<string>("GET", kEslintRulesReferenceUrl),
request<string>("GET", kStylisticRulesUrl)
]);
const eslintDom = new JSDOM(eslintResult.data);
const stylisticDom = new JSDOM(stylisticResult.data);
const rules = new Set([
...parseESLintRulesReferences(eslintDom),
...parseStylisticRules(stylisticDom)
]);

for (const rule of rules) {
if (kLocalRules.has(rule.ruleName) && rule.isDeprecated) {
console.error(
`Rule "${rule.ruleName}" is deprecated! (https://eslint.org/docs/latest/rules/${rule.ruleName})`
);
}
else if (kLocalRules.has(rule.ruleName) && rule.isRemoved) {
console.error(
`Rule "${rule.ruleName}" is removed! (https://eslint.org/docs/latest/rules/${rule.ruleName})`
);
}
else if (
!kLocalRules.has(rule.ruleName) &&
!kLocalRules.has(`@stylistic/${rule.ruleName}`) &&
!rule.isDeprecated &&
!rule.isRemoved
) {
const label = kEslintRulesReferenceUrl + rule.ruleName;
console.error(
`Rule "${rule.ruleName}" is not present in the local ESLint configuration!(${label})`
);
}
}
console.log("Done!");

function parseESLintRulesReferences(
dom: JSDOM
) {
return [
...dom.window.document.querySelectorAll("article.rule")
].map((rule) => {
return {
ruleName: parseRuleName(rule.textContent),
isDeprecated: rule.classList.contains("rule--deprecated"),
isRemoved: rule.classList.contains("rule--removed")
};
});
}

function parseStylisticRules(
dom: JSDOM
) {
return [
...dom.window.document.querySelectorAll("td a code")
].map((rule) => {
return {
ruleName: parseRuleName(rule.textContent),
isDeprecated: false,
isRemoved: false
};
});
}

function parseRuleName(textContent: string | null) {
if (typeof textContent === "string") {
return textContent
.replace(/\n/g, " ")
.trimStart()
.split(" ")[0];
}

return "";
}
64 changes: 25 additions & 39 deletions src/eslint/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,52 +1,36 @@
// Import Third-party Dependencies
import stylisticPlugin from "@stylistic/eslint-plugin";
import globals from "globals";
import tsEslint, { ConfigWithExtends } from "typescript-eslint";
import tsEslint, { type ConfigWithExtends } from "typescript-eslint";
import * as tsParser from "@typescript-eslint/parser";
import { SourceType } from "@typescript-eslint/types";
import type { SourceType } from "@typescript-eslint/types";

// Import Internal Dependencies
import bestPractices from "./rules/best-practices.js";
import ecmascript6 from "./rules/ecmascript6.js";
import eslintv9 from "./rules/eslintv9.js";
import possibleErrors from "./rules/possible-errors.js";
import styles from "./rules/styles.js";
import variables from "./rules/variables.js";
import stylistic from "./rules/stylistic.js";
import typescript from "./rules/typescript.js";
import { rules, rulesWithTS } from "./rules/index.js";

const kLanguageOptions = {
sourceType: "script",
globals: {
...globals.node
}
};
const kTypescriptLanguageOptions = {
...kLanguageOptions,
sourceType: "module" as SourceType,
parser: tsParser
};
const kRules: Record<string, any> = {
...bestPractices,
...possibleErrors,
...styles,
...ecmascript6,
...eslintv9,
...variables,
...stylistic
};

const kBaseTypeScriptConfigs: ConfigWithExtends[] = [
{
plugins: {
// @ts-ignore
"@stylistic": stylisticPlugin
},
rules: {
...kRules,
...typescript as any,
...rulesWithTS,
"no-undef": "off",
"no-redeclare": "off"
},
languageOptions: kTypescriptLanguageOptions,
languageOptions: {
...kLanguageOptions,
sourceType: "module" as SourceType,
parser: tsParser
},
files: ["**/*.ts"]
},
{
Expand All @@ -57,18 +41,20 @@ const kBaseTypeScriptConfigs: ConfigWithExtends[] = [
}
];

export const ESLintConfig = [{
plugins: {
"@stylistic": stylisticPlugin
},
rules: kRules,
languageOptions: kLanguageOptions
}];

export function typescriptConfig(config?: ConfigWithExtends) {
if (config) {
return tsEslint.config(...kBaseTypeScriptConfigs, config);
export const ESLintConfig = [
{
plugins: {
"@stylistic": stylisticPlugin
},
rules,
languageOptions: kLanguageOptions
}
];

return tsEslint.config(...kBaseTypeScriptConfigs);
export function typescriptConfig(
config?: ConfigWithExtends
) {
return config ?
tsEslint.config(...kBaseTypeScriptConfigs, config) :
tsEslint.config(...kBaseTypeScriptConfigs);
}
3 changes: 1 addition & 2 deletions src/eslint/src/rules/best-practices.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const rules = {
export default {
// See: https://eslint.org/docs/rules/accessor-pairs
"accessor-pairs": "off",

Expand Down Expand Up @@ -215,4 +215,3 @@ const rules = {
// See: https://eslint.org/docs/rules/yoda
yoda: "error"
};
export default rules;
4 changes: 1 addition & 3 deletions src/eslint/src/rules/ecmascript6.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const rules = {
export default {
// See: https://eslint.org/docs/rules/arrow-body-style
"arrow-body-style": ["error", "as-needed", { requireReturnForObjectLiteral: true }],

Expand Down Expand Up @@ -89,5 +89,3 @@ const rules = {
// See: https://eslint.style/rules/js/ryield-star-spacing
"@stylistic/yield-star-spacing": ["error", { before: false, after: true }]
};

export default rules;
3 changes: 1 addition & 2 deletions src/eslint/src/rules/eslintv9.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const rules = {
export default {
"no-constant-binary-expression": "error",
"no-constructor-return": "off",
"no-dupe-else-if": "error",
Expand Down Expand Up @@ -28,4 +28,3 @@ const rules = {
"prefer-regex-literals": "off",
strict: "off"
};
export default rules;
Loading

0 comments on commit f24f461

Please sign in to comment.