lint-config-sq11y 0.0.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.
@@ -0,0 +1,4 @@
1
+ import tslint from "typescript-eslint";
2
+ declare const _default: tslint.FlatConfig.Config | tslint.FlatConfig.Config[];
3
+ export default _default;
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAeA,OAAO,MAAM,MAAM,mBAAmB,CAAC;;AAsFvC,wBAEkD"}
package/dist/index.js ADDED
@@ -0,0 +1,77 @@
1
+ import { globalIgnores } from "eslint/config";
2
+ import { defineConfigWithVueTs, vueTsConfigs } from "@vue/eslint-config-typescript";
3
+ import { jsdoc } from "eslint-plugin-jsdoc";
4
+ import pluginVue from "eslint-plugin-vue";
5
+ import pluginOxlint from "eslint-plugin-oxlint";
6
+ import pluginStylistic from "@stylistic/eslint-plugin";
7
+ import pluginVueA11y from "eslint-plugin-vuejs-accessibility";
8
+ import skipFormatting from "eslint-config-prettier/flat";
9
+ import jslint from "@eslint/js";
10
+ import tslint from "typescript-eslint";
11
+ import requireComment from "./require-comment.js";
12
+ import isVueProject from "./is-vue-project.js";
13
+ const vueConfig = [
14
+ ...pluginVue.configs["flat/recommended"],
15
+ ...pluginVueA11y.configs["flat/recommended"],
16
+ vueTsConfigs.recommendedTypeChecked,
17
+ {
18
+ name: "sq11y/vue",
19
+ files: ["**/*.vue"],
20
+ plugins: {
21
+ sq11y: {
22
+ /* eslint-disable-next-line @typescript-eslint/no-unsafe-assignment */
23
+ rules: requireComment,
24
+ },
25
+ },
26
+ rules: {
27
+ "vue/multi-word-component-names": "off",
28
+ "vue/attributes-order": "error",
29
+ "vue/require-explicit-slots": "error",
30
+ "vue/define-emits-declaration": ["error", "type-based"],
31
+ "vue/require-prop-comment": "error",
32
+ "vue/block-order": ["error", { order: [["template", "script[setup]", "style"]] }],
33
+ "sq11y/require-emit-comment": "error",
34
+ "sq11y/require-slot-comment": "error",
35
+ },
36
+ },
37
+ ];
38
+ const config = (isVueProject) => [
39
+ globalIgnores(["**/dist/**", "**/node_modules/**", ".git"]),
40
+ pluginStylistic.configs.recommended,
41
+ jslint.configs.recommended,
42
+ jsdoc({ config: "flat/recommended" }),
43
+ ...tslint.configs.recommendedTypeChecked,
44
+ ...pluginOxlint.buildFromOxlintConfigFile(".oxlintrc.json"),
45
+ ...(isVueProject ? vueConfig : []),
46
+ skipFormatting,
47
+ {
48
+ languageOptions: {
49
+ parserOptions: {
50
+ projectService: {
51
+ allowDefaultProject: ["eslint.config.js", "stylelint.config.mjs"],
52
+ },
53
+ },
54
+ },
55
+ },
56
+ {
57
+ name: "sq11y/shared",
58
+ files: ["**/*.{vue,ts}"],
59
+ plugins: {
60
+ "@stylistic": pluginStylistic,
61
+ },
62
+ rules: {
63
+ "default-case": "error",
64
+ "default-case-last": "error",
65
+ "max-lines-per-function": ["error", { max: 80, skipComments: true }],
66
+ "prefer-destructuring": "error",
67
+ "no-dupe-class-members": "error",
68
+ "no-duplicate-case": "error",
69
+ "@typescript-eslint/consistent-type-imports": ["error"],
70
+ "@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_" }],
71
+ "@stylistic/spaced-comment": "error",
72
+ },
73
+ },
74
+ ];
75
+ export default isVueProject
76
+ ? defineConfigWithVueTs(...config(true))
77
+ : config(false);
@@ -0,0 +1,3 @@
1
+ declare const _default: boolean;
2
+ export default _default;
3
+ //# sourceMappingURL=is-vue-project.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"is-vue-project.d.ts","sourceRoot":"","sources":["../src/is-vue-project.ts"],"names":[],"mappings":";AA+BA,wBAAoC"}
@@ -0,0 +1,21 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ const hasPackageJSON = (root) => {
4
+ return fs.existsSync(path.resolve(root, "package.json"));
5
+ };
6
+ const searchForPackageRoot = (current, root = current) => {
7
+ if (hasPackageJSON(current)) {
8
+ return path.resolve(root, "package.json");
9
+ }
10
+ const dir = path.dirname(current);
11
+ if (!dir || dir === current) {
12
+ return path.resolve(root, "package.json");
13
+ }
14
+ return searchForPackageRoot(dir, root);
15
+ };
16
+ const hasDependency = (name) => {
17
+ const pkgPath = searchForPackageRoot(process.cwd());
18
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
19
+ return !!pkg.dependencies?.[name] || !!pkg.devDependencies?.[name];
20
+ };
21
+ export default hasDependency("vue");
@@ -0,0 +1,3 @@
1
+ declare const _default: any;
2
+ export default _default;
3
+ //# sourceMappingURL=require-comment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"require-comment.d.ts","sourceRoot":"","sources":["../src/require-comment.ts"],"names":[],"mappings":"wBAuFK,GAAG;AAJR,wBAIS"}
@@ -0,0 +1,61 @@
1
+ import { TSESTree } from "@typescript-eslint/utils";
2
+ import { getPropertySignatureName, findTypeDefinition } from "./utils.js";
3
+ const requireCommentRule = (signature, prop) => ({
4
+ name: `require-${prop}-comment`,
5
+ meta: {
6
+ type: "suggestion",
7
+ schema: [],
8
+ docs: {
9
+ description: `Enforce comments for each ${prop}.`,
10
+ },
11
+ messages: {
12
+ default: `The ${prop} "{{ name }}" should have a JSDoc comment`,
13
+ },
14
+ },
15
+ create(context) {
16
+ const { sourceCode } = context;
17
+ const checkForComments = (node) => {
18
+ const comments = sourceCode.getCommentsBefore(node);
19
+ if (comments.length === 0) {
20
+ context.report({
21
+ node: node.key,
22
+ messageId: "default",
23
+ data: {
24
+ name: getPropertySignatureName(sourceCode, node),
25
+ },
26
+ });
27
+ }
28
+ };
29
+ const PropertySignature = `CallExpression[callee.name="${signature}"] > TSTypeParameterInstantiation > TSTypeLiteral > TSPropertySignature`;
30
+ const TypeReference = `CallExpression[callee.name="${signature}"] > TSTypeParameterInstantiation > TSTypeReference`;
31
+ return {
32
+ [PropertySignature](node) {
33
+ checkForComments(node);
34
+ },
35
+ [TypeReference](node) {
36
+ const typeDefinition = findTypeDefinition(sourceCode, node);
37
+ if (!typeDefinition) {
38
+ return;
39
+ }
40
+ let typeElements = [];
41
+ if (typeDefinition.type === TSESTree.AST_NODE_TYPES.TSInterfaceDeclaration) {
42
+ typeElements = typeDefinition.body.body;
43
+ }
44
+ else if (typeDefinition.type === TSESTree.AST_NODE_TYPES.TSTypeAliasDeclaration &&
45
+ typeDefinition.typeAnnotation.type === TSESTree.AST_NODE_TYPES.TSTypeLiteral) {
46
+ typeElements = typeDefinition.typeAnnotation.members;
47
+ }
48
+ typeElements.forEach((typeElement) => {
49
+ if (typeElement.type === TSESTree.AST_NODE_TYPES.TSPropertySignature) {
50
+ checkForComments(typeElement);
51
+ }
52
+ });
53
+ },
54
+ };
55
+ },
56
+ });
57
+ export default {
58
+ "require-emit-comment": requireCommentRule("defineEmits", "emit"),
59
+ "require-slot-comment": requireCommentRule("defineSlots", "slot"),
60
+ /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
61
+ };
@@ -0,0 +1,5 @@
1
+ import { TSESTree } from "@typescript-eslint/utils";
2
+ import type { TSESLint } from "@typescript-eslint/utils";
3
+ export declare const findTypeDefinition: (sourceCode: TSESLint.SourceCode, node: TSESTree.TSTypeReference) => TSESTree.TSTypeReference | TSESTree.TSPropertySignatureComputedName | TSESTree.TSPropertySignatureNonComputedName | TSESTree.BlockStatement | TSESTree.CatchClause | TSESTree.ArrayExpression | TSESTree.ArrayPattern | TSESTree.ArrowFunctionExpressionWithBlockBody | TSESTree.ArrowFunctionExpressionWithExpressionBody | TSESTree.AssignmentExpression | TSESTree.AwaitExpression | TSESTree.PrivateInExpression | TSESTree.SymmetricBinaryExpression | TSESTree.CallExpression | TSESTree.ChainExpression | TSESTree.ClassExpression | TSESTree.ConditionalExpression | TSESTree.FunctionExpression | TSESTree.Identifier | TSESTree.ImportExpression | TSESTree.JSXElement | TSESTree.JSXFragment | TSESTree.BigIntLiteral | TSESTree.BooleanLiteral | TSESTree.NullLiteral | TSESTree.NumberLiteral | TSESTree.RegExpLiteral | TSESTree.StringLiteral | TSESTree.TemplateLiteral | TSESTree.LogicalExpression | TSESTree.MemberExpressionComputedName | TSESTree.MemberExpressionNonComputedName | TSESTree.MetaProperty | TSESTree.NewExpression | TSESTree.ObjectExpression | TSESTree.ObjectPattern | TSESTree.SequenceExpression | TSESTree.Super | TSESTree.TaggedTemplateExpression | TSESTree.ThisExpression | TSESTree.TSAsExpression | TSESTree.TSInstantiationExpression | TSESTree.TSNonNullExpression | TSESTree.TSSatisfiesExpression | TSESTree.TSTypeAssertion | TSESTree.UnaryExpressionBitwiseNot | TSESTree.UnaryExpressionDelete | TSESTree.UnaryExpressionMinus | TSESTree.UnaryExpressionNot | TSESTree.UnaryExpressionPlus | TSESTree.UnaryExpressionTypeof | TSESTree.UnaryExpressionVoid | TSESTree.UpdateExpression | TSESTree.YieldNoStarExpression | TSESTree.YieldStarExpression | TSESTree.ClassBody | TSESTree.ClassDeclarationWithOptionalName | TSESTree.StaticBlock | TSESTree.TSConditionalType | TSESTree.ForInStatement | TSESTree.ForOfStatement | TSESTree.ForStatement | TSESTree.BreakStatement | TSESTree.ContinueStatement | TSESTree.DebuggerStatement | TSESTree.DoWhileStatement | TSESTree.EmptyStatement | TSESTree.ExportAllDeclaration | TSESTree.ExportDefaultDeclaration | TSESTree.ExportNamedDeclarationWithoutSourceWithMultiple | TSESTree.ExportNamedDeclarationWithoutSourceWithSingle | TSESTree.ExportNamedDeclarationWithSource | TSESTree.ExpressionStatement | TSESTree.FunctionDeclarationWithName | TSESTree.IfStatement | TSESTree.ImportDeclaration | TSESTree.LabeledStatement | TSESTree.ReturnStatement | TSESTree.SwitchStatement | TSESTree.ThrowStatement | TSESTree.TryStatement | TSESTree.TSDeclareFunctionNoDeclare | TSESTree.TSDeclareFunctionWithDeclare | TSESTree.TSEnumDeclaration | TSESTree.TSExportAssignment | TSESTree.TSImportEqualsNamespaceDeclaration | TSESTree.TSImportEqualsRequireDeclaration | TSESTree.TSInterfaceDeclaration | TSESTree.TSModuleDeclarationGlobal | TSESTree.TSModuleDeclarationModuleWithIdentifierId | TSESTree.TSModuleDeclarationModuleWithStringIdDeclared | TSESTree.TSModuleDeclarationModuleWithStringIdNotDeclared | TSESTree.TSModuleDeclarationNamespace | TSESTree.TSNamespaceExportDeclaration | TSESTree.TSTypeAliasDeclaration | TSESTree.ConstDeclaration | TSESTree.LetOrVarDeclaredDeclaration | TSESTree.LetOrVarNonDeclaredDeclaration | TSESTree.UsingInForOfDeclaration | TSESTree.UsingInNormalContextDeclaration | TSESTree.WhileStatement | TSESTree.WithStatement | TSESTree.FunctionDeclarationWithOptionalName | TSESTree.TSEmptyBodyFunctionExpression | TSESTree.TSCallSignatureDeclaration | TSESTree.TSConstructorType | TSESTree.TSConstructSignatureDeclaration | TSESTree.TSFunctionType | TSESTree.TSMethodSignatureComputedName | TSESTree.TSMethodSignatureNonComputedName | TSESTree.TSInterfaceBody | TSESTree.TSTypeLiteral | TSESTree.AccessorPropertyComputedName | TSESTree.AccessorPropertyNonComputedName | TSESTree.AssignmentPattern | TSESTree.Decorator | TSESTree.ExportSpecifierWithStringOrLiteralLocal | TSESTree.ImportAttribute | TSESTree.ImportDefaultSpecifier | TSESTree.ImportNamespaceSpecifier | TSESTree.ImportSpecifier | TSESTree.JSXAttribute | TSESTree.JSXClosingElement | TSESTree.JSXClosingFragment | TSESTree.JSXEmptyExpression | TSESTree.JSXExpressionContainer | TSESTree.JSXIdentifier | TSESTree.JSXMemberExpression | TSESTree.JSXNamespacedName | TSESTree.JSXOpeningElement | TSESTree.JSXOpeningFragment | TSESTree.JSXSpreadAttribute | TSESTree.JSXSpreadChild | TSESTree.JSXText | TSESTree.MethodDefinitionComputedName | TSESTree.MethodDefinitionNonComputedName | TSESTree.PrivateIdentifier | TSESTree.PropertyComputedName | TSESTree.PropertyNonComputedName | TSESTree.PropertyDefinitionComputedName | TSESTree.PropertyDefinitionNonComputedName | TSESTree.RestElement | TSESTree.SpreadElement | TSESTree.SwitchCase | TSESTree.TemplateElement | TSESTree.TSAbstractAccessorPropertyComputedName | TSESTree.TSAbstractAccessorPropertyNonComputedName | TSESTree.TSAbstractKeyword | TSESTree.TSAbstractMethodDefinitionComputedName | TSESTree.TSAbstractMethodDefinitionNonComputedName | TSESTree.TSAbstractPropertyDefinitionComputedName | TSESTree.TSAbstractPropertyDefinitionNonComputedName | TSESTree.TSAnyKeyword | TSESTree.TSArrayType | TSESTree.TSAsyncKeyword | TSESTree.TSBigIntKeyword | TSESTree.TSBooleanKeyword | TSESTree.TSClassImplements | TSESTree.TSDeclareKeyword | TSESTree.TSEnumBody | TSESTree.TSEnumMember | TSESTree.TSExportKeyword | TSESTree.TSExternalModuleReference | TSESTree.TSImportType | TSESTree.TSIndexedAccessType | TSESTree.TSIndexSignature | TSESTree.TSInferType | TSESTree.TSInterfaceHeritage | TSESTree.TSIntersectionType | TSESTree.TSIntrinsicKeyword | TSESTree.TSLiteralType | TSESTree.TSMappedType | TSESTree.TSModuleBlock | TSESTree.TSNamedTupleMember | TSESTree.TSNeverKeyword | TSESTree.TSNullKeyword | TSESTree.TSNumberKeyword | TSESTree.TSObjectKeyword | TSESTree.TSOptionalType | TSESTree.TSParameterProperty | TSESTree.TSPrivateKeyword | TSESTree.TSProtectedKeyword | TSESTree.TSPublicKeyword | TSESTree.TSQualifiedName | TSESTree.TSReadonlyKeyword | TSESTree.TSRestType | TSESTree.TSStaticKeyword | TSESTree.TSStringKeyword | TSESTree.TSSymbolKeyword | TSESTree.TSTemplateLiteralType | TSESTree.TSThisType | TSESTree.TSTupleType | TSESTree.TSTypeAnnotation | TSESTree.TSTypeOperator | TSESTree.TSTypeParameter | TSESTree.TSTypeParameterDeclaration | TSESTree.TSTypeParameterInstantiation | TSESTree.TSTypePredicateNoAsserts | TSESTree.TSTypePredicateWithAsserts | TSESTree.TSTypeQuery | TSESTree.TSUndefinedKeyword | TSESTree.TSUnionType | TSESTree.TSUnknownKeyword | TSESTree.TSVoidKeyword | TSESTree.VariableDeclaratorDefiniteAssignment | TSESTree.VariableDeclaratorMaybeInit | undefined;
4
+ export declare const getPropertySignatureName: (sourceCode: TSESLint.SourceCode, node: TSESTree.TSPropertySignature) => string;
5
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAEpD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAEzD,eAAO,MAAM,kBAAkB,GAC7B,YAAY,QAAQ,CAAC,UAAU,EAC/B,MAAM,QAAQ,CAAC,eAAe,06MAiB/B,CAAC;AAEF,eAAO,MAAM,wBAAwB,GACnC,YAAY,QAAQ,CAAC,UAAU,EAC/B,MAAM,QAAQ,CAAC,mBAAmB,WAYnC,CAAC"}
package/dist/utils.js ADDED
@@ -0,0 +1,24 @@
1
+ import { TSESTree } from "@typescript-eslint/utils";
2
+ export const findTypeDefinition = (sourceCode, node) => {
3
+ if (node.typeName.type !== TSESTree.AST_NODE_TYPES.Identifier) {
4
+ return;
5
+ }
6
+ let currentScope = sourceCode.getScope(node);
7
+ while (currentScope) {
8
+ const variable = currentScope.set.get(node.typeName.name);
9
+ if (variable && variable.defs && variable.defs.length > 0) {
10
+ return variable.defs[0]?.node;
11
+ }
12
+ currentScope = currentScope.upper;
13
+ }
14
+ };
15
+ export const getPropertySignatureName = (sourceCode, node) => {
16
+ switch (node.key.type) {
17
+ case TSESTree.AST_NODE_TYPES.Identifier:
18
+ return node.key.name;
19
+ case TSESTree.AST_NODE_TYPES.Literal:
20
+ return String(node.key.value);
21
+ default:
22
+ return sourceCode.getText(node.key);
23
+ }
24
+ };
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "lint-config-sq11y",
3
+ "version": "0.0.0",
4
+ "homepage": "https://sq11y.github.io/lint-config/",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "github:sq11y/lint-config"
8
+ },
9
+ "files": [
10
+ "dist",
11
+ "stylelint.config.mjs"
12
+ ],
13
+ "type": "module",
14
+ "exports": {
15
+ "./eslint": "./dist/index.js",
16
+ "./stylelint": "./stylelint.config.mjs"
17
+ },
18
+ "devDependencies": {
19
+ "@eslint/js": "^10.0.1",
20
+ "@stylistic/eslint-plugin": "^5.10.0",
21
+ "@types/node": "^26.0.1",
22
+ "@typescript-eslint/utils": "^8.62.0",
23
+ "@vue/eslint-config-typescript": "^14.8.0",
24
+ "eslint-config-prettier": "^10.1.8",
25
+ "eslint-plugin-jsdoc": "^63.0.10",
26
+ "eslint-plugin-oxlint": "~1.69.0",
27
+ "eslint-plugin-vue": "~10.9.2",
28
+ "eslint-plugin-vuejs-accessibility": "^2.5.0",
29
+ "jiti": "^2.7.0",
30
+ "stylelint-config-recommended-vue": "^1.6.1",
31
+ "stylelint-config-standard": "^40.0.0",
32
+ "typescript": "^6.0.3",
33
+ "typescript-eslint": "^8.62.0"
34
+ },
35
+ "peerDependencies": {
36
+ "eslint": "^10.5.0",
37
+ "oxfmt": "^0.56.0",
38
+ "oxlint": "^1.71.0",
39
+ "stylelint": "^17.13.0"
40
+ },
41
+ "engines": {
42
+ "node": ">=24.18.0"
43
+ },
44
+ "scripts": {
45
+ "build": "tsc -p tsconfig.node.json"
46
+ }
47
+ }
@@ -0,0 +1,15 @@
1
+ /** @type {import('stylelint').Config} */
2
+
3
+ export default {
4
+ extends: ["stylelint-config-standard", "stylelint-config-recommended-vue"],
5
+
6
+ rules: {
7
+ "property-layout-mappings": "flow-relative",
8
+ "value-keyword-layout-mappings": "flow-relative",
9
+ "display-notation": "short",
10
+ "font-weight-notation": "numeric",
11
+ "declaration-no-important": true,
12
+ "max-nesting-depth": [2, { ignore: ["pseudo-classes", "blockless-at-rules"] }],
13
+ "selector-max-compound-selectors": 2,
14
+ },
15
+ };