@aicqtools/guardrail 1.0.0-alpha.10

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 (297) hide show
  1. package/LICENSE +21 -0
  2. package/dist/docs/build.d.ts +12 -0
  3. package/dist/docs/build.d.ts.map +1 -0
  4. package/dist/docs/build.js +23 -0
  5. package/dist/docs/build.js.map +1 -0
  6. package/dist/docs/index.d.ts +4 -0
  7. package/dist/docs/index.d.ts.map +1 -0
  8. package/dist/docs/index.js +3 -0
  9. package/dist/docs/index.js.map +1 -0
  10. package/dist/docs/render-rule-md.d.ts +4 -0
  11. package/dist/docs/render-rule-md.d.ts.map +1 -0
  12. package/dist/docs/render-rule-md.js +117 -0
  13. package/dist/docs/render-rule-md.js.map +1 -0
  14. package/dist/index.d.ts +14 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +8 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/matcher/index.d.ts +4 -0
  19. package/dist/matcher/index.d.ts.map +1 -0
  20. package/dist/matcher/index.js +3 -0
  21. package/dist/matcher/index.js.map +1 -0
  22. package/dist/matcher/traverse.d.ts +3 -0
  23. package/dist/matcher/traverse.d.ts.map +1 -0
  24. package/dist/matcher/traverse.js +9 -0
  25. package/dist/matcher/traverse.js.map +1 -0
  26. package/dist/matcher/yaml-rule.d.ts +34 -0
  27. package/dist/matcher/yaml-rule.d.ts.map +1 -0
  28. package/dist/matcher/yaml-rule.js +32 -0
  29. package/dist/matcher/yaml-rule.js.map +1 -0
  30. package/dist/mcp/handlers.d.ts +36 -0
  31. package/dist/mcp/handlers.d.ts.map +1 -0
  32. package/dist/mcp/handlers.js +32 -0
  33. package/dist/mcp/handlers.js.map +1 -0
  34. package/dist/mcp/index.d.ts +6 -0
  35. package/dist/mcp/index.d.ts.map +1 -0
  36. package/dist/mcp/index.js +4 -0
  37. package/dist/mcp/index.js.map +1 -0
  38. package/dist/mcp/server.d.ts +9 -0
  39. package/dist/mcp/server.d.ts.map +1 -0
  40. package/dist/mcp/server.js +53 -0
  41. package/dist/mcp/server.js.map +1 -0
  42. package/dist/mcp/stdio.d.ts +3 -0
  43. package/dist/mcp/stdio.d.ts.map +1 -0
  44. package/dist/mcp/stdio.js +8 -0
  45. package/dist/mcp/stdio.js.map +1 -0
  46. package/dist/rules-default/ai-explainability-metadata.d.ts +3 -0
  47. package/dist/rules-default/ai-explainability-metadata.d.ts.map +1 -0
  48. package/dist/rules-default/ai-explainability-metadata.js +41 -0
  49. package/dist/rules-default/ai-explainability-metadata.js.map +1 -0
  50. package/dist/rules-default/api-response-shape.d.ts +3 -0
  51. package/dist/rules-default/api-response-shape.d.ts.map +1 -0
  52. package/dist/rules-default/api-response-shape.js +52 -0
  53. package/dist/rules-default/api-response-shape.js.map +1 -0
  54. package/dist/rules-default/async-await-consistency.d.ts +3 -0
  55. package/dist/rules-default/async-await-consistency.d.ts.map +1 -0
  56. package/dist/rules-default/async-await-consistency.js +38 -0
  57. package/dist/rules-default/async-await-consistency.js.map +1 -0
  58. package/dist/rules-default/audit-log-ai-decision.d.ts +3 -0
  59. package/dist/rules-default/audit-log-ai-decision.d.ts.map +1 -0
  60. package/dist/rules-default/audit-log-ai-decision.js +33 -0
  61. package/dist/rules-default/audit-log-ai-decision.js.map +1 -0
  62. package/dist/rules-default/camelcase-migration-column.d.ts +3 -0
  63. package/dist/rules-default/camelcase-migration-column.d.ts.map +1 -0
  64. package/dist/rules-default/camelcase-migration-column.js +56 -0
  65. package/dist/rules-default/camelcase-migration-column.js.map +1 -0
  66. package/dist/rules-default/controller-needs-async-wrapper.d.ts +3 -0
  67. package/dist/rules-default/controller-needs-async-wrapper.d.ts.map +1 -0
  68. package/dist/rules-default/controller-needs-async-wrapper.js +56 -0
  69. package/dist/rules-default/controller-needs-async-wrapper.js.map +1 -0
  70. package/dist/rules-default/enforce-utf8-encoding.d.ts +10 -0
  71. package/dist/rules-default/enforce-utf8-encoding.d.ts.map +1 -0
  72. package/dist/rules-default/enforce-utf8-encoding.js +28 -0
  73. package/dist/rules-default/enforce-utf8-encoding.js.map +1 -0
  74. package/dist/rules-default/explicit-kst-timezone.d.ts +3 -0
  75. package/dist/rules-default/explicit-kst-timezone.d.ts.map +1 -0
  76. package/dist/rules-default/explicit-kst-timezone.js +49 -0
  77. package/dist/rules-default/explicit-kst-timezone.js.map +1 -0
  78. package/dist/rules-default/fk-needs-on-delete.d.ts +3 -0
  79. package/dist/rules-default/fk-needs-on-delete.d.ts.map +1 -0
  80. package/dist/rules-default/fk-needs-on-delete.js +54 -0
  81. package/dist/rules-default/fk-needs-on-delete.js.map +1 -0
  82. package/dist/rules-default/human-oversight-checkpoint.d.ts +3 -0
  83. package/dist/rules-default/human-oversight-checkpoint.d.ts.map +1 -0
  84. package/dist/rules-default/human-oversight-checkpoint.js +37 -0
  85. package/dist/rules-default/human-oversight-checkpoint.js.map +1 -0
  86. package/dist/rules-default/index.d.ts +6 -0
  87. package/dist/rules-default/index.d.ts.map +1 -0
  88. package/dist/rules-default/index.js +138 -0
  89. package/dist/rules-default/index.js.map +1 -0
  90. package/dist/rules-default/korean-comment-encoding.d.ts +3 -0
  91. package/dist/rules-default/korean-comment-encoding.d.ts.map +1 -0
  92. package/dist/rules-default/korean-comment-encoding.js +28 -0
  93. package/dist/rules-default/korean-comment-encoding.js.map +1 -0
  94. package/dist/rules-default/mask-card-number.d.ts +3 -0
  95. package/dist/rules-default/mask-card-number.d.ts.map +1 -0
  96. package/dist/rules-default/mask-card-number.js +45 -0
  97. package/dist/rules-default/mask-card-number.js.map +1 -0
  98. package/dist/rules-default/mask-pii-in-ai-prompt.d.ts +3 -0
  99. package/dist/rules-default/mask-pii-in-ai-prompt.d.ts.map +1 -0
  100. package/dist/rules-default/mask-pii-in-ai-prompt.js +41 -0
  101. package/dist/rules-default/mask-pii-in-ai-prompt.js.map +1 -0
  102. package/dist/rules-default/naver-kakao-oauth-webview.d.ts +3 -0
  103. package/dist/rules-default/naver-kakao-oauth-webview.d.ts.map +1 -0
  104. package/dist/rules-default/naver-kakao-oauth-webview.js +40 -0
  105. package/dist/rules-default/naver-kakao-oauth-webview.js.map +1 -0
  106. package/dist/rules-default/no-bare-except.d.ts +7 -0
  107. package/dist/rules-default/no-bare-except.d.ts.map +1 -0
  108. package/dist/rules-default/no-bare-except.js +23 -0
  109. package/dist/rules-default/no-bare-except.js.map +1 -0
  110. package/dist/rules-default/no-bare-throw.d.ts +7 -0
  111. package/dist/rules-default/no-bare-throw.d.ts.map +1 -0
  112. package/dist/rules-default/no-bare-throw.js +32 -0
  113. package/dist/rules-default/no-bare-throw.js.map +1 -0
  114. package/dist/rules-default/no-boolean-trap.d.ts +8 -0
  115. package/dist/rules-default/no-boolean-trap.d.ts.map +1 -0
  116. package/dist/rules-default/no-boolean-trap.js +33 -0
  117. package/dist/rules-default/no-boolean-trap.js.map +1 -0
  118. package/dist/rules-default/no-console-log.d.ts +3 -0
  119. package/dist/rules-default/no-console-log.d.ts.map +1 -0
  120. package/dist/rules-default/no-console-log.js +27 -0
  121. package/dist/rules-default/no-console-log.js.map +1 -0
  122. package/dist/rules-default/no-cvv-logging.d.ts +3 -0
  123. package/dist/rules-default/no-cvv-logging.d.ts.map +1 -0
  124. package/dist/rules-default/no-cvv-logging.js +36 -0
  125. package/dist/rules-default/no-cvv-logging.js.map +1 -0
  126. package/dist/rules-default/no-default-export-from-libs.d.ts +7 -0
  127. package/dist/rules-default/no-default-export-from-libs.d.ts.map +1 -0
  128. package/dist/rules-default/no-default-export-from-libs.js +24 -0
  129. package/dist/rules-default/no-default-export-from-libs.js.map +1 -0
  130. package/dist/rules-default/no-direct-anthropic.yaml +15 -0
  131. package/dist/rules-default/no-direct-openai.yaml +17 -0
  132. package/dist/rules-default/no-empty-catch.d.ts +3 -0
  133. package/dist/rules-default/no-empty-catch.d.ts.map +1 -0
  134. package/dist/rules-default/no-empty-catch.js +37 -0
  135. package/dist/rules-default/no-empty-catch.js.map +1 -0
  136. package/dist/rules-default/no-fstring-sql.d.ts +3 -0
  137. package/dist/rules-default/no-fstring-sql.d.ts.map +1 -0
  138. package/dist/rules-default/no-fstring-sql.js +24 -0
  139. package/dist/rules-default/no-fstring-sql.js.map +1 -0
  140. package/dist/rules-default/no-id-overwrite.d.ts +8 -0
  141. package/dist/rules-default/no-id-overwrite.d.ts.map +1 -0
  142. package/dist/rules-default/no-id-overwrite.js +27 -0
  143. package/dist/rules-default/no-id-overwrite.js.map +1 -0
  144. package/dist/rules-default/no-inline-date.yaml +9 -0
  145. package/dist/rules-default/no-inline-math-round.yaml +12 -0
  146. package/dist/rules-default/no-jsonb-circular.d.ts +3 -0
  147. package/dist/rules-default/no-jsonb-circular.d.ts.map +1 -0
  148. package/dist/rules-default/no-jsonb-circular.js +33 -0
  149. package/dist/rules-default/no-jsonb-circular.js.map +1 -0
  150. package/dist/rules-default/no-magic-number.d.ts +3 -0
  151. package/dist/rules-default/no-magic-number.d.ts.map +1 -0
  152. package/dist/rules-default/no-magic-number.js +145 -0
  153. package/dist/rules-default/no-magic-number.js.map +1 -0
  154. package/dist/rules-default/no-mutable-default-arg.d.ts +3 -0
  155. package/dist/rules-default/no-mutable-default-arg.d.ts.map +1 -0
  156. package/dist/rules-default/no-mutable-default-arg.js +30 -0
  157. package/dist/rules-default/no-mutable-default-arg.js.map +1 -0
  158. package/dist/rules-default/no-pickle.yaml +12 -0
  159. package/dist/rules-default/no-plain-card-number.d.ts +3 -0
  160. package/dist/rules-default/no-plain-card-number.d.ts.map +1 -0
  161. package/dist/rules-default/no-plain-card-number.js +51 -0
  162. package/dist/rules-default/no-plain-card-number.js.map +1 -0
  163. package/dist/rules-default/no-print-in-prod.yaml +9 -0
  164. package/dist/rules-default/no-process-env-leak.d.ts +7 -0
  165. package/dist/rules-default/no-process-env-leak.d.ts.map +1 -0
  166. package/dist/rules-default/no-process-env-leak.js +37 -0
  167. package/dist/rules-default/no-process-env-leak.js.map +1 -0
  168. package/dist/rules-default/no-shell-true.d.ts +3 -0
  169. package/dist/rules-default/no-shell-true.d.ts.map +1 -0
  170. package/dist/rules-default/no-shell-true.js +42 -0
  171. package/dist/rules-default/no-shell-true.js.map +1 -0
  172. package/dist/rules-default/prefer-const-array.d.ts +9 -0
  173. package/dist/rules-default/prefer-const-array.d.ts.map +1 -0
  174. package/dist/rules-default/prefer-const-array.js +34 -0
  175. package/dist/rules-default/prefer-const-array.js.map +1 -0
  176. package/dist/rules-default/prefer-named-imports.d.ts +8 -0
  177. package/dist/rules-default/prefer-named-imports.d.ts.map +1 -0
  178. package/dist/rules-default/prefer-named-imports.js +25 -0
  179. package/dist/rules-default/prefer-named-imports.js.map +1 -0
  180. package/dist/rules-default/preserve-transaction-log.d.ts +3 -0
  181. package/dist/rules-default/preserve-transaction-log.d.ts.map +1 -0
  182. package/dist/rules-default/preserve-transaction-log.js +33 -0
  183. package/dist/rules-default/preserve-transaction-log.js.map +1 -0
  184. package/dist/rules-default/pytest-fixture-naming.d.ts +3 -0
  185. package/dist/rules-default/pytest-fixture-naming.d.ts.map +1 -0
  186. package/dist/rules-default/pytest-fixture-naming.js +36 -0
  187. package/dist/rules-default/pytest-fixture-naming.js.map +1 -0
  188. package/dist/rules-default/requests-needs-timeout.d.ts +3 -0
  189. package/dist/rules-default/requests-needs-timeout.d.ts.map +1 -0
  190. package/dist/rules-default/requests-needs-timeout.js +43 -0
  191. package/dist/rules-default/requests-needs-timeout.js.map +1 -0
  192. package/dist/rules-default/require-idempotency-key.d.ts +3 -0
  193. package/dist/rules-default/require-idempotency-key.d.ts.map +1 -0
  194. package/dist/rules-default/require-idempotency-key.js +47 -0
  195. package/dist/rules-default/require-idempotency-key.js.map +1 -0
  196. package/dist/rules-default/require-tls-1-2-plus.d.ts +3 -0
  197. package/dist/rules-default/require-tls-1-2-plus.d.ts.map +1 -0
  198. package/dist/rules-default/require-tls-1-2-plus.js +30 -0
  199. package/dist/rules-default/require-tls-1-2-plus.js.map +1 -0
  200. package/dist/rules-default/rfc5987-korean-filename.d.ts +3 -0
  201. package/dist/rules-default/rfc5987-korean-filename.d.ts.map +1 -0
  202. package/dist/rules-default/rfc5987-korean-filename.js +32 -0
  203. package/dist/rules-default/rfc5987-korean-filename.js.map +1 -0
  204. package/dist/rules-default/route-needs-auth.d.ts +3 -0
  205. package/dist/rules-default/route-needs-auth.d.ts.map +1 -0
  206. package/dist/rules-default/route-needs-auth.js +48 -0
  207. package/dist/rules-default/route-needs-auth.js.map +1 -0
  208. package/dist/rules-default/route-needs-rate-limit.d.ts +3 -0
  209. package/dist/rules-default/route-needs-rate-limit.d.ts.map +1 -0
  210. package/dist/rules-default/route-needs-rate-limit.js +47 -0
  211. package/dist/rules-default/route-needs-rate-limit.js.map +1 -0
  212. package/dist/rules-default/separate-refund-permission.d.ts +3 -0
  213. package/dist/rules-default/separate-refund-permission.d.ts.map +1 -0
  214. package/dist/rules-default/separate-refund-permission.js +33 -0
  215. package/dist/rules-default/separate-refund-permission.js.map +1 -0
  216. package/dist/rules-default/track-ai-model-version.d.ts +3 -0
  217. package/dist/rules-default/track-ai-model-version.d.ts.map +1 -0
  218. package/dist/rules-default/track-ai-model-version.js +37 -0
  219. package/dist/rules-default/track-ai-model-version.js.map +1 -0
  220. package/dist/rules-default/type-hint-required-public.d.ts +10 -0
  221. package/dist/rules-default/type-hint-required-public.d.ts.map +1 -0
  222. package/dist/rules-default/type-hint-required-public.js +29 -0
  223. package/dist/rules-default/type-hint-required-public.js.map +1 -0
  224. package/dist/rules-default/verify-pg-response.d.ts +3 -0
  225. package/dist/rules-default/verify-pg-response.d.ts.map +1 -0
  226. package/dist/rules-default/verify-pg-response.js +37 -0
  227. package/dist/rules-default/verify-pg-response.js.map +1 -0
  228. package/dist/rules-default/won-format-thousands.d.ts +3 -0
  229. package/dist/rules-default/won-format-thousands.d.ts.map +1 -0
  230. package/dist/rules-default/won-format-thousands.js +24 -0
  231. package/dist/rules-default/won-format-thousands.js.map +1 -0
  232. package/dist/runner/apply-rule-config.d.ts +69 -0
  233. package/dist/runner/apply-rule-config.d.ts.map +1 -0
  234. package/dist/runner/apply-rule-config.js +164 -0
  235. package/dist/runner/apply-rule-config.js.map +1 -0
  236. package/dist/runner/context.d.ts +12 -0
  237. package/dist/runner/context.d.ts.map +1 -0
  238. package/dist/runner/context.js +34 -0
  239. package/dist/runner/context.js.map +1 -0
  240. package/dist/runner/index.d.ts +9 -0
  241. package/dist/runner/index.d.ts.map +1 -0
  242. package/dist/runner/index.js +6 -0
  243. package/dist/runner/index.js.map +1 -0
  244. package/dist/runner/ruleset-signature.d.ts +4 -0
  245. package/dist/runner/ruleset-signature.d.ts.map +1 -0
  246. package/dist/runner/ruleset-signature.js +11 -0
  247. package/dist/runner/ruleset-signature.js.map +1 -0
  248. package/dist/runner/run-file.d.ts +10 -0
  249. package/dist/runner/run-file.d.ts.map +1 -0
  250. package/dist/runner/run-file.js +48 -0
  251. package/dist/runner/run-file.js.map +1 -0
  252. package/dist/runner/run-project.d.ts +30 -0
  253. package/dist/runner/run-project.d.ts.map +1 -0
  254. package/dist/runner/run-project.js +118 -0
  255. package/dist/runner/run-project.js.map +1 -0
  256. package/dist/runner/run-rule.d.ts +5 -0
  257. package/dist/runner/run-rule.d.ts.map +1 -0
  258. package/dist/runner/run-rule.js +53 -0
  259. package/dist/runner/run-rule.js.map +1 -0
  260. package/dist/runner/suppressions.d.ts +37 -0
  261. package/dist/runner/suppressions.d.ts.map +1 -0
  262. package/dist/runner/suppressions.js +127 -0
  263. package/dist/runner/suppressions.js.map +1 -0
  264. package/dist/suggest/analyze.d.ts +10 -0
  265. package/dist/suggest/analyze.d.ts.map +1 -0
  266. package/dist/suggest/analyze.js +193 -0
  267. package/dist/suggest/analyze.js.map +1 -0
  268. package/dist/suggest/format.d.ts +13 -0
  269. package/dist/suggest/format.d.ts.map +1 -0
  270. package/dist/suggest/format.js +120 -0
  271. package/dist/suggest/format.js.map +1 -0
  272. package/dist/suggest/index.d.ts +5 -0
  273. package/dist/suggest/index.d.ts.map +1 -0
  274. package/dist/suggest/index.js +4 -0
  275. package/dist/suggest/index.js.map +1 -0
  276. package/dist/suggest/mine.d.ts +11 -0
  277. package/dist/suggest/mine.d.ts.map +1 -0
  278. package/dist/suggest/mine.js +207 -0
  279. package/dist/suggest/mine.js.map +1 -0
  280. package/dist/suggest/types.d.ts +74 -0
  281. package/dist/suggest/types.d.ts.map +1 -0
  282. package/dist/suggest/types.js +2 -0
  283. package/dist/suggest/types.js.map +1 -0
  284. package/dist/sync/index.d.ts +5 -0
  285. package/dist/sync/index.d.ts.map +1 -0
  286. package/dist/sync/index.js +3 -0
  287. package/dist/sync/index.js.map +1 -0
  288. package/dist/sync/render.d.ts +9 -0
  289. package/dist/sync/render.d.ts.map +1 -0
  290. package/dist/sync/render.js +70 -0
  291. package/dist/sync/render.js.map +1 -0
  292. package/dist/sync/sync-files.d.ts +12 -0
  293. package/dist/sync/sync-files.d.ts.map +1 -0
  294. package/dist/sync/sync-files.js +29 -0
  295. package/dist/sync/sync-files.js.map +1 -0
  296. package/package.json +71 -0
  297. package/scripts/copy-yaml-rules.mjs +19 -0
@@ -0,0 +1,3 @@
1
+ declare const _default: import("@aicqtools/rule-sdk").FunctionRule;
2
+ export default _default;
3
+ //# sourceMappingURL=no-shell-true.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-shell-true.d.ts","sourceRoot":"","sources":["../../src/rules-default/no-shell-true.ts"],"names":[],"mappings":";AAgBA,wBAoBG"}
@@ -0,0 +1,42 @@
1
+ import { defineRule } from '@aicqtools/rule-sdk';
2
+ const SUBPROCESS_FNS = new Set(['run', 'call', 'check_call', 'check_output', 'Popen']);
3
+ function hasShellTrue(args, textOf) {
4
+ for (let i = 0; i < args.namedChildCount; i++) {
5
+ const arg = args.namedChild(i);
6
+ if (!arg || arg.type !== 'keyword_argument')
7
+ continue;
8
+ const name = arg.childForFieldName('name');
9
+ const value = arg.childForFieldName('value');
10
+ if (name && value && textOf(name) === 'shell' && textOf(value) === 'True')
11
+ return true;
12
+ }
13
+ return false;
14
+ }
15
+ export default defineRule({
16
+ id: 'no-shell-true',
17
+ language: 'python',
18
+ severity: 'error',
19
+ message: 'subprocess with shell=True is a command injection vector — pass a list of args instead.',
20
+ messageKo: 'subprocess의 shell=True는 명령어 주입 위험 — 인자를 리스트로 전달하세요.',
21
+ visitors: {
22
+ call(node, ctx) {
23
+ const fn = node.childForFieldName('function');
24
+ if (!fn || fn.type !== 'attribute')
25
+ return;
26
+ const obj = fn.childForFieldName('object');
27
+ const attr = fn.childForFieldName('attribute');
28
+ if (!obj || !attr)
29
+ return;
30
+ if (ctx.textOf(obj) !== 'subprocess')
31
+ return;
32
+ if (!SUBPROCESS_FNS.has(ctx.textOf(attr)))
33
+ return;
34
+ const args = node.childForFieldName('arguments');
35
+ if (!args)
36
+ return;
37
+ if (hasShellTrue(args, ctx.textOf))
38
+ ctx.report({ node });
39
+ },
40
+ },
41
+ });
42
+ //# sourceMappingURL=no-shell-true.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-shell-true.js","sourceRoot":"","sources":["../../src/rules-default/no-shell-true.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,cAAc,EAAE,OAAO,CAAC,CAAC,CAAC;AAEvF,SAAS,YAAY,CAAC,IAAuB,EAAE,MAAwC;IACrF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9C,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QAC/B,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,KAAK,kBAAkB;YAAE,SAAS;QACtD,MAAM,IAAI,GAAG,GAAG,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAC3C,MAAM,KAAK,GAAG,GAAG,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAC7C,IAAI,IAAI,IAAI,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,OAAO,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,MAAM;YAAE,OAAO,IAAI,CAAC;IACzF,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,eAAe,UAAU,CAAC;IACxB,EAAE,EAAE,eAAe;IACnB,QAAQ,EAAE,QAAQ;IAClB,QAAQ,EAAE,OAAO;IACjB,OAAO,EAAE,yFAAyF;IAClG,SAAS,EAAE,qDAAqD;IAChE,QAAQ,EAAE;QACR,IAAI,CAAC,IAAI,EAAE,GAAG;YACZ,MAAM,EAAE,GAAG,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;YAC9C,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,IAAI,KAAK,WAAW;gBAAE,OAAO;YAC3C,MAAM,GAAG,GAAG,EAAE,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;YAC3C,MAAM,IAAI,GAAG,EAAE,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;YAC/C,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI;gBAAE,OAAO;YAC1B,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,YAAY;gBAAE,OAAO;YAC7C,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBAAE,OAAO;YAClD,MAAM,IAAI,GAAG,IAAI,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;YACjD,IAAI,CAAC,IAAI;gBAAE,OAAO;YAClB,IAAI,YAAY,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC;gBAAE,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3D,CAAC;KACF;CACF,CAAC,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * If a `let` declares an array literal (`let xs = []` or `let xs: T[] = []`)
3
+ * and is initialized once, prefer `const`. This is a heuristic — false positives
4
+ * exist when the variable is reassigned (not just mutated) later. Limited scope:
5
+ * only flags top-level `let xs = [...]` in functions.
6
+ */
7
+ declare const _default: import("@aicqtools/rule-sdk").FunctionRule;
8
+ export default _default;
9
+ //# sourceMappingURL=prefer-const-array.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prefer-const-array.d.ts","sourceRoot":"","sources":["../../src/rules-default/prefer-const-array.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;;AACH,wBAqBG"}
@@ -0,0 +1,34 @@
1
+ import { defineRule } from '@aicqtools/rule-sdk';
2
+ /**
3
+ * If a `let` declares an array literal (`let xs = []` or `let xs: T[] = []`)
4
+ * and is initialized once, prefer `const`. This is a heuristic — false positives
5
+ * exist when the variable is reassigned (not just mutated) later. Limited scope:
6
+ * only flags top-level `let xs = [...]` in functions.
7
+ */
8
+ export default defineRule({
9
+ id: 'prefer-const-array',
10
+ language: ['typescript', 'javascript', 'tsx'],
11
+ severity: 'info',
12
+ message: 'Use `const` for array variables that are not reassigned (mutation via push/splice is allowed).',
13
+ messageKo: '재할당하지 않는 배열은 `const`를 사용하세요 (push/splice 같은 mutation은 const에서도 가능).',
14
+ visitors: {
15
+ lexical_declaration(node, ctx) {
16
+ const text = ctx.textOf(node);
17
+ if (!text.startsWith('let '))
18
+ return;
19
+ // Look for `= [` initialization
20
+ let initIsArray = false;
21
+ for (let i = 0; i < node.namedChildCount; i++) {
22
+ const decl = node.namedChild(i);
23
+ if (!decl || decl.type !== 'variable_declarator')
24
+ continue;
25
+ const value = decl.childForFieldName('value');
26
+ if (value && value.type === 'array')
27
+ initIsArray = true;
28
+ }
29
+ if (initIsArray)
30
+ ctx.report({ node });
31
+ },
32
+ },
33
+ });
34
+ //# sourceMappingURL=prefer-const-array.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prefer-const-array.js","sourceRoot":"","sources":["../../src/rules-default/prefer-const-array.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD;;;;;GAKG;AACH,eAAe,UAAU,CAAC;IACxB,EAAE,EAAE,oBAAoB;IACxB,QAAQ,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,KAAK,CAAC;IAC7C,QAAQ,EAAE,MAAM;IAChB,OAAO,EAAE,gGAAgG;IACzG,SAAS,EAAE,qEAAqE;IAChF,QAAQ,EAAE;QACR,mBAAmB,CAAC,IAAI,EAAE,GAAG;YAC3B,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC9B,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;gBAAE,OAAO;YACrC,gCAAgC;YAChC,IAAI,WAAW,GAAG,KAAK,CAAC;YACxB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;gBAChC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,qBAAqB;oBAAE,SAAS;gBAC3D,MAAM,KAAK,GAAG,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;gBAC9C,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO;oBAAE,WAAW,GAAG,IAAI,CAAC;YAC1D,CAAC;YACD,IAAI,WAAW;gBAAE,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;QACxC,CAAC;KACF;CACF,CAAC,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * `import * as X from 'module'` namespace imports prevent tree-shaking and
3
+ * obscure dependency analysis. Prefer named imports unless the module
4
+ * genuinely exports many disparate symbols (rare).
5
+ */
6
+ declare const _default: import("@aicqtools/rule-sdk").FunctionRule;
7
+ export default _default;
8
+ //# sourceMappingURL=prefer-named-imports.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prefer-named-imports.d.ts","sourceRoot":"","sources":["../../src/rules-default/prefer-named-imports.ts"],"names":[],"mappings":"AAEA;;;;GAIG;;AACH,wBAgBG"}
@@ -0,0 +1,25 @@
1
+ import { defineRule } from '@aicqtools/rule-sdk';
2
+ /**
3
+ * `import * as X from 'module'` namespace imports prevent tree-shaking and
4
+ * obscure dependency analysis. Prefer named imports unless the module
5
+ * genuinely exports many disparate symbols (rare).
6
+ */
7
+ export default defineRule({
8
+ id: 'prefer-named-imports',
9
+ language: ['typescript', 'javascript', 'tsx'],
10
+ severity: 'info',
11
+ message: 'Avoid `import * as X` namespace imports; use named imports for tree-shaking.',
12
+ messageKo: '`import * as X` 네임스페이스 import 지양 — tree-shaking을 위해 named import 권장.',
13
+ visitors: {
14
+ import_statement(node, ctx) {
15
+ const text = ctx.textOf(node);
16
+ if (/import\s+\*\s+as\s+\w+/.test(text)) {
17
+ // Allow type-only namespace imports (less impact on bundle)
18
+ if (/import\s+type\s+\*/.test(text))
19
+ return;
20
+ ctx.report({ node });
21
+ }
22
+ },
23
+ },
24
+ });
25
+ //# sourceMappingURL=prefer-named-imports.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prefer-named-imports.js","sourceRoot":"","sources":["../../src/rules-default/prefer-named-imports.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD;;;;GAIG;AACH,eAAe,UAAU,CAAC;IACxB,EAAE,EAAE,sBAAsB;IAC1B,QAAQ,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,KAAK,CAAC;IAC7C,QAAQ,EAAE,MAAM;IAChB,OAAO,EAAE,8EAA8E;IACvF,SAAS,EAAE,sEAAsE;IACjF,QAAQ,EAAE;QACR,gBAAgB,CAAC,IAAI,EAAE,GAAG;YACxB,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC9B,IAAI,wBAAwB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBACxC,4DAA4D;gBAC5D,IAAI,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC;oBAAE,OAAO;gBAC5C,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;YACvB,CAAC;QACH,CAAC;KACF;CACF,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ declare const _default: import("@aicqtools/rule-sdk").FunctionRule;
2
+ export default _default;
3
+ //# sourceMappingURL=preserve-transaction-log.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preserve-transaction-log.d.ts","sourceRoot":"","sources":["../../src/rules-default/preserve-transaction-log.ts"],"names":[],"mappings":";AAsBA,wBAWG"}
@@ -0,0 +1,33 @@
1
+ import { defineRule } from '@aicqtools/rule-sdk';
2
+ /**
3
+ * PCI DSS § 10: financial transactions must produce an audit trail.
4
+ * Detect functions named pay/charge/payment/refund that lack any logging
5
+ * or transaction-table write call in their body.
6
+ */
7
+ const TX_NAME = /^(pay|charge|payment|refund|cancelRefund|issueRefund|pay\w*|charge\w*|payment\w*|refund\w*)$/;
8
+ const LOG_OR_AUDIT = /\b(logger|auditLog|audit|winston|pino)\.\w+|\bconsole\.(log|info|warn|error)|\b(transactions|payment_log|paymentLogs|auditLogs|tx_log)\b.*\.(insert|create|save|push)/;
9
+ function check(node, ctx) {
10
+ const name = node.childForFieldName('name');
11
+ if (!name)
12
+ return;
13
+ const fnName = ctx.textOf(name);
14
+ if (!TX_NAME.test(fnName))
15
+ return;
16
+ const text = ctx.textOf(node);
17
+ if (LOG_OR_AUDIT.test(text))
18
+ return;
19
+ ctx.report({ node });
20
+ }
21
+ export default defineRule({
22
+ id: 'preserve-transaction-log',
23
+ language: ['typescript', 'tsx'],
24
+ severity: 'error',
25
+ message: 'Payment/refund function does not produce an audit log entry (PCI DSS § 10.2 — implement audit logs for all access to cardholder data).',
26
+ messageKo: '결제/환불 함수에 감사 로그 기록이 없습니다 (PCI DSS § 10.2 — 카드 소지자 데이터 접근에 대한 감사 로그 필수).',
27
+ docs: 'https://github.com/aicqtools/aicqtools/blob/main/docs/rules/preserve-transaction-log.md',
28
+ visitors: {
29
+ function_declaration: check,
30
+ method_definition: check,
31
+ },
32
+ });
33
+ //# sourceMappingURL=preserve-transaction-log.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preserve-transaction-log.js","sourceRoot":"","sources":["../../src/rules-default/preserve-transaction-log.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGjD;;;;GAIG;AACH,MAAM,OAAO,GAAG,8FAA8F,CAAC;AAC/G,MAAM,YAAY,GAAG,uKAAuK,CAAC;AAE7L,SAAS,KAAK,CAAC,IAAuB,EAAE,GAAgB;IACtD,MAAM,IAAI,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC5C,IAAI,CAAC,IAAI;QAAE,OAAO;IAClB,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;QAAE,OAAO;IAClC,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC9B,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO;IACpC,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;AACvB,CAAC;AAED,eAAe,UAAU,CAAC;IACxB,EAAE,EAAE,0BAA0B;IAC9B,QAAQ,EAAE,CAAC,YAAY,EAAE,KAAK,CAAC;IAC/B,QAAQ,EAAE,OAAO;IACjB,OAAO,EAAE,wIAAwI;IACjJ,SAAS,EAAE,yEAAyE;IACpF,IAAI,EAAE,yFAAyF;IAC/F,QAAQ,EAAE;QACR,oBAAoB,EAAE,KAAK;QAC3B,iBAAiB,EAAE,KAAK;KACzB;CACF,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ declare const _default: import("@aicqtools/rule-sdk").FunctionRule;
2
+ export default _default;
3
+ //# sourceMappingURL=pytest-fixture-naming.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pytest-fixture-naming.d.ts","sourceRoot":"","sources":["../../src/rules-default/pytest-fixture-naming.ts"],"names":[],"mappings":";AAgBA,wBAeG"}
@@ -0,0 +1,36 @@
1
+ import { defineRule } from '@aicqtools/rule-sdk';
2
+ function hasPytestFixtureDecorator(node, textOf) {
3
+ // function_definition's parent is decorated_definition when decorated
4
+ const parent = node.parent;
5
+ if (!parent || parent.type !== 'decorated_definition')
6
+ return false;
7
+ for (let i = 0; i < parent.namedChildCount; i++) {
8
+ const child = parent.namedChild(i);
9
+ if (!child || child.type !== 'decorator')
10
+ continue;
11
+ const text = textOf(child);
12
+ if (/@pytest\.fixture\b/.test(text) || /^@fixture\b/.test(text))
13
+ return true;
14
+ }
15
+ return false;
16
+ }
17
+ export default defineRule({
18
+ id: 'pytest-fixture-naming',
19
+ language: 'python',
20
+ severity: 'warning',
21
+ message: 'pytest fixture should not start with `test_` (it would be collected as a test instead).',
22
+ messageKo: 'pytest fixture 함수는 `test_`로 시작하면 안 됩니다 (테스트로 인식되어 버립니다).',
23
+ visitors: {
24
+ function_definition(node, ctx) {
25
+ const name = node.childForFieldName('name');
26
+ if (!name)
27
+ return;
28
+ const nameText = ctx.textOf(name);
29
+ if (!nameText.startsWith('test_'))
30
+ return;
31
+ if (hasPytestFixtureDecorator(node, ctx.textOf))
32
+ ctx.report({ node: name });
33
+ },
34
+ },
35
+ });
36
+ //# sourceMappingURL=pytest-fixture-naming.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pytest-fixture-naming.js","sourceRoot":"","sources":["../../src/rules-default/pytest-fixture-naming.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,SAAS,yBAAyB,CAAC,IAAuB,EAAE,MAAwC;IAClG,sEAAsE;IACtE,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IAC3B,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,KAAK,sBAAsB;QAAE,OAAO,KAAK,CAAC;IACpE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,eAAe,EAAE,CAAC,EAAE,EAAE,CAAC;QAChD,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QACnC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW;YAAE,SAAS;QACnD,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC3B,IAAI,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;IAC/E,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,eAAe,UAAU,CAAC;IACxB,EAAE,EAAE,uBAAuB;IAC3B,QAAQ,EAAE,QAAQ;IAClB,QAAQ,EAAE,SAAS;IACnB,OAAO,EAAE,yFAAyF;IAClG,SAAS,EAAE,0DAA0D;IACrE,QAAQ,EAAE;QACR,mBAAmB,CAAC,IAAI,EAAE,GAAG;YAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;YAC5C,IAAI,CAAC,IAAI;gBAAE,OAAO;YAClB,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAClC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC;gBAAE,OAAO;YAC1C,IAAI,yBAAyB,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC;gBAAE,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9E,CAAC;KACF;CACF,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ declare const _default: import("@aicqtools/rule-sdk").FunctionRule;
2
+ export default _default;
3
+ //# sourceMappingURL=requests-needs-timeout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requests-needs-timeout.d.ts","sourceRoot":"","sources":["../../src/rules-default/requests-needs-timeout.ts"],"names":[],"mappings":";AAiBA,wBAoBG"}
@@ -0,0 +1,43 @@
1
+ import { defineRule } from '@aicqtools/rule-sdk';
2
+ const REQUESTS_METHODS = new Set(['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'request']);
3
+ function hasTimeoutKwarg(args, textOf) {
4
+ for (let i = 0; i < args.namedChildCount; i++) {
5
+ const arg = args.namedChild(i);
6
+ if (!arg)
7
+ continue;
8
+ if (arg.type === 'keyword_argument') {
9
+ const name = arg.childForFieldName('name');
10
+ if (name && textOf(name) === 'timeout')
11
+ return true;
12
+ }
13
+ }
14
+ return false;
15
+ }
16
+ export default defineRule({
17
+ id: 'requests-needs-timeout',
18
+ language: 'python',
19
+ severity: 'error',
20
+ message: 'requests call missing `timeout=...` — without it the call can hang indefinitely.',
21
+ messageKo: 'requests 호출에 `timeout=...` 누락 — 무한 대기 위험.',
22
+ visitors: {
23
+ call(node, ctx) {
24
+ const fn = node.childForFieldName('function');
25
+ if (!fn || fn.type !== 'attribute')
26
+ return;
27
+ const obj = fn.childForFieldName('object');
28
+ const attr = fn.childForFieldName('attribute');
29
+ if (!obj || !attr)
30
+ return;
31
+ if (ctx.textOf(obj) !== 'requests')
32
+ return;
33
+ if (!REQUESTS_METHODS.has(ctx.textOf(attr)))
34
+ return;
35
+ const args = node.childForFieldName('arguments');
36
+ if (!args)
37
+ return;
38
+ if (!hasTimeoutKwarg(args, ctx.textOf))
39
+ ctx.report({ node });
40
+ },
41
+ },
42
+ });
43
+ //# sourceMappingURL=requests-needs-timeout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requests-needs-timeout.js","sourceRoot":"","sources":["../../src/rules-default/requests-needs-timeout.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC;AAE1G,SAAS,eAAe,CAAC,IAAuB,EAAE,MAAwC;IACxF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9C,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QAC/B,IAAI,CAAC,GAAG;YAAE,SAAS;QACnB,IAAI,GAAG,CAAC,IAAI,KAAK,kBAAkB,EAAE,CAAC;YACpC,MAAM,IAAI,GAAG,GAAG,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;YAC3C,IAAI,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,SAAS;gBAAE,OAAO,IAAI,CAAC;QACtD,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,eAAe,UAAU,CAAC;IACxB,EAAE,EAAE,wBAAwB;IAC5B,QAAQ,EAAE,QAAQ;IAClB,QAAQ,EAAE,OAAO;IACjB,OAAO,EAAE,kFAAkF;IAC3F,SAAS,EAAE,2CAA2C;IACtD,QAAQ,EAAE;QACR,IAAI,CAAC,IAAI,EAAE,GAAG;YACZ,MAAM,EAAE,GAAG,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;YAC9C,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,IAAI,KAAK,WAAW;gBAAE,OAAO;YAC3C,MAAM,GAAG,GAAG,EAAE,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;YAC3C,MAAM,IAAI,GAAG,EAAE,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;YAC/C,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI;gBAAE,OAAO;YAC1B,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,UAAU;gBAAE,OAAO;YAC3C,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBAAE,OAAO;YACpD,MAAM,IAAI,GAAG,IAAI,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;YACjD,IAAI,CAAC,IAAI;gBAAE,OAAO;YAClB,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC;gBAAE,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/D,CAAC;KACF;CACF,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ declare const _default: import("@aicqtools/rule-sdk").FunctionRule;
2
+ export default _default;
3
+ //# sourceMappingURL=require-idempotency-key.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"require-idempotency-key.d.ts","sourceRoot":"","sources":["../../src/rules-default/require-idempotency-key.ts"],"names":[],"mappings":";AAgBA,wBA2BG"}
@@ -0,0 +1,47 @@
1
+ import { defineRule } from '@aicqtools/rule-sdk';
2
+ /**
3
+ * Payment best practice: charge/pay/refund operations must include an
4
+ * idempotency key to prevent double-spend on retry. Detect functions whose
5
+ * name contains `pay` / `charge` / `payment` and which lack an
6
+ * `idempotencyKey` / `Idempotency-Key` reference in the body.
7
+ *
8
+ * Limitation: name-based detection — functions named differently
9
+ * (`processOrder`, `bill`, etc.) are not flagged.
10
+ */
11
+ const PAYMENT_NAME = /^(pay|charge|payment|chargePayment|pay\w*|charge\w*|payment\w*|process(Pay|Payment|Charge))$/;
12
+ const IDEMPOTENCY = /\b(idempotency[_-]?key|idempotencyKey|Idempotency-Key)\b/i;
13
+ export default defineRule({
14
+ id: 'require-idempotency-key',
15
+ language: ['typescript', 'tsx'],
16
+ severity: 'error',
17
+ message: 'Payment function missing an idempotency key — required to prevent double-charge on retry (payment-domain best practice; aligns with PCI DSS § 10.2 audit trail integrity).',
18
+ messageKo: '결제 함수에 idempotency key 누락 — 재시도 시 중복 청구 방지 필수 (결제 도메인 권장 사항; PCI DSS § 10.2 감사 추적 무결성 정렬).',
19
+ docs: 'https://github.com/aicqtools/aicqtools/blob/main/docs/rules/require-idempotency-key.md',
20
+ visitors: {
21
+ function_declaration(node, ctx) {
22
+ const name = node.childForFieldName('name');
23
+ if (!name)
24
+ return;
25
+ const fnName = ctx.textOf(name);
26
+ if (!PAYMENT_NAME.test(fnName))
27
+ return;
28
+ const text = ctx.textOf(node);
29
+ if (IDEMPOTENCY.test(text))
30
+ return;
31
+ ctx.report({ node });
32
+ },
33
+ method_definition(node, ctx) {
34
+ const name = node.childForFieldName('name');
35
+ if (!name)
36
+ return;
37
+ const fnName = ctx.textOf(name);
38
+ if (!PAYMENT_NAME.test(fnName))
39
+ return;
40
+ const text = ctx.textOf(node);
41
+ if (IDEMPOTENCY.test(text))
42
+ return;
43
+ ctx.report({ node });
44
+ },
45
+ },
46
+ });
47
+ //# sourceMappingURL=require-idempotency-key.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"require-idempotency-key.js","sourceRoot":"","sources":["../../src/rules-default/require-idempotency-key.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGjD;;;;;;;;GAQG;AACH,MAAM,YAAY,GAAG,8FAA8F,CAAC;AACpH,MAAM,WAAW,GAAG,2DAA2D,CAAC;AAEhF,eAAe,UAAU,CAAC;IACxB,EAAE,EAAE,yBAAyB;IAC7B,QAAQ,EAAE,CAAC,YAAY,EAAE,KAAK,CAAC;IAC/B,QAAQ,EAAE,OAAO;IACjB,OAAO,EAAE,4KAA4K;IACrL,SAAS,EAAE,4FAA4F;IACvG,IAAI,EAAE,wFAAwF;IAC9F,QAAQ,EAAE;QACR,oBAAoB,CAAC,IAAuB,EAAE,GAAgB;YAC5D,MAAM,IAAI,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;YAC5C,IAAI,CAAC,IAAI;gBAAE,OAAO;YAClB,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAChC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC;gBAAE,OAAO;YACvC,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC9B,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC;gBAAE,OAAO;YACnC,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;QACvB,CAAC;QACD,iBAAiB,CAAC,IAAuB,EAAE,GAAgB;YACzD,MAAM,IAAI,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;YAC5C,IAAI,CAAC,IAAI;gBAAE,OAAO;YAClB,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAChC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC;gBAAE,OAAO;YACvC,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC9B,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC;gBAAE,OAAO;YACnC,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;QACvB,CAAC;KACF;CACF,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ declare const _default: import("@aicqtools/rule-sdk").FunctionRule;
2
+ export default _default;
3
+ //# sourceMappingURL=require-tls-1-2-plus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"require-tls-1-2-plus.d.ts","sourceRoot":"","sources":["../../src/rules-default/require-tls-1-2-plus.ts"],"names":[],"mappings":";AAWA,wBAkBG"}
@@ -0,0 +1,30 @@
1
+ import { defineRule } from '@aicqtools/rule-sdk';
2
+ /**
3
+ * PCI DSS § 4.1: cardholder data in transit must use strong cryptography.
4
+ * Detect TLS configuration that explicitly allows TLSv1 / TLSv1.1 via
5
+ * `secureProtocol` or `minVersion` options.
6
+ */
7
+ const FORBIDDEN_PROTO = /['"`](TLSv1(_method)?|TLSv1\.1|TLSv1_1(_method)?|SSLv\d|SSLv\d_method)['"`]/;
8
+ export default defineRule({
9
+ id: 'require-tls-1-2-plus',
10
+ language: ['typescript', 'tsx'],
11
+ severity: 'error',
12
+ message: 'TLS configuration allows TLS < 1.2 (PCI DSS § 4.2.1 — strong cryptography for cardholder data in transit).',
13
+ messageKo: 'TLS 1.2 미만 프로토콜을 허용하는 설정 (PCI DSS § 4.2.1 — 카드 소지자 데이터 전송 시 강한 암호화 필수).',
14
+ docs: 'https://github.com/aicqtools/aicqtools/blob/main/docs/rules/require-tls-1-2-plus.md',
15
+ visitors: {
16
+ pair(node, ctx) {
17
+ const key = node.childForFieldName('key');
18
+ const value = node.childForFieldName('value');
19
+ if (!key || !value)
20
+ return;
21
+ const keyText = ctx.textOf(key).replace(/^['"`]|['"`]$/g, '');
22
+ if (keyText !== 'secureProtocol' && keyText !== 'minVersion')
23
+ return;
24
+ const valueText = ctx.textOf(value);
25
+ if (FORBIDDEN_PROTO.test(valueText))
26
+ ctx.report({ node });
27
+ },
28
+ },
29
+ });
30
+ //# sourceMappingURL=require-tls-1-2-plus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"require-tls-1-2-plus.js","sourceRoot":"","sources":["../../src/rules-default/require-tls-1-2-plus.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGjD;;;;GAIG;AACH,MAAM,eAAe,GAAG,6EAA6E,CAAC;AAEtG,eAAe,UAAU,CAAC;IACxB,EAAE,EAAE,sBAAsB;IAC1B,QAAQ,EAAE,CAAC,YAAY,EAAE,KAAK,CAAC;IAC/B,QAAQ,EAAE,OAAO;IACjB,OAAO,EAAE,4GAA4G;IACrH,SAAS,EAAE,yEAAyE;IACpF,IAAI,EAAE,qFAAqF;IAC3F,QAAQ,EAAE;QACR,IAAI,CAAC,IAAuB,EAAE,GAAgB;YAC5C,MAAM,GAAG,GAAG,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;YAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;YAC9C,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK;gBAAE,OAAO;YAC3B,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC;YAC9D,IAAI,OAAO,KAAK,gBAAgB,IAAI,OAAO,KAAK,YAAY;gBAAE,OAAO;YACrE,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACpC,IAAI,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC;gBAAE,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5D,CAAC;KACF;CACF,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ declare const _default: import("@aicqtools/rule-sdk").FunctionRule;
2
+ export default _default;
3
+ //# sourceMappingURL=rfc5987-korean-filename.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rfc5987-korean-filename.d.ts","sourceRoot":"","sources":["../../src/rules-default/rfc5987-korean-filename.ts"],"names":[],"mappings":";AAcA,wBAeG"}
@@ -0,0 +1,32 @@
1
+ import { defineRule } from '@aicqtools/rule-sdk';
2
+ /**
3
+ * `Content-Disposition: attachment; filename="<korean>.csv"` without RFC 5987 encoding
4
+ * breaks Korean filenames in older browsers (esp. IE11/old Safari). Use
5
+ * `filename*=UTF-8''<encoded>` form.
6
+ *
7
+ * Heuristic: inspect whole call expressions (e.g. `setHeader("Content-Disposition", "...")`)
8
+ * so multi-arg patterns where the header name and value live in separate strings are caught.
9
+ */
10
+ const HAS_KOREAN = /[ㄱ-힝]/;
11
+ const HAS_RFC5987 = /filename\*\s*=\s*UTF-8''/i;
12
+ const HAS_CONTENT_DISPOSITION = /Content-Disposition/i;
13
+ export default defineRule({
14
+ id: 'rfc5987-korean-filename',
15
+ language: ['typescript', 'javascript', 'tsx'],
16
+ severity: 'warning',
17
+ message: 'Content-Disposition with Korean filename should use RFC 5987 (`filename*=UTF-8\'\'...`).',
18
+ messageKo: '한글 파일명 Content-Disposition은 RFC 5987 인코딩 필요 (`filename*=UTF-8\'\'...`).',
19
+ visitors: {
20
+ call_expression(node, ctx) {
21
+ const text = ctx.textOf(node);
22
+ if (!HAS_CONTENT_DISPOSITION.test(text))
23
+ return;
24
+ if (!HAS_KOREAN.test(text))
25
+ return;
26
+ if (HAS_RFC5987.test(text))
27
+ return;
28
+ ctx.report({ node });
29
+ },
30
+ },
31
+ });
32
+ //# sourceMappingURL=rfc5987-korean-filename.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rfc5987-korean-filename.js","sourceRoot":"","sources":["../../src/rules-default/rfc5987-korean-filename.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD;;;;;;;GAOG;AACH,MAAM,UAAU,GAAG,OAAO,CAAC;AAC3B,MAAM,WAAW,GAAG,2BAA2B,CAAC;AAChD,MAAM,uBAAuB,GAAG,sBAAsB,CAAC;AAEvD,eAAe,UAAU,CAAC;IACxB,EAAE,EAAE,yBAAyB;IAC7B,QAAQ,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,KAAK,CAAC;IAC7C,QAAQ,EAAE,SAAS;IACnB,OAAO,EAAE,0FAA0F;IACnG,SAAS,EAAE,yEAAyE;IACpF,QAAQ,EAAE;QACR,eAAe,CAAC,IAAI,EAAE,GAAG;YACvB,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC9B,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC;gBAAE,OAAO;YAChD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;gBAAE,OAAO;YACnC,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC;gBAAE,OAAO;YACnC,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;QACvB,CAAC;KACF;CACF,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ declare const _default: import("@aicqtools/rule-sdk").FunctionRule;
2
+ export default _default;
3
+ //# sourceMappingURL=route-needs-auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-needs-auth.d.ts","sourceRoot":"","sources":["../../src/rules-default/route-needs-auth.ts"],"names":[],"mappings":";AAkBA,wBA2BG"}
@@ -0,0 +1,48 @@
1
+ import { defineRule } from '@aicqtools/rule-sdk';
2
+ const ROUTER_METHODS = new Set(['get', 'post', 'put', 'patch', 'delete']);
3
+ const AUTH_PATTERN = /auth(enticate)?|requireUser|requireAuth|isAuthenticated/i;
4
+ // Public path patterns that don't require auth
5
+ const PUBLIC_PATH_PATTERN = /^["'`](\/health|\/ping|\/login|\/signup|\/auth\/|\/public\/)/;
6
+ function isRouterCall(callee, textOf) {
7
+ if (callee.type !== 'member_expression')
8
+ return false;
9
+ const obj = callee.childForFieldName('object');
10
+ const prop = callee.childForFieldName('property');
11
+ if (!obj || !prop)
12
+ return false;
13
+ const objText = textOf(obj);
14
+ if (objText !== 'router' && objText !== 'app')
15
+ return false;
16
+ return ROUTER_METHODS.has(textOf(prop));
17
+ }
18
+ export default defineRule({
19
+ id: 'route-needs-auth',
20
+ language: ['typescript', 'javascript', 'tsx'],
21
+ severity: 'error',
22
+ message: 'Route is missing an authentication middleware (e.g. `authenticate`, `requireAuth`).',
23
+ messageKo: '라우트에 인증 미들웨어가 빠졌습니다 (`authenticate` / `requireAuth` 등).',
24
+ visitors: {
25
+ call_expression(node, ctx) {
26
+ const callee = node.childForFieldName('function');
27
+ if (!callee || !isRouterCall(callee, ctx.textOf))
28
+ return;
29
+ const args = node.childForFieldName('arguments');
30
+ if (!args || args.namedChildCount < 2)
31
+ return;
32
+ const pathArg = args.namedChild(0);
33
+ if (pathArg && PUBLIC_PATH_PATTERN.test(ctx.textOf(pathArg)))
34
+ return;
35
+ let hasAuth = false;
36
+ for (let i = 1; i < args.namedChildCount; i++) {
37
+ const arg = args.namedChild(i);
38
+ if (arg && AUTH_PATTERN.test(ctx.textOf(arg))) {
39
+ hasAuth = true;
40
+ break;
41
+ }
42
+ }
43
+ if (!hasAuth)
44
+ ctx.report({ node });
45
+ },
46
+ },
47
+ });
48
+ //# sourceMappingURL=route-needs-auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-needs-auth.js","sourceRoot":"","sources":["../../src/rules-default/route-needs-auth.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;AAC1E,MAAM,YAAY,GAAG,0DAA0D,CAAC;AAChF,+CAA+C;AAC/C,MAAM,mBAAmB,GAAG,8DAA8D,CAAC;AAE3F,SAAS,YAAY,CAAC,MAAyB,EAAE,MAAwC;IACvF,IAAI,MAAM,CAAC,IAAI,KAAK,mBAAmB;QAAE,OAAO,KAAK,CAAC;IACtD,MAAM,GAAG,GAAG,MAAM,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IAC/C,MAAM,IAAI,GAAG,MAAM,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;IAClD,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI;QAAE,OAAO,KAAK,CAAC;IAChC,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAC5B,IAAI,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK;QAAE,OAAO,KAAK,CAAC;IAC5D,OAAO,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;AAC1C,CAAC;AAED,eAAe,UAAU,CAAC;IACxB,EAAE,EAAE,kBAAkB;IACtB,QAAQ,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,KAAK,CAAC;IAC7C,QAAQ,EAAE,OAAO;IACjB,OAAO,EAAE,qFAAqF;IAC9F,SAAS,EAAE,yDAAyD;IACpE,QAAQ,EAAE;QACR,eAAe,CAAC,IAAI,EAAE,GAAG;YACvB,MAAM,MAAM,GAAG,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;YAClD,IAAI,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC;gBAAE,OAAO;YACzD,MAAM,IAAI,GAAG,IAAI,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;YACjD,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,eAAe,GAAG,CAAC;gBAAE,OAAO;YAE9C,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YACnC,IAAI,OAAO,IAAI,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;gBAAE,OAAO;YAErE,IAAI,OAAO,GAAG,KAAK,CAAC;YACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC9C,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;gBAC/B,IAAI,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;oBAC9C,OAAO,GAAG,IAAI,CAAC;oBACf,MAAM;gBACR,CAAC;YACH,CAAC;YACD,IAAI,CAAC,OAAO;gBAAE,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;QACrC,CAAC;KACF;CACF,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ declare const _default: import("@aicqtools/rule-sdk").FunctionRule;
2
+ export default _default;
3
+ //# sourceMappingURL=route-needs-rate-limit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-needs-rate-limit.d.ts","sourceRoot":"","sources":["../../src/rules-default/route-needs-rate-limit.ts"],"names":[],"mappings":";AAqBA,wBAuBG"}
@@ -0,0 +1,47 @@
1
+ import { defineRule } from '@aicqtools/rule-sdk';
2
+ const ROUTER_METHODS = new Set(['get', 'post', 'put', 'patch', 'delete']);
3
+ const RATE_LIMIT_PATTERN = /rate.?limit/i;
4
+ function isRouterCall(callee, textOf) {
5
+ if (callee.type !== 'member_expression')
6
+ return false;
7
+ const obj = callee.childForFieldName('object');
8
+ const prop = callee.childForFieldName('property');
9
+ if (!obj || !prop)
10
+ return false;
11
+ const objText = textOf(obj);
12
+ if (objText !== 'router' && objText !== 'app')
13
+ return false;
14
+ return ROUTER_METHODS.has(textOf(prop));
15
+ }
16
+ function argHasRateLimit(arg, textOf) {
17
+ const text = textOf(arg);
18
+ return RATE_LIMIT_PATTERN.test(text);
19
+ }
20
+ export default defineRule({
21
+ id: 'route-needs-rate-limit',
22
+ language: ['typescript', 'javascript', 'tsx'],
23
+ severity: 'error',
24
+ message: 'New route is missing a rate-limit middleware.',
25
+ messageKo: '새 라우트에 rate-limit 미들웨어가 빠졌습니다.',
26
+ visitors: {
27
+ call_expression(node, ctx) {
28
+ const callee = node.childForFieldName('function');
29
+ if (!callee || !isRouterCall(callee, ctx.textOf))
30
+ return;
31
+ const args = node.childForFieldName('arguments');
32
+ if (!args)
33
+ return;
34
+ let hasRateLimit = false;
35
+ for (let i = 0; i < args.namedChildCount; i++) {
36
+ const arg = args.namedChild(i);
37
+ if (arg && argHasRateLimit(arg, ctx.textOf)) {
38
+ hasRateLimit = true;
39
+ break;
40
+ }
41
+ }
42
+ if (!hasRateLimit)
43
+ ctx.report({ node });
44
+ },
45
+ },
46
+ });
47
+ //# sourceMappingURL=route-needs-rate-limit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-needs-rate-limit.js","sourceRoot":"","sources":["../../src/rules-default/route-needs-rate-limit.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;AAC1E,MAAM,kBAAkB,GAAG,cAAc,CAAC;AAE1C,SAAS,YAAY,CAAC,MAAyB,EAAE,MAAwC;IACvF,IAAI,MAAM,CAAC,IAAI,KAAK,mBAAmB;QAAE,OAAO,KAAK,CAAC;IACtD,MAAM,GAAG,GAAG,MAAM,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IAC/C,MAAM,IAAI,GAAG,MAAM,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;IAClD,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI;QAAE,OAAO,KAAK,CAAC;IAChC,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAC5B,IAAI,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK;QAAE,OAAO,KAAK,CAAC;IAC5D,OAAO,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;AAC1C,CAAC;AAED,SAAS,eAAe,CAAC,GAAsB,EAAE,MAAwC;IACvF,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IACzB,OAAO,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACvC,CAAC;AAED,eAAe,UAAU,CAAC;IACxB,EAAE,EAAE,wBAAwB;IAC5B,QAAQ,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,KAAK,CAAC;IAC7C,QAAQ,EAAE,OAAO;IACjB,OAAO,EAAE,+CAA+C;IACxD,SAAS,EAAE,gCAAgC;IAC3C,QAAQ,EAAE;QACR,eAAe,CAAC,IAAI,EAAE,GAAG;YACvB,MAAM,MAAM,GAAG,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;YAClD,IAAI,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC;gBAAE,OAAO;YACzD,MAAM,IAAI,GAAG,IAAI,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;YACjD,IAAI,CAAC,IAAI;gBAAE,OAAO;YAClB,IAAI,YAAY,GAAG,KAAK,CAAC;YACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC9C,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;gBAC/B,IAAI,GAAG,IAAI,eAAe,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;oBAC5C,YAAY,GAAG,IAAI,CAAC;oBACpB,MAAM;gBACR,CAAC;YACH,CAAC;YACD,IAAI,CAAC,YAAY;gBAAE,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1C,CAAC;KACF;CACF,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ declare const _default: import("@aicqtools/rule-sdk").FunctionRule;
2
+ export default _default;
3
+ //# sourceMappingURL=separate-refund-permission.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"separate-refund-permission.d.ts","sourceRoot":"","sources":["../../src/rules-default/separate-refund-permission.ts"],"names":[],"mappings":";AAsBA,wBAWG"}