@simplysm/lint 14.0.42 → 14.0.43

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.
@@ -1,5 +1,8 @@
1
1
  declare const _default: {
2
2
  rules: {
3
+ "ng-template-no-strict-null-check": import("@typescript-eslint/utils/ts-eslint").RuleModule<"noStrictNullCheck", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
4
+ name: string;
5
+ };
3
6
  "ng-template-no-todo-comments": import("@typescript-eslint/utils/ts-eslint").RuleModule<"noTodo", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
4
7
  name: string;
5
8
  };
@@ -1 +1 @@
1
- {"version":3,"file":"eslint-plugin.d.ts","sourceRoot":"","sources":["../src/eslint-plugin.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAQA,wBAUE"}
1
+ {"version":3,"file":"eslint-plugin.d.ts","sourceRoot":"","sources":["../src/eslint-plugin.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AASA,wBAWE"}
@@ -1,3 +1,4 @@
1
+ import ngTemplateNoStrictNullCheck from "./rules/ng-template-no-strict-null-check.js";
1
2
  import ngTemplateNoTodoComments from "./rules/ng-template-no-todo-comments.js";
2
3
  import ngTemplateSdRequireBindingAttrs from "./rules/ng-template-sd-require-binding-attrs.js";
3
4
  import noHardPrivate from "./rules/no-hard-private.js";
@@ -7,6 +8,7 @@ import tsNoUnusedInjects from "./rules/ts-no-unused-injects.js";
7
8
  import tsNoUnusedProtectedReadonly from "./rules/ts-no-unused-protected-readonly.js";
8
9
  export default {
9
10
  rules: {
11
+ "ng-template-no-strict-null-check": ngTemplateNoStrictNullCheck,
10
12
  "ng-template-no-todo-comments": ngTemplateNoTodoComments,
11
13
  "ng-template-sd-require-binding-attrs": ngTemplateSdRequireBindingAttrs,
12
14
  "no-hard-private": noHardPrivate,
@@ -1 +1 @@
1
- {"version":3,"file":"eslint-plugin.js","sourceRoot":"","sources":["../src/eslint-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,wBAAwB,MAAM,sCAAsC,CAAC;AAC5E,OAAO,+BAA+B,MAAM,8CAA8C,CAAC;AAC3F,OAAO,aAAa,MAAM,yBAAyB,CAAC;AACpD,OAAO,4BAA4B,MAAM,0CAA0C,CAAC;AACpF,OAAO,4BAA4B,MAAM,2CAA2C,CAAC;AACrF,OAAO,iBAAiB,MAAM,8BAA8B,CAAC;AAC7D,OAAO,2BAA2B,MAAM,yCAAyC,CAAC;AAElF,eAAe;IACb,KAAK,EAAE;QACL,8BAA8B,EAAE,wBAAwB;QACxD,sCAAsC,EAAE,+BAA+B;QACvE,iBAAiB,EAAE,aAAa;QAChC,kCAAkC,EAAE,4BAA4B;QAChE,mCAAmC,EAAE,4BAA4B;QACjE,sBAAsB,EAAE,iBAAiB;QACzC,iCAAiC,EAAE,2BAA2B;KAC/D;CACF,CAAC"}
1
+ {"version":3,"file":"eslint-plugin.js","sourceRoot":"","sources":["../src/eslint-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,2BAA2B,MAAM,0CAA0C,CAAC;AACnF,OAAO,wBAAwB,MAAM,sCAAsC,CAAC;AAC5E,OAAO,+BAA+B,MAAM,8CAA8C,CAAC;AAC3F,OAAO,aAAa,MAAM,yBAAyB,CAAC;AACpD,OAAO,4BAA4B,MAAM,0CAA0C,CAAC;AACpF,OAAO,4BAA4B,MAAM,2CAA2C,CAAC;AACrF,OAAO,iBAAiB,MAAM,8BAA8B,CAAC;AAC7D,OAAO,2BAA2B,MAAM,yCAAyC,CAAC;AAElF,eAAe;IACb,KAAK,EAAE;QACL,kCAAkC,EAAE,2BAA2B;QAC/D,8BAA8B,EAAE,wBAAwB;QACxD,sCAAsC,EAAE,+BAA+B;QACvE,iBAAiB,EAAE,aAAa;QAChC,kCAAkC,EAAE,4BAA4B;QAChE,mCAAmC,EAAE,4BAA4B;QACjE,sBAAsB,EAAE,iBAAiB;QACzC,iCAAiC,EAAE,2BAA2B;KAC/D;CACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"eslint-recommended.d.ts","sourceRoot":"","sources":["../src/eslint-recommended.ts"],"names":[],"mappings":"AAAA,OAAiB,EAAE,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAC;;AAkF9D,wBA0KE"}
1
+ {"version":3,"file":"eslint-recommended.d.ts","sourceRoot":"","sources":["../src/eslint-recommended.ts"],"names":[],"mappings":"AAAA,OAAiB,EAAE,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAC;;AAkG9D,wBA4KE"}
@@ -8,7 +8,7 @@ import { ESLint } from "eslint";
8
8
  import { fileURLToPath } from "url";
9
9
  const commonRules = {
10
10
  "no-warning-comments": "warn",
11
- "eqeqeq": ["error", "always", { null: "ignore" }],
11
+ "eqeqeq": ["error", "always", { null: "never" }],
12
12
  "no-self-compare": "error",
13
13
  "array-callback-return": "error",
14
14
  };
@@ -59,6 +59,22 @@ const noDirectEnvAccessRules = {
59
59
  selector: 'CallExpression[callee.name="env"][arguments.0.value="NODE_ENV"]',
60
60
  message: "NODE_ENV 환경변수는 사용할 수 없습니다.",
61
61
  },
62
+ {
63
+ selector: 'BinaryExpression[operator="==="][right.type="Identifier"][right.name="undefined"]',
64
+ message: "`== null`를 사용하지 마세요. `== null`을 사용하세요.",
65
+ },
66
+ {
67
+ selector: 'BinaryExpression[operator="==="][left.type="Identifier"][left.name="undefined"]',
68
+ message: "`== null`를 사용하지 마세요. `== null`을 사용하세요.",
69
+ },
70
+ {
71
+ selector: 'BinaryExpression[operator="!=="][right.type="Identifier"][right.name="undefined"]',
72
+ message: "`!= null`를 사용하지 마세요. `!= null`을 사용하세요.",
73
+ },
74
+ {
75
+ selector: 'BinaryExpression[operator="!=="][left.type="Identifier"][left.name="undefined"]',
76
+ message: "`!= null`를 사용하지 마세요. `!= null`을 사용하세요.",
77
+ },
62
78
  ],
63
79
  };
64
80
  const unusedImportsRules = {
@@ -208,8 +224,10 @@ export default tseslint.config({
208
224
  "@simplysm": plugin,
209
225
  },
210
226
  rules: {
227
+ "@simplysm/ng-template-no-strict-null-check": "error",
211
228
  "@simplysm/ng-template-no-todo-comments": "warn",
212
229
  "@simplysm/ng-template-sd-require-binding-attrs": "error",
230
+ "@angular-eslint/template/eqeqeq": ["error", { allowNullOrUndefined: true }],
213
231
  "@angular-eslint/template/label-has-associated-control": "off",
214
232
  },
215
233
  }, {
@@ -1 +1 @@
1
- {"version":3,"file":"eslint-recommended.js","sourceRoot":"","sources":["../src/eslint-recommended.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"eslint-recommended.js","sourceRoot":"","sources":["../src/eslint-recommended.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Angular 템플릿에서 `=== null`, `!== null`, `=== undefined`, `!== undefined` 사용을 금지하는 ESLint 규칙.
3
+ *
4
+ * @remarks
5
+ * `== null` / `!= null`로 통일하도록 강제합니다.
6
+ * 인라인 템플릿에서 offset 매핑 문제로 autofix는 제공하지 않습니다.
7
+ */
8
+ declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<"noStrictNullCheck", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
9
+ name: string;
10
+ };
11
+ export default _default;
12
+ //# sourceMappingURL=ng-template-no-strict-null-check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ng-template-no-strict-null-check.d.ts","sourceRoot":"","sources":["../../src/rules/ng-template-no-strict-null-check.ts"],"names":[],"mappings":"AAGA;;;;;;GAMG;;;;AACH,wBAqDG"}
@@ -0,0 +1,57 @@
1
+ import { getTemplateParserServices } from "@angular-eslint/utils";
2
+ import { createRule } from "../utils/create-rule.js";
3
+ /**
4
+ * Angular 템플릿에서 `=== null`, `!== null`, `=== undefined`, `!== undefined` 사용을 금지하는 ESLint 규칙.
5
+ *
6
+ * @remarks
7
+ * `== null` / `!= null`로 통일하도록 강제합니다.
8
+ * 인라인 템플릿에서 offset 매핑 문제로 autofix는 제공하지 않습니다.
9
+ */
10
+ export default createRule({
11
+ name: "ng-template-no-strict-null-check",
12
+ meta: {
13
+ type: "problem",
14
+ docs: {
15
+ description: "Angular 템플릿에서 `=== null`, `!== null`, `=== undefined`, `!== undefined`를 금지합니다. `== null` / `!= null`을 사용하세요.",
16
+ },
17
+ schema: [],
18
+ messages: {
19
+ noStrictNullCheck: '`{{actual}}`을 사용하지 마세요. `{{replacement}}`를 사용하세요.',
20
+ },
21
+ },
22
+ defaultOptions: [],
23
+ create(context) {
24
+ const parserServices = getTemplateParserServices(context);
25
+ const sourceCode = context.sourceCode;
26
+ return {
27
+ 'Binary[operation=/^(===|!==)$/]'(node) {
28
+ const { left, right, operation } = node;
29
+ const leftIsNil = isNilValue(left);
30
+ const rightIsNil = isNilValue(right);
31
+ if (!leftIsNil && !rightIsNil)
32
+ return;
33
+ const looseOp = operation === "===" ? "==" : "!=";
34
+ const nilSide = leftIsNil ? left : right;
35
+ const otherSide = leftIsNil ? right : left;
36
+ const actualText = `${getNodeText(otherSide, sourceCode)} ${operation} ${getNodeText(nilSide, sourceCode)}`;
37
+ const replacementText = `${getNodeText(otherSide, sourceCode)} ${looseOp} null`;
38
+ const loc = parserServices.convertNodeSourceSpanToLoc(node.sourceSpan);
39
+ context.report({
40
+ loc,
41
+ messageId: "noStrictNullCheck",
42
+ data: {
43
+ actual: actualText,
44
+ replacement: replacementText,
45
+ },
46
+ });
47
+ },
48
+ };
49
+ },
50
+ });
51
+ function isNilValue(node) {
52
+ return "value" in node && node.value == null;
53
+ }
54
+ function getNodeText(node, sourceCode) {
55
+ return sourceCode.getText().slice(node.span.start, node.span.end);
56
+ }
57
+ //# sourceMappingURL=ng-template-no-strict-null-check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ng-template-no-strict-null-check.js","sourceRoot":"","sources":["../../src/rules/ng-template-no-strict-null-check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD;;;;;;GAMG;AACH,eAAe,UAAU,CAAC;IACxB,IAAI,EAAE,kCAAkC;IACxC,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACJ,WAAW,EACT,8GAA8G;SACjH;QACD,MAAM,EAAE,EAAE;QACV,QAAQ,EAAE;YACR,iBAAiB,EACf,mDAAmD;SACtD;KACF;IACD,cAAc,EAAE,EAAE;IAClB,MAAM,CAAC,OAAO;QACZ,MAAM,cAAc,GAAG,yBAAyB,CAAC,OAAgB,CAAC,CAAC;QACnE,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;QAEtC,OAAO;YACL,iCAAiC,CAC/B,IAKC;gBAED,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC;gBACxC,MAAM,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;gBACnC,MAAM,UAAU,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;gBACrC,IAAI,CAAC,SAAS,IAAI,CAAC,UAAU;oBAAE,OAAO;gBAEtC,MAAM,OAAO,GAAG,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;gBAClD,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;gBACzC,MAAM,SAAS,GAAG,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;gBAE3C,MAAM,UAAU,GAAG,GAAG,WAAW,CAAC,SAAS,EAAE,UAAU,CAAC,IAAI,SAAS,IAAI,WAAW,CAAC,OAAO,EAAE,UAAU,CAAC,EAAE,CAAC;gBAC5G,MAAM,eAAe,GAAG,GAAG,WAAW,CAAC,SAAS,EAAE,UAAU,CAAC,IAAI,OAAO,OAAO,CAAC;gBAEhF,MAAM,GAAG,GAAG,cAAc,CAAC,0BAA0B,CAAC,IAAI,CAAC,UAAmB,CAAC,CAAC;gBAEhF,OAAO,CAAC,MAAM,CAAC;oBACb,GAAG;oBACH,SAAS,EAAE,mBAAmB;oBAC9B,IAAI,EAAE;wBACJ,MAAM,EAAE,UAAU;wBAClB,WAAW,EAAE,eAAe;qBAC7B;iBACF,CAAC,CAAC;YACL,CAAC;SACO,CAAC;IACb,CAAC;CACF,CAAC,CAAC;AAEH,SAAS,UAAU,CAAC,IAAyB;IAC3C,OAAO,OAAO,IAAI,IAAI,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC;AAC/C,CAAC;AAED,SAAS,WAAW,CAClB,IAA8C,EAC9C,UAAiC;IAEjC,OAAO,UAAU,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACpE,CAAC"}
@@ -24,7 +24,7 @@ export default createRule({
24
24
  const source = sourceCode.getText();
25
25
  const commentRegex = /<!--([\s\S]*?)-->/g;
26
26
  let match;
27
- while ((match = commentRegex.exec(source)) !== null) {
27
+ while ((match = commentRegex.exec(source)) != null) {
28
28
  const commentContent = match[1];
29
29
  const todoIndex = commentContent.indexOf("TODO:");
30
30
  if (todoIndex < 0)
@@ -1 +1 @@
1
- {"version":3,"file":"ng-template-no-todo-comments.js","sourceRoot":"","sources":["../../src/rules/ng-template-no-todo-comments.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD;;;;;;GAMG;AACH,eAAe,UAAU,CAAC;IACxB,IAAI,EAAE,8BAA8B;IACpC,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACJ,WAAW,EAAE,4BAA4B;SAC1C;QACD,MAAM,EAAE,EAAE;QACV,QAAQ,EAAE;YACR,MAAM,EAAE,aAAa;SACtB;KACF;IACD,cAAc,EAAE,EAAE;IAClB,MAAM,CAAC,OAAO;QACZ,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;QACtC,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,EAAE,CAAC;QACpC,MAAM,YAAY,GAAG,oBAAoB,CAAC;QAC1C,IAAI,KAAK,CAAC;QACV,OAAO,CAAC,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YACpD,MAAM,cAAc,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YAChC,MAAM,SAAS,GAAG,cAAc,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAClD,IAAI,SAAS,GAAG,CAAC;gBAAE,SAAS;YAE5B,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;YAC1B,MAAM,GAAG,GAAG,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;YACpC,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAC3D,MAAM,GAAG,GAAG,UAAU,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;YAC9C,MAAM,MAAM,GAAG,UAAU,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;YAE/C,OAAO,CAAC,MAAM,CAAC;gBACb,GAAG,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE;gBAChC,SAAS,EAAE,QAAQ;gBACnB,IAAI,EAAE,EAAE,OAAO,EAAE;aAClB,CAAC,CAAC;QACL,CAAC;QAED,OAAO,EAAE,CAAC;IACZ,CAAC;CACF,CAAC,CAAC"}
1
+ {"version":3,"file":"ng-template-no-todo-comments.js","sourceRoot":"","sources":["../../src/rules/ng-template-no-todo-comments.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD;;;;;;GAMG;AACH,eAAe,UAAU,CAAC;IACxB,IAAI,EAAE,8BAA8B;IACpC,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACJ,WAAW,EAAE,4BAA4B;SAC1C;QACD,MAAM,EAAE,EAAE;QACV,QAAQ,EAAE;YACR,MAAM,EAAE,aAAa;SACtB;KACF;IACD,cAAc,EAAE,EAAE;IAClB,MAAM,CAAC,OAAO;QACZ,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;QACtC,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,EAAE,CAAC;QACpC,MAAM,YAAY,GAAG,oBAAoB,CAAC;QAC1C,IAAI,KAAK,CAAC;QACV,OAAO,CAAC,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;YACnD,MAAM,cAAc,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YAChC,MAAM,SAAS,GAAG,cAAc,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAClD,IAAI,SAAS,GAAG,CAAC;gBAAE,SAAS;YAE5B,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;YAC1B,MAAM,GAAG,GAAG,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;YACpC,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAC3D,MAAM,GAAG,GAAG,UAAU,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;YAC9C,MAAM,MAAM,GAAG,UAAU,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;YAE/C,OAAO,CAAC,MAAM,CAAC;gBACb,GAAG,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE;gBAChC,SAAS,EAAE,QAAQ;gBACnB,IAAI,EAAE,EAAE,OAAO,EAAE;aAClB,CAAC,CAAC;QACL,CAAC;QAED,OAAO,EAAE,CAAC;IACZ,CAAC;CACF,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simplysm/lint",
3
- "version": "14.0.42",
3
+ "version": "14.0.43",
4
4
  "description": "심플리즘 패키지 - ESLint plugin",
5
5
  "author": "심플리즘",
6
6
  "license": "Apache-2.0",
@@ -1,3 +1,4 @@
1
+ import ngTemplateNoStrictNullCheck from "./rules/ng-template-no-strict-null-check";
1
2
  import ngTemplateNoTodoComments from "./rules/ng-template-no-todo-comments";
2
3
  import ngTemplateSdRequireBindingAttrs from "./rules/ng-template-sd-require-binding-attrs";
3
4
  import noHardPrivate from "./rules/no-hard-private";
@@ -8,6 +9,7 @@ import tsNoUnusedProtectedReadonly from "./rules/ts-no-unused-protected-readonly
8
9
 
9
10
  export default {
10
11
  rules: {
12
+ "ng-template-no-strict-null-check": ngTemplateNoStrictNullCheck,
11
13
  "ng-template-no-todo-comments": ngTemplateNoTodoComments,
12
14
  "ng-template-sd-require-binding-attrs": ngTemplateSdRequireBindingAttrs,
13
15
  "no-hard-private": noHardPrivate,
@@ -9,7 +9,7 @@ import { fileURLToPath } from "url";
9
9
 
10
10
  const commonRules: FlatConfig.Rules = {
11
11
  "no-warning-comments": "warn",
12
- "eqeqeq": ["error", "always", { null: "ignore" }],
12
+ "eqeqeq": ["error", "always", { null: "never" }],
13
13
  "no-self-compare": "error",
14
14
  "array-callback-return": "error",
15
15
  };
@@ -64,6 +64,22 @@ const noDirectEnvAccessRules: FlatConfig.Rules = {
64
64
  selector: 'CallExpression[callee.name="env"][arguments.0.value="NODE_ENV"]',
65
65
  message: "NODE_ENV 환경변수는 사용할 수 없습니다.",
66
66
  },
67
+ {
68
+ selector: 'BinaryExpression[operator="==="][right.type="Identifier"][right.name="undefined"]',
69
+ message: "`== null`를 사용하지 마세요. `== null`을 사용하세요.",
70
+ },
71
+ {
72
+ selector: 'BinaryExpression[operator="==="][left.type="Identifier"][left.name="undefined"]',
73
+ message: "`== null`를 사용하지 마세요. `== null`을 사용하세요.",
74
+ },
75
+ {
76
+ selector: 'BinaryExpression[operator="!=="][right.type="Identifier"][right.name="undefined"]',
77
+ message: "`!= null`를 사용하지 마세요. `!= null`을 사용하세요.",
78
+ },
79
+ {
80
+ selector: 'BinaryExpression[operator="!=="][left.type="Identifier"][left.name="undefined"]',
81
+ message: "`!= null`를 사용하지 마세요. `!= null`을 사용하세요.",
82
+ },
67
83
  ],
68
84
  };
69
85
 
@@ -231,8 +247,10 @@ export default tseslint.config(
231
247
  "@simplysm": plugin as unknown as ESLint.Plugin,
232
248
  },
233
249
  rules: {
250
+ "@simplysm/ng-template-no-strict-null-check": "error",
234
251
  "@simplysm/ng-template-no-todo-comments": "warn",
235
252
  "@simplysm/ng-template-sd-require-binding-attrs": "error",
253
+ "@angular-eslint/template/eqeqeq": ["error", { allowNullOrUndefined: true }],
236
254
  "@angular-eslint/template/label-has-associated-control": "off",
237
255
  },
238
256
  },
@@ -0,0 +1,75 @@
1
+ import { getTemplateParserServices } from "@angular-eslint/utils";
2
+ import { createRule } from "../utils/create-rule";
3
+
4
+ /**
5
+ * Angular 템플릿에서 `=== null`, `!== null`, `=== undefined`, `!== undefined` 사용을 금지하는 ESLint 규칙.
6
+ *
7
+ * @remarks
8
+ * `== null` / `!= null`로 통일하도록 강제합니다.
9
+ * 인라인 템플릿에서 offset 매핑 문제로 autofix는 제공하지 않습니다.
10
+ */
11
+ export default createRule({
12
+ name: "ng-template-no-strict-null-check",
13
+ meta: {
14
+ type: "problem",
15
+ docs: {
16
+ description:
17
+ "Angular 템플릿에서 `=== null`, `!== null`, `=== undefined`, `!== undefined`를 금지합니다. `== null` / `!= null`을 사용하세요.",
18
+ },
19
+ schema: [],
20
+ messages: {
21
+ noStrictNullCheck:
22
+ '`{{actual}}`을 사용하지 마세요. `{{replacement}}`를 사용하세요.',
23
+ },
24
+ },
25
+ defaultOptions: [],
26
+ create(context) {
27
+ const parserServices = getTemplateParserServices(context as never);
28
+ const sourceCode = context.sourceCode;
29
+
30
+ return {
31
+ 'Binary[operation=/^(===|!==)$/]'(
32
+ node: {
33
+ left: { value?: unknown; span: { start: number; end: number } };
34
+ right: { value?: unknown; span: { start: number; end: number } };
35
+ operation: "===" | "!==";
36
+ sourceSpan: { start: number; end: number };
37
+ },
38
+ ) {
39
+ const { left, right, operation } = node;
40
+ const leftIsNil = isNilValue(left);
41
+ const rightIsNil = isNilValue(right);
42
+ if (!leftIsNil && !rightIsNil) return;
43
+
44
+ const looseOp = operation === "===" ? "==" : "!=";
45
+ const nilSide = leftIsNil ? left : right;
46
+ const otherSide = leftIsNil ? right : left;
47
+
48
+ const actualText = `${getNodeText(otherSide, sourceCode)} ${operation} ${getNodeText(nilSide, sourceCode)}`;
49
+ const replacementText = `${getNodeText(otherSide, sourceCode)} ${looseOp} null`;
50
+
51
+ const loc = parserServices.convertNodeSourceSpanToLoc(node.sourceSpan as never);
52
+
53
+ context.report({
54
+ loc,
55
+ messageId: "noStrictNullCheck",
56
+ data: {
57
+ actual: actualText,
58
+ replacement: replacementText,
59
+ },
60
+ });
61
+ },
62
+ } as never;
63
+ },
64
+ });
65
+
66
+ function isNilValue(node: { value?: unknown }): boolean {
67
+ return "value" in node && node.value == null;
68
+ }
69
+
70
+ function getNodeText(
71
+ node: { span: { start: number; end: number } },
72
+ sourceCode: { getText(): string },
73
+ ): string {
74
+ return sourceCode.getText().slice(node.span.start, node.span.end);
75
+ }
@@ -25,7 +25,7 @@ export default createRule({
25
25
  const source = sourceCode.getText();
26
26
  const commentRegex = /<!--([\s\S]*?)-->/g;
27
27
  let match;
28
- while ((match = commentRegex.exec(source)) !== null) {
28
+ while ((match = commentRegex.exec(source)) != null) {
29
29
  const commentContent = match[1];
30
30
  const todoIndex = commentContent.indexOf("TODO:");
31
31
  if (todoIndex < 0) continue;