@memberjunction/react-linter 0.0.1 → 5.38.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.
Files changed (330) hide show
  1. package/dist/component-linter.d.ts +77 -0
  2. package/dist/component-linter.d.ts.map +1 -0
  3. package/dist/component-linter.js +1206 -0
  4. package/dist/component-linter.js.map +1 -0
  5. package/dist/control-flow-analyzer.d.ts +184 -0
  6. package/dist/control-flow-analyzer.d.ts.map +1 -0
  7. package/dist/control-flow-analyzer.js +798 -0
  8. package/dist/control-flow-analyzer.js.map +1 -0
  9. package/dist/index.d.ts +6 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +8 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/library-lint-cache.d.ts +50 -0
  14. package/dist/library-lint-cache.d.ts.map +1 -0
  15. package/dist/library-lint-cache.js +173 -0
  16. package/dist/library-lint-cache.js.map +1 -0
  17. package/dist/lint-rule.d.ts +70 -0
  18. package/dist/lint-rule.d.ts.map +1 -0
  19. package/dist/lint-rule.js +30 -0
  20. package/dist/lint-rule.js.map +1 -0
  21. package/dist/lint-utils.d.ts +131 -0
  22. package/dist/lint-utils.d.ts.map +1 -0
  23. package/dist/lint-utils.js +358 -0
  24. package/dist/lint-utils.js.map +1 -0
  25. package/dist/linter-options.d.ts +51 -0
  26. package/dist/linter-options.d.ts.map +1 -0
  27. package/dist/linter-options.js +2 -0
  28. package/dist/linter-options.js.map +1 -0
  29. package/dist/prop-value-extractor.d.ts +147 -0
  30. package/dist/prop-value-extractor.d.ts.map +1 -0
  31. package/dist/prop-value-extractor.js +472 -0
  32. package/dist/prop-value-extractor.js.map +1 -0
  33. package/dist/runtime-rules/ai-tools-availability-check.d.ts +9 -0
  34. package/dist/runtime-rules/ai-tools-availability-check.d.ts.map +1 -0
  35. package/dist/runtime-rules/ai-tools-availability-check.js +223 -0
  36. package/dist/runtime-rules/ai-tools-availability-check.js.map +1 -0
  37. package/dist/runtime-rules/callback-event-validation.d.ts +22 -0
  38. package/dist/runtime-rules/callback-event-validation.d.ts.map +1 -0
  39. package/dist/runtime-rules/callback-event-validation.js +561 -0
  40. package/dist/runtime-rules/callback-event-validation.js.map +1 -0
  41. package/dist/runtime-rules/chart-field-validation.d.ts +10 -0
  42. package/dist/runtime-rules/chart-field-validation.d.ts.map +1 -0
  43. package/dist/runtime-rules/chart-field-validation.js +270 -0
  44. package/dist/runtime-rules/chart-field-validation.js.map +1 -0
  45. package/dist/runtime-rules/child-component-prop-validation.d.ts +11 -0
  46. package/dist/runtime-rules/child-component-prop-validation.d.ts.map +1 -0
  47. package/dist/runtime-rules/child-component-prop-validation.js +443 -0
  48. package/dist/runtime-rules/child-component-prop-validation.js.map +1 -0
  49. package/dist/runtime-rules/component-name-mismatch.d.ts +19 -0
  50. package/dist/runtime-rules/component-name-mismatch.d.ts.map +1 -0
  51. package/dist/runtime-rules/component-name-mismatch.js +82 -0
  52. package/dist/runtime-rules/component-name-mismatch.js.map +1 -0
  53. package/dist/runtime-rules/component-not-in-dependencies.d.ts +20 -0
  54. package/dist/runtime-rules/component-not-in-dependencies.d.ts.map +1 -0
  55. package/dist/runtime-rules/component-not-in-dependencies.js +92 -0
  56. package/dist/runtime-rules/component-not-in-dependencies.js.map +1 -0
  57. package/dist/runtime-rules/component-props-validation.d.ts +25 -0
  58. package/dist/runtime-rules/component-props-validation.d.ts.map +1 -0
  59. package/dist/runtime-rules/component-props-validation.js +228 -0
  60. package/dist/runtime-rules/component-props-validation.js.map +1 -0
  61. package/dist/runtime-rules/component-usage-without-destructuring.d.ts +20 -0
  62. package/dist/runtime-rules/component-usage-without-destructuring.d.ts.map +1 -0
  63. package/dist/runtime-rules/component-usage-without-destructuring.js +124 -0
  64. package/dist/runtime-rules/component-usage-without-destructuring.js.map +1 -0
  65. package/dist/runtime-rules/data-result-validation.d.ts +9 -0
  66. package/dist/runtime-rules/data-result-validation.d.ts.map +1 -0
  67. package/dist/runtime-rules/data-result-validation.js +763 -0
  68. package/dist/runtime-rules/data-result-validation.js.map +1 -0
  69. package/dist/runtime-rules/datagrid-field-validation.d.ts +10 -0
  70. package/dist/runtime-rules/datagrid-field-validation.d.ts.map +1 -0
  71. package/dist/runtime-rules/datagrid-field-validation.js +249 -0
  72. package/dist/runtime-rules/datagrid-field-validation.js.map +1 -0
  73. package/dist/runtime-rules/dependency-shadowing.d.ts +20 -0
  74. package/dist/runtime-rules/dependency-shadowing.d.ts.map +1 -0
  75. package/dist/runtime-rules/dependency-shadowing.js +147 -0
  76. package/dist/runtime-rules/dependency-shadowing.js.map +1 -0
  77. package/dist/runtime-rules/entity-field-access-validation.d.ts +12 -0
  78. package/dist/runtime-rules/entity-field-access-validation.d.ts.map +1 -0
  79. package/dist/runtime-rules/entity-field-access-validation.js +304 -0
  80. package/dist/runtime-rules/entity-field-access-validation.js.map +1 -0
  81. package/dist/runtime-rules/event-parameter-validation.d.ts +22 -0
  82. package/dist/runtime-rules/event-parameter-validation.d.ts.map +1 -0
  83. package/dist/runtime-rules/event-parameter-validation.js +406 -0
  84. package/dist/runtime-rules/event-parameter-validation.js.map +1 -0
  85. package/dist/runtime-rules/index.d.ts +61 -0
  86. package/dist/runtime-rules/index.d.ts.map +1 -0
  87. package/dist/runtime-rules/index.js +62 -0
  88. package/dist/runtime-rules/index.js.map +1 -0
  89. package/dist/runtime-rules/library-variable-names.d.ts +24 -0
  90. package/dist/runtime-rules/library-variable-names.d.ts.map +1 -0
  91. package/dist/runtime-rules/library-variable-names.js +88 -0
  92. package/dist/runtime-rules/library-variable-names.js.map +1 -0
  93. package/dist/runtime-rules/no-child-implementation.d.ts +18 -0
  94. package/dist/runtime-rules/no-child-implementation.d.ts.map +1 -0
  95. package/dist/runtime-rules/no-child-implementation.js +57 -0
  96. package/dist/runtime-rules/no-child-implementation.js.map +1 -0
  97. package/dist/runtime-rules/no-data-prop.d.ts +22 -0
  98. package/dist/runtime-rules/no-data-prop.d.ts.map +1 -0
  99. package/dist/runtime-rules/no-data-prop.js +111 -0
  100. package/dist/runtime-rules/no-data-prop.js.map +1 -0
  101. package/dist/runtime-rules/no-export-statements.d.ts +18 -0
  102. package/dist/runtime-rules/no-export-statements.d.ts.map +1 -0
  103. package/dist/runtime-rules/no-export-statements.js +143 -0
  104. package/dist/runtime-rules/no-export-statements.js.map +1 -0
  105. package/dist/runtime-rules/no-iife-wrapper.d.ts +18 -0
  106. package/dist/runtime-rules/no-iife-wrapper.d.ts.map +1 -0
  107. package/dist/runtime-rules/no-iife-wrapper.js +217 -0
  108. package/dist/runtime-rules/no-iife-wrapper.js.map +1 -0
  109. package/dist/runtime-rules/no-import-statements.d.ts +18 -0
  110. package/dist/runtime-rules/no-import-statements.d.ts.map +1 -0
  111. package/dist/runtime-rules/no-import-statements.js +65 -0
  112. package/dist/runtime-rules/no-import-statements.js.map +1 -0
  113. package/dist/runtime-rules/no-react-destructuring.d.ts +18 -0
  114. package/dist/runtime-rules/no-react-destructuring.d.ts.map +1 -0
  115. package/dist/runtime-rules/no-react-destructuring.js +60 -0
  116. package/dist/runtime-rules/no-react-destructuring.js.map +1 -0
  117. package/dist/runtime-rules/no-require-statements.d.ts +18 -0
  118. package/dist/runtime-rules/no-require-statements.d.ts.map +1 -0
  119. package/dist/runtime-rules/no-require-statements.js +109 -0
  120. package/dist/runtime-rules/no-require-statements.js.map +1 -0
  121. package/dist/runtime-rules/no-return-component.d.ts +18 -0
  122. package/dist/runtime-rules/no-return-component.d.ts.map +1 -0
  123. package/dist/runtime-rules/no-return-component.js +106 -0
  124. package/dist/runtime-rules/no-return-component.js.map +1 -0
  125. package/dist/runtime-rules/no-unwrap-utility-libs.d.ts +20 -0
  126. package/dist/runtime-rules/no-unwrap-utility-libs.d.ts.map +1 -0
  127. package/dist/runtime-rules/no-unwrap-utility-libs.js +75 -0
  128. package/dist/runtime-rules/no-unwrap-utility-libs.js.map +1 -0
  129. package/dist/runtime-rules/no-use-reducer.d.ts +19 -0
  130. package/dist/runtime-rules/no-use-reducer.d.ts.map +1 -0
  131. package/dist/runtime-rules/no-use-reducer.js +78 -0
  132. package/dist/runtime-rules/no-use-reducer.js.map +1 -0
  133. package/dist/runtime-rules/no-window-access.d.ts +23 -0
  134. package/dist/runtime-rules/no-window-access.d.ts.map +1 -0
  135. package/dist/runtime-rules/no-window-access.js +136 -0
  136. package/dist/runtime-rules/no-window-access.js.map +1 -0
  137. package/dist/runtime-rules/noisy-settings-updates.d.ts +18 -0
  138. package/dist/runtime-rules/noisy-settings-updates.d.ts.map +1 -0
  139. package/dist/runtime-rules/noisy-settings-updates.js +110 -0
  140. package/dist/runtime-rules/noisy-settings-updates.js.map +1 -0
  141. package/dist/runtime-rules/overflow-hidden-on-layout-container.d.ts +30 -0
  142. package/dist/runtime-rules/overflow-hidden-on-layout-container.d.ts.map +1 -0
  143. package/dist/runtime-rules/overflow-hidden-on-layout-container.js +220 -0
  144. package/dist/runtime-rules/overflow-hidden-on-layout-container.js.map +1 -0
  145. package/dist/runtime-rules/pass-standard-props.d.ts +19 -0
  146. package/dist/runtime-rules/pass-standard-props.d.ts.map +1 -0
  147. package/dist/runtime-rules/pass-standard-props.js +82 -0
  148. package/dist/runtime-rules/pass-standard-props.js.map +1 -0
  149. package/dist/runtime-rules/prefer-async-await.d.ts +17 -0
  150. package/dist/runtime-rules/prefer-async-await.d.ts.map +1 -0
  151. package/dist/runtime-rules/prefer-async-await.js +52 -0
  152. package/dist/runtime-rules/prefer-async-await.js.map +1 -0
  153. package/dist/runtime-rules/prefer-jsx-syntax.d.ts +17 -0
  154. package/dist/runtime-rules/prefer-jsx-syntax.d.ts.map +1 -0
  155. package/dist/runtime-rules/prefer-jsx-syntax.js +51 -0
  156. package/dist/runtime-rules/prefer-jsx-syntax.js.map +1 -0
  157. package/dist/runtime-rules/prop-state-sync.d.ts +19 -0
  158. package/dist/runtime-rules/prop-state-sync.d.ts.map +1 -0
  159. package/dist/runtime-rules/prop-state-sync.js +76 -0
  160. package/dist/runtime-rules/prop-state-sync.js.map +1 -0
  161. package/dist/runtime-rules/property-name-consistency.d.ts +20 -0
  162. package/dist/runtime-rules/property-name-consistency.d.ts.map +1 -0
  163. package/dist/runtime-rules/property-name-consistency.js +172 -0
  164. package/dist/runtime-rules/property-name-consistency.js.map +1 -0
  165. package/dist/runtime-rules/query-result-field-access-validation.d.ts +10 -0
  166. package/dist/runtime-rules/query-result-field-access-validation.d.ts.map +1 -0
  167. package/dist/runtime-rules/query-result-field-access-validation.js +304 -0
  168. package/dist/runtime-rules/query-result-field-access-validation.js.map +1 -0
  169. package/dist/runtime-rules/react-component-naming.d.ts +19 -0
  170. package/dist/runtime-rules/react-component-naming.d.ts.map +1 -0
  171. package/dist/runtime-rules/react-component-naming.js +72 -0
  172. package/dist/runtime-rules/react-component-naming.js.map +1 -0
  173. package/dist/runtime-rules/react-hooks-rules.d.ts +27 -0
  174. package/dist/runtime-rules/react-hooks-rules.d.ts.map +1 -0
  175. package/dist/runtime-rules/react-hooks-rules.js +223 -0
  176. package/dist/runtime-rules/react-hooks-rules.js.map +1 -0
  177. package/dist/runtime-rules/required-queries-not-called.d.ts +19 -0
  178. package/dist/runtime-rules/required-queries-not-called.d.ts.map +1 -0
  179. package/dist/runtime-rules/required-queries-not-called.js +146 -0
  180. package/dist/runtime-rules/required-queries-not-called.js.map +1 -0
  181. package/dist/runtime-rules/runquery-call-validation.d.ts +11 -0
  182. package/dist/runtime-rules/runquery-call-validation.d.ts.map +1 -0
  183. package/dist/runtime-rules/runquery-call-validation.js +886 -0
  184. package/dist/runtime-rules/runquery-call-validation.js.map +1 -0
  185. package/dist/runtime-rules/runview-call-validation.d.ts +10 -0
  186. package/dist/runtime-rules/runview-call-validation.d.ts.map +1 -0
  187. package/dist/runtime-rules/runview-call-validation.js +336 -0
  188. package/dist/runtime-rules/runview-call-validation.js.map +1 -0
  189. package/dist/runtime-rules/saved-user-settings-pattern.d.ts +19 -0
  190. package/dist/runtime-rules/saved-user-settings-pattern.d.ts.map +1 -0
  191. package/dist/runtime-rules/saved-user-settings-pattern.js +90 -0
  192. package/dist/runtime-rules/saved-user-settings-pattern.js.map +1 -0
  193. package/dist/runtime-rules/search-availability-check.d.ts +9 -0
  194. package/dist/runtime-rules/search-availability-check.d.ts.map +1 -0
  195. package/dist/runtime-rules/search-availability-check.js +220 -0
  196. package/dist/runtime-rules/search-availability-check.js.map +1 -0
  197. package/dist/runtime-rules/search-call-validation.d.ts +9 -0
  198. package/dist/runtime-rules/search-call-validation.d.ts.map +1 -0
  199. package/dist/runtime-rules/search-call-validation.js +336 -0
  200. package/dist/runtime-rules/search-call-validation.js.map +1 -0
  201. package/dist/runtime-rules/server-reload-on-client-operation.d.ts +18 -0
  202. package/dist/runtime-rules/server-reload-on-client-operation.d.ts.map +1 -0
  203. package/dist/runtime-rules/server-reload-on-client-operation.js +107 -0
  204. package/dist/runtime-rules/server-reload-on-client-operation.js.map +1 -0
  205. package/dist/runtime-rules/single-function-only.d.ts +18 -0
  206. package/dist/runtime-rules/single-function-only.d.ts.map +1 -0
  207. package/dist/runtime-rules/single-function-only.js +103 -0
  208. package/dist/runtime-rules/single-function-only.js.map +1 -0
  209. package/dist/runtime-rules/string-replace-all-occurrences.d.ts +19 -0
  210. package/dist/runtime-rules/string-replace-all-occurrences.d.ts.map +1 -0
  211. package/dist/runtime-rules/string-replace-all-occurrences.js +109 -0
  212. package/dist/runtime-rules/string-replace-all-occurrences.js.map +1 -0
  213. package/dist/runtime-rules/string-template-validation.d.ts +22 -0
  214. package/dist/runtime-rules/string-template-validation.d.ts.map +1 -0
  215. package/dist/runtime-rules/string-template-validation.js +163 -0
  216. package/dist/runtime-rules/string-template-validation.js.map +1 -0
  217. package/dist/runtime-rules/styles-validation.d.ts +10 -0
  218. package/dist/runtime-rules/styles-validation.d.ts.map +1 -0
  219. package/dist/runtime-rules/styles-validation.js +153 -0
  220. package/dist/runtime-rules/styles-validation.js.map +1 -0
  221. package/dist/runtime-rules/type-inference-errors.d.ts +23 -0
  222. package/dist/runtime-rules/type-inference-errors.d.ts.map +1 -0
  223. package/dist/runtime-rules/type-inference-errors.js +53 -0
  224. package/dist/runtime-rules/type-inference-errors.js.map +1 -0
  225. package/dist/runtime-rules/type-mismatch-operation.d.ts +23 -0
  226. package/dist/runtime-rules/type-mismatch-operation.d.ts.map +1 -0
  227. package/dist/runtime-rules/type-mismatch-operation.js +145 -0
  228. package/dist/runtime-rules/type-mismatch-operation.js.map +1 -0
  229. package/dist/runtime-rules/undefined-component-usage.d.ts +20 -0
  230. package/dist/runtime-rules/undefined-component-usage.d.ts.map +1 -0
  231. package/dist/runtime-rules/undefined-component-usage.js +138 -0
  232. package/dist/runtime-rules/undefined-component-usage.js.map +1 -0
  233. package/dist/runtime-rules/undefined-jsx-component.d.ts +25 -0
  234. package/dist/runtime-rules/undefined-jsx-component.d.ts.map +1 -0
  235. package/dist/runtime-rules/undefined-jsx-component.js +269 -0
  236. package/dist/runtime-rules/undefined-jsx-component.js.map +1 -0
  237. package/dist/runtime-rules/unsafe-array-operations.d.ts +25 -0
  238. package/dist/runtime-rules/unsafe-array-operations.d.ts.map +1 -0
  239. package/dist/runtime-rules/unsafe-array-operations.js +347 -0
  240. package/dist/runtime-rules/unsafe-array-operations.js.map +1 -0
  241. package/dist/runtime-rules/unsafe-formatting-methods.d.ts +24 -0
  242. package/dist/runtime-rules/unsafe-formatting-methods.d.ts.map +1 -0
  243. package/dist/runtime-rules/unsafe-formatting-methods.js +277 -0
  244. package/dist/runtime-rules/unsafe-formatting-methods.js.map +1 -0
  245. package/dist/runtime-rules/unused-component-dependencies.d.ts +19 -0
  246. package/dist/runtime-rules/unused-component-dependencies.d.ts.map +1 -0
  247. package/dist/runtime-rules/unused-component-dependencies.js +90 -0
  248. package/dist/runtime-rules/unused-component-dependencies.js.map +1 -0
  249. package/dist/runtime-rules/unused-libraries.d.ts +19 -0
  250. package/dist/runtime-rules/unused-libraries.d.ts.map +1 -0
  251. package/dist/runtime-rules/unused-libraries.js +127 -0
  252. package/dist/runtime-rules/unused-libraries.js.map +1 -0
  253. package/dist/runtime-rules/use-function-declaration.d.ts +18 -0
  254. package/dist/runtime-rules/use-function-declaration.d.ts.map +1 -0
  255. package/dist/runtime-rules/use-function-declaration.js +127 -0
  256. package/dist/runtime-rules/use-function-declaration.js.map +1 -0
  257. package/dist/runtime-rules/use-unwrap-components.d.ts +19 -0
  258. package/dist/runtime-rules/use-unwrap-components.d.ts.map +1 -0
  259. package/dist/runtime-rules/use-unwrap-components.js +84 -0
  260. package/dist/runtime-rules/use-unwrap-components.js.map +1 -0
  261. package/dist/runtime-rules/useeffect-unstable-dependencies.d.ts +23 -0
  262. package/dist/runtime-rules/useeffect-unstable-dependencies.d.ts.map +1 -0
  263. package/dist/runtime-rules/useeffect-unstable-dependencies.js +215 -0
  264. package/dist/runtime-rules/useeffect-unstable-dependencies.js.map +1 -0
  265. package/dist/runtime-rules/utilities-api-validation.d.ts +24 -0
  266. package/dist/runtime-rules/utilities-api-validation.d.ts.map +1 -0
  267. package/dist/runtime-rules/utilities-api-validation.js +121 -0
  268. package/dist/runtime-rules/utilities-api-validation.js.map +1 -0
  269. package/dist/runtime-rules/utilities-no-direct-instantiation.d.ts +20 -0
  270. package/dist/runtime-rules/utilities-no-direct-instantiation.d.ts.map +1 -0
  271. package/dist/runtime-rules/utilities-no-direct-instantiation.js +58 -0
  272. package/dist/runtime-rules/utilities-no-direct-instantiation.js.map +1 -0
  273. package/dist/runtime-rules/validate-component-references.d.ts +19 -0
  274. package/dist/runtime-rules/validate-component-references.d.ts.map +1 -0
  275. package/dist/runtime-rules/validate-component-references.js +255 -0
  276. package/dist/runtime-rules/validate-component-references.js.map +1 -0
  277. package/dist/schema-validation/component-prop-rule.d.ts +131 -0
  278. package/dist/schema-validation/component-prop-rule.d.ts.map +1 -0
  279. package/dist/schema-validation/component-prop-rule.js +625 -0
  280. package/dist/schema-validation/component-prop-rule.js.map +1 -0
  281. package/dist/schema-validation/index.d.ts +26 -0
  282. package/dist/schema-validation/index.d.ts.map +1 -0
  283. package/dist/schema-validation/index.js +26 -0
  284. package/dist/schema-validation/index.js.map +1 -0
  285. package/dist/schema-validation/semantic-validators/index.d.ts +23 -0
  286. package/dist/schema-validation/semantic-validators/index.d.ts.map +1 -0
  287. package/dist/schema-validation/semantic-validators/index.js +23 -0
  288. package/dist/schema-validation/semantic-validators/index.js.map +1 -0
  289. package/dist/schema-validation/semantic-validators/required-when-validator.d.ts +43 -0
  290. package/dist/schema-validation/semantic-validators/required-when-validator.d.ts.map +1 -0
  291. package/dist/schema-validation/semantic-validators/required-when-validator.js +94 -0
  292. package/dist/schema-validation/semantic-validators/required-when-validator.js.map +1 -0
  293. package/dist/schema-validation/semantic-validators/semantic-validator-registry.d.ts +122 -0
  294. package/dist/schema-validation/semantic-validators/semantic-validator-registry.d.ts.map +1 -0
  295. package/dist/schema-validation/semantic-validators/semantic-validator-registry.js +166 -0
  296. package/dist/schema-validation/semantic-validators/semantic-validator-registry.js.map +1 -0
  297. package/dist/schema-validation/semantic-validators/semantic-validator.d.ts +260 -0
  298. package/dist/schema-validation/semantic-validators/semantic-validator.d.ts.map +1 -0
  299. package/dist/schema-validation/semantic-validators/semantic-validator.js +301 -0
  300. package/dist/schema-validation/semantic-validators/semantic-validator.js.map +1 -0
  301. package/dist/schema-validation/semantic-validators/sql-where-clause-validator.d.ts +115 -0
  302. package/dist/schema-validation/semantic-validators/sql-where-clause-validator.d.ts.map +1 -0
  303. package/dist/schema-validation/semantic-validators/sql-where-clause-validator.js +381 -0
  304. package/dist/schema-validation/semantic-validators/sql-where-clause-validator.js.map +1 -0
  305. package/dist/schema-validation/semantic-validators/subset-of-entity-fields-validator.d.ts +60 -0
  306. package/dist/schema-validation/semantic-validators/subset-of-entity-fields-validator.d.ts.map +1 -0
  307. package/dist/schema-validation/semantic-validators/subset-of-entity-fields-validator.js +195 -0
  308. package/dist/schema-validation/semantic-validators/subset-of-entity-fields-validator.js.map +1 -0
  309. package/dist/schema-validation/semantic-validators/validation-context.d.ts +335 -0
  310. package/dist/schema-validation/semantic-validators/validation-context.d.ts.map +1 -0
  311. package/dist/schema-validation/semantic-validators/validation-context.js +13 -0
  312. package/dist/schema-validation/semantic-validators/validation-context.js.map +1 -0
  313. package/dist/styles-type-analyzer.d.ts +64 -0
  314. package/dist/styles-type-analyzer.d.ts.map +1 -0
  315. package/dist/styles-type-analyzer.js +242 -0
  316. package/dist/styles-type-analyzer.js.map +1 -0
  317. package/dist/type-context.d.ts +184 -0
  318. package/dist/type-context.d.ts.map +1 -0
  319. package/dist/type-context.js +415 -0
  320. package/dist/type-context.js.map +1 -0
  321. package/dist/type-inference-engine.d.ts +181 -0
  322. package/dist/type-inference-engine.d.ts.map +1 -0
  323. package/dist/type-inference-engine.js +1151 -0
  324. package/dist/type-inference-engine.js.map +1 -0
  325. package/dist/type-rules/type-compatibility-rule.d.ts +85 -0
  326. package/dist/type-rules/type-compatibility-rule.d.ts.map +1 -0
  327. package/dist/type-rules/type-compatibility-rule.js +211 -0
  328. package/dist/type-rules/type-compatibility-rule.js.map +1 -0
  329. package/package.json +35 -7
  330. package/README.md +0 -45
@@ -0,0 +1,763 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { traverse } from '../lint-utils.js';
8
+ import { RegisterClass } from '@memberjunction/global';
9
+ import * as t from '@babel/types';
10
+ import { BaseLintRule } from '../lint-rule.js';
11
+ /**
12
+ * Rule: data-result-validation
13
+ *
14
+ * Consolidates all RunView AND RunQuery RESULT USAGE validation into one rule.
15
+ * Absorbs checks from:
16
+ * - runview-runquery-result-validation (all)
17
+ * - runquery-runview-spread-operator (all)
18
+ * - runview-result-null-safety (all)
19
+ *
20
+ * Architecture:
21
+ * - Phase 1: Collect result variables from await utilities.rv.RunView/RunViews/rq.RunQuery
22
+ * - Phase 2: Validate usage of tracked result variables
23
+ *
24
+ * Checks:
25
+ * 1. Invalid property access (.data, .rows, .records -> suggest .Results)
26
+ * 2. Direct array method on result (.map, .filter, etc. -> use .Results.map)
27
+ * 3. Passing result to setState without .Results
28
+ * 4. Array.isArray pattern on result (always false since result is object)
29
+ * 5. .length on result object
30
+ * 6. Incorrect nested property access (result.data.entities)
31
+ * 7. Destructuring invalid properties (const { data } = result)
32
+ * 8. Weak fallback pattern (result?.records ?? result?.Rows ?? [])
33
+ * 9. Spread operator on result object ([...result] or {...result})
34
+ * 10. Missing Success check - .Results accessed without Success guard (medium severity)
35
+ * 11. Incorrect optional check (.length on result)
36
+ *
37
+ * Severity: critical/high/medium
38
+ * Applies to: all components
39
+ */
40
+ const RULE_NAME = 'data-result-validation';
41
+ // Valid properties per result type
42
+ const RUNVIEW_RESULT_PROPS = [
43
+ 'Success', 'Results', 'UserViewRunID', 'RowCount', 'TotalRowCount', 'ExecutionTime', 'ErrorMessage',
44
+ ];
45
+ const RUNQUERY_RESULT_PROPS = [
46
+ 'QueryID', 'QueryName', 'Success', 'Results', 'RowCount', 'TotalRowCount',
47
+ 'ExecutionTime', 'ErrorMessage', 'AppliedParameters', 'CacheHit', 'CacheKey', 'CacheTTLRemaining',
48
+ ];
49
+ const VALID_RUNVIEW_RESULT = new Set(RUNVIEW_RESULT_PROPS);
50
+ const VALID_RUNQUERY_RESULT = new Set(RUNQUERY_RESULT_PROPS);
51
+ const SEARCH_RESULT_PROPS = [
52
+ 'Success', 'Results', 'TotalCount', 'ElapsedMs', 'SourceCounts', 'Providers', 'ErrorMessage',
53
+ ];
54
+ const VALID_SEARCH_RESULT = new Set(SEARCH_RESULT_PROPS);
55
+ const ARRAY_METHODS = new Set(['map', 'filter', 'forEach', 'reduce', 'find', 'some', 'every', 'sort', 'concat']);
56
+ const ARRAY_EXPECTING_FUNCS = new Set([
57
+ 'map', 'filter', 'forEach', 'reduce', 'sort', 'concat',
58
+ 'processChartData', 'processData', 'transformData',
59
+ 'setData', 'setItems', 'setResults', 'setRows',
60
+ ]);
61
+ const INCORRECT_TO_CORRECT = {
62
+ data: 'Results', Data: 'Results',
63
+ rows: 'Results', Rows: 'Results',
64
+ records: 'Results', Records: 'Results',
65
+ items: 'Results', Items: 'Results',
66
+ values: 'Results', Values: 'Results',
67
+ result: 'Results', Result: 'Results',
68
+ resultSet: 'Results', ResultSet: 'Results',
69
+ dataset: 'Results', Dataset: 'Results',
70
+ response: 'Results', Response: 'Results',
71
+ };
72
+ // ── Phase 1: Collect result variables ────────────────────────────────
73
+ /**
74
+ * Attempts to extract utilities sub-object name and method name from a callee node.
75
+ * Handles both MemberExpression (direct) and OptionalMemberExpression (optional chaining) patterns.
76
+ * Returns [subObject, method] if matched, null otherwise.
77
+ */
78
+ function extractUtilitiesCallInfo(callee) {
79
+ // Get the method name from the outermost property
80
+ let methodName = null;
81
+ let objectNode = null;
82
+ if (t.isMemberExpression(callee) && t.isIdentifier(callee.property)) {
83
+ methodName = callee.property.name;
84
+ objectNode = callee.object;
85
+ }
86
+ else if (t.isOptionalMemberExpression(callee) && t.isIdentifier(callee.property)) {
87
+ methodName = callee.property.name;
88
+ objectNode = callee.object;
89
+ }
90
+ if (!methodName || !objectNode)
91
+ return null;
92
+ // Check if the object is utilities.xxx (direct or optional)
93
+ let subObject = null;
94
+ if (t.isMemberExpression(objectNode) && t.isIdentifier(objectNode.object) &&
95
+ objectNode.object.name === 'utilities' && t.isIdentifier(objectNode.property)) {
96
+ subObject = objectNode.property.name;
97
+ }
98
+ else if (t.isOptionalMemberExpression(objectNode) && t.isIdentifier(objectNode.object) &&
99
+ objectNode.object.name === 'utilities' && t.isIdentifier(objectNode.property)) {
100
+ subObject = objectNode.property.name;
101
+ }
102
+ if (!subObject)
103
+ return null;
104
+ return [subObject, methodName];
105
+ }
106
+ /**
107
+ * Resolves a MethodType from a utilities sub-object name and method name.
108
+ */
109
+ function resolveMethodType(subObject, method) {
110
+ if (subObject === 'rv' && (method === 'RunView' || method === 'RunViews')) {
111
+ return method;
112
+ }
113
+ if (subObject === 'rq' && method === 'RunQuery')
114
+ return 'RunQuery';
115
+ if (subObject === 'search' && method === 'Search')
116
+ return 'Search';
117
+ if (subObject === 'search' && method === 'PreviewSearch')
118
+ return 'PreviewSearch';
119
+ return null;
120
+ }
121
+ /**
122
+ * Records a result variable from an AwaitExpression's parent (variable declarator or assignment).
123
+ */
124
+ function recordResultVariable(path, methodType, resultVariables) {
125
+ const parent = path.parent;
126
+ if (t.isVariableDeclarator(parent) && t.isIdentifier(parent.id)) {
127
+ resultVariables.set(parent.id.name, {
128
+ line: parent.id.loc?.start.line || 0,
129
+ column: parent.id.loc?.start.column || 0,
130
+ method: methodType,
131
+ varName: parent.id.name,
132
+ });
133
+ }
134
+ else if (t.isAssignmentExpression(parent) && t.isIdentifier(parent.left)) {
135
+ resultVariables.set(parent.left.name, {
136
+ line: parent.left.loc?.start.line || 0,
137
+ column: parent.left.loc?.start.column || 0,
138
+ method: methodType,
139
+ varName: parent.left.name,
140
+ });
141
+ }
142
+ }
143
+ function collectResultVariables(ast) {
144
+ const resultVariables = new Map();
145
+ traverse(ast, {
146
+ AwaitExpression(path) {
147
+ const callExpr = path.node.argument;
148
+ // Handle both CallExpression and OptionalCallExpression
149
+ if (!t.isCallExpression(callExpr) && !t.isOptionalCallExpression(callExpr))
150
+ return;
151
+ const info = extractUtilitiesCallInfo(callExpr.callee);
152
+ if (!info)
153
+ return;
154
+ const methodType = resolveMethodType(info[0], info[1]);
155
+ if (!methodType)
156
+ return;
157
+ recordResultVariable(path, methodType, resultVariables);
158
+ },
159
+ });
160
+ return resultVariables;
161
+ }
162
+ // ── Scope-based binding check ────────────────────────────────────────
163
+ function isVariableFromRunQueryOrView(path, varName, methodName) {
164
+ const binding = path.scope.getBinding(varName);
165
+ if (!binding)
166
+ return false;
167
+ const bindingPath = binding.path;
168
+ if (!t.isVariableDeclarator(bindingPath.node))
169
+ return false;
170
+ const init = bindingPath.node.init;
171
+ if (!init)
172
+ return false;
173
+ // Handle both CallExpression and OptionalCallExpression inside AwaitExpression
174
+ if (t.isAwaitExpression(init) && (t.isCallExpression(init.argument) || t.isOptionalCallExpression(init.argument))) {
175
+ const call = init.argument;
176
+ const info = extractUtilitiesCallInfo(call.callee);
177
+ if (info) {
178
+ const [subObj, calledMethod] = info;
179
+ if (methodName === 'RunView' && subObj === 'rv' && (calledMethod === 'RunView' || calledMethod === 'RunViews'))
180
+ return true;
181
+ if (methodName === 'RunQuery' && subObj === 'rq' && calledMethod === 'RunQuery')
182
+ return true;
183
+ if (methodName === 'Search' && subObj === 'search' && calledMethod === 'Search')
184
+ return true;
185
+ if (methodName === 'PreviewSearch' && subObj === 'search' && calledMethod === 'PreviewSearch')
186
+ return true;
187
+ }
188
+ // Fallback: check just the method name without full utilities path
189
+ if (t.isCallExpression(call) && t.isMemberExpression(call.callee) && t.isIdentifier(call.callee.property)) {
190
+ const calledMethod = call.callee.property.name;
191
+ const isFromMethod = calledMethod === methodName || (methodName === 'RunView' && calledMethod === 'RunViews');
192
+ return isFromMethod;
193
+ }
194
+ }
195
+ return false;
196
+ }
197
+ // ── Success guard checking ───────────────────────────────────────────
198
+ function testChecksSuccess(test, varName) {
199
+ if (t.isMemberExpression(test) &&
200
+ t.isIdentifier(test.object) &&
201
+ test.object.name === varName &&
202
+ t.isIdentifier(test.property) &&
203
+ (test.property.name === 'Success' || test.property.name === 'Results'))
204
+ return true;
205
+ if (t.isOptionalMemberExpression(test) &&
206
+ t.isIdentifier(test.object) &&
207
+ test.object.name === varName &&
208
+ t.isIdentifier(test.property) &&
209
+ (test.property.name === 'Success' || test.property.name === 'Results'))
210
+ return true;
211
+ if (t.isLogicalExpression(test) && test.operator === '&&') {
212
+ return testChecksSuccess(test.left, varName) || testChecksSuccess(test.right, varName);
213
+ }
214
+ return false;
215
+ }
216
+ function testChecksNegatedSuccess(test, varName) {
217
+ if (t.isUnaryExpression(test) && test.operator === '!') {
218
+ return testChecksSuccess(test.argument, varName);
219
+ }
220
+ return false;
221
+ }
222
+ function blockContainsReturn(node) {
223
+ if (t.isReturnStatement(node))
224
+ return true;
225
+ if (t.isBlockStatement(node))
226
+ return node.body.some(s => t.isReturnStatement(s));
227
+ return false;
228
+ }
229
+ function isDescendantOf(targetNode, containerNode) {
230
+ if (targetNode === containerNode)
231
+ return true;
232
+ let found = false;
233
+ traverse(containerNode, {
234
+ enter(innerPath) {
235
+ if (innerPath.node === targetNode) {
236
+ found = true;
237
+ innerPath.stop();
238
+ }
239
+ },
240
+ noScope: true,
241
+ });
242
+ return found;
243
+ }
244
+ function isPrecededByEarlyReturnGuard(path, varName) {
245
+ let blockPath = path;
246
+ while (blockPath && !blockPath.isBlockStatement() && !blockPath.isProgram()) {
247
+ blockPath = blockPath.parentPath;
248
+ }
249
+ if (!blockPath)
250
+ return false;
251
+ const container = blockPath.node;
252
+ const body = t.isBlockStatement(container) ? container.body : t.isProgram(container) ? container.body : [];
253
+ const targetLine = path.node.loc?.start.line ?? 0;
254
+ for (const stmt of body) {
255
+ if ((stmt.loc?.start.line ?? 0) >= targetLine)
256
+ break;
257
+ if (t.isIfStatement(stmt) &&
258
+ testChecksNegatedSuccess(stmt.test, varName) &&
259
+ blockContainsReturn(stmt.consequent))
260
+ return true;
261
+ }
262
+ return false;
263
+ }
264
+ function isInsideSuccessGuard(path, varName) {
265
+ let current = path.parentPath;
266
+ while (current) {
267
+ if (current.isIfStatement()) {
268
+ if (testChecksSuccess(current.node.test, varName) && isDescendantOf(path.node, current.node.consequent)) {
269
+ return true;
270
+ }
271
+ }
272
+ if (current.isLogicalExpression() && current.node.operator === '&&') {
273
+ if (testChecksSuccess(current.node.left, varName))
274
+ return true;
275
+ }
276
+ if (current.isConditionalExpression()) {
277
+ if (testChecksSuccess(current.node.test, varName))
278
+ return true;
279
+ }
280
+ current = current.parentPath;
281
+ }
282
+ return isPrecededByEarlyReturnGuard(path, varName);
283
+ }
284
+ // ── Property access validation helper ────────────────────────────────
285
+ function validatePropertyAccess(objName, propName, isFromRunQuery, isFromRunView, isFromSearch, line, column, code, violations) {
286
+ if (!isFromRunQuery && !isFromRunView && !isFromSearch)
287
+ return;
288
+ const isValidQueryProp = VALID_RUNQUERY_RESULT.has(propName);
289
+ const isValidViewProp = VALID_RUNVIEW_RESULT.has(propName);
290
+ const isValidSearchProp = VALID_SEARCH_RESULT.has(propName);
291
+ if (isFromRunQuery && !isValidQueryProp) {
292
+ const suggestion = INCORRECT_TO_CORRECT[propName];
293
+ violations.push({
294
+ rule: RULE_NAME,
295
+ severity: 'critical',
296
+ line, column,
297
+ message: suggestion
298
+ ? `RunQuery results don't have a ".${propName}" property. Use ".${suggestion}" instead. Change "${objName}.${propName}" to "${objName}.${suggestion}"`
299
+ : `Invalid property "${propName}" on RunQuery result. Valid properties: ${RUNQUERY_RESULT_PROPS.join(', ')}`,
300
+ code,
301
+ });
302
+ }
303
+ else if (isFromRunView && !isValidViewProp) {
304
+ const suggestion = INCORRECT_TO_CORRECT[propName];
305
+ violations.push({
306
+ rule: RULE_NAME,
307
+ severity: 'critical',
308
+ line, column,
309
+ message: suggestion
310
+ ? `RunView results don't have a ".${propName}" property. Use ".${suggestion}" instead. Change "${objName}.${propName}" to "${objName}.${suggestion}"`
311
+ : `Invalid property "${propName}" on RunView result. Valid properties: ${RUNVIEW_RESULT_PROPS.join(', ')}`,
312
+ code,
313
+ });
314
+ }
315
+ else if (isFromSearch && !isValidSearchProp) {
316
+ const suggestion = INCORRECT_TO_CORRECT[propName];
317
+ violations.push({
318
+ rule: RULE_NAME,
319
+ severity: 'critical',
320
+ line, column,
321
+ message: suggestion
322
+ ? `Search results don't have a ".${propName}" property. Use ".${suggestion}" instead. Change "${objName}.${propName}" to "${objName}.${suggestion}"`
323
+ : `Invalid property "${propName}" on Search result. Valid properties: ${SEARCH_RESULT_PROPS.join(', ')}`,
324
+ code,
325
+ });
326
+ }
327
+ }
328
+ // ── Main Rule ────────────────────────────────────────────────────────
329
+ let DataResultValidationRule = class DataResultValidationRule extends BaseLintRule {
330
+ get Name() { return 'data-result-validation'; }
331
+ get AppliesTo() { return 'all'; }
332
+ Test(ast) {
333
+ const violations = [];
334
+ // Phase 1: Collect result variables
335
+ const resultVariables = collectResultVariables(ast);
336
+ if (resultVariables.size === 0)
337
+ return violations;
338
+ // Collect simple set for null-safety (just variable names)
339
+ const resultVarNames = new Set(resultVariables.keys());
340
+ // Phase 2: Validate usage
341
+ traverse(ast, {
342
+ // ── Array methods + setState + array-expecting funcs ──────
343
+ CallExpression(path) {
344
+ const callee = path.node.callee;
345
+ // Check 2: result.map(), result.filter(), etc.
346
+ if (t.isMemberExpression(callee) && t.isIdentifier(callee.object) && t.isIdentifier(callee.property)) {
347
+ const objName = callee.object.name;
348
+ const methodName = callee.property.name;
349
+ if (ARRAY_METHODS.has(methodName)) {
350
+ const isFromRunView = isVariableFromRunQueryOrView(path, objName, 'RunView');
351
+ const isFromRunQuery = isVariableFromRunQueryOrView(path, objName, 'RunQuery');
352
+ const isFromSearch = isVariableFromRunQueryOrView(path, objName, 'Search');
353
+ const isFromPreviewSearch = isVariableFromRunQueryOrView(path, objName, 'PreviewSearch');
354
+ if (isFromRunView || isFromRunQuery || isFromSearch || isFromPreviewSearch) {
355
+ const methodType = isFromRunView ? 'RunView' : isFromRunQuery ? 'RunQuery' : isFromSearch ? 'Search' : 'PreviewSearch';
356
+ violations.push({
357
+ rule: RULE_NAME,
358
+ severity: 'critical',
359
+ line: path.node.loc?.start.line || 0,
360
+ column: path.node.loc?.start.column || 0,
361
+ message: `Cannot call array method "${methodName}" directly on ${methodType} result. Use "${objName}.Results.${methodName}(...)" instead. ${methodType} returns an object with { Success, Results, ... }, not an array.`,
362
+ code: `${objName}.${methodName}(...)`,
363
+ });
364
+ }
365
+ }
366
+ }
367
+ // Check 3 & 4: setState patterns
368
+ if (t.isIdentifier(callee)) {
369
+ const funcName = callee.name;
370
+ const setStatePatterns = [/^set[A-Z]/, /^update[A-Z]/];
371
+ const isSetStateFunction = setStatePatterns.some((pattern) => pattern.test(funcName));
372
+ if (isSetStateFunction && path.node.arguments.length > 0) {
373
+ const firstArg = path.node.arguments[0];
374
+ // Check 4: Array.isArray ternary pattern in setState
375
+ if (t.isConditionalExpression(firstArg)) {
376
+ const test = firstArg.test;
377
+ const consequent = firstArg.consequent;
378
+ if (t.isCallExpression(test) &&
379
+ t.isMemberExpression(test.callee) &&
380
+ t.isIdentifier(test.callee.object) &&
381
+ test.callee.object.name === 'Array' &&
382
+ t.isIdentifier(test.callee.property) &&
383
+ test.callee.property.name === 'isArray' &&
384
+ test.arguments.length === 1 &&
385
+ t.isIdentifier(test.arguments[0])) {
386
+ const varName = test.arguments[0].name;
387
+ if (resultVariables.has(varName) && t.isIdentifier(consequent) && consequent.name === varName) {
388
+ const resultInfo = resultVariables.get(varName);
389
+ violations.push({
390
+ rule: RULE_NAME,
391
+ severity: 'critical',
392
+ line: firstArg.loc?.start.line || 0,
393
+ column: firstArg.loc?.start.column || 0,
394
+ message: `Passing ${resultInfo.method} result with incorrect Array.isArray check to ${funcName}. This will always pass an empty array because ${resultInfo.method} returns an object, not an array.
395
+
396
+ Correct pattern:
397
+ if (${varName}.Success) {
398
+ ${funcName}(${varName}.Results || []);
399
+ } else {
400
+ console.error('Failed to load data:', ${varName}.ErrorMessage);
401
+ }`,
402
+ code: `${funcName}(Array.isArray(${varName}) ? ${varName} : [])`,
403
+ });
404
+ }
405
+ }
406
+ }
407
+ // Check 3: Passing result directly to setState
408
+ if (t.isIdentifier(firstArg) && resultVariables.has(firstArg.name)) {
409
+ const resultInfo = resultVariables.get(firstArg.name);
410
+ violations.push({
411
+ rule: RULE_NAME,
412
+ severity: 'critical',
413
+ line: firstArg.loc?.start.line || 0,
414
+ column: firstArg.loc?.start.column || 0,
415
+ message: `Passing ${resultInfo.method} result directly to ${funcName}. Use "${firstArg.name}.Results" or check "${firstArg.name}.Success" first. ${resultInfo.method} returns { Success, Results, ErrorMessage }, not the data array.`,
416
+ code: `${funcName}(${firstArg.name})`,
417
+ });
418
+ }
419
+ }
420
+ }
421
+ // Check: passing result to array-expecting functions
422
+ for (const arg of path.node.arguments) {
423
+ if (!t.isIdentifier(arg) || !resultVariables.has(arg.name))
424
+ continue;
425
+ const resultInfo = resultVariables.get(arg.name);
426
+ let funcName = '';
427
+ if (t.isIdentifier(path.node.callee)) {
428
+ funcName = path.node.callee.name;
429
+ }
430
+ else if (t.isMemberExpression(path.node.callee) && t.isIdentifier(path.node.callee.property)) {
431
+ funcName = path.node.callee.property.name;
432
+ }
433
+ if (ARRAY_EXPECTING_FUNCS.has(funcName.toLowerCase()) ||
434
+ Array.from(ARRAY_EXPECTING_FUNCS).some((f) => funcName.toLowerCase().includes(f.toLowerCase()))) {
435
+ violations.push({
436
+ rule: RULE_NAME,
437
+ severity: 'critical',
438
+ line: arg.loc?.start.line || 0,
439
+ column: arg.loc?.start.column || 0,
440
+ message: `Passing ${resultInfo.method} result object directly to ${funcName}() which expects an array.
441
+ Correct pattern:
442
+ if (${resultInfo.varName}?.Success) {
443
+ ${funcName}(${resultInfo.varName}.Results);
444
+ } else {
445
+ console.error('${resultInfo.method} failed:', ${resultInfo.varName}?.ErrorMessage);
446
+ ${funcName}([]); // Provide empty array as fallback
447
+ }`,
448
+ code: `${funcName}(${arg.name})`,
449
+ });
450
+ }
451
+ }
452
+ },
453
+ // ── Property access (MemberExpression) ─────────────────────
454
+ MemberExpression(path) {
455
+ if (!t.isIdentifier(path.node.object) || !t.isIdentifier(path.node.property))
456
+ return;
457
+ const objName = path.node.object.name;
458
+ const propName = path.node.property.name;
459
+ const hasBinding = path.scope.hasBinding(objName);
460
+ const isFromRunQuery = hasBinding && isVariableFromRunQueryOrView(path, objName, 'RunQuery');
461
+ const isFromRunView = hasBinding && isVariableFromRunQueryOrView(path, objName, 'RunView');
462
+ const isFromSearch = hasBinding && (isVariableFromRunQueryOrView(path, objName, 'Search') || isVariableFromRunQueryOrView(path, objName, 'PreviewSearch'));
463
+ // Check 5: .length on result
464
+ if (propName === 'length' && resultVariables.has(objName)) {
465
+ const resultInfo = resultVariables.get(objName);
466
+ violations.push({
467
+ rule: RULE_NAME,
468
+ severity: 'critical',
469
+ line: path.node.loc?.start.line || 0,
470
+ column: path.node.loc?.start.column || 0,
471
+ message: `Cannot check .length on ${resultInfo.method} result directly. ${resultInfo.method} returns an object with Success and Results properties.
472
+ Correct pattern:
473
+ if (${resultInfo.varName}?.Success && ${resultInfo.varName}?.Results?.length > 0) {
474
+ // Process ${resultInfo.varName}.Results array
475
+ }`,
476
+ code: `${objName}.length`,
477
+ });
478
+ }
479
+ // Check 1: Invalid property access
480
+ validatePropertyAccess(objName, propName, isFromRunQuery, isFromRunView, isFromSearch, path.node.loc?.start.line || 0, path.node.loc?.start.column || 0, `${objName}.${propName}`, violations);
481
+ // Check 6: Nested incorrect access like result.data.entities
482
+ if ((isFromRunQuery || isFromRunView || isFromSearch) &&
483
+ t.isMemberExpression(path.parent) &&
484
+ t.isIdentifier(path.parent.property) &&
485
+ (propName === 'data' || propName === 'Data')) {
486
+ const nestedProp = path.parent.property.name;
487
+ const sourceType = isFromSearch ? 'Search' : 'RunQuery/RunView';
488
+ violations.push({
489
+ rule: RULE_NAME,
490
+ severity: 'critical',
491
+ line: path.parent.loc?.start.line || 0,
492
+ column: path.parent.loc?.start.column || 0,
493
+ message: `Incorrect nested property access "${objName}.${propName}.${nestedProp}". ${sourceType} results use ".Results" directly for the data array. Change to "${objName}.Results"`,
494
+ code: `${objName}.${propName}.${nestedProp}`,
495
+ });
496
+ }
497
+ // Check 10: Missing Success check (null safety)
498
+ if (propName === 'Results' && resultVarNames.has(objName)) {
499
+ if (!isInsideSuccessGuard(path, objName)) {
500
+ const resultInfo = resultVariables.get(objName);
501
+ const sourceDesc = resultInfo && (resultInfo.method === 'Search' || resultInfo.method === 'PreviewSearch')
502
+ ? 'Search' : 'RunView/RunQuery';
503
+ violations.push({
504
+ rule: RULE_NAME,
505
+ severity: 'medium',
506
+ line: path.node.loc?.start.line ?? 0,
507
+ column: path.node.loc?.start.column ?? 0,
508
+ message: `Accessing "${objName}.Results" without checking "${objName}.Success" first. ${sourceDesc} can fail, and .Results may be undefined when Success is false.`,
509
+ code: `${objName}.Results`,
510
+ suggestion: {
511
+ text: `Wrap in a Success check before accessing Results`,
512
+ example: `if (${objName}.Success) {\n ${objName}.Results.map(...);\n} else {\n console.error('Query failed:', ${objName}.ErrorMessage);\n}`,
513
+ },
514
+ });
515
+ }
516
+ }
517
+ },
518
+ // ── Optional member expressions ────────────────────────────
519
+ OptionalMemberExpression(path) {
520
+ if (!t.isIdentifier(path.node.object) || !t.isIdentifier(path.node.property))
521
+ return;
522
+ const objName = path.node.object.name;
523
+ const propName = path.node.property.name;
524
+ const hasBinding = path.scope.hasBinding(objName);
525
+ const isFromRunQuery = hasBinding && isVariableFromRunQueryOrView(path, objName, 'RunQuery');
526
+ const isFromRunView = hasBinding && isVariableFromRunQueryOrView(path, objName, 'RunView');
527
+ const isFromSearch = hasBinding && (isVariableFromRunQueryOrView(path, objName, 'Search') || isVariableFromRunQueryOrView(path, objName, 'PreviewSearch'));
528
+ // Check 1 (optional chaining variant)
529
+ validatePropertyAccess(objName, propName, isFromRunQuery, isFromRunView, isFromSearch, path.node.loc?.start.line || 0, path.node.loc?.start.column || 0, `${objName}?.${propName}`, violations);
530
+ // Note: result?.Results is inherently null-safe — do NOT flag for missing Success check
531
+ },
532
+ // ── Check 8: Weak fallback patterns ────────────────────────
533
+ LogicalExpression(path) {
534
+ if (path.node.operator !== '??')
535
+ return;
536
+ const invalidAccesses = [];
537
+ const checkNode = (node) => {
538
+ if (t.isOptionalMemberExpression(node) && t.isIdentifier(node.object) && t.isIdentifier(node.property)) {
539
+ const objName = node.object.name;
540
+ const propName = node.property.name;
541
+ const hasBinding = path.scope.hasBinding(objName);
542
+ const isFromRunQuery = hasBinding && isVariableFromRunQueryOrView(path, objName, 'RunQuery');
543
+ const isFromRunView = hasBinding && isVariableFromRunQueryOrView(path, objName, 'RunView');
544
+ const isFromSearch = hasBinding && (isVariableFromRunQueryOrView(path, objName, 'Search') || isVariableFromRunQueryOrView(path, objName, 'PreviewSearch'));
545
+ if (isFromRunQuery || isFromRunView || isFromSearch) {
546
+ const isValidQueryProp = VALID_RUNQUERY_RESULT.has(propName);
547
+ const isValidViewProp = VALID_RUNVIEW_RESULT.has(propName);
548
+ const isValidSearchProp = VALID_SEARCH_RESULT.has(propName);
549
+ if ((isFromRunQuery && !isValidQueryProp) || (isFromRunView && !isValidViewProp) || (isFromSearch && !isValidSearchProp)) {
550
+ invalidAccesses.push({ objName, propName, line: node.loc?.start.line || 0 });
551
+ }
552
+ }
553
+ }
554
+ else if (t.isLogicalExpression(node) && node.operator === '??') {
555
+ checkNode(node.left);
556
+ checkNode(node.right);
557
+ }
558
+ };
559
+ checkNode(path.node);
560
+ if (invalidAccesses.length >= 2) {
561
+ const objName = invalidAccesses[0].objName;
562
+ const props = invalidAccesses.map((a) => a.propName).join(', ');
563
+ violations.push({
564
+ rule: RULE_NAME,
565
+ severity: 'critical',
566
+ line: path.node.loc?.start.line || 0,
567
+ column: path.node.loc?.start.column || 0,
568
+ message: `Weak fallback pattern detected: "${objName}?.${invalidAccesses[0].propName} ?? ${objName}?.${invalidAccesses[1].propName} ?? ..." uses multiple INVALID properties (${props}). This masks the real issue. Use "${objName}?.Results ?? []" instead.`,
569
+ code: path.toString().substring(0, 100),
570
+ });
571
+ }
572
+ },
573
+ // ── Check 7: Destructuring invalid properties ──────────────
574
+ VariableDeclarator(path) {
575
+ if (!t.isObjectPattern(path.node.id) || !t.isIdentifier(path.node.init))
576
+ return;
577
+ const sourceName = path.node.init.name;
578
+ const hasBinding = path.scope.hasBinding(sourceName);
579
+ const isFromRunQuery = hasBinding && isVariableFromRunQueryOrView(path, sourceName, 'RunQuery');
580
+ const isFromRunView = hasBinding && isVariableFromRunQueryOrView(path, sourceName, 'RunView');
581
+ const isFromSearch = hasBinding && (isVariableFromRunQueryOrView(path, sourceName, 'Search') || isVariableFromRunQueryOrView(path, sourceName, 'PreviewSearch'));
582
+ if (!isFromRunQuery && !isFromRunView && !isFromSearch)
583
+ return;
584
+ for (const prop of path.node.id.properties) {
585
+ if (!t.isObjectProperty(prop) || !t.isIdentifier(prop.key))
586
+ continue;
587
+ const propName = prop.key.name;
588
+ const isValidQueryProp = VALID_RUNQUERY_RESULT.has(propName);
589
+ const isValidViewProp = VALID_RUNVIEW_RESULT.has(propName);
590
+ const isValidSearchProp = VALID_SEARCH_RESULT.has(propName);
591
+ if (isFromRunQuery && !isValidQueryProp) {
592
+ const suggestion = INCORRECT_TO_CORRECT[propName];
593
+ violations.push({
594
+ rule: RULE_NAME,
595
+ severity: 'critical',
596
+ line: prop.loc?.start.line || 0,
597
+ column: prop.loc?.start.column || 0,
598
+ message: suggestion
599
+ ? `Destructuring invalid property "${propName}" from RunQuery result. Use "${suggestion}" instead.`
600
+ : `Destructuring invalid property "${propName}" from RunQuery result. Valid properties: ${RUNQUERY_RESULT_PROPS.join(', ')}`,
601
+ code: `{ ${propName} }`,
602
+ });
603
+ }
604
+ else if (isFromRunView && !isValidViewProp) {
605
+ const suggestion = INCORRECT_TO_CORRECT[propName];
606
+ violations.push({
607
+ rule: RULE_NAME,
608
+ severity: 'critical',
609
+ line: prop.loc?.start.line || 0,
610
+ column: prop.loc?.start.column || 0,
611
+ message: suggestion
612
+ ? `Destructuring invalid property "${propName}" from RunView result. Use "${suggestion}" instead.`
613
+ : `Destructuring invalid property "${propName}" from RunView result. Valid properties: ${RUNVIEW_RESULT_PROPS.join(', ')}`,
614
+ code: `{ ${propName} }`,
615
+ });
616
+ }
617
+ else if (isFromSearch && !isValidSearchProp) {
618
+ const suggestion = INCORRECT_TO_CORRECT[propName];
619
+ violations.push({
620
+ rule: RULE_NAME,
621
+ severity: 'critical',
622
+ line: prop.loc?.start.line || 0,
623
+ column: prop.loc?.start.column || 0,
624
+ message: suggestion
625
+ ? `Destructuring invalid property "${propName}" from Search result. Use "${suggestion}" instead.`
626
+ : `Destructuring invalid property "${propName}" from Search result. Valid properties: ${SEARCH_RESULT_PROPS.join(', ')}`,
627
+ code: `{ ${propName} }`,
628
+ });
629
+ }
630
+ }
631
+ },
632
+ // ── Check 4 & 11: ConditionalExpression patterns ───────────
633
+ ConditionalExpression(path) {
634
+ const test = path.node.test;
635
+ const consequent = path.node.consequent;
636
+ const alternate = path.node.alternate;
637
+ if (t.isCallExpression(test) &&
638
+ t.isMemberExpression(test.callee) &&
639
+ t.isIdentifier(test.callee.object) &&
640
+ test.callee.object.name === 'Array' &&
641
+ t.isIdentifier(test.callee.property) &&
642
+ test.callee.property.name === 'isArray' &&
643
+ test.arguments.length === 1 &&
644
+ t.isIdentifier(test.arguments[0])) {
645
+ const varName = test.arguments[0].name;
646
+ if (resultVariables.has(varName) &&
647
+ t.isIdentifier(consequent) &&
648
+ consequent.name === varName &&
649
+ t.isArrayExpression(alternate) &&
650
+ alternate.elements.length === 0) {
651
+ const resultInfo = resultVariables.get(varName);
652
+ violations.push({
653
+ rule: RULE_NAME,
654
+ severity: 'critical',
655
+ line: test.loc?.start.line || 0,
656
+ column: test.loc?.start.column || 0,
657
+ message: `${resultInfo.method} never returns an array directly. The pattern "Array.isArray(${varName}) ? ${varName} : []" will always evaluate to [] because ${varName} is an object with { Success, Results, ErrorMessage }.
658
+
659
+ Correct patterns:
660
+ // Option 1: Simple with fallback
661
+ ${varName}.Results || []
662
+
663
+ // Option 2: Check success first
664
+ if (${varName}.Success) {
665
+ setData(${varName}.Results || []);
666
+ } else {
667
+ console.error('Failed:', ${varName}.ErrorMessage);
668
+ setData([]);
669
+ }`,
670
+ code: `Array.isArray(${varName}) ? ${varName} : []`,
671
+ });
672
+ }
673
+ }
674
+ },
675
+ // ── Check 9: Spread operator on result object ──────────────
676
+ SpreadElement(path) {
677
+ if (!t.isIdentifier(path.node.argument))
678
+ return;
679
+ const varName = path.node.argument.name;
680
+ if (!resultVariables.has(varName))
681
+ return;
682
+ const resultInfo = resultVariables.get(varName);
683
+ violations.push({
684
+ rule: RULE_NAME,
685
+ severity: 'critical',
686
+ line: path.node.loc?.start.line || 0,
687
+ column: path.node.loc?.start.column || 0,
688
+ message: `Cannot use spread operator on ${resultInfo.method} result object. Use ...${varName}.Results to spread the data array.
689
+
690
+ Correct pattern:
691
+ const allData = [...existingData, ...${varName}.Results];
692
+
693
+ // Or with null safety:
694
+ const allData = [...existingData, ...(${varName}.Results || [])];`,
695
+ code: `...${varName}`,
696
+ });
697
+ },
698
+ // ── Check 11: IfStatement patterns ─────────────────────────
699
+ IfStatement(path) {
700
+ const test = path.node.test;
701
+ // Pattern: if (result) - check for Results access without Success check
702
+ if (t.isIdentifier(test) && resultVariables.has(test.name)) {
703
+ const resultInfo = resultVariables.get(test.name);
704
+ let checksSuccess = false;
705
+ let checksResults = false;
706
+ path.traverse({
707
+ MemberExpression(innerPath) {
708
+ if (t.isIdentifier(innerPath.node.object) && innerPath.node.object.name === test.name) {
709
+ const prop = t.isIdentifier(innerPath.node.property) ? innerPath.node.property.name : '';
710
+ if (prop === 'Success')
711
+ checksSuccess = true;
712
+ if (prop === 'Results')
713
+ checksResults = true;
714
+ }
715
+ },
716
+ });
717
+ if (checksResults && !checksSuccess) {
718
+ violations.push({
719
+ rule: RULE_NAME,
720
+ severity: 'high',
721
+ line: test.loc?.start.line || 0,
722
+ column: test.loc?.start.column || 0,
723
+ message: `Checking ${resultInfo.method} result without verifying Success property.
724
+ Correct pattern:
725
+ if (${resultInfo.varName}?.Success) {
726
+ const data = ${resultInfo.varName}.Results;
727
+ } else {
728
+ // Handle error: ${resultInfo.varName}.ErrorMessage
729
+ }`,
730
+ code: `if (${test.name})`,
731
+ });
732
+ }
733
+ }
734
+ // Pattern: if (result?.length)
735
+ if (t.isOptionalMemberExpression(test) &&
736
+ t.isIdentifier(test.object) &&
737
+ t.isIdentifier(test.property) &&
738
+ test.property.name === 'length' &&
739
+ resultVariables.has(test.object.name)) {
740
+ const resultInfo = resultVariables.get(test.object.name);
741
+ violations.push({
742
+ rule: RULE_NAME,
743
+ severity: 'critical',
744
+ line: test.loc?.start.line || 0,
745
+ column: test.loc?.start.column || 0,
746
+ message: `Incorrect check: "${test.object.name}?.length" on ${resultInfo.method} result.
747
+ Correct pattern:
748
+ if (${resultInfo.varName}?.Success && ${resultInfo.varName}?.Results?.length > 0) {
749
+ const processedData = processChartData(${resultInfo.varName}.Results);
750
+ }`,
751
+ code: `if (${test.object.name}?.length)`,
752
+ });
753
+ }
754
+ },
755
+ });
756
+ return violations;
757
+ }
758
+ };
759
+ DataResultValidationRule = __decorate([
760
+ RegisterClass(BaseLintRule, 'data-result-validation')
761
+ ], DataResultValidationRule);
762
+ export { DataResultValidationRule };
763
+ //# sourceMappingURL=data-result-validation.js.map