@sun-asterisk/sunlint 1.3.47 → 1.3.49

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 (185) hide show
  1. package/config/rules/rules-registry-generated.json +1717 -282
  2. package/core/architecture-integration.js +57 -15
  3. package/core/cli-action-handler.js +51 -36
  4. package/core/config-manager.js +6 -0
  5. package/core/config-merger.js +33 -0
  6. package/core/config-validator.js +37 -2
  7. package/core/file-targeting-service.js +148 -15
  8. package/core/init-command.js +118 -70
  9. package/core/output-service.js +12 -3
  10. package/core/project-detector.js +517 -0
  11. package/core/scoring-service.js +12 -6
  12. package/core/summary-report-service.js +9 -4
  13. package/core/tui-select.js +245 -0
  14. package/engines/arch-detect/rules/layered/l001-presentation-layer.js +7 -15
  15. package/engines/arch-detect/rules/layered/l002-business-layer.js +7 -15
  16. package/engines/arch-detect/rules/layered/l003-data-layer.js +7 -15
  17. package/engines/arch-detect/rules/layered/l004-model-layer.js +7 -15
  18. package/engines/arch-detect/rules/layered/l005-layer-separation.js +22 -2
  19. package/engines/arch-detect/rules/layered/l006-dependency-direction.js +8 -5
  20. package/engines/arch-detect/rules/modular/m005-no-deep-imports.js +67 -29
  21. package/engines/arch-detect/rules/presentation/pr001-view-layer.js +16 -9
  22. package/engines/arch-detect/rules/presentation/pr006-router-layer.js +33 -8
  23. package/engines/arch-detect/rules/presentation/pr007-interactor-layer.js +35 -6
  24. package/engines/arch-detect/rules/project-scanner/ps003-framework-detection.js +56 -10
  25. package/engines/impact/cli.js +54 -39
  26. package/engines/impact/config/default-config.js +105 -5
  27. package/engines/impact/core/impact-analyzer.js +12 -15
  28. package/engines/impact/core/utils/gitignore-parser.js +123 -0
  29. package/engines/impact/core/utils/method-call-graph.js +272 -87
  30. package/origin-rules/dart-en.md +1 -1
  31. package/origin-rules/go-en.md +231 -0
  32. package/origin-rules/php-en.md +107 -0
  33. package/origin-rules/python-en.md +113 -0
  34. package/origin-rules/ruby-en.md +607 -0
  35. package/package.json +1 -1
  36. package/scripts/copy-arch-detect.js +5 -1
  37. package/scripts/copy-impact-analyzer.js +5 -1
  38. package/scripts/generate-rules-registry.js +30 -14
  39. package/skill-assets/sunlint-code-quality/SKILL.md +3 -2
  40. package/skill-assets/sunlint-code-quality/rules/dart/C006-verb-noun-functions.md +45 -0
  41. package/skill-assets/sunlint-code-quality/rules/dart/C013-no-dead-code.md +53 -0
  42. package/skill-assets/sunlint-code-quality/rules/dart/C014-dependency-injection.md +92 -0
  43. package/skill-assets/sunlint-code-quality/rules/dart/C017-no-constructor-logic.md +62 -0
  44. package/skill-assets/sunlint-code-quality/rules/dart/C018-generic-errors.md +57 -0
  45. package/skill-assets/sunlint-code-quality/rules/dart/C019-error-log-level.md +50 -0
  46. package/skill-assets/sunlint-code-quality/rules/dart/C020-no-unused-imports.md +46 -0
  47. package/skill-assets/sunlint-code-quality/rules/dart/C022-no-unused-variables.md +50 -0
  48. package/skill-assets/sunlint-code-quality/rules/dart/C023-no-duplicate-names.md +56 -0
  49. package/skill-assets/sunlint-code-quality/rules/dart/C024-centralize-constants.md +75 -0
  50. package/skill-assets/sunlint-code-quality/rules/dart/C029-catch-log-root-cause.md +53 -0
  51. package/skill-assets/sunlint-code-quality/rules/dart/C030-custom-error-classes.md +86 -0
  52. package/skill-assets/sunlint-code-quality/rules/dart/C033-separate-data-access.md +90 -0
  53. package/skill-assets/sunlint-code-quality/rules/dart/C035-error-context-logging.md +62 -0
  54. package/skill-assets/sunlint-code-quality/rules/dart/C041-no-hardcoded-secrets.md +75 -0
  55. package/skill-assets/sunlint-code-quality/rules/dart/C042-boolean-naming.md +73 -0
  56. package/skill-assets/sunlint-code-quality/rules/dart/C052-widget-parsing.md +84 -0
  57. package/skill-assets/sunlint-code-quality/rules/dart/C060-superclass-logic.md +91 -0
  58. package/skill-assets/sunlint-code-quality/rules/dart/C067-no-hardcoded-config.md +108 -0
  59. package/skill-assets/sunlint-code-quality/rules/go/G001-explicit-error-handling.md +53 -0
  60. package/skill-assets/sunlint-code-quality/rules/go/G002-context-first-argument.md +44 -0
  61. package/skill-assets/sunlint-code-quality/rules/go/G003-receiver-consistency.md +38 -0
  62. package/skill-assets/sunlint-code-quality/rules/go/G004-avoid-panic.md +49 -0
  63. package/skill-assets/sunlint-code-quality/rules/go/G005-goroutine-leak-prevention.md +49 -0
  64. package/skill-assets/sunlint-code-quality/rules/go/G006-interface-consumer-definition.md +45 -0
  65. package/skill-assets/sunlint-code-quality/rules/go/GN001-gin-binding-validation.md +57 -0
  66. package/skill-assets/sunlint-code-quality/rules/go/GN002-gin-error-response.md +48 -0
  67. package/skill-assets/sunlint-code-quality/rules/go/GN003-graceful-shutdown.md +57 -0
  68. package/skill-assets/sunlint-code-quality/rules/go/GN004-gin-route-logical-grouping.md +54 -0
  69. package/skill-assets/sunlint-code-quality/rules/go-gin/AGENTS.md +149 -0
  70. package/skill-assets/sunlint-code-quality/rules/go-gin/GN001-abort-after-response.md +75 -0
  71. package/skill-assets/sunlint-code-quality/rules/go-gin/GN002-request-context.md +64 -0
  72. package/skill-assets/sunlint-code-quality/rules/go-gin/GN003-bind-error-handling.md +70 -0
  73. package/skill-assets/sunlint-code-quality/rules/go-gin/GN004-dependency-injection.md +78 -0
  74. package/skill-assets/sunlint-code-quality/rules/go-gin/GN005-route-groups-middleware.md +71 -0
  75. package/skill-assets/sunlint-code-quality/rules/go-gin/GN006-http-status-codes.md +91 -0
  76. package/skill-assets/sunlint-code-quality/rules/go-gin/GN007-release-mode.md +64 -0
  77. package/skill-assets/sunlint-code-quality/rules/go-gin/GN008-struct-validation-tags.md +90 -0
  78. package/skill-assets/sunlint-code-quality/rules/go-gin/GN009-recovery-middleware.md +68 -0
  79. package/skill-assets/sunlint-code-quality/rules/go-gin/GN010-context-scope.md +68 -0
  80. package/skill-assets/sunlint-code-quality/rules/go-gin/GN011-middleware-concerns.md +92 -0
  81. package/skill-assets/sunlint-code-quality/rules/go-gin/GN012-no-log-sensitive.md +84 -0
  82. package/skill-assets/sunlint-code-quality/rules/java/J001-try-with-resources.md +86 -0
  83. package/skill-assets/sunlint-code-quality/rules/java/J002-equals-and-hashcode.md +88 -0
  84. package/skill-assets/sunlint-code-quality/rules/java/J003-string-comparison.md +72 -0
  85. package/skill-assets/sunlint-code-quality/rules/java/J004-use-java-time.md +91 -0
  86. package/skill-assets/sunlint-code-quality/rules/java/J005-no-print-stack-trace.md +80 -0
  87. package/skill-assets/sunlint-code-quality/rules/java/J006-no-system-println.md +89 -0
  88. package/skill-assets/sunlint-code-quality/rules/java/J007-proper-logger.md +91 -0
  89. package/skill-assets/sunlint-code-quality/rules/java/J008-thread-safe-singleton.md +119 -0
  90. package/skill-assets/sunlint-code-quality/rules/java/J009-utility-class-constructor.md +82 -0
  91. package/skill-assets/sunlint-code-quality/rules/java/J010-preserve-stack-trace.md +119 -0
  92. package/skill-assets/sunlint-code-quality/rules/java/J011-null-safe-compare.md +88 -0
  93. package/skill-assets/sunlint-code-quality/rules/java/J012-use-enum-collections.md +104 -0
  94. package/skill-assets/sunlint-code-quality/rules/java/J013-return-empty-not-null.md +102 -0
  95. package/skill-assets/sunlint-code-quality/rules/java/J014-hardcoded-crypto-key.md +108 -0
  96. package/skill-assets/sunlint-code-quality/rules/java/J015-optional-instead-of-null.md +109 -0
  97. package/skill-assets/sunlint-code-quality/rules/php-laravel/AGENTS.md +124 -0
  98. package/skill-assets/sunlint-code-quality/rules/php-laravel/LV001-form-request-validation.md +64 -0
  99. package/skill-assets/sunlint-code-quality/rules/php-laravel/LV002-eager-load-no-n-plus-1.md +58 -0
  100. package/skill-assets/sunlint-code-quality/rules/php-laravel/LV003-config-not-env.md +54 -0
  101. package/skill-assets/sunlint-code-quality/rules/php-laravel/LV004-fillable-mass-assignment.md +51 -0
  102. package/skill-assets/sunlint-code-quality/rules/php-laravel/LV005-policies-gates-authorization.md +71 -0
  103. package/skill-assets/sunlint-code-quality/rules/php-laravel/LV006-queue-heavy-tasks.md +68 -0
  104. package/skill-assets/sunlint-code-quality/rules/php-laravel/LV007-hash-passwords.md +51 -0
  105. package/skill-assets/sunlint-code-quality/rules/php-laravel/LV008-route-model-binding.md +67 -0
  106. package/skill-assets/sunlint-code-quality/rules/php-laravel/LV009-api-resources.md +72 -0
  107. package/skill-assets/sunlint-code-quality/rules/php-laravel/LV010-chunk-large-datasets.md +58 -0
  108. package/skill-assets/sunlint-code-quality/rules/php-laravel/LV011-db-transactions.md +73 -0
  109. package/skill-assets/sunlint-code-quality/rules/php-laravel/LV012-service-layer.md +78 -0
  110. package/skill-assets/sunlint-code-quality/rules/php-laravel/LV013-testing-factories.md +75 -0
  111. package/skill-assets/sunlint-code-quality/rules/php-laravel/LV014-service-container.md +61 -0
  112. package/skill-assets/sunlint-code-quality/rules/python/P001-mutable-default-argument.md +55 -0
  113. package/skill-assets/sunlint-code-quality/rules/python/P002-specify-file-encoding.md +45 -0
  114. package/skill-assets/sunlint-code-quality/rules/python/P003-context-manager-for-resources.md +54 -0
  115. package/skill-assets/sunlint-code-quality/rules/python/P004-no-bare-except.md +65 -0
  116. package/skill-assets/sunlint-code-quality/rules/python/P005-use-isinstance.md +60 -0
  117. package/skill-assets/sunlint-code-quality/rules/python/P006-timezone-aware-datetime.md +58 -0
  118. package/skill-assets/sunlint-code-quality/rules/python/P007-use-pathlib.md +62 -0
  119. package/skill-assets/sunlint-code-quality/rules/python/P008-no-wildcard-import.md +52 -0
  120. package/skill-assets/sunlint-code-quality/rules/python/P009-logging-lazy-format.md +50 -0
  121. package/skill-assets/sunlint-code-quality/rules/python/P010-exception-chaining.md +57 -0
  122. package/skill-assets/sunlint-code-quality/rules/python/P011-subprocess-check.md +59 -0
  123. package/skill-assets/sunlint-code-quality/rules/python/P012-requests-timeout.md +70 -0
  124. package/skill-assets/sunlint-code-quality/rules/python/P013-no-global-statement.md +73 -0
  125. package/skill-assets/sunlint-code-quality/rules/python/P014-no-modify-collection-while-iterating.md +66 -0
  126. package/skill-assets/sunlint-code-quality/rules/python/P015-prefer-fstrings.md +61 -0
  127. package/skill-assets/sunlint-code-quality/rules/ruby-rails/AGENTS.md +121 -0
  128. package/skill-assets/sunlint-code-quality/rules/ruby-rails/RR001-strong-parameters.md +55 -0
  129. package/skill-assets/sunlint-code-quality/rules/ruby-rails/RR002-eager-load-includes.md +51 -0
  130. package/skill-assets/sunlint-code-quality/rules/ruby-rails/RR003-service-objects.md +99 -0
  131. package/skill-assets/sunlint-code-quality/rules/ruby-rails/RR004-active-job-background.md +67 -0
  132. package/skill-assets/sunlint-code-quality/rules/ruby-rails/RR005-pagination.md +53 -0
  133. package/skill-assets/sunlint-code-quality/rules/ruby-rails/RR006-find-each-batches.md +53 -0
  134. package/skill-assets/sunlint-code-quality/rules/ruby-rails/RR007-http-status-codes.md +76 -0
  135. package/skill-assets/sunlint-code-quality/rules/ruby-rails/RR008-before-action-auth.md +77 -0
  136. package/skill-assets/sunlint-code-quality/rules/ruby-rails/RR009-rails-credentials.md +61 -0
  137. package/skill-assets/sunlint-code-quality/rules/ruby-rails/RR010-scopes.md +57 -0
  138. package/skill-assets/sunlint-code-quality/rules/ruby-rails/RR011-counter-cache.md +59 -0
  139. package/skill-assets/sunlint-code-quality/rules/ruby-rails/RR012-render-json-status.md +42 -0
  140. package/skill-assets/sunlint-code-quality/rules/swift/C006-verb-noun-functions.md +37 -0
  141. package/skill-assets/sunlint-code-quality/rules/swift/C013-no-dead-code.md +55 -0
  142. package/skill-assets/sunlint-code-quality/rules/swift/C014-dependency-injection.md +69 -0
  143. package/skill-assets/sunlint-code-quality/rules/swift/C017-no-constructor-logic.md +66 -0
  144. package/skill-assets/sunlint-code-quality/rules/swift/C018-generic-errors.md +64 -0
  145. package/skill-assets/sunlint-code-quality/rules/swift/C019-error-log-level.md +64 -0
  146. package/skill-assets/sunlint-code-quality/rules/swift/C020-no-unused-imports.md +47 -0
  147. package/skill-assets/sunlint-code-quality/rules/swift/C022-no-unused-variables.md +46 -0
  148. package/skill-assets/sunlint-code-quality/rules/swift/C023-no-duplicate-names.md +55 -0
  149. package/skill-assets/sunlint-code-quality/rules/swift/C024-centralize-constants.md +68 -0
  150. package/skill-assets/sunlint-code-quality/rules/swift/C029-catch-log-root-cause.md +69 -0
  151. package/skill-assets/sunlint-code-quality/rules/swift/C030-custom-error-classes.md +77 -0
  152. package/skill-assets/sunlint-code-quality/rules/swift/C033-separate-data-access.md +89 -0
  153. package/skill-assets/sunlint-code-quality/rules/swift/C035-error-context-logging.md +66 -0
  154. package/skill-assets/sunlint-code-quality/rules/swift/C041-no-hardcoded-secrets.md +65 -0
  155. package/skill-assets/sunlint-code-quality/rules/swift/C042-boolean-naming.md +60 -0
  156. package/skill-assets/sunlint-code-quality/rules/swift/C052-controller-parsing.md +67 -0
  157. package/skill-assets/sunlint-code-quality/rules/swift/C060-superclass-logic.md +95 -0
  158. package/skill-assets/sunlint-code-quality/rules/swift/C067-no-hardcoded-config.md +80 -0
  159. package/skill-assets/sunlint-code-quality/rules/swift/S003-sql-injection.md +65 -0
  160. package/skill-assets/sunlint-code-quality/rules/swift/S004-no-log-credentials.md +67 -0
  161. package/skill-assets/sunlint-code-quality/rules/swift/S005-server-authorization.md +73 -0
  162. package/skill-assets/sunlint-code-quality/rules/swift/S006-default-credentials.md +76 -0
  163. package/skill-assets/sunlint-code-quality/rules/swift/S007-output-encoding.md +96 -0
  164. package/skill-assets/sunlint-code-quality/rules/swift/S009-approved-crypto.md +86 -0
  165. package/skill-assets/sunlint-code-quality/rules/swift/S010-csprng.md +71 -0
  166. package/skill-assets/sunlint-code-quality/rules/swift/S011-insecure-deserialization.md +74 -0
  167. package/skill-assets/sunlint-code-quality/rules/swift/S012-secrets-management.md +81 -0
  168. package/skill-assets/sunlint-code-quality/rules/swift/S013-tls-connections.md +67 -0
  169. package/skill-assets/sunlint-code-quality/rules/swift/S017-parameterized-queries.md +86 -0
  170. package/skill-assets/sunlint-code-quality/rules/swift/S019-session-management.md +131 -0
  171. package/skill-assets/sunlint-code-quality/rules/swift/S020-kvc-injection.md +91 -0
  172. package/skill-assets/sunlint-code-quality/rules/swift/S025-input-validation.md +125 -0
  173. package/skill-assets/sunlint-code-quality/rules/swift/S029-brute-force-protection.md +120 -0
  174. package/skill-assets/sunlint-code-quality/rules/swift/S036-path-traversal.md +102 -0
  175. package/skill-assets/sunlint-code-quality/rules/swift/S039-tls-certificate-validation.md +109 -0
  176. package/skill-assets/sunlint-code-quality/rules/swift/S041-logout-invalidation.md +103 -0
  177. package/skill-assets/sunlint-code-quality/rules/swift/S043-password-hashing.md +116 -0
  178. package/skill-assets/sunlint-code-quality/rules/swift/S044-critical-changes-reauth.md +145 -0
  179. package/skill-assets/sunlint-code-quality/rules/swift/S045-debug-info-exposure.md +116 -0
  180. package/skill-assets/sunlint-code-quality/rules/swift/S046-unvalidated-redirect.md +140 -0
  181. package/skill-assets/sunlint-code-quality/rules/swift/S051-token-expiry.md +134 -0
  182. package/skill-assets/sunlint-code-quality/rules/swift/S053-jwt-validation.md +139 -0
  183. package/skill-assets/sunlint-code-quality/rules/swift/S059-background-snapshot-protection.md +113 -0
  184. package/skill-assets/sunlint-code-quality/rules/swift/S060-data-protection-api.md +106 -0
  185. package/skill-assets/sunlint-code-quality/rules/swift/S061-jailbreak-detection.md +132 -0
@@ -0,0 +1,607 @@
1
+ # 📘 Ruby/Rails Specific Coding Rules
2
+
3
+ ### 📘 Rule RB001 – Use snake_case for symbols, methods, and variables
4
+
5
+ - **Objective**: Follow Ruby community naming conventions for consistency and readability.
6
+ - **Details**:
7
+ - Use `snake_case` (all lowercase with underscores) for symbols, methods, and variables.
8
+ - Avoid camelCase or other naming styles for these elements.
9
+ - **Applies to**: Ruby/Rails
10
+ - **Tool**: RuboCop (`Naming/VariableName`, `Naming/MethodName`)
11
+ - **Principle**: CODE_QUALITY
12
+ - **Version**: 1.0
13
+ - **Status**: activated
14
+ - **Severity**: major
15
+
16
+ ### 📘 Rule RB002 – Use CamelCase for classes and modules
17
+
18
+ - **Objective**: Follow Ruby community naming conventions for classes and modules.
19
+ - **Details**:
20
+ - Use `CamelCase` (also known as PascalCase) for class and module names.
21
+ - Keep acronyms uppercase (e.g., `HTTPClient`, `XMLParser`).
22
+ - **Applies to**: Ruby/Rails
23
+ - **Tool**: RuboCop (`Naming/ClassName`)
24
+ - **Principle**: CODE_QUALITY
25
+ - **Version**: 1.0
26
+ - **Status**: activated
27
+ - **Severity**: major
28
+
29
+ ### 📘 Rule RB003 – Use SCREAMING_SNAKE_CASE for constants
30
+
31
+ - **Objective**: Clearly distinguish constants from other identifiers.
32
+ - **Details**:
33
+ - Use `SCREAMING_SNAKE_CASE` for constants that do not refer to classes or modules.
34
+ - Example: `MAX_RETRY_COUNT`, `DEFAULT_TIMEOUT`.
35
+ - **Applies to**: Ruby/Rails
36
+ - **Tool**: RuboCop (`Naming/ConstantName`)
37
+ - **Principle**: CODE_QUALITY
38
+ - **Version**: 1.0
39
+ - **Status**: activated
40
+ - **Severity**: major
41
+
42
+ ### 📘 Rule RB004 – Predicate methods should end with ?
43
+
44
+ - **Objective**: Make boolean-returning methods immediately recognizable.
45
+ - **Details**:
46
+ - Methods that return boolean values should end with a question mark (`?`).
47
+ - Avoid prefixing with auxiliary verbs like `is_`, `does_`, or `can_`.
48
+ - Example: `valid?`, `empty?`, `authenticated?` instead of `is_valid`, `is_empty`.
49
+ - **Applies to**: Ruby/Rails
50
+ - **Tool**: RuboCop (`Naming/PredicateName`)
51
+ - **Principle**: CODE_QUALITY
52
+ - **Version**: 1.0
53
+ - **Status**: activated
54
+ - **Severity**: major
55
+
56
+ ### 📘 Rule RB005 – Dangerous methods should end with !
57
+
58
+ - **Objective**: Clearly indicate methods that modify the receiver or can raise exceptions.
59
+ - **Details**:
60
+ - Methods that modify the object in place or can raise exceptions should end with a bang (`!`).
61
+ - Example: `save!`, `destroy!`, `sort!`, `update!`.
62
+ - **Applies to**: Ruby/Rails
63
+ - **Tool**: RuboCop (`Style/BangPredicate`)
64
+ - **Principle**: CODE_QUALITY
65
+ - **Version**: 1.0
66
+ - **Status**: activated
67
+ - **Severity**: major
68
+
69
+ ### 📘 Rule RB006 – Use 2 spaces for indentation
70
+
71
+ - **Objective**: Follow Ruby community standard for code formatting.
72
+ - **Details**:
73
+ - Use 2 spaces for indentation, never tabs.
74
+ - Ensure consistent indentation throughout the codebase.
75
+ - **Applies to**: Ruby/Rails
76
+ - **Tool**: RuboCop (`Layout/IndentationWidth`)
77
+ - **Principle**: CODE_QUALITY
78
+ - **Version**: 1.0
79
+ - **Status**: activated
80
+ - **Severity**: minor
81
+
82
+ ### 📘 Rule RB007 – Keep lines under 120 characters
83
+
84
+ - **Objective**: Improve code readability and prevent horizontal scrolling.
85
+ - **Details**:
86
+ - Limit line length to 120 characters maximum.
87
+ - Break long lines into multiple lines when necessary.
88
+ - **Applies to**: Ruby/Rails
89
+ - **Tool**: RuboCop (`Layout/LineLength`)
90
+ - **Principle**: CODE_QUALITY
91
+ - **Version**: 1.0
92
+ - **Status**: activated
93
+ - **Severity**: minor
94
+
95
+ ### 📘 Rule RB008 – Avoid rescuing the Exception class
96
+
97
+ - **Objective**: Prevent hiding critical system errors.
98
+ - **Details**:
99
+ - Never rescue the generic `Exception` class as it catches system-level errors.
100
+ - Rescue specific exception classes or `StandardError` instead.
101
+ - Example: Rescue `ActiveRecord::RecordNotFound` instead of `Exception`.
102
+ - **Applies to**: Ruby/Rails
103
+ - **Tool**: RuboCop (`Lint/RescueException`)
104
+ - **Principle**: CODE_QUALITY
105
+ - **Version**: 1.0
106
+ - **Status**: activated
107
+ - **Severity**: critical
108
+
109
+ ### 📘 Rule RB009 – Use save! or handle return values
110
+
111
+ - **Objective**: Ensure database operations are properly validated and errors are not silently ignored.
112
+ - **Details**:
113
+ - Use bang methods (`save!`, `create!`, `update!`, `destroy!`) to raise exceptions on failure.
114
+ - If using non-bang methods, always check the return value.
115
+ - Never ignore the return value of persistence methods.
116
+ - **Applies to**: Ruby/Rails
117
+ - **Tool**: RuboCop (`Rails/SaveBang`)
118
+ - **Principle**: CODE_QUALITY
119
+ - **Version**: 1.0
120
+ - **Status**: activated
121
+ - **Severity**: critical
122
+
123
+ ### 📘 Rule RB010 – Avoid N+1 queries with eager loading
124
+
125
+ - **Objective**: Prevent performance issues caused by N+1 query problems.
126
+ - **Details**:
127
+ - Use `includes`, `preload`, or `eager_load` to load associations upfront.
128
+ - Avoid iterating over collections and accessing associations without eager loading.
129
+ - Example: `User.includes(:posts)` instead of `User.all` when accessing posts.
130
+ - **Applies to**: Ruby/Rails
131
+ - **Tool**: Bullet gem, RuboCop Rails (`Rails/FindEach`)
132
+ - **Principle**: CODE_QUALITY, PERFORMANCE
133
+ - **Version**: 1.0
134
+ - **Status**: activated
135
+ - **Severity**: major
136
+
137
+ ### 📘 Rule RB011 – Use find_each for large collections
138
+
139
+ - **Objective**: Reduce memory consumption when iterating over large datasets.
140
+ - **Details**:
141
+ - Use `find_each` or `find_in_batches` instead of `each` for large ActiveRecord collections.
142
+ - `find_each` loads records in batches (default 1000) to avoid loading all records into memory.
143
+ - **Applies to**: Ruby/Rails
144
+ - **Tool**: RuboCop (`Rails/FindEach`)
145
+ - **Principle**: CODE_QUALITY, PERFORMANCE
146
+ - **Version**: 1.0
147
+ - **Status**: activated
148
+ - **Severity**: major
149
+
150
+ ### 📘 Rule RB012 – Avoid SQL injection with parameterized queries
151
+
152
+ - **Objective**: Prevent SQL injection vulnerabilities.
153
+ - **Details**:
154
+ - Never use string interpolation in SQL queries.
155
+ - Use parameterized queries with `?` or named placeholders (`:name`).
156
+ - Use hash conditions for `where` clauses instead of SQL fragments.
157
+ - **Applies to**: Ruby/Rails
158
+ - **Tool**: Brakeman, RuboCop (`Rails/SquishedSQLHeredocs`)
159
+ - **Principle**: SECURITY
160
+ - **Version**: 1.0
161
+ - **Status**: activated
162
+ - **Severity**: critical
163
+
164
+ ### 📘 Rule RB013 – Prefer has_many :through over HABTM
165
+
166
+ - **Objective**: Allow for additional attributes and validations on join models.
167
+ - **Details**:
168
+ - Use `has_many :through` instead of `has_and_belongs_to_many` for many-to-many relationships.
169
+ - This provides more flexibility for adding attributes to the join table.
170
+ - **Applies to**: Ruby/Rails
171
+ - **Tool**: RuboCop (`Rails/HasAndBelongsToMany`)
172
+ - **Principle**: CODE_QUALITY
173
+ - **Version**: 1.0
174
+ - **Status**: activated
175
+ - **Severity**: major
176
+
177
+ ### 📘 Rule RB014 – Always define dependent option for associations
178
+
179
+ - **Objective**: Prevent orphaned records and ensure data integrity.
180
+ - **Details**:
181
+ - Always specify the `dependent` option for `has_many` and `has_one` associations.
182
+ - Options: `:destroy`, `:delete_all`, `:nullify`, `:restrict_with_exception`, `:restrict_with_error`.
183
+ - **Applies to**: Ruby/Rails
184
+ - **Tool**: Custom linter
185
+ - **Principle**: CODE_QUALITY
186
+ - **Version**: 1.0
187
+ - **Status**: activated
188
+ - **Severity**: major
189
+
190
+ ### 📘 Rule RB015 – Use new-style validations
191
+
192
+ - **Objective**: Follow modern Rails conventions for model validations.
193
+ - **Details**:
194
+ - Use new-style validations: `validates :email, presence: true, uniqueness: true`.
195
+ - Avoid old-style validations like `validates_presence_of :email`.
196
+ - **Applies to**: Ruby/Rails
197
+ - **Tool**: RuboCop (`Rails/Validation`)
198
+ - **Principle**: CODE_QUALITY
199
+ - **Version**: 1.0
200
+ - **Status**: activated
201
+ - **Severity**: major
202
+
203
+ ### 📘 Rule RB016 – Keep controllers thin
204
+
205
+ - **Objective**: Maintain single responsibility and improve testability.
206
+ - **Details**:
207
+ - Controllers should only handle HTTP requests and responses.
208
+ - Extract complex business logic into service objects, models, or concerns.
209
+ - Aim for controllers with 5-7 lines of code per action.
210
+ - **Applies to**: Ruby/Rails
211
+ - **Tool**: RuboCop (`Metrics/MethodLength`)
212
+ - **Principle**: CODE_QUALITY
213
+ - **Version**: 1.0
214
+ - **Status**: activated
215
+ - **Severity**: major
216
+
217
+ ### 📘 Rule RB017 – Avoid fat models
218
+
219
+ - **Objective**: Prevent models from becoming monolithic and hard to maintain.
220
+ - **Details**:
221
+ - Keep models focused on associations, validations, and simple domain logic.
222
+ - Extract complex workflows into service objects.
223
+ - Use concerns for clearly reusable behavior only.
224
+ - **Applies to**: Ruby/Rails
225
+ - **Tool**: RuboCop (`Metrics/ClassLength`)
226
+ - **Principle**: CODE_QUALITY
227
+ - **Version**: 1.0
228
+ - **Status**: activated
229
+ - **Severity**: major
230
+
231
+ ### 📘 Rule RB018 – Use service objects for complex business logic
232
+
233
+ - **Objective**: Improve code organization and testability.
234
+ - **Details**:
235
+ - Extract complex business logic (payments, onboarding, multi-step processes) into service objects.
236
+ - Service objects should have a single public method (e.g., `call`, `execute`, `perform`).
237
+ - Place service objects in `app/services/`.
238
+ - **Applies to**: Ruby/Rails
239
+ - **Tool**: Custom linter
240
+ - **Principle**: CODE_QUALITY
241
+ - **Version**: 1.0
242
+ - **Status**: activated
243
+ - **Severity**: major
244
+
245
+ ### 📘 Rule RB019 – Avoid needless metaprogramming
246
+
247
+ - **Objective**: Maintain code clarity and debuggability.
248
+ - **Details**:
249
+ - Avoid using metaprogramming (`define_method`, `method_missing`, `class_eval`) unless absolutely necessary.
250
+ - Metaprogramming makes code harder to understand, debug, and maintain.
251
+ - Prefer explicit code over clever metaprogramming.
252
+ - **Applies to**: Ruby/Rails
253
+ - **Tool**: RuboCop (`Style/MethodMissingSuper`)
254
+ - **Principle**: CODE_QUALITY
255
+ - **Version**: 1.0
256
+ - **Status**: activated
257
+ - **Severity**: major
258
+
259
+ ### 📘 Rule RB020 – Use pluck for selecting specific columns
260
+
261
+ - **Objective**: Improve query performance by selecting only needed columns.
262
+ - **Details**:
263
+ - Use `pluck` to select specific columns from multiple records.
264
+ - Use `pick` for a single value from a single record.
265
+ - Prefer `ids` over `pluck(:id)` for getting an array of IDs.
266
+ - **Applies to**: Ruby/Rails
267
+ - **Tool**: RuboCop (`Rails/Pluck`, `Rails/PluckId`)
268
+ - **Principle**: CODE_QUALITY, PERFORMANCE
269
+ - **Version**: 1.0
270
+ - **Status**: activated
271
+ - **Severity**: major
272
+
273
+ ### 📘 Rule RB021 – Use size over count or length
274
+
275
+ - **Objective**: Optimize performance by using the most efficient method.
276
+ - **Details**:
277
+ - Use `size` instead of `count` or `length` for ActiveRecord collections.
278
+ - `size` intelligently chooses between `count` (SQL query) and `length` (array size) based on whether the collection is loaded.
279
+ - **Applies to**: Ruby/Rails
280
+ - **Tool**: RuboCop (`Rails/SkipsModelValidations`)
281
+ - **Principle**: CODE_QUALITY, PERFORMANCE
282
+ - **Version**: 1.0
283
+ - **Status**: activated
284
+ - **Severity**: minor
285
+
286
+ ### 📘 Rule RB022 – Order by timestamp columns, not id
287
+
288
+ - **Objective**: Ensure consistent ordering across database systems.
289
+ - **Details**:
290
+ - Order records chronologically by timestamp columns (`created_at`, `updated_at`) instead of `id`.
291
+ - IDs may not be sequential in distributed systems or with UUID primary keys.
292
+ - **Applies to**: Ruby/Rails
293
+ - **Tool**: Custom linter
294
+ - **Principle**: CODE_QUALITY
295
+ - **Version**: 1.0
296
+ - **Status**: activated
297
+ - **Severity**: major
298
+
299
+ ### 📘 Rule RB023 – Use where.missing for Rails 6.1+
300
+
301
+ - **Objective**: Use modern Rails APIs for finding records with missing associations.
302
+ - **Details**:
303
+ - Use `where.missing(:association)` instead of left joins with null checks.
304
+ - This is more readable and expressive.
305
+ - **Applies to**: Ruby/Rails
306
+ - **Tool**: RuboCop (`Rails/WhereMissing`)
307
+ - **Principle**: CODE_QUALITY
308
+ - **Version**: 1.0
309
+ - **Status**: activated
310
+ - **Severity**: minor
311
+
312
+ ### 📘 Rule RB024 – Keep methods under 10 lines
313
+
314
+ - **Objective**: Improve code readability and maintainability.
315
+ - **Details**:
316
+ - Limit methods to 10 lines of code (excluding blank lines and comments).
317
+ - Extract complex logic into smaller, well-named private methods.
318
+ - **Applies to**: Ruby/Rails
319
+ - **Tool**: RuboCop (`Metrics/MethodLength`)
320
+ - **Principle**: CODE_QUALITY
321
+ - **Version**: 1.0
322
+ - **Status**: activated
323
+ - **Severity**: major
324
+
325
+ ### 📘 Rule RB025 – Limit method parameters to 4
326
+
327
+ - **Objective**: Reduce method complexity and improve readability.
328
+ - **Details**:
329
+ - Limit methods to 4 parameters maximum.
330
+ - If more parameters are needed, consider using a hash or parameter object.
331
+ - **Applies to**: Ruby/Rails
332
+ - **Tool**: RuboCop (`Metrics/ParameterLists`)
333
+ - **Principle**: CODE_QUALITY
334
+ - **Version**: 1.0
335
+ - **Status**: activated
336
+ - **Severity**: major
337
+
338
+ ### 📘 Rule RB026 – Avoid deep nesting (max 3 levels)
339
+
340
+ - **Objective**: Improve code readability and reduce cyclomatic complexity.
341
+ - **Details**:
342
+ - Limit nesting to 3 levels maximum.
343
+ - Use guard clauses, early returns, or extract methods to flatten code.
344
+ - **Applies to**: Ruby/Rails
345
+ - **Tool**: RuboCop (`Metrics/BlockNesting`)
346
+ - **Principle**: CODE_QUALITY
347
+ - **Version**: 1.0
348
+ - **Status**: activated
349
+ - **Severity**: major
350
+
351
+ ### 📘 Rule RB027 – Use guard clauses for early returns
352
+
353
+ - **Objective**: Reduce nesting and improve code clarity.
354
+ - **Details**:
355
+ - Use guard clauses to handle edge cases early and return.
356
+ - This keeps the main logic at the top level of the method.
357
+ - Example: `return unless condition` instead of wrapping everything in `if condition`.
358
+ - **Applies to**: Ruby/Rails
359
+ - **Tool**: RuboCop (`Style/GuardClause`)
360
+ - **Principle**: CODE_QUALITY
361
+ - **Version**: 1.0
362
+ - **Status**: activated
363
+ - **Severity**: major
364
+
365
+ ### 📘 Rule RB028 – Keep classes under 100 lines
366
+
367
+ - **Objective**: Maintain single responsibility and improve maintainability.
368
+ - **Details**:
369
+ - Limit classes to 100 lines of code (excluding blank lines and comments).
370
+ - Extract responsibilities into separate classes or modules if a class grows too large.
371
+ - **Applies to**: Ruby/Rails
372
+ - **Tool**: RuboCop (`Metrics/ClassLength`)
373
+ - **Principle**: CODE_QUALITY
374
+ - **Version**: 1.0
375
+ - **Status**: activated
376
+ - **Severity**: major
377
+
378
+ ### 📘 Rule RB029 – Use meaningful variable and method names
379
+
380
+ - **Objective**: Improve code self-documentation and readability.
381
+ - **Details**:
382
+ - Use descriptive names that clearly convey purpose.
383
+ - Avoid single-letter variables except for common iterators (i, j, k).
384
+ - Avoid abbreviations unless they are widely understood.
385
+ - **Applies to**: Ruby/Rails
386
+ - **Tool**: RuboCop (`Naming/VariableName`)
387
+ - **Principle**: CODE_QUALITY
388
+ - **Version**: 1.0
389
+ - **Status**: activated
390
+ - **Severity**: major
391
+
392
+ ### 📘 Rule RB030 – Don't Repeat Yourself (DRY)
393
+
394
+ - **Objective**: Reduce code duplication and improve maintainability.
395
+ - **Details**:
396
+ - Extract repeated code into methods, helpers, concerns, or partials.
397
+ - Use inheritance, composition, or modules to share behavior.
398
+ - Avoid copy-pasting code blocks.
399
+ - **Applies to**: Ruby/Rails
400
+ - **Tool**: Reek, RuboCop (`Style/IdenticalConditionalBranches`)
401
+ - **Principle**: CODE_QUALITY
402
+ - **Version**: 1.0
403
+ - **Status**: activated
404
+ - **Severity**: major
405
+
406
+ ### 📘 Rule RB031 – Follow MVC architecture strictly
407
+
408
+ - **Objective**: Maintain clear separation of concerns.
409
+ - **Details**:
410
+ - Models: Data, associations, validations, simple domain logic.
411
+ - Views: Presentation only, no business logic.
412
+ - Controllers: HTTP handling, delegate to models/services.
413
+ - Avoid putting business logic in views or controllers.
414
+ - **Applies to**: Ruby/Rails
415
+ - **Tool**: Custom linter
416
+ - **Principle**: CODE_QUALITY
417
+ - **Version**: 1.0
418
+ - **Status**: activated
419
+ - **Severity**: critical
420
+
421
+ ### 📘 Rule RB032 – Use concerns judiciously
422
+
423
+ - **Objective**: Prevent concerns from becoming dumping grounds for unrelated code.
424
+ - **Details**:
425
+ - Only use concerns for clearly reusable behavior across multiple models/controllers.
426
+ - Each concern should have a single, well-defined responsibility.
427
+ - Avoid creating "god concerns" with mixed responsibilities.
428
+ - **Applies to**: Ruby/Rails
429
+ - **Tool**: Custom linter
430
+ - **Principle**: CODE_QUALITY
431
+ - **Version**: 1.0
432
+ - **Status**: activated
433
+ - **Severity**: major
434
+
435
+ ### 📘 Rule RB033 – Document callbacks and use them sparingly
436
+
437
+ - **Objective**: Prevent hidden side effects and improve code clarity.
438
+ - **Details**:
439
+ - Document all callbacks with comments explaining their purpose.
440
+ - Use callbacks only when necessary (e.g., setting defaults, cleaning up).
441
+ - Avoid complex business logic in callbacks.
442
+ - Consider using service objects instead of callbacks for complex workflows.
443
+ - **Applies to**: Ruby/Rails
444
+ - **Tool**: Custom linter
445
+ - **Principle**: CODE_QUALITY
446
+ - **Version**: 1.0
447
+ - **Status**: activated
448
+ - **Severity**: major
449
+
450
+ ### 📘 Rule RB034 – Use decorators for view logic
451
+
452
+ - **Objective**: Keep models and views clean by separating presentation logic.
453
+ - **Details**:
454
+ - Use decorator pattern (e.g., Draper gem) to separate formatting logic from models.
455
+ - Decorators handle presentation concerns like formatting dates, currency, or generating display strings.
456
+ - Keep views focused on rendering, not logic.
457
+ - **Applies to**: Ruby/Rails
458
+ - **Tool**: Custom linter
459
+ - **Principle**: CODE_QUALITY
460
+ - **Version**: 1.0
461
+ - **Status**: activated
462
+ - **Severity**: major
463
+
464
+ ### 📘 Rule RB035 – Write comprehensive tests
465
+
466
+ - **Objective**: Ensure code quality and prevent regressions.
467
+ - **Details**:
468
+ - Write unit tests for models, services, and helpers.
469
+ - Write integration tests for controllers and request flows.
470
+ - Write system tests for critical user journeys.
471
+ - Aim for high test coverage (>80%) for business-critical code.
472
+ - **Applies to**: Ruby/Rails
473
+ - **Tool**: RSpec, Minitest, SimpleCov
474
+ - **Principle**: CODE_QUALITY
475
+ - **Version**: 1.0
476
+ - **Status**: activated
477
+ - **Severity**: critical
478
+
479
+ ### 📘 Rule RB036 – Use frozen_string_literal: true
480
+
481
+ - **Objective**: Improve memory efficiency and prepare for Ruby 4.0 string immutability.
482
+ - **Details**:
483
+ - Add `# frozen_string_literal: true` magic comment at the top of every Ruby file.
484
+ - This prevents accidental string mutations and allows the VM to optimize string allocations.
485
+ - **Applies to**: Ruby/Rails
486
+ - **Tool**: RuboCop (`Style/FrozenStringLiteralComment`)
487
+ - **Principle**: PERFORMANCE
488
+ - **Version**: 1.1
489
+ - **Status**: activated
490
+ - **Severity**: minor
491
+
492
+ ### 📘 Rule RB037 – Use 'it' as a default block parameter (Ruby 3.4+)
493
+
494
+ - **Objective**: Enhance code readability for concise block operations.
495
+ - **Details**:
496
+ - In Ruby 3.4+, use the implicit `it` keyword instead of explicit single-use block parameters like `|x|`.
497
+ - Example: `users.map { it.name }` instead of `users.map { |u| u.name }`.
498
+ - **Applies to**: Ruby 3.4+
499
+ - **Tool**: RuboCop (`Style/ItAssignment`)
500
+ - **Principle**: CODE_QUALITY
501
+ - **Version**: 1.1
502
+ - **Status**: activated
503
+ - **Severity**: minor
504
+
505
+ ### 📘 Rule RB038 – Use modern hash-based enum syntax
506
+
507
+ - **Objective**: Use the more readable and explicit enum configuration in ActiveRecord.
508
+ - **Details**:
509
+ - Prefer `enum :status, { pending: 0, active: 1 }` over the older `enum status: [:pending, :active]`.
510
+ - Using a hash explicitly maps values to database integers, preventing accidental shifts if elements are reordered.
511
+ - **Applies to**: Rails 7+
512
+ - **Tool**: RuboCop (`Rails/EnumSyntax`)
513
+ - **Principle**: CODE_QUALITY
514
+ - **Version**: 1.1
515
+ - **Status**: activated
516
+ - **Severity**: major
517
+
518
+ ### 📘 Rule RB039 – Prefer Solid Adapters for Infrastructure (Rails 8+)
519
+
520
+ - **Objective**: Simplify deployment and reduce external dependencies.
521
+ - **Details**:
522
+ - For Rails 8 projects, prefer `Solid Queue`, `Solid Cache`, and `Solid Cable` over Redis-based solutions when high-performance external scaling isn't strictly required.
523
+ - This keeps the stack "lean" by using the database for jobs and caching.
524
+ - **Applies to**: Rails 8+
525
+ - **Tool**: Manual Review
526
+ - **Principle**: ARCHITECTURE
527
+ - **Version**: 1.1
528
+ - **Status**: activated
529
+ - **Severity**: major
530
+
531
+ ### 📘 Rule RB040 – Use built-in Rails 8 Authentication for greenfield projects
532
+
533
+ - **Objective**: Use the native, lightweight authentication system to reduce dependency on Devise.
534
+ - **Details**:
535
+ - Use the `bin/rails generate authentication` command for new projects.
536
+ - Only opt for `Devise` if complex features like OmniAuth, lockable, or confirmable are required and cannot be easily implemented.
537
+ - **Applies to**: Rails 8+
538
+ - **Tool**: Manual Review
539
+ - **Principle**: ARCHITECTURE
540
+ - **Version**: 1.1
541
+ - **Status**: activated
542
+ - **Severity**: major
543
+
544
+ ### 📘 Rule RB041 – Use Async Query Loading for slow interactions
545
+
546
+ - **Objective**: Improve web performance by loading database data concurrently with view rendering.
547
+ - **Details**:
548
+ - Use `.load_async` on ActiveRecord relations when multiple independent queries are needed for a single page.
549
+ - Example: `@posts = Post.all.load_async` followed by `@users = User.all.load_async`.
550
+ - **Applies to**: Rails 7.1+
551
+ - **Tool**: Manual Review
552
+ - **Principle**: PERFORMANCE
553
+ - **Version**: 1.1
554
+ - **Status**: activated
555
+ - **Severity**: major
556
+
557
+ ### 📘 Rule RB042 – Minimize custom JavaScript with Hotwire/Turbo 2.0
558
+
559
+ - **Objective**: Focus on the Rails "Majestic Monolith" approach for better maintainability.
560
+ - **Details**:
561
+ - Prefer `Turbo Frames` and `Turbo Streams` for interaction.
562
+ - Use `Stimulus` for small client-side behaviors.
563
+ - Avoid full-blown SPA frameworks (React/Vue) unless the UI specifically requires complex client-side state management.
564
+ - **Applies to**: Rails 7+
565
+ - **Tool**: Manual Review
566
+ - **Principle**: ARCHITECTURE
567
+ - **Version**: 1.1
568
+ - **Status**: activated
569
+ - **Severity**: major
570
+
571
+ ### 📘 Rule RB043 – Use Propshaft as the default asset pipeline
572
+
573
+ - **Objective**: Use the modern, simplified asset pipeline instead of Sprockets.
574
+ - **Details**:
575
+ - For new Rails 7+ projects, use `Propshaft` to handle asset digests and paths without the complexity of Sprockets' transpilation.
576
+ - **Applies to**: Rails 7+
577
+ - **Tool**: Manual Review
578
+ - **Principle**: ARCHITECTURE
579
+ - **Version**: 1.1
580
+ - **Status**: activated
581
+ - **Severity**: minor
582
+
583
+ ### 📘 Rule RB044 – Use Structured Logging for Observability
584
+
585
+ - **Objective**: Improve log parsing and searching in production environments.
586
+ - **Details**:
587
+ - Configure `config.log_formatter = JSONFormatter.new` (or similar) in production.
588
+ - Include request IDs and user context in logs to facilitate tracing.
589
+ - **Applies to**: Ruby/Rails
590
+ - **Tool**: Lograge gem
591
+ - **Principle**: MAINTAINABILITY
592
+ - **Version**: 1.1
593
+ - **Status**: activated
594
+ - **Severity**: major
595
+
596
+ ### 📘 Rule RB045 – Use Prism as the default parser for tooling
597
+
598
+ - **Objective**: Leverage the faster, more accurate Ruby parser.
599
+ - **Details**:
600
+ - Configure tools like `RuboCop` or `SyntaxTree` to use `Prism` for parsing where supported in Ruby 3.4+.
601
+ - **Applies to**: Ruby 3.4+
602
+ - **Tool**: RuboCop (`ParserEngine: prism`)
603
+ - **Principle**: TOOLING
604
+ - **Version**: 1.1
605
+ - **Status**: activated
606
+ - **Severity**: minor
607
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sun-asterisk/sunlint",
3
- "version": "1.3.47",
3
+ "version": "1.3.49",
4
4
  "description": "☀️ SunLint - Multi-language static analysis tool for code quality and security | Sun* Engineering Standards",
5
5
  "main": "cli.js",
6
6
  "bin": {
@@ -17,7 +17,11 @@ function copyDir(src, dest) {
17
17
 
18
18
  // Clean destination
19
19
  if (fs.existsSync(dest)) {
20
- fs.rmSync(dest, { recursive: true });
20
+ if (fs.rmSync) {
21
+ fs.rmSync(dest, { recursive: true });
22
+ } else {
23
+ fs.rmdirSync(dest, { recursive: true });
24
+ }
21
25
  }
22
26
  fs.mkdirSync(dest, { recursive: true });
23
27
 
@@ -81,7 +81,11 @@ if (!fs.existsSync(SOURCE)) {
81
81
 
82
82
  // Clean destination
83
83
  if (fs.existsSync(DEST)) {
84
- fs.rmSync(DEST, { recursive: true });
84
+ if (fs.rmSync) {
85
+ fs.rmSync(DEST, { recursive: true });
86
+ } else {
87
+ fs.rmdirSync(DEST, { recursive: true });
88
+ }
85
89
  }
86
90
  fs.mkdirSync(DEST, { recursive: true });
87
91