@fjall/eslint-plugin 3.11.0 → 4.1.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.
package/index.js CHANGED
@@ -26,6 +26,7 @@ import requireAbortPrecheckInSdkLoop from "./require-abort-precheck-in-sdk-loop.
26
26
  import requireAbortCompositionOnSdkSend from "./require-abort-composition-on-sdk-send.js";
27
27
  import noClassicConnectedAccountAssume from "./no-classic-connected-account-assume.js";
28
28
  import noRawDbTransaction from "./no-raw-db-transaction.js";
29
+ import noRawExitCode from "./no-raw-exit-code.js";
29
30
 
30
31
  export default {
31
32
  rules: {
@@ -58,6 +59,7 @@ export default {
58
59
  "require-abort-precheck-in-sdk-loop": requireAbortPrecheckInSdkLoop,
59
60
  "require-abort-composition-on-sdk-send": requireAbortCompositionOnSdkSend,
60
61
  "no-classic-connected-account-assume": noClassicConnectedAccountAssume,
61
- "no-raw-db-transaction": noRawDbTransaction
62
+ "no-raw-db-transaction": noRawDbTransaction,
63
+ "no-raw-exit-code": noRawExitCode
62
64
  }
63
65
  };
@@ -0,0 +1,82 @@
1
+ /**
2
+ * ESLint Rule: no-raw-exit-code
3
+ *
4
+ * Exit codes live in the registry (cli/src/util/exitCodes.ts) - one owner
5
+ * per number, per-family tables, documented cross-family reuse. A raw
6
+ * numeric literal in `process.exit(N)` or `process.exitCode = N` bypasses
7
+ * that contract and reintroduces the collision class the registry closed
8
+ * (codemod IO_ERROR 4 vs deploy destruction-withheld 4).
9
+ *
10
+ * Flags:
11
+ * - process.exit(<numeric literal>)
12
+ * - process.exitCode = <numeric literal> (including negated literals)
13
+ *
14
+ * Allowed:
15
+ * - process.exit(SOME_CONSTANT) / process.exitCode = someVariable
16
+ * - the registry module itself (it defines the numbers)
17
+ */
18
+
19
+ const REGISTRY_PATH_FRAGMENT = "util/exitCodes.ts";
20
+
21
+ function isNumericLiteral(node) {
22
+ if (node === undefined || node === null) return false;
23
+ if (node.type === "Literal" && typeof node.value === "number") return true;
24
+ // -1 parses as UnaryExpression("-", Literal(1))
25
+ return (
26
+ node.type === "UnaryExpression" &&
27
+ node.operator === "-" &&
28
+ isNumericLiteral(node.argument)
29
+ );
30
+ }
31
+
32
+ function isProcessMember(node, propertyName) {
33
+ return (
34
+ node.type === "MemberExpression" &&
35
+ node.object.type === "Identifier" &&
36
+ node.object.name === "process" &&
37
+ node.property.type === "Identifier" &&
38
+ node.property.name === propertyName
39
+ );
40
+ }
41
+
42
+ /** @type {import('eslint').Rule.RuleModule} */
43
+ export default {
44
+ meta: {
45
+ type: "problem",
46
+ docs: {
47
+ description:
48
+ "Exit codes must come from the registry (cli/src/util/exitCodes.ts), never raw numeric literals",
49
+ category: "Best Practices",
50
+ recommended: false
51
+ },
52
+ messages: {
53
+ rawExit:
54
+ "Raw numeric exit code. Import a named constant from util/exitCodes.ts (the exit-code registry) so the number keeps exactly one meaning per family."
55
+ },
56
+ schema: []
57
+ },
58
+
59
+ create(context) {
60
+ const filename = context.filename ?? context.getFilename();
61
+ if (filename.replaceAll("\\", "/").endsWith(REGISTRY_PATH_FRAGMENT)) {
62
+ return {};
63
+ }
64
+
65
+ return {
66
+ CallExpression(node) {
67
+ if (!isProcessMember(node.callee, "exit")) return;
68
+ if (node.arguments.length === 0) return;
69
+ if (isNumericLiteral(node.arguments[0])) {
70
+ context.report({ node, messageId: "rawExit" });
71
+ }
72
+ },
73
+ AssignmentExpression(node) {
74
+ if (node.operator !== "=") return;
75
+ if (!isProcessMember(node.left, "exitCode")) return;
76
+ if (isNumericLiteral(node.right)) {
77
+ context.report({ node, messageId: "rawExit" });
78
+ }
79
+ }
80
+ };
81
+ }
82
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fjall/eslint-plugin",
3
- "version": "3.11.0",
3
+ "version": "4.1.0",
4
4
  "description": "ESLint plugin with Fjall-specific coding standard rules",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -32,5 +32,5 @@
32
32
  "vitest": "^4.1.5"
33
33
  },
34
34
  "license": "SEE LICENSE IN LICENSE",
35
- "gitHead": "a15125ea026d52428ff5433d098699899695ca3f"
35
+ "gitHead": "09dee795753839b82aedbb7d0cef1c5ef283df55"
36
36
  }