@dvukovic/style-guide 0.3.108 → 0.3.110

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dvukovic/style-guide",
3
- "version": "0.3.108",
3
+ "version": "0.3.110",
4
4
  "description": "My own style guide",
5
5
  "repository": {
6
6
  "type": "git",
@@ -125,3 +125,15 @@ pageleave
125
125
  opensearchservice
126
126
  httponly
127
127
  unthrown
128
+ supabase
129
+ tslog
130
+ fkey
131
+ msword
132
+ openxmlformats
133
+ officedocument
134
+ wordprocessingml
135
+ presentationml
136
+ spreadsheetml
137
+ pageleave
138
+ autocapture
139
+ opensearchservice
@@ -1,4 +1,5 @@
1
1
  import { noCommentedOutCode } from "../rules/no-commented-out-code/no-commented-out-code.js"
2
+ import { noT } from "../rules/no-t/no-t.js"
2
3
 
3
4
  /** @type {import("@eslint/config-helpers").Config} */
4
5
  export const dvukovic = {
@@ -6,10 +7,12 @@ export const dvukovic = {
6
7
  dvukovic: {
7
8
  rules: {
8
9
  "no-commented-out-code": noCommentedOutCode,
10
+ "no-t": noT,
9
11
  },
10
12
  },
11
13
  },
12
14
  rules: {
13
15
  "dvukovic/no-commented-out-code": "error",
16
+ "dvukovic/no-t": "error",
14
17
  },
15
18
  }
@@ -0,0 +1,43 @@
1
+ export const noT = {
2
+ create(context) {
3
+ const [{ prefix = "" } = {}] = context.options
4
+
5
+ return {
6
+ "TSTypeParameter > Identifier[name=/^.$/]"(node) {
7
+ context.report({
8
+ data: { name: node.name },
9
+ messageId: "forbidden",
10
+ node,
11
+ })
12
+ },
13
+ "TSTypeParameter > Identifier[name=/^.{2,}$/]"(node) {
14
+ if (prefix && !node.name.startsWith(prefix)) {
15
+ context.report({
16
+ data: { name: node.name, prefix },
17
+ messageId: "prefix",
18
+ node,
19
+ })
20
+ }
21
+ },
22
+ }
23
+ },
24
+ meta: {
25
+ docs: {
26
+ description: "Forbids single-character type parameters.",
27
+ },
28
+ messages: {
29
+ forbidden: `Single-character type parameters are forbidden. Choose a more descriptive name for "{{name}}"`,
30
+ prefix: `Type parameter "{{name}}" does not have prefix "{{prefix}}"`,
31
+ },
32
+ schema: [
33
+ {
34
+ additionalProperties: false,
35
+ properties: {
36
+ prefix: { type: "string" },
37
+ },
38
+ type: "object",
39
+ },
40
+ ],
41
+ type: "problem",
42
+ },
43
+ }
@@ -0,0 +1,85 @@
1
+ import { ESLint } from "eslint"
2
+ import tseslint from "typescript-eslint"
3
+
4
+ import { dvukovic } from "../../plugins/dvukovic.js"
5
+
6
+ const eslint = new ESLint({
7
+ overrideConfig: [
8
+ {
9
+ files: ["**/*.ts"],
10
+ languageOptions: {
11
+ parser: tseslint.parser,
12
+ },
13
+ },
14
+ dvukovic,
15
+ ],
16
+ overrideConfigFile: true,
17
+ })
18
+
19
+ describe("dvukovic/no-t", () => {
20
+ test("detects single-character type parameter", async () => {
21
+ const code = `function foo<T>(arg: T): T { return arg }\n`
22
+
23
+ const results = await eslint.lintText(code, { filePath: "test.ts" })
24
+ const errors = results[0]?.messages.filter((message) => {
25
+ return message.ruleId === "dvukovic/no-t"
26
+ })
27
+
28
+ expect(errors?.length).toBe(1)
29
+ })
30
+
31
+ test("detects multiple single-character type parameters", async () => {
32
+ const code = `type Entry<K, V> = { key: K; value: V }\n`
33
+
34
+ const results = await eslint.lintText(code, { filePath: "test.ts" })
35
+ const errors = results[0]?.messages.filter((message) => {
36
+ return message.ruleId === "dvukovic/no-t"
37
+ })
38
+
39
+ expect(errors?.length).toBe(2)
40
+ })
41
+
42
+ test("allows descriptive type parameters", async () => {
43
+ const code = `function foo<Element>(arg: Element): Element { return arg }\n`
44
+
45
+ const results = await eslint.lintText(code, { filePath: "test.ts" })
46
+ const errors = results[0]?.messages.filter((message) => {
47
+ return message.ruleId === "dvukovic/no-t"
48
+ })
49
+
50
+ expect(errors?.length).toBe(0)
51
+ })
52
+
53
+ test("allows descriptive type parameters in type alias", async () => {
54
+ const code = `type Entry<Key, Value> = { key: Key; value: Value }\n`
55
+
56
+ const results = await eslint.lintText(code, { filePath: "test.ts" })
57
+ const errors = results[0]?.messages.filter((message) => {
58
+ return message.ruleId === "dvukovic/no-t"
59
+ })
60
+
61
+ expect(errors?.length).toBe(0)
62
+ })
63
+
64
+ test("detects single-character in interface", async () => {
65
+ const code = `interface Container<T> { value: T }\n`
66
+
67
+ const results = await eslint.lintText(code, { filePath: "test.ts" })
68
+ const errors = results[0]?.messages.filter((message) => {
69
+ return message.ruleId === "dvukovic/no-t"
70
+ })
71
+
72
+ expect(errors?.length).toBe(1)
73
+ })
74
+
75
+ test("detects single-character in class", async () => {
76
+ const code = `class Box<T> { constructor(public value: T) {} }\n`
77
+
78
+ const results = await eslint.lintText(code, { filePath: "test.ts" })
79
+ const errors = results[0]?.messages.filter((message) => {
80
+ return message.ruleId === "dvukovic/no-t"
81
+ })
82
+
83
+ expect(errors?.length).toBe(1)
84
+ })
85
+ })