eslint-plugin-runtime-cleanup 1.2.8

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.
Files changed (217) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/LICENSE +21 -0
  3. package/README.md +117 -0
  4. package/dist/_internal/ast-node.d.ts +19 -0
  5. package/dist/_internal/ast-node.d.ts.map +1 -0
  6. package/dist/_internal/ast-node.js +42 -0
  7. package/dist/_internal/ast-node.js.map +1 -0
  8. package/dist/_internal/bounded-cache.d.ts +37 -0
  9. package/dist/_internal/bounded-cache.d.ts.map +1 -0
  10. package/dist/_internal/bounded-cache.js +63 -0
  11. package/dist/_internal/bounded-cache.js.map +1 -0
  12. package/dist/_internal/cycle-safe-linked-search.d.ts +48 -0
  13. package/dist/_internal/cycle-safe-linked-search.d.ts.map +1 -0
  14. package/dist/_internal/cycle-safe-linked-search.js +70 -0
  15. package/dist/_internal/cycle-safe-linked-search.js.map +1 -0
  16. package/dist/_internal/expression-boolean-memoizer.d.ts +17 -0
  17. package/dist/_internal/expression-boolean-memoizer.d.ts.map +1 -0
  18. package/dist/_internal/expression-boolean-memoizer.js +22 -0
  19. package/dist/_internal/expression-boolean-memoizer.js.map +1 -0
  20. package/dist/_internal/filter-callback.d.ts +52 -0
  21. package/dist/_internal/filter-callback.d.ts.map +1 -0
  22. package/dist/_internal/filter-callback.js +108 -0
  23. package/dist/_internal/filter-callback.js.map +1 -0
  24. package/dist/_internal/floating-resource.d.ts +29 -0
  25. package/dist/_internal/floating-resource.d.ts.map +1 -0
  26. package/dist/_internal/floating-resource.js +114 -0
  27. package/dist/_internal/floating-resource.js.map +1 -0
  28. package/dist/_internal/member-call.d.ts +53 -0
  29. package/dist/_internal/member-call.d.ts.map +1 -0
  30. package/dist/_internal/member-call.js +61 -0
  31. package/dist/_internal/member-call.js.map +1 -0
  32. package/dist/_internal/normalize-expression-text.d.ts +21 -0
  33. package/dist/_internal/normalize-expression-text.d.ts.map +1 -0
  34. package/dist/_internal/normalize-expression-text.js +186 -0
  35. package/dist/_internal/normalize-expression-text.js.map +1 -0
  36. package/dist/_internal/nullish-comparison.d.ts +44 -0
  37. package/dist/_internal/nullish-comparison.d.ts.map +1 -0
  38. package/dist/_internal/nullish-comparison.js +162 -0
  39. package/dist/_internal/nullish-comparison.js.map +1 -0
  40. package/dist/_internal/plugin-settings.d.ts +30 -0
  41. package/dist/_internal/plugin-settings.d.ts.map +1 -0
  42. package/dist/_internal/plugin-settings.js +90 -0
  43. package/dist/_internal/plugin-settings.js.map +1 -0
  44. package/dist/_internal/report-adapter.d.ts +24 -0
  45. package/dist/_internal/report-adapter.d.ts.map +1 -0
  46. package/dist/_internal/report-adapter.js +35 -0
  47. package/dist/_internal/report-adapter.js.map +1 -0
  48. package/dist/_internal/rule-catalog.d.ts +47 -0
  49. package/dist/_internal/rule-catalog.d.ts.map +1 -0
  50. package/dist/_internal/rule-catalog.js +97 -0
  51. package/dist/_internal/rule-catalog.js.map +1 -0
  52. package/dist/_internal/rule-docs-metadata.d.ts +35 -0
  53. package/dist/_internal/rule-docs-metadata.d.ts.map +1 -0
  54. package/dist/_internal/rule-docs-metadata.js +172 -0
  55. package/dist/_internal/rule-docs-metadata.js.map +1 -0
  56. package/dist/_internal/rule-docs-url.d.ts +15 -0
  57. package/dist/_internal/rule-docs-url.d.ts.map +1 -0
  58. package/dist/_internal/rule-docs-url.js +15 -0
  59. package/dist/_internal/rule-docs-url.js.map +1 -0
  60. package/dist/_internal/rules-registry.d.ts +11 -0
  61. package/dist/_internal/rules-registry.d.ts.map +1 -0
  62. package/dist/_internal/rules-registry.js +53 -0
  63. package/dist/_internal/rules-registry.js.map +1 -0
  64. package/dist/_internal/runtime-cleanup-config-references.d.ts +38 -0
  65. package/dist/_internal/runtime-cleanup-config-references.d.ts.map +1 -0
  66. package/dist/_internal/runtime-cleanup-config-references.js +78 -0
  67. package/dist/_internal/runtime-cleanup-config-references.js.map +1 -0
  68. package/dist/_internal/safe-type-operation.d.ts +89 -0
  69. package/dist/_internal/safe-type-operation.d.ts.map +1 -0
  70. package/dist/_internal/safe-type-operation.js +147 -0
  71. package/dist/_internal/safe-type-operation.js.map +1 -0
  72. package/dist/_internal/scope-variable.d.ts +17 -0
  73. package/dist/_internal/scope-variable.d.ts.map +1 -0
  74. package/dist/_internal/scope-variable.js +30 -0
  75. package/dist/_internal/scope-variable.js.map +1 -0
  76. package/dist/_internal/type-checker.d.ts +11 -0
  77. package/dist/_internal/type-checker.d.ts.map +1 -0
  78. package/dist/_internal/type-checker.js +25 -0
  79. package/dist/_internal/type-checker.js.map +1 -0
  80. package/dist/_internal/type-predicate-autofix-safety.d.ts +16 -0
  81. package/dist/_internal/type-predicate-autofix-safety.d.ts.map +1 -0
  82. package/dist/_internal/type-predicate-autofix-safety.js +54 -0
  83. package/dist/_internal/type-predicate-autofix-safety.js.map +1 -0
  84. package/dist/_internal/type-reference-node.d.ts +23 -0
  85. package/dist/_internal/type-reference-node.d.ts.map +1 -0
  86. package/dist/_internal/type-reference-node.js +41 -0
  87. package/dist/_internal/type-reference-node.js.map +1 -0
  88. package/dist/_internal/typed-rule.d.ts +91 -0
  89. package/dist/_internal/typed-rule.d.ts.map +1 -0
  90. package/dist/_internal/typed-rule.js +121 -0
  91. package/dist/_internal/typed-rule.js.map +1 -0
  92. package/dist/_internal/value-rewrite-autofix-safety.d.ts +29 -0
  93. package/dist/_internal/value-rewrite-autofix-safety.d.ts.map +1 -0
  94. package/dist/_internal/value-rewrite-autofix-safety.js +108 -0
  95. package/dist/_internal/value-rewrite-autofix-safety.js.map +1 -0
  96. package/dist/plugin.cjs +3693 -0
  97. package/dist/plugin.cjs.map +7 -0
  98. package/dist/plugin.d.cts +75 -0
  99. package/dist/plugin.d.ts +75 -0
  100. package/dist/plugin.d.ts.map +1 -0
  101. package/dist/plugin.js +223 -0
  102. package/dist/plugin.js.map +1 -0
  103. package/dist/rules/no-floating-abort-controllers.d.ts +9 -0
  104. package/dist/rules/no-floating-abort-controllers.d.ts.map +1 -0
  105. package/dist/rules/no-floating-abort-controllers.js +144 -0
  106. package/dist/rules/no-floating-abort-controllers.js.map +1 -0
  107. package/dist/rules/no-floating-audio-contexts.d.ts +9 -0
  108. package/dist/rules/no-floating-audio-contexts.d.ts.map +1 -0
  109. package/dist/rules/no-floating-audio-contexts.js +95 -0
  110. package/dist/rules/no-floating-audio-contexts.js.map +1 -0
  111. package/dist/rules/no-floating-broadcast-channels.d.ts +9 -0
  112. package/dist/rules/no-floating-broadcast-channels.d.ts.map +1 -0
  113. package/dist/rules/no-floating-broadcast-channels.js +151 -0
  114. package/dist/rules/no-floating-broadcast-channels.js.map +1 -0
  115. package/dist/rules/no-floating-child-processes.d.ts +9 -0
  116. package/dist/rules/no-floating-child-processes.d.ts.map +1 -0
  117. package/dist/rules/no-floating-child-processes.js +259 -0
  118. package/dist/rules/no-floating-child-processes.js.map +1 -0
  119. package/dist/rules/no-floating-disposable-stacks.d.ts +9 -0
  120. package/dist/rules/no-floating-disposable-stacks.d.ts.map +1 -0
  121. package/dist/rules/no-floating-disposable-stacks.js +177 -0
  122. package/dist/rules/no-floating-disposable-stacks.js.map +1 -0
  123. package/dist/rules/no-floating-file-watchers.d.ts +9 -0
  124. package/dist/rules/no-floating-file-watchers.d.ts.map +1 -0
  125. package/dist/rules/no-floating-file-watchers.js +241 -0
  126. package/dist/rules/no-floating-file-watchers.js.map +1 -0
  127. package/dist/rules/no-floating-geolocation-watches.d.ts +9 -0
  128. package/dist/rules/no-floating-geolocation-watches.d.ts.map +1 -0
  129. package/dist/rules/no-floating-geolocation-watches.js +156 -0
  130. package/dist/rules/no-floating-geolocation-watches.js.map +1 -0
  131. package/dist/rules/no-floating-infinite-animations.d.ts +9 -0
  132. package/dist/rules/no-floating-infinite-animations.d.ts.map +1 -0
  133. package/dist/rules/no-floating-infinite-animations.js +131 -0
  134. package/dist/rules/no-floating-infinite-animations.js.map +1 -0
  135. package/dist/rules/no-floating-media-streams.d.ts +9 -0
  136. package/dist/rules/no-floating-media-streams.d.ts.map +1 -0
  137. package/dist/rules/no-floating-media-streams.js +175 -0
  138. package/dist/rules/no-floating-media-streams.js.map +1 -0
  139. package/dist/rules/no-floating-message-channels.d.ts +9 -0
  140. package/dist/rules/no-floating-message-channels.d.ts.map +1 -0
  141. package/dist/rules/no-floating-message-channels.js +150 -0
  142. package/dist/rules/no-floating-message-channels.js.map +1 -0
  143. package/dist/rules/no-floating-network-connections.d.ts +9 -0
  144. package/dist/rules/no-floating-network-connections.d.ts.map +1 -0
  145. package/dist/rules/no-floating-network-connections.js +170 -0
  146. package/dist/rules/no-floating-network-connections.js.map +1 -0
  147. package/dist/rules/no-floating-object-urls.d.ts +9 -0
  148. package/dist/rules/no-floating-object-urls.d.ts.map +1 -0
  149. package/dist/rules/no-floating-object-urls.js +83 -0
  150. package/dist/rules/no-floating-object-urls.js.map +1 -0
  151. package/dist/rules/no-floating-observers.d.ts +9 -0
  152. package/dist/rules/no-floating-observers.d.ts.map +1 -0
  153. package/dist/rules/no-floating-observers.js +160 -0
  154. package/dist/rules/no-floating-observers.js.map +1 -0
  155. package/dist/rules/no-floating-servers.d.ts +9 -0
  156. package/dist/rules/no-floating-servers.d.ts.map +1 -0
  157. package/dist/rules/no-floating-servers.js +282 -0
  158. package/dist/rules/no-floating-servers.js.map +1 -0
  159. package/dist/rules/no-floating-streams.d.ts +9 -0
  160. package/dist/rules/no-floating-streams.d.ts.map +1 -0
  161. package/dist/rules/no-floating-streams.js +222 -0
  162. package/dist/rules/no-floating-streams.js.map +1 -0
  163. package/dist/rules/no-floating-timers.d.ts +9 -0
  164. package/dist/rules/no-floating-timers.d.ts.map +1 -0
  165. package/dist/rules/no-floating-timers.js +145 -0
  166. package/dist/rules/no-floating-timers.js.map +1 -0
  167. package/dist/rules/no-floating-wake-locks.d.ts +9 -0
  168. package/dist/rules/no-floating-wake-locks.d.ts.map +1 -0
  169. package/dist/rules/no-floating-wake-locks.js +159 -0
  170. package/dist/rules/no-floating-wake-locks.js.map +1 -0
  171. package/dist/rules/no-floating-web-stream-locks.d.ts +9 -0
  172. package/dist/rules/no-floating-web-stream-locks.d.ts.map +1 -0
  173. package/dist/rules/no-floating-web-stream-locks.js +87 -0
  174. package/dist/rules/no-floating-web-stream-locks.js.map +1 -0
  175. package/dist/rules/no-floating-workers.d.ts +9 -0
  176. package/dist/rules/no-floating-workers.d.ts.map +1 -0
  177. package/dist/rules/no-floating-workers.js +185 -0
  178. package/dist/rules/no-floating-workers.js.map +1 -0
  179. package/dist/rules/no-unmanaged-event-listeners.d.ts +9 -0
  180. package/dist/rules/no-unmanaged-event-listeners.d.ts.map +1 -0
  181. package/dist/rules/no-unmanaged-event-listeners.js +210 -0
  182. package/dist/rules/no-unmanaged-event-listeners.js.map +1 -0
  183. package/docs/rules/getting-started.md +29 -0
  184. package/docs/rules/guides/adoption-checklist.md +31 -0
  185. package/docs/rules/guides/preset-selection-strategy.md +24 -0
  186. package/docs/rules/guides/rollout-and-fix-safety.md +42 -0
  187. package/docs/rules/guides/snapshot-testing.md +20 -0
  188. package/docs/rules/guides/type-aware-linting-readiness.md +20 -0
  189. package/docs/rules/no-floating-abort-controllers.md +126 -0
  190. package/docs/rules/no-floating-audio-contexts.md +104 -0
  191. package/docs/rules/no-floating-broadcast-channels.md +105 -0
  192. package/docs/rules/no-floating-child-processes.md +123 -0
  193. package/docs/rules/no-floating-disposable-stacks.md +118 -0
  194. package/docs/rules/no-floating-file-watchers.md +111 -0
  195. package/docs/rules/no-floating-geolocation-watches.md +95 -0
  196. package/docs/rules/no-floating-infinite-animations.md +110 -0
  197. package/docs/rules/no-floating-media-streams.md +113 -0
  198. package/docs/rules/no-floating-message-channels.md +114 -0
  199. package/docs/rules/no-floating-network-connections.md +116 -0
  200. package/docs/rules/no-floating-object-urls.md +102 -0
  201. package/docs/rules/no-floating-observers.md +108 -0
  202. package/docs/rules/no-floating-servers.md +127 -0
  203. package/docs/rules/no-floating-streams.md +120 -0
  204. package/docs/rules/no-floating-timers.md +120 -0
  205. package/docs/rules/no-floating-wake-locks.md +109 -0
  206. package/docs/rules/no-floating-web-stream-locks.md +105 -0
  207. package/docs/rules/no-floating-workers.md +123 -0
  208. package/docs/rules/no-unmanaged-event-listeners.md +143 -0
  209. package/docs/rules/overview.md +44 -0
  210. package/docs/rules/presets/all.md +35 -0
  211. package/docs/rules/presets/experimental.md +44 -0
  212. package/docs/rules/presets/index.md +54 -0
  213. package/docs/rules/presets/minimal.md +17 -0
  214. package/docs/rules/presets/recommended-type-checked.md +43 -0
  215. package/docs/rules/presets/recommended.md +34 -0
  216. package/docs/rules/presets/strict.md +36 -0
  217. package/package.json +323 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-floating-audio-contexts.js","sourceRoot":"","sources":["../../src/rules/no-floating-audio-contexts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * Require BroadcastChannel handles to be retained so they can be closed.
4
+ */
5
+ import { type TSESLint } from "@typescript-eslint/utils";
6
+ /** Rule implementation for `runtime-cleanup/no-floating-broadcast-channels`. */
7
+ declare const noFloatingBroadcastChannels: TSESLint.RuleModule<"floatingBroadcastChannel", readonly []>;
8
+ export default noFloatingBroadcastChannels;
9
+ //# sourceMappingURL=no-floating-broadcast-channels.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-floating-broadcast-channels.d.ts","sourceRoot":"","sources":["../../src/rules/no-floating-broadcast-channels.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAEH,KAAK,QAAQ,EAEhB,MAAM,0BAA0B,CAAC;AAsLlC,gFAAgF;AAChF,QAAA,MAAM,2BAA2B,EAAE,QAAQ,CAAC,UAAU,CAClD,0BAA0B,EAC1B,SAAS,EAAE,CA2Cb,CAAC;AAEH,eAAe,2BAA2B,CAAC"}
@@ -0,0 +1,151 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * Require BroadcastChannel handles to be retained so they can be closed.
4
+ */
5
+ import { AST_NODE_TYPES, } from "@typescript-eslint/utils";
6
+ import { getParentNode } from "../_internal/ast-node.js";
7
+ import { createRuleDocsUrl } from "../_internal/rule-docs-url.js";
8
+ import { getVariableInScopeChain } from "../_internal/scope-variable.js";
9
+ import { createTypedRule, } from "../_internal/typed-rule.js";
10
+ const broadcastChannelConstructorName = "BroadcastChannel";
11
+ const globalReceiverNames = [
12
+ "globalThis",
13
+ "self",
14
+ "window",
15
+ ];
16
+ const globalReceiverNameSet = new Set(globalReceiverNames);
17
+ const isGlobalReceiverName = (name) => globalReceiverNameSet.has(name);
18
+ const getTransparentWrappedExpression = (node) => {
19
+ if (node.type === AST_NODE_TYPES.ChainExpression) {
20
+ return node.expression;
21
+ }
22
+ if (node.type === AST_NODE_TYPES.TSAsExpression) {
23
+ return node.expression;
24
+ }
25
+ if (node.type === AST_NODE_TYPES.TSNonNullExpression) {
26
+ return node.expression;
27
+ }
28
+ if (node.type === AST_NODE_TYPES.TSSatisfiesExpression) {
29
+ return node.expression;
30
+ }
31
+ if (node.type === AST_NODE_TYPES.TSTypeAssertion) {
32
+ return node.expression;
33
+ }
34
+ return undefined;
35
+ };
36
+ const getStaticPropertyName = (node, computed) => {
37
+ if (!computed && node.type === AST_NODE_TYPES.Identifier) {
38
+ return node.name;
39
+ }
40
+ if (computed &&
41
+ node.type === AST_NODE_TYPES.Literal &&
42
+ typeof node.value === "string") {
43
+ return node.value;
44
+ }
45
+ return undefined;
46
+ };
47
+ const isShadowedBroadcastChannelIdentifier = (context, identifier) => {
48
+ const scope = context.sourceCode.getScope(identifier);
49
+ const variable = getVariableInScopeChain(scope, identifier.name);
50
+ return variable !== null && variable.defs.length > 0;
51
+ };
52
+ const isDirectBroadcastChannelConstructor = (context, callee) => callee.type === AST_NODE_TYPES.Identifier &&
53
+ callee.name === broadcastChannelConstructorName &&
54
+ !isShadowedBroadcastChannelIdentifier(context, callee);
55
+ const isMemberBroadcastChannelConstructor = (callee) => callee.type === AST_NODE_TYPES.MemberExpression &&
56
+ !callee.optional &&
57
+ callee.object.type === AST_NODE_TYPES.Identifier &&
58
+ isGlobalReceiverName(callee.object.name) &&
59
+ getStaticPropertyName(callee.property, callee.computed) ===
60
+ broadcastChannelConstructorName;
61
+ const isBroadcastChannelConstructor = (context, callee) => isDirectBroadcastChannelConstructor(context, callee) ||
62
+ isMemberBroadcastChannelConstructor(callee);
63
+ const isDiscardedBroadcastChannel = (node) => {
64
+ let current = node;
65
+ let parent = getParentNode(current);
66
+ while (parent !== undefined) {
67
+ const wrappedExpression = getTransparentWrappedExpression(parent);
68
+ if (wrappedExpression === current) {
69
+ current = parent;
70
+ parent = getParentNode(current);
71
+ continue;
72
+ }
73
+ if (parent.type === AST_NODE_TYPES.ExpressionStatement &&
74
+ parent.expression === current) {
75
+ return true;
76
+ }
77
+ if (parent.type === AST_NODE_TYPES.UnaryExpression &&
78
+ parent.operator === "void" &&
79
+ parent.argument === current) {
80
+ const unaryParent = getParentNode(parent);
81
+ return unaryParent?.type === AST_NODE_TYPES.ExpressionStatement;
82
+ }
83
+ return false;
84
+ }
85
+ return false;
86
+ };
87
+ const isImmediateBroadcastChannelMethodReceiver = (node) => {
88
+ let current = node;
89
+ let parent = getParentNode(current);
90
+ while (parent !== undefined) {
91
+ const wrappedExpression = getTransparentWrappedExpression(parent);
92
+ if (wrappedExpression === current) {
93
+ current = parent;
94
+ parent = getParentNode(current);
95
+ continue;
96
+ }
97
+ if (parent.type !== AST_NODE_TYPES.MemberExpression ||
98
+ parent.object !== current ||
99
+ parent.optional) {
100
+ return false;
101
+ }
102
+ if (getStaticPropertyName(parent.property, parent.computed) === "close") {
103
+ return false;
104
+ }
105
+ const callExpression = getParentNode(parent);
106
+ return (callExpression?.type === AST_NODE_TYPES.CallExpression &&
107
+ callExpression.callee === parent);
108
+ }
109
+ return false;
110
+ };
111
+ /** Rule implementation for `runtime-cleanup/no-floating-broadcast-channels`. */
112
+ const noFloatingBroadcastChannels = createTypedRule({
113
+ create(context) {
114
+ return {
115
+ NewExpression(node) {
116
+ if (!isBroadcastChannelConstructor(context, node.callee) ||
117
+ (!isDiscardedBroadcastChannel(node) &&
118
+ !isImmediateBroadcastChannelMethodReceiver(node))) {
119
+ return;
120
+ }
121
+ context.report({
122
+ messageId: "floatingBroadcastChannel",
123
+ node,
124
+ });
125
+ },
126
+ };
127
+ },
128
+ defaultOptions: [],
129
+ meta: {
130
+ docs: {
131
+ description: "require BroadcastChannel handles to be retained so they can be closed.",
132
+ recommended: true,
133
+ requiresTypeChecking: false,
134
+ runtimeCleanupConfigs: [
135
+ "runtime-cleanup.configs.recommended",
136
+ "runtime-cleanup.configs.recommended-type-checked",
137
+ "runtime-cleanup.configs.strict",
138
+ "runtime-cleanup.configs.all",
139
+ ],
140
+ url: createRuleDocsUrl("no-floating-broadcast-channels"),
141
+ },
142
+ messages: {
143
+ floatingBroadcastChannel: "Store or return the BroadcastChannel handle so close() can release the channel during cleanup.",
144
+ },
145
+ schema: [],
146
+ type: "problem",
147
+ },
148
+ name: "no-floating-broadcast-channels",
149
+ });
150
+ export default noFloatingBroadcastChannels;
151
+ //# sourceMappingURL=no-floating-broadcast-channels.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-floating-broadcast-channels.js","sourceRoot":"","sources":["../../src/rules/no-floating-broadcast-channels.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * Require child process handles to be retained so they can be killed during cleanup.
4
+ */
5
+ import { type TSESLint } from "@typescript-eslint/utils";
6
+ /** Rule implementation for `runtime-cleanup/no-floating-child-processes`. */
7
+ declare const noFloatingChildProcesses: TSESLint.RuleModule<"floatingChildProcess", readonly []>;
8
+ export default noFloatingChildProcesses;
9
+ //# sourceMappingURL=no-floating-child-processes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-floating-child-processes.d.ts","sourceRoot":"","sources":["../../src/rules/no-floating-child-processes.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAEH,KAAK,QAAQ,EAEhB,MAAM,0BAA0B,CAAC;AAsWlC,6EAA6E;AAC7E,QAAA,MAAM,wBAAwB,EAAE,QAAQ,CAAC,UAAU,CAC/C,sBAAsB,EACtB,SAAS,EAAE,CAiDb,CAAC;AAEH,eAAe,wBAAwB,CAAC"}
@@ -0,0 +1,259 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * Require child process handles to be retained so they can be killed during cleanup.
4
+ */
5
+ import { AST_NODE_TYPES, } from "@typescript-eslint/utils";
6
+ import { getParentNode } from "../_internal/ast-node.js";
7
+ import { createRuleDocsUrl } from "../_internal/rule-docs-url.js";
8
+ import { getVariableInScopeChain } from "../_internal/scope-variable.js";
9
+ import { createTypedRule, } from "../_internal/typed-rule.js";
10
+ const childProcessFactoryNames = [
11
+ "exec",
12
+ "execFile",
13
+ "fork",
14
+ "spawn",
15
+ ];
16
+ const childProcessModuleNames = [
17
+ "child_process",
18
+ "node:child_process",
19
+ ];
20
+ const immediateCleanupMethodNames = [
21
+ "disconnect",
22
+ "kill",
23
+ ];
24
+ const childProcessFactoryNameSet = new Set(childProcessFactoryNames);
25
+ const childProcessModuleNameSet = new Set(childProcessModuleNames);
26
+ const immediateCleanupMethodNameSet = new Set(immediateCleanupMethodNames);
27
+ const isChildProcessFactoryName = (name) => childProcessFactoryNameSet.has(name);
28
+ const isImmediateCleanupMethodName = (name) => immediateCleanupMethodNameSet.has(name);
29
+ const getTransparentWrappedExpression = (node) => {
30
+ if (node.type === AST_NODE_TYPES.ChainExpression) {
31
+ return node.expression;
32
+ }
33
+ if (node.type === AST_NODE_TYPES.TSAsExpression) {
34
+ return node.expression;
35
+ }
36
+ if (node.type === AST_NODE_TYPES.TSNonNullExpression) {
37
+ return node.expression;
38
+ }
39
+ if (node.type === AST_NODE_TYPES.TSSatisfiesExpression) {
40
+ return node.expression;
41
+ }
42
+ if (node.type === AST_NODE_TYPES.TSTypeAssertion) {
43
+ return node.expression;
44
+ }
45
+ return undefined;
46
+ };
47
+ const getStaticPropertyName = (node) => {
48
+ if (node.type === AST_NODE_TYPES.Identifier) {
49
+ return node.name;
50
+ }
51
+ if (node.type === AST_NODE_TYPES.Literal &&
52
+ typeof node.value === "string") {
53
+ return node.value;
54
+ }
55
+ return undefined;
56
+ };
57
+ const getImportSourceValue = (node) => {
58
+ const parent = getParentNode(node);
59
+ if (parent?.type === AST_NODE_TYPES.ImportDeclaration &&
60
+ typeof parent.source.value === "string") {
61
+ return parent.source.value;
62
+ }
63
+ return undefined;
64
+ };
65
+ const getRequireSourceValue = (expression) => {
66
+ if (expression?.type !== AST_NODE_TYPES.CallExpression ||
67
+ expression.callee.type !== AST_NODE_TYPES.Identifier ||
68
+ expression.callee.name !== "require") {
69
+ return undefined;
70
+ }
71
+ const [source] = expression.arguments;
72
+ return source?.type === AST_NODE_TYPES.Literal &&
73
+ typeof source.value === "string"
74
+ ? source.value
75
+ : undefined;
76
+ };
77
+ const getDefinitionModuleSource = (node) => {
78
+ if (node.type === AST_NODE_TYPES.ImportDefaultSpecifier ||
79
+ node.type === AST_NODE_TYPES.ImportNamespaceSpecifier ||
80
+ node.type === AST_NODE_TYPES.ImportSpecifier) {
81
+ return getImportSourceValue(node);
82
+ }
83
+ if (node.type === AST_NODE_TYPES.VariableDeclarator) {
84
+ return getRequireSourceValue(node.init);
85
+ }
86
+ return undefined;
87
+ };
88
+ const getImportedSpecifierName = (node) => getStaticPropertyName(node.imported);
89
+ const getObjectPatternPropertyNameForIdentifier = (objectPattern, identifierName) => {
90
+ for (const property of objectPattern.properties) {
91
+ if (property.type !== AST_NODE_TYPES.Property ||
92
+ property.value.type !== AST_NODE_TYPES.Identifier ||
93
+ property.value.name !== identifierName) {
94
+ continue;
95
+ }
96
+ return getStaticPropertyName(property.key);
97
+ }
98
+ return undefined;
99
+ };
100
+ const isChildProcessModuleSource = (source) => source !== undefined && childProcessModuleNameSet.has(source);
101
+ const getDefinitionForIdentifier = (context, identifier) => {
102
+ const scope = context.sourceCode.getScope(identifier);
103
+ const variable = getVariableInScopeChain(scope, identifier.name);
104
+ return variable?.defs[0];
105
+ };
106
+ const isChildProcessModuleBinding = (context, identifier) => {
107
+ const definition = getDefinitionForIdentifier(context, identifier);
108
+ if (definition === undefined) {
109
+ return false;
110
+ }
111
+ return isChildProcessModuleSource(getDefinitionModuleSource(definition.node));
112
+ };
113
+ const getNamedChildProcessFactoryBindingName = (context, identifier) => {
114
+ const definition = getDefinitionForIdentifier(context, identifier);
115
+ if (definition === undefined) {
116
+ return undefined;
117
+ }
118
+ const source = getDefinitionModuleSource(definition.node);
119
+ if (!isChildProcessModuleSource(source)) {
120
+ return undefined;
121
+ }
122
+ if (definition.node.type === AST_NODE_TYPES.ImportSpecifier) {
123
+ const importedName = getImportedSpecifierName(definition.node);
124
+ return importedName !== undefined &&
125
+ isChildProcessFactoryName(importedName)
126
+ ? importedName
127
+ : undefined;
128
+ }
129
+ if (definition.node.type === AST_NODE_TYPES.VariableDeclarator &&
130
+ definition.node.id.type === AST_NODE_TYPES.ObjectPattern) {
131
+ const propertyName = getObjectPatternPropertyNameForIdentifier(definition.node.id, identifier.name);
132
+ return propertyName !== undefined &&
133
+ isChildProcessFactoryName(propertyName)
134
+ ? propertyName
135
+ : undefined;
136
+ }
137
+ return undefined;
138
+ };
139
+ const getRequireMemberFactoryName = (callee) => {
140
+ if (callee.type !== AST_NODE_TYPES.MemberExpression ||
141
+ callee.computed ||
142
+ callee.optional ||
143
+ callee.property.type !== AST_NODE_TYPES.Identifier ||
144
+ !isChildProcessFactoryName(callee.property.name) ||
145
+ callee.object.type !== AST_NODE_TYPES.CallExpression ||
146
+ !isChildProcessModuleSource(getRequireSourceValue(callee.object))) {
147
+ return undefined;
148
+ }
149
+ return callee.property.name;
150
+ };
151
+ const getModuleMemberFactoryName = (context, callee) => {
152
+ if (callee.type !== AST_NODE_TYPES.MemberExpression ||
153
+ callee.computed ||
154
+ callee.optional ||
155
+ callee.object.type !== AST_NODE_TYPES.Identifier ||
156
+ callee.property.type !== AST_NODE_TYPES.Identifier ||
157
+ !isChildProcessFactoryName(callee.property.name) ||
158
+ !isChildProcessModuleBinding(context, callee.object)) {
159
+ return undefined;
160
+ }
161
+ return callee.property.name;
162
+ };
163
+ const getChildProcessFactoryName = (context, callee) => {
164
+ if (callee.type === AST_NODE_TYPES.Identifier) {
165
+ return getNamedChildProcessFactoryBindingName(context, callee);
166
+ }
167
+ return (getModuleMemberFactoryName(context, callee) ??
168
+ getRequireMemberFactoryName(callee));
169
+ };
170
+ const isDiscardedChildProcessHandle = (node) => {
171
+ let current = node;
172
+ let parent = getParentNode(current);
173
+ while (parent !== undefined) {
174
+ const wrappedExpression = getTransparentWrappedExpression(parent);
175
+ if (wrappedExpression === current) {
176
+ current = parent;
177
+ parent = getParentNode(current);
178
+ continue;
179
+ }
180
+ if (parent.type === AST_NODE_TYPES.ExpressionStatement &&
181
+ parent.expression === current) {
182
+ return true;
183
+ }
184
+ if (parent.type === AST_NODE_TYPES.UnaryExpression &&
185
+ parent.operator === "void" &&
186
+ parent.argument === current) {
187
+ const unaryParent = getParentNode(parent);
188
+ return unaryParent?.type === AST_NODE_TYPES.ExpressionStatement;
189
+ }
190
+ return false;
191
+ }
192
+ return false;
193
+ };
194
+ const isImmediateChildProcessMethodReceiver = (node) => {
195
+ let current = node;
196
+ let parent = getParentNode(current);
197
+ while (parent !== undefined) {
198
+ const wrappedExpression = getTransparentWrappedExpression(parent);
199
+ if (wrappedExpression === current) {
200
+ current = parent;
201
+ parent = getParentNode(current);
202
+ continue;
203
+ }
204
+ if (parent.type !== AST_NODE_TYPES.MemberExpression ||
205
+ parent.object !== current ||
206
+ parent.computed ||
207
+ parent.property.type !== AST_NODE_TYPES.Identifier ||
208
+ isImmediateCleanupMethodName(parent.property.name)) {
209
+ return false;
210
+ }
211
+ const callExpression = getParentNode(parent);
212
+ return (callExpression?.type === AST_NODE_TYPES.CallExpression &&
213
+ callExpression.callee === parent);
214
+ }
215
+ return false;
216
+ };
217
+ /** Rule implementation for `runtime-cleanup/no-floating-child-processes`. */
218
+ const noFloatingChildProcesses = createTypedRule({
219
+ create(context) {
220
+ return {
221
+ CallExpression(node) {
222
+ const factoryName = getChildProcessFactoryName(context, node.callee);
223
+ if (factoryName === undefined ||
224
+ (!isDiscardedChildProcessHandle(node) &&
225
+ !isImmediateChildProcessMethodReceiver(node))) {
226
+ return;
227
+ }
228
+ context.report({
229
+ data: { factoryName },
230
+ messageId: "floatingChildProcess",
231
+ node,
232
+ });
233
+ },
234
+ };
235
+ },
236
+ defaultOptions: [],
237
+ meta: {
238
+ docs: {
239
+ description: "require child process handles to be retained so they can be killed during cleanup.",
240
+ recommended: true,
241
+ requiresTypeChecking: false,
242
+ runtimeCleanupConfigs: [
243
+ "runtime-cleanup.configs.recommended",
244
+ "runtime-cleanup.configs.recommended-type-checked",
245
+ "runtime-cleanup.configs.strict",
246
+ "runtime-cleanup.configs.all",
247
+ ],
248
+ url: createRuleDocsUrl("no-floating-child-processes"),
249
+ },
250
+ messages: {
251
+ floatingChildProcess: "Store or return the child process handle from {{factoryName}} so it can be killed during cleanup.",
252
+ },
253
+ schema: [],
254
+ type: "problem",
255
+ },
256
+ name: "no-floating-child-processes",
257
+ });
258
+ export default noFloatingChildProcesses;
259
+ //# sourceMappingURL=no-floating-child-processes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-floating-child-processes.js","sourceRoot":"","sources":["../../src/rules/no-floating-child-processes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * Require DisposableStack handles to be retained so registered disposers run.
4
+ */
5
+ import { type TSESLint } from "@typescript-eslint/utils";
6
+ /** Rule implementation for `runtime-cleanup/no-floating-disposable-stacks`. */
7
+ declare const noFloatingDisposableStacks: TSESLint.RuleModule<"floatingDisposableStack", readonly []>;
8
+ export default noFloatingDisposableStacks;
9
+ //# sourceMappingURL=no-floating-disposable-stacks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-floating-disposable-stacks.d.ts","sourceRoot":"","sources":["../../src/rules/no-floating-disposable-stacks.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAEH,KAAK,QAAQ,EAEhB,MAAM,0BAA0B,CAAC;AAmOlC,+EAA+E;AAC/E,QAAA,MAAM,0BAA0B,EAAE,QAAQ,CAAC,UAAU,CACjD,yBAAyB,EACzB,SAAS,EAAE,CAiDb,CAAC;AAEH,eAAe,0BAA0B,CAAC"}
@@ -0,0 +1,177 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * Require DisposableStack handles to be retained so registered disposers run.
4
+ */
5
+ import { AST_NODE_TYPES, } from "@typescript-eslint/utils";
6
+ import { getParentNode } from "../_internal/ast-node.js";
7
+ import { createRuleDocsUrl } from "../_internal/rule-docs-url.js";
8
+ import { getVariableInScopeChain } from "../_internal/scope-variable.js";
9
+ import { createTypedRule, } from "../_internal/typed-rule.js";
10
+ const disposableStackConstructorNames = [
11
+ "AsyncDisposableStack",
12
+ "DisposableStack",
13
+ ];
14
+ const cleanupMethodNames = [
15
+ "dispose",
16
+ "disposeAsync",
17
+ ];
18
+ const globalReceiverNames = [
19
+ "globalThis",
20
+ "self",
21
+ "window",
22
+ ];
23
+ const disposableStackConstructorNameSet = new Set(disposableStackConstructorNames);
24
+ const cleanupMethodNameSet = new Set(cleanupMethodNames);
25
+ const globalReceiverNameSet = new Set(globalReceiverNames);
26
+ const isDisposableStackConstructorName = (name) => disposableStackConstructorNameSet.has(name);
27
+ const isCleanupMethodName = (name) => cleanupMethodNameSet.has(name);
28
+ const isGlobalReceiverName = (name) => globalReceiverNameSet.has(name);
29
+ const getTransparentWrappedExpression = (node) => {
30
+ if (node.type === AST_NODE_TYPES.ChainExpression) {
31
+ return node.expression;
32
+ }
33
+ if (node.type === AST_NODE_TYPES.TSAsExpression) {
34
+ return node.expression;
35
+ }
36
+ if (node.type === AST_NODE_TYPES.TSNonNullExpression) {
37
+ return node.expression;
38
+ }
39
+ if (node.type === AST_NODE_TYPES.TSSatisfiesExpression) {
40
+ return node.expression;
41
+ }
42
+ if (node.type === AST_NODE_TYPES.TSTypeAssertion) {
43
+ return node.expression;
44
+ }
45
+ return undefined;
46
+ };
47
+ const getStaticPropertyName = (node, computed) => {
48
+ if (!computed && node.type === AST_NODE_TYPES.Identifier) {
49
+ return node.name;
50
+ }
51
+ if (computed &&
52
+ node.type === AST_NODE_TYPES.Literal &&
53
+ typeof node.value === "string") {
54
+ return node.value;
55
+ }
56
+ return undefined;
57
+ };
58
+ const isShadowedDisposableStackIdentifier = (context, identifier) => {
59
+ const scope = context.sourceCode.getScope(identifier);
60
+ const variable = getVariableInScopeChain(scope, identifier.name);
61
+ return variable !== null && variable.defs.length > 0;
62
+ };
63
+ const getDirectDisposableStackConstructorName = (context, callee) => {
64
+ if (callee.type !== AST_NODE_TYPES.Identifier ||
65
+ !isDisposableStackConstructorName(callee.name) ||
66
+ isShadowedDisposableStackIdentifier(context, callee)) {
67
+ return undefined;
68
+ }
69
+ return callee.name;
70
+ };
71
+ const getMemberDisposableStackConstructorName = (callee) => {
72
+ if (callee.type !== AST_NODE_TYPES.MemberExpression ||
73
+ callee.optional ||
74
+ callee.object.type !== AST_NODE_TYPES.Identifier ||
75
+ !isGlobalReceiverName(callee.object.name)) {
76
+ return undefined;
77
+ }
78
+ const constructorName = getStaticPropertyName(callee.property, callee.computed);
79
+ return constructorName !== undefined &&
80
+ isDisposableStackConstructorName(constructorName)
81
+ ? constructorName
82
+ : undefined;
83
+ };
84
+ const getDisposableStackConstructorName = (context, callee) => getDirectDisposableStackConstructorName(context, callee) ??
85
+ getMemberDisposableStackConstructorName(callee);
86
+ const isDiscardedDisposableStack = (node) => {
87
+ let current = node;
88
+ let parent = getParentNode(current);
89
+ while (parent !== undefined) {
90
+ const wrappedExpression = getTransparentWrappedExpression(parent);
91
+ if (wrappedExpression === current) {
92
+ current = parent;
93
+ parent = getParentNode(current);
94
+ continue;
95
+ }
96
+ if (parent.type === AST_NODE_TYPES.ExpressionStatement &&
97
+ parent.expression === current) {
98
+ return true;
99
+ }
100
+ if (parent.type === AST_NODE_TYPES.UnaryExpression &&
101
+ parent.operator === "void" &&
102
+ parent.argument === current) {
103
+ const unaryParent = getParentNode(parent);
104
+ return unaryParent?.type === AST_NODE_TYPES.ExpressionStatement;
105
+ }
106
+ return false;
107
+ }
108
+ return false;
109
+ };
110
+ const isImmediateDisposableStackMethodReceiver = (node) => {
111
+ let current = node;
112
+ let parent = getParentNode(current);
113
+ while (parent !== undefined) {
114
+ const wrappedExpression = getTransparentWrappedExpression(parent);
115
+ if (wrappedExpression === current) {
116
+ current = parent;
117
+ parent = getParentNode(current);
118
+ continue;
119
+ }
120
+ if (parent.type !== AST_NODE_TYPES.MemberExpression ||
121
+ parent.object !== current ||
122
+ parent.optional) {
123
+ return false;
124
+ }
125
+ const methodName = getStaticPropertyName(parent.property, parent.computed);
126
+ if (methodName === undefined || isCleanupMethodName(methodName)) {
127
+ return false;
128
+ }
129
+ const callExpression = getParentNode(parent);
130
+ return (callExpression?.type === AST_NODE_TYPES.CallExpression &&
131
+ callExpression.callee === parent);
132
+ }
133
+ return false;
134
+ };
135
+ /** Rule implementation for `runtime-cleanup/no-floating-disposable-stacks`. */
136
+ const noFloatingDisposableStacks = createTypedRule({
137
+ create(context) {
138
+ return {
139
+ NewExpression(node) {
140
+ const constructorName = getDisposableStackConstructorName(context, node.callee);
141
+ if (constructorName === undefined ||
142
+ (!isDiscardedDisposableStack(node) &&
143
+ !isImmediateDisposableStackMethodReceiver(node))) {
144
+ return;
145
+ }
146
+ context.report({
147
+ data: { constructorName },
148
+ messageId: "floatingDisposableStack",
149
+ node,
150
+ });
151
+ },
152
+ };
153
+ },
154
+ defaultOptions: [],
155
+ meta: {
156
+ docs: {
157
+ description: "require DisposableStack handles to be retained so registered disposers run.",
158
+ recommended: true,
159
+ requiresTypeChecking: false,
160
+ runtimeCleanupConfigs: [
161
+ "runtime-cleanup.configs.recommended",
162
+ "runtime-cleanup.configs.recommended-type-checked",
163
+ "runtime-cleanup.configs.strict",
164
+ "runtime-cleanup.configs.all",
165
+ ],
166
+ url: createRuleDocsUrl("no-floating-disposable-stacks"),
167
+ },
168
+ messages: {
169
+ floatingDisposableStack: "Store, return, or use the {{constructorName}} handle so registered disposers run during cleanup.",
170
+ },
171
+ schema: [],
172
+ type: "problem",
173
+ },
174
+ name: "no-floating-disposable-stacks",
175
+ });
176
+ export default noFloatingDisposableStacks;
177
+ //# sourceMappingURL=no-floating-disposable-stacks.js.map