devkill 0.12.2

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 (274) hide show
  1. package/LICENSE +21 -0
  2. package/README.es.md +253 -0
  3. package/README.id.md +238 -0
  4. package/README.md +377 -0
  5. package/README.pt.md +241 -0
  6. package/README.tr.md +242 -0
  7. package/lib/cli/cli.controller.d.ts +81 -0
  8. package/lib/cli/cli.controller.js +760 -0
  9. package/lib/cli/cli.controller.js.map +1 -0
  10. package/lib/cli/interfaces/cli-options.interface.d.ts +5 -0
  11. package/lib/cli/interfaces/cli-options.interface.js +2 -0
  12. package/lib/cli/interfaces/cli-options.interface.js.map +1 -0
  13. package/lib/cli/interfaces/command-keys.interface.d.ts +17 -0
  14. package/lib/cli/interfaces/command-keys.interface.js +2 -0
  15. package/lib/cli/interfaces/command-keys.interface.js.map +1 -0
  16. package/lib/cli/interfaces/config.interface.d.ts +17 -0
  17. package/lib/cli/interfaces/config.interface.js +2 -0
  18. package/lib/cli/interfaces/config.interface.js.map +1 -0
  19. package/lib/cli/interfaces/index.d.ts +11 -0
  20. package/lib/cli/interfaces/index.js +12 -0
  21. package/lib/cli/interfaces/index.js.map +1 -0
  22. package/lib/cli/interfaces/json-output.interface.d.ts +30 -0
  23. package/lib/cli/interfaces/json-output.interface.js +2 -0
  24. package/lib/cli/interfaces/json-output.interface.js.map +1 -0
  25. package/lib/cli/interfaces/key-press.interface.d.ts +7 -0
  26. package/lib/cli/interfaces/key-press.interface.js +2 -0
  27. package/lib/cli/interfaces/key-press.interface.js.map +1 -0
  28. package/lib/cli/interfaces/node-version.interface.d.ts +5 -0
  29. package/lib/cli/interfaces/node-version.interface.js +2 -0
  30. package/lib/cli/interfaces/node-version.interface.js.map +1 -0
  31. package/lib/cli/interfaces/stats.interface.d.ts +15 -0
  32. package/lib/cli/interfaces/stats.interface.js +2 -0
  33. package/lib/cli/interfaces/stats.interface.js.map +1 -0
  34. package/lib/cli/interfaces/ui-positions.interface.d.ts +5 -0
  35. package/lib/cli/interfaces/ui-positions.interface.js +2 -0
  36. package/lib/cli/interfaces/ui-positions.interface.js.map +1 -0
  37. package/lib/cli/interfaces/version.interface.d.ts +5 -0
  38. package/lib/cli/interfaces/version.interface.js +2 -0
  39. package/lib/cli/interfaces/version.interface.js.map +1 -0
  40. package/lib/cli/models/start-parameters.model.d.ts +7 -0
  41. package/lib/cli/models/start-parameters.model.js +25 -0
  42. package/lib/cli/models/start-parameters.model.js.map +1 -0
  43. package/lib/cli/services/console.service.d.ts +23 -0
  44. package/lib/cli/services/console.service.js +87 -0
  45. package/lib/cli/services/console.service.js.map +1 -0
  46. package/lib/cli/services/https.service.d.ts +4 -0
  47. package/lib/cli/services/https.service.js +32 -0
  48. package/lib/cli/services/https.service.js.map +1 -0
  49. package/lib/cli/services/index.d.ts +7 -0
  50. package/lib/cli/services/index.js +8 -0
  51. package/lib/cli/services/index.js.map +1 -0
  52. package/lib/cli/services/json-output.service.d.ts +20 -0
  53. package/lib/cli/services/json-output.service.js +101 -0
  54. package/lib/cli/services/json-output.service.js.map +1 -0
  55. package/lib/cli/services/results.service.d.ts +13 -0
  56. package/lib/cli/services/results.service.js +61 -0
  57. package/lib/cli/services/results.service.js.map +1 -0
  58. package/lib/cli/services/scan.service.d.ts +13 -0
  59. package/lib/cli/services/scan.service.js +79 -0
  60. package/lib/cli/services/scan.service.js.map +1 -0
  61. package/lib/cli/services/spinner.service.d.ts +9 -0
  62. package/lib/cli/services/spinner.service.js +27 -0
  63. package/lib/cli/services/spinner.service.js.map +1 -0
  64. package/lib/cli/services/ui.service.d.ts +17 -0
  65. package/lib/cli/services/ui.service.js +59 -0
  66. package/lib/cli/services/ui.service.js.map +1 -0
  67. package/lib/cli/services/update.service.d.ts +15 -0
  68. package/lib/cli/services/update.service.js +37 -0
  69. package/lib/cli/services/update.service.js.map +1 -0
  70. package/lib/cli/ui/base.ui.d.ts +28 -0
  71. package/lib/cli/ui/base.ui.js +49 -0
  72. package/lib/cli/ui/base.ui.js.map +1 -0
  73. package/lib/cli/ui/components/general.ui.d.ts +7 -0
  74. package/lib/cli/ui/components/general.ui.js +13 -0
  75. package/lib/cli/ui/components/general.ui.js.map +1 -0
  76. package/lib/cli/ui/components/header/header-ui.constants.d.ts +7 -0
  77. package/lib/cli/ui/components/header/header-ui.constants.js +7 -0
  78. package/lib/cli/ui/components/header/header-ui.constants.js.map +1 -0
  79. package/lib/cli/ui/components/header/header.ui.d.ts +18 -0
  80. package/lib/cli/ui/components/header/header.ui.js +96 -0
  81. package/lib/cli/ui/components/header/header.ui.js.map +1 -0
  82. package/lib/cli/ui/components/header/stats.ui.d.ts +25 -0
  83. package/lib/cli/ui/components/header/stats.ui.js +198 -0
  84. package/lib/cli/ui/components/header/stats.ui.js.map +1 -0
  85. package/lib/cli/ui/components/header/status.ui.d.ts +33 -0
  86. package/lib/cli/ui/components/header/status.ui.js +188 -0
  87. package/lib/cli/ui/components/header/status.ui.js.map +1 -0
  88. package/lib/cli/ui/components/help/help-command.ui.d.ts +9 -0
  89. package/lib/cli/ui/components/help/help-command.ui.js +61 -0
  90. package/lib/cli/ui/components/help/help-command.ui.js.map +1 -0
  91. package/lib/cli/ui/components/help/help.constants.d.ts +8 -0
  92. package/lib/cli/ui/components/help/help.constants.js +270 -0
  93. package/lib/cli/ui/components/help/help.constants.js.map +1 -0
  94. package/lib/cli/ui/components/help/help.ui.d.ts +30 -0
  95. package/lib/cli/ui/components/help/help.ui.js +176 -0
  96. package/lib/cli/ui/components/help/help.ui.js.map +1 -0
  97. package/lib/cli/ui/components/logs.ui.d.ts +24 -0
  98. package/lib/cli/ui/components/logs.ui.js +132 -0
  99. package/lib/cli/ui/components/logs.ui.js.map +1 -0
  100. package/lib/cli/ui/components/options.ui.d.ts +29 -0
  101. package/lib/cli/ui/components/options.ui.js +327 -0
  102. package/lib/cli/ui/components/options.ui.js.map +1 -0
  103. package/lib/cli/ui/components/profile-picker.ui.d.ts +25 -0
  104. package/lib/cli/ui/components/profile-picker.ui.js +117 -0
  105. package/lib/cli/ui/components/profile-picker.ui.js.map +1 -0
  106. package/lib/cli/ui/components/result-details.ui.d.ts +23 -0
  107. package/lib/cli/ui/components/result-details.ui.js +182 -0
  108. package/lib/cli/ui/components/result-details.ui.js.map +1 -0
  109. package/lib/cli/ui/components/results.ui.d.ts +86 -0
  110. package/lib/cli/ui/components/results.ui.js +620 -0
  111. package/lib/cli/ui/components/results.ui.js.map +1 -0
  112. package/lib/cli/ui/components/warning.ui.d.ts +12 -0
  113. package/lib/cli/ui/components/warning.ui.js +30 -0
  114. package/lib/cli/ui/components/warning.ui.js.map +1 -0
  115. package/lib/cli/ui/heavy.ui.d.ts +18 -0
  116. package/lib/cli/ui/heavy.ui.js +37 -0
  117. package/lib/cli/ui/heavy.ui.js.map +1 -0
  118. package/lib/cli/ui/index.d.ts +14 -0
  119. package/lib/cli/ui/index.js +15 -0
  120. package/lib/cli/ui/index.js.map +1 -0
  121. package/lib/constants/cli.constants.d.ts +14 -0
  122. package/lib/constants/cli.constants.js +138 -0
  123. package/lib/constants/cli.constants.js.map +1 -0
  124. package/lib/constants/index.d.ts +8 -0
  125. package/lib/constants/index.js +9 -0
  126. package/lib/constants/index.js.map +1 -0
  127. package/lib/constants/main.constants.d.ts +96 -0
  128. package/lib/constants/main.constants.js +79 -0
  129. package/lib/constants/main.constants.js.map +1 -0
  130. package/lib/constants/messages.constants.d.ts +31 -0
  131. package/lib/constants/messages.constants.js +37 -0
  132. package/lib/constants/messages.constants.js.map +1 -0
  133. package/lib/constants/options.constants.d.ts +6 -0
  134. package/lib/constants/options.constants.js +8 -0
  135. package/lib/constants/options.constants.js.map +1 -0
  136. package/lib/constants/os-service-map.constants.d.ts +10 -0
  137. package/lib/constants/os-service-map.constants.js +11 -0
  138. package/lib/constants/os-service-map.constants.js.map +1 -0
  139. package/lib/constants/result-descriptions.constants.d.ts +142 -0
  140. package/lib/constants/result-descriptions.constants.js +203 -0
  141. package/lib/constants/result-descriptions.constants.js.map +1 -0
  142. package/lib/constants/sort.result.d.ts +6 -0
  143. package/lib/constants/sort.result.js +22 -0
  144. package/lib/constants/sort.result.js.map +1 -0
  145. package/lib/constants/spinner.constants.d.ts +5 -0
  146. package/lib/constants/spinner.constants.js +88 -0
  147. package/lib/constants/spinner.constants.js.map +1 -0
  148. package/lib/constants/status.constants.d.ts +7 -0
  149. package/lib/constants/status.constants.js +9 -0
  150. package/lib/constants/status.constants.js.map +1 -0
  151. package/lib/constants/update.constants.d.ts +2 -0
  152. package/lib/constants/update.constants.js +3 -0
  153. package/lib/constants/update.constants.js.map +1 -0
  154. package/lib/constants/workers.constants.d.ts +14 -0
  155. package/lib/constants/workers.constants.js +16 -0
  156. package/lib/constants/workers.constants.js.map +1 -0
  157. package/lib/core/constants/global-ignored.constants.d.ts +1 -0
  158. package/lib/core/constants/global-ignored.constants.js +44 -0
  159. package/lib/core/constants/global-ignored.constants.js.map +1 -0
  160. package/lib/core/constants/index.d.ts +1 -0
  161. package/lib/core/constants/index.js +2 -0
  162. package/lib/core/constants/index.js.map +1 -0
  163. package/lib/core/constants/profiles.constants.d.ts +8 -0
  164. package/lib/core/constants/profiles.constants.js +138 -0
  165. package/lib/core/constants/profiles.constants.js.map +1 -0
  166. package/lib/core/devkill.d.ts +25 -0
  167. package/lib/core/devkill.js +129 -0
  168. package/lib/core/devkill.js.map +1 -0
  169. package/lib/core/index.d.ts +4 -0
  170. package/lib/core/index.js +5 -0
  171. package/lib/core/index.js.map +1 -0
  172. package/lib/core/interfaces/devkill.interface.d.ts +78 -0
  173. package/lib/core/interfaces/devkill.interface.js +2 -0
  174. package/lib/core/interfaces/devkill.interface.js.map +1 -0
  175. package/lib/core/interfaces/devkillrc-config.interface.d.ts +87 -0
  176. package/lib/core/interfaces/devkillrc-config.interface.js +12 -0
  177. package/lib/core/interfaces/devkillrc-config.interface.js.map +1 -0
  178. package/lib/core/interfaces/file-service.interface.d.ts +76 -0
  179. package/lib/core/interfaces/file-service.interface.js +2 -0
  180. package/lib/core/interfaces/file-service.interface.js.map +1 -0
  181. package/lib/core/interfaces/folder.interface.d.ts +89 -0
  182. package/lib/core/interfaces/folder.interface.js +2 -0
  183. package/lib/core/interfaces/folder.interface.js.map +1 -0
  184. package/lib/core/interfaces/index.d.ts +6 -0
  185. package/lib/core/interfaces/index.js +7 -0
  186. package/lib/core/interfaces/index.js.map +1 -0
  187. package/lib/core/interfaces/logger-service.interface.d.ts +59 -0
  188. package/lib/core/interfaces/logger-service.interface.js +2 -0
  189. package/lib/core/interfaces/logger-service.interface.js.map +1 -0
  190. package/lib/core/interfaces/npkill.interface.d.ts +78 -0
  191. package/lib/core/interfaces/npkill.interface.js +2 -0
  192. package/lib/core/interfaces/npkill.interface.js.map +1 -0
  193. package/lib/core/interfaces/npkillrc-config.interface.d.ts +87 -0
  194. package/lib/core/interfaces/npkillrc-config.interface.js +12 -0
  195. package/lib/core/interfaces/npkillrc-config.interface.js.map +1 -0
  196. package/lib/core/interfaces/profile.interface.d.ts +9 -0
  197. package/lib/core/interfaces/profile.interface.js +2 -0
  198. package/lib/core/interfaces/profile.interface.js.map +1 -0
  199. package/lib/core/interfaces/search-status.model.d.ts +35 -0
  200. package/lib/core/interfaces/search-status.model.js +48 -0
  201. package/lib/core/interfaces/search-status.model.js.map +1 -0
  202. package/lib/core/interfaces/services.interface.d.ts +26 -0
  203. package/lib/core/interfaces/services.interface.js +2 -0
  204. package/lib/core/interfaces/services.interface.js.map +1 -0
  205. package/lib/core/npkill.d.ts +25 -0
  206. package/lib/core/npkill.js +129 -0
  207. package/lib/core/npkill.js.map +1 -0
  208. package/lib/core/services/config/config-merger.d.ts +17 -0
  209. package/lib/core/services/config/config-merger.js +57 -0
  210. package/lib/core/services/config/config-merger.js.map +1 -0
  211. package/lib/core/services/config/config-validator.d.ts +3 -0
  212. package/lib/core/services/config/config-validator.js +43 -0
  213. package/lib/core/services/config/config-validator.js.map +1 -0
  214. package/lib/core/services/config/index.d.ts +4 -0
  215. package/lib/core/services/config/index.js +5 -0
  216. package/lib/core/services/config/index.js.map +1 -0
  217. package/lib/core/services/config/profile-validator.d.ts +6 -0
  218. package/lib/core/services/config/profile-validator.js +68 -0
  219. package/lib/core/services/config/profile-validator.js.map +1 -0
  220. package/lib/core/services/config/property-validators.d.ts +33 -0
  221. package/lib/core/services/config/property-validators.js +125 -0
  222. package/lib/core/services/config/property-validators.js.map +1 -0
  223. package/lib/core/services/config.service.d.ts +37 -0
  224. package/lib/core/services/config.service.js +100 -0
  225. package/lib/core/services/config.service.js.map +1 -0
  226. package/lib/core/services/files/files.service.d.ts +28 -0
  227. package/lib/core/services/files/files.service.js +207 -0
  228. package/lib/core/services/files/files.service.js.map +1 -0
  229. package/lib/core/services/files/files.worker.d.ts +1 -0
  230. package/lib/core/services/files/files.worker.js +286 -0
  231. package/lib/core/services/files/files.worker.js.map +1 -0
  232. package/lib/core/services/files/files.worker.service.d.ts +90 -0
  233. package/lib/core/services/files/files.worker.service.js +216 -0
  234. package/lib/core/services/files/files.worker.service.js.map +1 -0
  235. package/lib/core/services/files/index.d.ts +4 -0
  236. package/lib/core/services/files/index.js +5 -0
  237. package/lib/core/services/files/index.js.map +1 -0
  238. package/lib/core/services/files/unix-files.service.d.ts +9 -0
  239. package/lib/core/services/files/unix-files.service.js +28 -0
  240. package/lib/core/services/files/unix-files.service.js.map +1 -0
  241. package/lib/core/services/files/windows-files.service.d.ts +9 -0
  242. package/lib/core/services/files/windows-files.service.js +16 -0
  243. package/lib/core/services/files/windows-files.service.js.map +1 -0
  244. package/lib/core/services/index.d.ts +5 -0
  245. package/lib/core/services/index.js +6 -0
  246. package/lib/core/services/index.js.map +1 -0
  247. package/lib/core/services/logger.service.d.ts +22 -0
  248. package/lib/core/services/logger.service.js +84 -0
  249. package/lib/core/services/logger.service.js.map +1 -0
  250. package/lib/core/services/profiles.service.d.ts +54 -0
  251. package/lib/core/services/profiles.service.js +86 -0
  252. package/lib/core/services/profiles.service.js.map +1 -0
  253. package/lib/core/services/stream.service.d.ts +12 -0
  254. package/lib/core/services/stream.service.js +39 -0
  255. package/lib/core/services/stream.service.js.map +1 -0
  256. package/lib/dirname.d.ts +2 -0
  257. package/lib/dirname.js +6 -0
  258. package/lib/dirname.js.map +1 -0
  259. package/lib/index.d.ts +2 -0
  260. package/lib/index.js +11 -0
  261. package/lib/index.js.map +1 -0
  262. package/lib/main.d.ts +2 -0
  263. package/lib/main.js +19 -0
  264. package/lib/main.js.map +1 -0
  265. package/lib/utils/get-file-content.d.ts +1 -0
  266. package/lib/utils/get-file-content.js +6 -0
  267. package/lib/utils/get-file-content.js.map +1 -0
  268. package/lib/utils/is-safe-to-delete.d.ts +1 -0
  269. package/lib/utils/is-safe-to-delete.js +9 -0
  270. package/lib/utils/is-safe-to-delete.js.map +1 -0
  271. package/lib/utils/unit-conversions.d.ts +11 -0
  272. package/lib/utils/unit-conversions.js +54 -0
  273. package/lib/utils/unit-conversions.js.map +1 -0
  274. package/package.json +96 -0
@@ -0,0 +1,100 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { homedir } from 'node:os';
3
+ import { join } from 'node:path';
4
+ import { applyFileConfigProperties, validateConfig } from './config/index.js';
5
+ const DEFAULT_CONFIG_FILENAME = '.devkillrc';
6
+ /**
7
+ * Service responsible for loading and parsing .devkillrc configuration files.
8
+ */
9
+ export class ConfigService {
10
+ /**
11
+ * Loads configuration with priority order:
12
+ * 1. Custom path specified via --config parameter
13
+ * 2. Current working directory ./.devkillrc
14
+ * 3. User's home directory ~/.devkillrc
15
+ * @param customPath Optional custom path to a configuration file
16
+ * @returns Configuration load result containing the parsed config or error information
17
+ */
18
+ loadConfig(customPath) {
19
+ const configPath = this.resolveConfigPath(customPath);
20
+ if (!existsSync(configPath)) {
21
+ return {
22
+ config: null,
23
+ configPath,
24
+ error: customPath
25
+ ? `Custom config file not found: ${configPath}`
26
+ : undefined,
27
+ };
28
+ }
29
+ try {
30
+ const fileContent = readFileSync(configPath, 'utf-8');
31
+ const parsedConfig = JSON.parse(fileContent);
32
+ const validationResult = validateConfig(parsedConfig);
33
+ if (!validationResult.isValid) {
34
+ return {
35
+ configPath,
36
+ config: null,
37
+ error: validationResult.error,
38
+ };
39
+ }
40
+ return {
41
+ config: parsedConfig,
42
+ configPath,
43
+ };
44
+ }
45
+ catch (error) {
46
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
47
+ return {
48
+ config: null,
49
+ configPath,
50
+ error: `Failed to parse config file: ${errorMessage}.`,
51
+ };
52
+ }
53
+ }
54
+ /**
55
+ * Resolves the configuration file path based on priority order.
56
+ * Priority: custom path > cwd > home directory
57
+ * @param customPath Optional custom path specified by user
58
+ * @returns Resolved configuration file path
59
+ */
60
+ resolveConfigPath(customPath) {
61
+ // Priority 1: Custom path from --config flag
62
+ if (customPath) {
63
+ return customPath;
64
+ }
65
+ // Priority 2: Current working directory
66
+ const cwdPath = join(process.cwd(), DEFAULT_CONFIG_FILENAME);
67
+ if (existsSync(cwdPath)) {
68
+ return cwdPath;
69
+ }
70
+ // Priority 3: User's home directory
71
+ return join(homedir(), DEFAULT_CONFIG_FILENAME);
72
+ }
73
+ /**
74
+ * Merges configuration from .devkillrc with a base configuration.
75
+ * Config file values take precedence over base values.
76
+ * @param baseConfig Base configuration object
77
+ * @param fileConfig Configuration loaded from .devkillrc
78
+ * @returns Merged configuration
79
+ */
80
+ mergeConfigs(baseConfig, fileConfig) {
81
+ if (!fileConfig) {
82
+ return baseConfig;
83
+ }
84
+ const merged = { ...baseConfig };
85
+ applyFileConfigProperties(merged, baseConfig, fileConfig);
86
+ return merged;
87
+ }
88
+ /**
89
+ * Gets custom profiles from the configuration file.
90
+ * @param config Configuration loaded from .devkillrc
91
+ * @returns Record of user-defined profiles
92
+ */
93
+ getUserDefinedProfiles(config) {
94
+ if (!config || !config.profiles) {
95
+ return {};
96
+ }
97
+ return config.profiles;
98
+ }
99
+ }
100
+ //# sourceMappingURL=config.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.service.js","sourceRoot":"","sources":["../../../src/core/services/config.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAMjC,OAAO,EAAE,yBAAyB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAE9E,MAAM,uBAAuB,GAAG,YAAY,CAAC;AAE7C;;GAEG;AACH,MAAM,OAAO,aAAa;IACxB;;;;;;;OAOG;IACH,UAAU,CAAC,UAAmB;QAC5B,MAAM,UAAU,GAAG,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;QAEtD,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC5B,OAAO;gBACL,MAAM,EAAE,IAAI;gBACZ,UAAU;gBACV,KAAK,EAAE,UAAU;oBACf,CAAC,CAAC,iCAAiC,UAAU,EAAE;oBAC/C,CAAC,CAAC,SAAS;aACd,CAAC;QACJ,CAAC;QAED,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;YACtD,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAqB,CAAC;YAEjE,MAAM,gBAAgB,GAAG,cAAc,CAAC,YAAY,CAAC,CAAC;YACtD,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC;gBAC9B,OAAO;oBACL,UAAU;oBACV,MAAM,EAAE,IAAI;oBACZ,KAAK,EAAE,gBAAgB,CAAC,KAAK;iBAC9B,CAAC;YACJ,CAAC;YAED,OAAO;gBACL,MAAM,EAAE,YAAY;gBACpB,UAAU;aACX,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,YAAY,GAChB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;YAC3D,OAAO;gBACL,MAAM,EAAE,IAAI;gBACZ,UAAU;gBACV,KAAK,EAAE,gCAAgC,YAAY,GAAG;aACvD,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACK,iBAAiB,CAAC,UAAmB;QAC3C,6CAA6C;QAC7C,IAAI,UAAU,EAAE,CAAC;YACf,OAAO,UAAU,CAAC;QACpB,CAAC;QAED,wCAAwC;QACxC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,uBAAuB,CAAC,CAAC;QAC7D,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACxB,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,oCAAoC;QACpC,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,uBAAuB,CAAC,CAAC;IAClD,CAAC;IAED;;;;;;OAMG;IACH,YAAY,CACV,UAAa,EACb,UAAmC;QAEnC,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,OAAO,UAAU,CAAC;QACpB,CAAC;QAED,MAAM,MAAM,GAAG,EAAE,GAAG,UAAU,EAAE,CAAC;QACjC,yBAAyB,CACvB,MAAiC,EACjC,UAAqC,EACrC,UAAU,CACX,CAAC;QAEF,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;OAIG;IACH,sBAAsB,CACpB,MAA+B;QAE/B,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YAChC,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,OAAO,MAAM,CAAC,QAAQ,CAAC;IACzB,CAAC;CACF"}
@@ -0,0 +1,28 @@
1
+ import type { GetNewestFileResult, IFileService, IFileStat, RiskAnalysis, ScanOptions } from '@core/index.js';
2
+ import type { IsValidRootFolderResult } from '@core/interfaces/devkill.interface.js';
3
+ import { type Observable } from 'rxjs';
4
+ import type { FileWorkerService } from './files.worker.service.js';
5
+ export declare abstract class FileService implements IFileService {
6
+ fileWorkerService: FileWorkerService;
7
+ constructor(fileWorkerService: FileWorkerService);
8
+ abstract deleteDir(path: string): Promise<boolean>;
9
+ listDir(path: string, params: ScanOptions): Observable<string>;
10
+ getFolderSize(path: string): Observable<number>;
11
+ stopScan(): void;
12
+ /** Used for dry-run or testing. */
13
+ fakeDeleteDir(): Promise<boolean>;
14
+ isValidRootFolder(path: string): IsValidRootFolderResult;
15
+ /**
16
+ * > Why dangerous?
17
+ * It is probable that if the node_module is included in some hidden directory, it is
18
+ * required by some application like "spotify", "vscode" or "Discord" and deleting it
19
+ * would imply breaking the application (until the dependencies are reinstalled).
20
+ *
21
+ * In the case of macOS applications and Windows AppData directory, these locations often contain
22
+ * application-specific data or configurations that should not be tampered with. Deleting directories
23
+ * from these locations could potentially disrupt the normal operation of these applications.
24
+ */
25
+ isDangerous(originalPath: string): RiskAnalysis;
26
+ getRecentModificationInDir(path: string): Promise<GetNewestFileResult | null>;
27
+ getFileStatsInDir(dirname: string): Promise<IFileStat[]>;
28
+ }
@@ -0,0 +1,207 @@
1
+ import fs, { accessSync, statSync } from 'node:fs';
2
+ import { readdir, stat } from 'node:fs/promises';
3
+ import os from 'node:os';
4
+ import path from 'node:path';
5
+ import { Subject, map } from 'rxjs';
6
+ export class FileService {
7
+ fileWorkerService;
8
+ constructor(fileWorkerService) {
9
+ this.fileWorkerService = fileWorkerService;
10
+ }
11
+ listDir(path, params) {
12
+ const stream$ = new Subject();
13
+ this.fileWorkerService.startScan(stream$, { ...params, rootPath: path });
14
+ return stream$;
15
+ }
16
+ getFolderSize(path) {
17
+ const stream$ = new Subject();
18
+ this.fileWorkerService.getFolderSize(stream$, path);
19
+ return stream$.pipe(map((data) => data));
20
+ }
21
+ stopScan() {
22
+ this.fileWorkerService.stopScan();
23
+ }
24
+ /** Used for dry-run or testing. */
25
+ async fakeDeleteDir() {
26
+ const randomDelay = Math.floor(Math.random() * 4000 + 200);
27
+ await new Promise((resolve) => setTimeout(resolve, randomDelay));
28
+ return true;
29
+ }
30
+ isValidRootFolder(path) {
31
+ let stat;
32
+ try {
33
+ stat = statSync(path);
34
+ }
35
+ catch {
36
+ return { isValid: false, invalidReason: 'The path does not exist.' };
37
+ }
38
+ if (!stat.isDirectory()) {
39
+ return {
40
+ isValid: false,
41
+ invalidReason: 'The path must point to a directory.',
42
+ };
43
+ }
44
+ try {
45
+ accessSync(path, fs.constants.R_OK);
46
+ }
47
+ catch {
48
+ return {
49
+ isValid: false,
50
+ invalidReason: 'Cannot read the specified path.',
51
+ };
52
+ }
53
+ return { isValid: true };
54
+ }
55
+ /**
56
+ * > Why dangerous?
57
+ * It is probable that if the node_module is included in some hidden directory, it is
58
+ * required by some application like "spotify", "vscode" or "Discord" and deleting it
59
+ * would imply breaking the application (until the dependencies are reinstalled).
60
+ *
61
+ * In the case of macOS applications and Windows AppData directory, these locations often contain
62
+ * application-specific data or configurations that should not be tampered with. Deleting directories
63
+ * from these locations could potentially disrupt the normal operation of these applications.
64
+ */
65
+ isDangerous(originalPath) {
66
+ const isUnc = originalPath.startsWith('\\\\') || originalPath.startsWith('//');
67
+ const absolutePath = isUnc
68
+ ? originalPath
69
+ : path.isAbsolute(originalPath)
70
+ ? originalPath
71
+ : path.resolve(process.cwd(), originalPath);
72
+ const normalizePath = (p) => {
73
+ let normalized = p.replace(/\\/g, '/').toLowerCase();
74
+ if (/^[a-z]:\//.test(normalized)) {
75
+ normalized = normalized.substring(2);
76
+ }
77
+ return normalized;
78
+ };
79
+ const normalizedPath = normalizePath(absolutePath);
80
+ const normalizedOriginal = normalizePath(originalPath);
81
+ const home = process.env.HOME ?? process.env.USERPROFILE ?? os.homedir() ?? '';
82
+ let isInHome = false;
83
+ let normalizedHome = '';
84
+ if (home !== '') {
85
+ // Normalize the home path. If it's already absolute, just normalize separators.
86
+ // Only use path.resolve() if it's a relative path to avoid cross-platform issues.
87
+ const homeAbsolute = path.isAbsolute(home) ? home : path.resolve(home);
88
+ normalizedHome = normalizePath(homeAbsolute);
89
+ isInHome =
90
+ normalizedPath === normalizedHome ||
91
+ normalizedPath.startsWith(`${normalizedHome}/`);
92
+ }
93
+ if (isInHome) {
94
+ // Relative path inside HOME (without the HOME prefix)
95
+ let rel = normalizedPath.slice(normalizedHome.length);
96
+ if (rel.startsWith('/'))
97
+ rel = rel.slice(1);
98
+ // Special sensitive locations inside HOME
99
+ if (rel === '.config' || rel.startsWith('.config/')) {
100
+ return {
101
+ isSensitive: true,
102
+ reason: 'Contains user configuration data (~/.config)',
103
+ };
104
+ }
105
+ if (rel === '.local/share' || rel.startsWith('.local/share/')) {
106
+ return {
107
+ isSensitive: true,
108
+ reason: 'User data folder (~/.local/share)',
109
+ };
110
+ }
111
+ // ~/.cache is safe to delete but system-wide, mark as sensitive
112
+ if (rel === '.cache' || rel.startsWith('.cache/')) {
113
+ return {
114
+ isSensitive: true,
115
+ reason: 'System-wide cache directory (~/.cache)',
116
+ };
117
+ }
118
+ // Whitelisted hidden top-level folders inside HOME
119
+ if (/^\.(npm|pnpm)(\/|$)/.test(rel)) {
120
+ return { isSensitive: false };
121
+ }
122
+ // Only consider TOP-LEVEL hidden entries inside HOME as sensitive
123
+ const topLevel = rel.split('/')[0] ?? '';
124
+ if (topLevel.startsWith('.') &&
125
+ topLevel !== '.' &&
126
+ topLevel !== '..' &&
127
+ !['.npm', '.pnpm'].includes(topLevel)) {
128
+ return { isSensitive: true, reason: 'Contains unsafe hidden folder' };
129
+ }
130
+ }
131
+ // macOs
132
+ if (/\/applications\/[^/]+\.app\//.test(normalizedPath)) {
133
+ return { isSensitive: true, reason: 'Inside macOS .app package' };
134
+ }
135
+ // Windows UNC network paths (e.g., \\server\\share -> //server/share)
136
+ if (normalizedOriginal.startsWith('//')) {
137
+ if (/\/\.[^/]+(\/|$)/.test(normalizedOriginal)) {
138
+ return { isSensitive: true, reason: 'Hidden path in network share' };
139
+ }
140
+ }
141
+ // Windows
142
+ if (normalizedPath.includes('/appdata/roaming')) {
143
+ return {
144
+ isSensitive: true,
145
+ reason: 'Inside Windows AppData Roaming folder',
146
+ };
147
+ }
148
+ if (normalizedPath.includes('/appdata/local')) {
149
+ if (/\/\.(cache|npm|pnpm)(\/|$)/.test(normalizedPath)) {
150
+ return { isSensitive: false };
151
+ }
152
+ return {
153
+ isSensitive: true,
154
+ reason: 'Inside Windows AppData Local folder',
155
+ };
156
+ }
157
+ if (/program files( \(x86\))?\//.test(normalizedPath)) {
158
+ return { isSensitive: true, reason: 'Inside Program Files folder' };
159
+ }
160
+ return { isSensitive: false };
161
+ }
162
+ async getRecentModificationInDir(path) {
163
+ const files = await this.getFileStatsInDir(path);
164
+ const sorted = files.sort((a, b) => b.modificationTime - a.modificationTime);
165
+ const newestFile = sorted.length > 0 ? sorted[0] : null;
166
+ if (!newestFile) {
167
+ return null;
168
+ }
169
+ return {
170
+ timestamp: newestFile.modificationTime,
171
+ name: newestFile.path.split('/').pop() || '',
172
+ path: newestFile.path,
173
+ };
174
+ }
175
+ async getFileStatsInDir(dirname) {
176
+ const ignoredFolders = new Set(['node_modules', '.git', 'coverage', 'dist']);
177
+ try {
178
+ const items = await readdir(dirname, { withFileTypes: true });
179
+ const files = [];
180
+ await Promise.all(items.map(async (item) => {
181
+ if (item.isDirectory()) {
182
+ if (ignoredFolders.has(item.name.toLowerCase()))
183
+ return;
184
+ const subFiles = await this.getFileStatsInDir(`${dirname}/${item.name}`).catch(() => []);
185
+ files.push(...subFiles);
186
+ }
187
+ else {
188
+ try {
189
+ const filePath = `${dirname}/${item.name}`;
190
+ const fileStat = await stat(filePath);
191
+ files.push({
192
+ path: filePath,
193
+ modificationTime: fileStat.mtimeMs / 1000,
194
+ });
195
+ }
196
+ catch { }
197
+ }
198
+ }));
199
+ return files;
200
+ }
201
+ catch {
202
+ // If we can't read the directory (e.g., permission denied), return empty array.
203
+ return [];
204
+ }
205
+ }
206
+ }
207
+ //# sourceMappingURL=files.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.service.js","sourceRoot":"","sources":["../../../../src/core/services/files/files.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,286 @@
1
+ import EventEmitter from 'node:events';
2
+ import { lstat, opendir, readdir } from 'node:fs/promises';
3
+ import { join } from 'node:path';
4
+ import { parentPort } from 'node:worker_threads';
5
+ import { EVENTS, MAX_PROCS } from '../../../constants/workers.constants.js';
6
+ import { GLOBAL_IGNORE } from '../../constants/global-ignored.constants.js';
7
+ const ETaskOperation = {
8
+ explore: 0,
9
+ getFolderSize: 1,
10
+ getFolderSizeChild: 2,
11
+ };
12
+ (() => {
13
+ let id = 0;
14
+ let fileWalker;
15
+ let tunnel;
16
+ if (parentPort === null) {
17
+ throw new Error('Worker must be spawned from a parent thread.');
18
+ }
19
+ parentPort.on('message', (message) => {
20
+ if (message?.type === EVENTS.startup) {
21
+ id = message.value.id;
22
+ tunnel = message.value.channel;
23
+ fileWalker = new FileWalker();
24
+ initTunnelListeners();
25
+ initFileWalkerListeners();
26
+ notifyWorkerReady();
27
+ }
28
+ });
29
+ function notifyWorkerReady() {
30
+ tunnel.postMessage({
31
+ type: EVENTS.alive,
32
+ value: null,
33
+ });
34
+ }
35
+ function initTunnelListeners() {
36
+ tunnel.on('message', (message) => {
37
+ if (message?.type === EVENTS.exploreConfig) {
38
+ fileWalker.setSearchConfig(message.value);
39
+ }
40
+ if (message?.type === EVENTS.explore) {
41
+ fileWalker.enqueueTask(message.value.path, ETaskOperation.explore);
42
+ }
43
+ if (message?.type === EVENTS.getFolderSize) {
44
+ fileWalker.enqueueTask(message.value.path, ETaskOperation.getFolderSize, true);
45
+ }
46
+ if (message?.type === EVENTS.stop) {
47
+ fileWalker.stop();
48
+ }
49
+ });
50
+ }
51
+ function initFileWalkerListeners() {
52
+ fileWalker.events.on('newResult', ({ results }) => {
53
+ tunnel.postMessage({
54
+ type: EVENTS.scanResult,
55
+ value: { results, workerId: id, pending: fileWalker.pendingJobs },
56
+ });
57
+ });
58
+ fileWalker.events.on('folderSizeResult', (result) => {
59
+ tunnel.postMessage({
60
+ type: EVENTS.GetSizeResult,
61
+ value: {
62
+ results: result,
63
+ workerId: id,
64
+ pending: fileWalker.pendingJobs,
65
+ },
66
+ });
67
+ });
68
+ }
69
+ })();
70
+ class FileWalker {
71
+ events = new EventEmitter();
72
+ searchConfig = {
73
+ rootPath: '',
74
+ targets: [''],
75
+ exclude: [],
76
+ };
77
+ taskQueue = [];
78
+ completedTasks = 0;
79
+ procs = 0;
80
+ shouldStop = false;
81
+ setSearchConfig(params) {
82
+ this.searchConfig = params;
83
+ }
84
+ stop() {
85
+ this.shouldStop = true;
86
+ }
87
+ enqueueTask(path, operation, priorize = false, sizeCollector) {
88
+ if (this.shouldStop) {
89
+ return;
90
+ }
91
+ const task = { path, operation };
92
+ if (sizeCollector) {
93
+ task.sizeCollector = sizeCollector;
94
+ }
95
+ if (priorize) {
96
+ this.taskQueue.unshift(task);
97
+ }
98
+ else {
99
+ this.taskQueue.push(task);
100
+ }
101
+ this.processQueue();
102
+ }
103
+ async run(path) {
104
+ this.updateProcs(1);
105
+ try {
106
+ const dir = await opendir(path);
107
+ await this.analizeDir(path, dir);
108
+ }
109
+ catch {
110
+ this.completeTask();
111
+ }
112
+ }
113
+ async analizeDir(path, dir) {
114
+ const results = [];
115
+ let entry = null;
116
+ // biome-ignore lint/suspicious/noAssignInExpressions: idiomatic async directory iteration pattern
117
+ while ((entry = await dir.read().catch(() => null)) != null) {
118
+ this.newDirEntry(path, entry, results);
119
+ }
120
+ this.events.emit('newResult', { results });
121
+ await dir.close();
122
+ this.completeTask();
123
+ if (this.taskQueue.length === 0 && this.procs === 0) {
124
+ this.completeAll();
125
+ }
126
+ }
127
+ async runGetFolderSize(path) {
128
+ this.updateProcs(1);
129
+ try {
130
+ const collector = {
131
+ total: 0,
132
+ pending: 1,
133
+ onComplete: (finalSize) => {
134
+ this.events.emit('folderSizeResult', { path, size: finalSize });
135
+ },
136
+ };
137
+ this.enqueueTask(path, ETaskOperation.getFolderSizeChild, false, collector);
138
+ this.completeTask();
139
+ }
140
+ catch {
141
+ // If anything fails during setup, emit size 0 and complete
142
+ this.events.emit('folderSizeResult', { path, size: 0 });
143
+ this.completeTask();
144
+ }
145
+ }
146
+ async runGetFolderSizeChild(path, collector) {
147
+ if (!collector) {
148
+ // Should not happen with proper initiation, but safe.
149
+ this.completeTask();
150
+ return;
151
+ }
152
+ this.updateProcs(1);
153
+ try {
154
+ const entries = await readdir(path, { withFileTypes: true });
155
+ let currentLevelSize = 0;
156
+ const directoriesToProcess = [];
157
+ for (let i = 0; i < entries.length; i += 100) {
158
+ const chunk = entries.slice(i, i + 100);
159
+ await Promise.all(chunk.map(async (entry) => {
160
+ const fullPath = join(path, entry.name);
161
+ try {
162
+ if (entry.isSymbolicLink()) {
163
+ return;
164
+ }
165
+ if (entry.isDirectory()) {
166
+ currentLevelSize += 4096; // General directory size
167
+ directoriesToProcess.push(fullPath);
168
+ }
169
+ else {
170
+ const stats = await lstat(fullPath);
171
+ const size = typeof stats.blocks === 'number'
172
+ ? stats.blocks * 512
173
+ : stats.size;
174
+ currentLevelSize += size;
175
+ }
176
+ }
177
+ catch {
178
+ // Ignore permissions errors.
179
+ }
180
+ }));
181
+ }
182
+ collector.total += currentLevelSize;
183
+ collector.pending += directoriesToProcess.length;
184
+ for (const dirPath of directoriesToProcess) {
185
+ this.enqueueTask(dirPath, ETaskOperation.getFolderSizeChild, false, collector);
186
+ }
187
+ }
188
+ catch {
189
+ // Ignore permissions errors.
190
+ }
191
+ finally {
192
+ collector.pending -= 1;
193
+ if (collector.pending === 0) {
194
+ collector.onComplete(collector.total);
195
+ }
196
+ this.completeTask();
197
+ }
198
+ }
199
+ newDirEntry(path, entry, results) {
200
+ if (entry.isSymbolicLink() || !entry.isDirectory()) {
201
+ return;
202
+ }
203
+ const isTarget = this.isTargetFolder(entry.name);
204
+ if (GLOBAL_IGNORE.has(entry.name) && !isTarget) {
205
+ return;
206
+ }
207
+ const subpath = join(path, entry.name);
208
+ if (this.isExcluded(subpath)) {
209
+ return;
210
+ }
211
+ results.push({
212
+ path: subpath,
213
+ isTarget,
214
+ });
215
+ }
216
+ isExcluded(path) {
217
+ if (this.searchConfig.exclude == null) {
218
+ return false;
219
+ }
220
+ return this.searchConfig.exclude.some((ex) => path.includes(ex));
221
+ }
222
+ isTargetFolder(path) {
223
+ return this.searchConfig.targets.includes(path);
224
+ }
225
+ completeTask() {
226
+ this.updateProcs(-1);
227
+ this.processQueue();
228
+ this.completedTasks++;
229
+ }
230
+ updateProcs(value) {
231
+ this.procs += value;
232
+ }
233
+ processQueue() {
234
+ while (this.procs < MAX_PROCS &&
235
+ this.taskQueue.length > 0 &&
236
+ !this.shouldStop) {
237
+ const task = this.taskQueue.shift();
238
+ if (!task?.path) {
239
+ continue;
240
+ }
241
+ switch (task.operation) {
242
+ case ETaskOperation.explore:
243
+ this.run(task.path).catch(() => {
244
+ this.completeTask();
245
+ });
246
+ break;
247
+ case ETaskOperation.getFolderSize:
248
+ this.runGetFolderSize(task.path).catch(() => {
249
+ // If runGetFolderSize fails, we need to emit a size of 0
250
+ // Otherwise the stream will hang forever
251
+ this.events.emit('folderSizeResult', { path: task.path, size: 0 });
252
+ });
253
+ break;
254
+ case ETaskOperation.getFolderSizeChild:
255
+ this.runGetFolderSizeChild(task.path, task.sizeCollector).catch(() => {
256
+ // Ensure we always decrement the collector even on errors
257
+ if (task.sizeCollector == null) {
258
+ // This shouldn't happen, but if it does, we can't recover properly
259
+ // The best we can do is not crash
260
+ return;
261
+ }
262
+ task.sizeCollector.pending -= 1;
263
+ if (task.sizeCollector.pending === 0) {
264
+ task.sizeCollector.onComplete(task.sizeCollector.total);
265
+ }
266
+ this.completeTask();
267
+ });
268
+ break;
269
+ }
270
+ }
271
+ }
272
+ completeAll() {
273
+ // Any future action.
274
+ }
275
+ /* get stats(): WorkerStats {
276
+ return {
277
+ pendingSearchTasks: this.taskQueue.length,
278
+ completedSearchTasks: this.completedTasks,
279
+ procs: this.procs,
280
+ };
281
+ } */
282
+ get pendingJobs() {
283
+ return this.taskQueue.length;
284
+ }
285
+ }
286
+ //# sourceMappingURL=files.worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.worker.js","sourceRoot":"","sources":["../../../../src/core/services/files/files.worker.ts"],"names":[],"mappings":"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"}