@iobroker/js-controller-cli 7.2.3 → 8.0.0-alpha.2-20260923-99da17fcc

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 (225) hide show
  1. package/build/cjs/index.js +3 -3
  2. package/build/cjs/lib/_Types.d.ts +8 -1
  3. package/build/cjs/lib/cli/cliCert.d.ts +7 -4
  4. package/build/cjs/lib/cli/cliCert.js +10 -6
  5. package/build/cjs/lib/cli/cliCert.js.map +2 -2
  6. package/build/cjs/lib/cli/cliCommand.d.ts +63 -15
  7. package/build/cjs/lib/cli/cliCommand.js +8 -1
  8. package/build/cjs/lib/cli/cliCommand.js.map +2 -2
  9. package/build/cjs/lib/cli/cliCompact.d.ts +5 -2
  10. package/build/cjs/lib/cli/cliCompact.js +9 -2
  11. package/build/cjs/lib/cli/cliCompact.js.map +2 -2
  12. package/build/cjs/lib/cli/cliDebug.d.ts +5 -2
  13. package/build/cjs/lib/cli/cliDebug.js +8 -1
  14. package/build/cjs/lib/cli/cliDebug.js.map +2 -2
  15. package/build/cjs/lib/cli/cliHost.d.ts +13 -10
  16. package/build/cjs/lib/cli/cliHost.js +13 -5
  17. package/build/cjs/lib/cli/cliHost.js.map +2 -2
  18. package/build/cjs/lib/cli/cliLogs.d.ts +9 -3
  19. package/build/cjs/lib/cli/cliLogs.js +12 -1
  20. package/build/cjs/lib/cli/cliLogs.js.map +2 -2
  21. package/build/cjs/lib/cli/cliMessage.d.ts +2 -1
  22. package/build/cjs/lib/cli/cliMessage.js +5 -0
  23. package/build/cjs/lib/cli/cliMessage.js.map +2 -2
  24. package/build/cjs/lib/cli/cliObjects.d.ts +21 -18
  25. package/build/cjs/lib/cli/cliObjects.js +51 -33
  26. package/build/cjs/lib/cli/cliObjects.js.map +2 -2
  27. package/build/cjs/lib/cli/cliPlugin.d.ts +3 -3
  28. package/build/cjs/lib/cli/cliPlugin.js +6 -0
  29. package/build/cjs/lib/cli/cliPlugin.js.map +2 -2
  30. package/build/cjs/lib/cli/cliProcess.d.ts +17 -7
  31. package/build/cjs/lib/cli/cliProcess.js +77 -24
  32. package/build/cjs/lib/cli/cliProcess.js.map +3 -3
  33. package/build/cjs/lib/cli/cliStates.d.ts +7 -4
  34. package/build/cjs/lib/cli/cliStates.js +14 -6
  35. package/build/cjs/lib/cli/cliStates.js.map +2 -2
  36. package/build/cjs/lib/cli/cliTools.js +11 -0
  37. package/build/cjs/lib/cli/cliTools.js.map +1 -1
  38. package/build/cjs/lib/cli/messages.js +47 -46
  39. package/build/cjs/lib/cli/messages.js.map +1 -1
  40. package/build/cjs/lib/progressBar.d.ts +59 -0
  41. package/build/cjs/lib/progressBar.js +115 -0
  42. package/build/cjs/lib/progressBar.js.map +7 -0
  43. package/build/cjs/lib/setup/customError.d.ts +4 -0
  44. package/build/cjs/lib/setup/customError.js +7 -0
  45. package/build/cjs/lib/setup/customError.js.map +2 -2
  46. package/build/cjs/lib/setup/dbConnection.js +69 -64
  47. package/build/cjs/lib/setup/dbConnection.js.map +3 -3
  48. package/build/cjs/lib/setup/formatters.d.ts +4 -4
  49. package/build/cjs/lib/setup/formatters.js +5 -0
  50. package/build/cjs/lib/setup/formatters.js.map +2 -2
  51. package/build/cjs/lib/setup/multihostClient.js +6 -2
  52. package/build/cjs/lib/setup/multihostClient.js.map +1 -1
  53. package/build/cjs/lib/setup/pluginInfos.d.ts +5 -0
  54. package/build/cjs/lib/setup/pluginInfos.js +2 -0
  55. package/build/cjs/lib/setup/pluginInfos.js.map +2 -2
  56. package/build/cjs/lib/setup/setupBackup.d.ts +53 -0
  57. package/build/cjs/lib/setup/setupBackup.js +125 -14
  58. package/build/cjs/lib/setup/setupBackup.js.map +3 -3
  59. package/build/cjs/lib/setup/setupInstall.d.ts +66 -15
  60. package/build/cjs/lib/setup/setupInstall.js +282 -28
  61. package/build/cjs/lib/setup/setupInstall.js.map +2 -2
  62. package/build/cjs/lib/setup/setupLicense.d.ts +13 -0
  63. package/build/cjs/lib/setup/setupLicense.js +33 -2
  64. package/build/cjs/lib/setup/setupLicense.js.map +2 -2
  65. package/build/cjs/lib/setup/setupList.d.ts +55 -1
  66. package/build/cjs/lib/setup/setupList.js +78 -24
  67. package/build/cjs/lib/setup/setupList.js.map +3 -3
  68. package/build/cjs/lib/setup/setupMultihost.d.ts +7 -0
  69. package/build/cjs/lib/setup/setupMultihost.js +78 -11
  70. package/build/cjs/lib/setup/setupMultihost.js.map +3 -3
  71. package/build/cjs/lib/setup/setupPacketManager.d.ts +10 -0
  72. package/build/cjs/lib/setup/setupPacketManager.js +16 -6
  73. package/build/cjs/lib/setup/setupPacketManager.js.map +2 -2
  74. package/build/cjs/lib/setup/setupRepo.d.ts +19 -0
  75. package/build/cjs/lib/setup/setupRepo.js +141 -13
  76. package/build/cjs/lib/setup/setupRepo.js.map +2 -2
  77. package/build/cjs/lib/setup/setupSetup.d.ts +34 -0
  78. package/build/cjs/lib/setup/setupSetup.js +209 -35
  79. package/build/cjs/lib/setup/setupSetup.js.map +3 -3
  80. package/build/cjs/lib/setup/setupUpgrade.d.ts +13 -2
  81. package/build/cjs/lib/setup/setupUpgrade.js +72 -12
  82. package/build/cjs/lib/setup/setupUpgrade.js.map +2 -2
  83. package/build/cjs/lib/setup/setupUpload.d.ts +77 -1
  84. package/build/cjs/lib/setup/setupUpload.js +152 -9
  85. package/build/cjs/lib/setup/setupUpload.js.map +2 -2
  86. package/build/cjs/lib/setup/setupUsers.d.ts +44 -14
  87. package/build/cjs/lib/setup/setupUsers.js +330 -17
  88. package/build/cjs/lib/setup/setupUsers.js.map +2 -2
  89. package/build/cjs/lib/setup/setupVendor.d.ts +14 -1
  90. package/build/cjs/lib/setup/setupVendor.js +40 -8
  91. package/build/cjs/lib/setup/setupVendor.js.map +2 -2
  92. package/build/cjs/lib/setup/setupVisDebug.d.ts +16 -2
  93. package/build/cjs/lib/setup/setupVisDebug.js +41 -17
  94. package/build/cjs/lib/setup/setupVisDebug.js.map +3 -3
  95. package/build/cjs/lib/setup/utils.d.ts +1 -1
  96. package/build/cjs/lib/setup/utils.js +13 -9
  97. package/build/cjs/lib/setup/utils.js.map +3 -3
  98. package/build/cjs/lib/setup.d.ts +1 -1
  99. package/build/cjs/lib/setup.js +858 -1758
  100. package/build/cjs/lib/setup.js.map +3 -3
  101. package/build/esm/lib/_Types.d.ts +8 -1
  102. package/build/esm/lib/_Types.d.ts.map +1 -1
  103. package/build/esm/lib/cli/cliCert.d.ts +7 -4
  104. package/build/esm/lib/cli/cliCert.d.ts.map +1 -1
  105. package/build/esm/lib/cli/cliCert.js +6 -6
  106. package/build/esm/lib/cli/cliCert.js.map +1 -1
  107. package/build/esm/lib/cli/cliCommand.d.ts +63 -15
  108. package/build/esm/lib/cli/cliCommand.d.ts.map +1 -1
  109. package/build/esm/lib/cli/cliCommand.js +4 -1
  110. package/build/esm/lib/cli/cliCommand.js.map +1 -1
  111. package/build/esm/lib/cli/cliCompact.d.ts +5 -2
  112. package/build/esm/lib/cli/cliCompact.d.ts.map +1 -1
  113. package/build/esm/lib/cli/cliCompact.js +5 -2
  114. package/build/esm/lib/cli/cliCompact.js.map +1 -1
  115. package/build/esm/lib/cli/cliDebug.d.ts +5 -2
  116. package/build/esm/lib/cli/cliDebug.d.ts.map +1 -1
  117. package/build/esm/lib/cli/cliDebug.js +4 -1
  118. package/build/esm/lib/cli/cliDebug.js.map +1 -1
  119. package/build/esm/lib/cli/cliHost.d.ts +13 -10
  120. package/build/esm/lib/cli/cliHost.d.ts.map +1 -1
  121. package/build/esm/lib/cli/cliHost.js +8 -5
  122. package/build/esm/lib/cli/cliHost.js.map +1 -1
  123. package/build/esm/lib/cli/cliLogs.d.ts +9 -3
  124. package/build/esm/lib/cli/cliLogs.d.ts.map +1 -1
  125. package/build/esm/lib/cli/cliLogs.js +8 -1
  126. package/build/esm/lib/cli/cliLogs.js.map +1 -1
  127. package/build/esm/lib/cli/cliMessage.d.ts +2 -1
  128. package/build/esm/lib/cli/cliMessage.d.ts.map +1 -1
  129. package/build/esm/lib/cli/cliMessage.js +1 -0
  130. package/build/esm/lib/cli/cliMessage.js.map +1 -1
  131. package/build/esm/lib/cli/cliObjects.d.ts +21 -18
  132. package/build/esm/lib/cli/cliObjects.d.ts.map +1 -1
  133. package/build/esm/lib/cli/cliObjects.js +44 -38
  134. package/build/esm/lib/cli/cliObjects.js.map +1 -1
  135. package/build/esm/lib/cli/cliPlugin.d.ts +3 -3
  136. package/build/esm/lib/cli/cliPlugin.d.ts.map +1 -1
  137. package/build/esm/lib/cli/cliPlugin.js +1 -1
  138. package/build/esm/lib/cli/cliPlugin.js.map +1 -1
  139. package/build/esm/lib/cli/cliProcess.d.ts +17 -7
  140. package/build/esm/lib/cli/cliProcess.d.ts.map +1 -1
  141. package/build/esm/lib/cli/cliProcess.js +73 -12
  142. package/build/esm/lib/cli/cliProcess.js.map +1 -1
  143. package/build/esm/lib/cli/cliStates.d.ts +7 -4
  144. package/build/esm/lib/cli/cliStates.d.ts.map +1 -1
  145. package/build/esm/lib/cli/cliStates.js +6 -2
  146. package/build/esm/lib/cli/cliStates.js.map +1 -1
  147. package/build/esm/lib/progressBar.d.ts +59 -0
  148. package/build/esm/lib/progressBar.d.ts.map +1 -0
  149. package/build/esm/lib/progressBar.js +104 -0
  150. package/build/esm/lib/progressBar.js.map +1 -0
  151. package/build/esm/lib/setup/customError.d.ts +4 -0
  152. package/build/esm/lib/setup/customError.d.ts.map +1 -1
  153. package/build/esm/lib/setup/customError.js +3 -0
  154. package/build/esm/lib/setup/customError.js.map +1 -1
  155. package/build/esm/lib/setup/dbConnection.d.ts.map +1 -1
  156. package/build/esm/lib/setup/dbConnection.js +10 -13
  157. package/build/esm/lib/setup/dbConnection.js.map +1 -1
  158. package/build/esm/lib/setup/formatters.d.ts +4 -4
  159. package/build/esm/lib/setup/formatters.js +4 -4
  160. package/build/esm/lib/setup/pluginInfos.d.ts +5 -0
  161. package/build/esm/lib/setup/pluginInfos.d.ts.map +1 -1
  162. package/build/esm/lib/setup/pluginInfos.js +5 -0
  163. package/build/esm/lib/setup/pluginInfos.js.map +1 -1
  164. package/build/esm/lib/setup/setupBackup.d.ts +53 -0
  165. package/build/esm/lib/setup/setupBackup.d.ts.map +1 -1
  166. package/build/esm/lib/setup/setupBackup.js +132 -13
  167. package/build/esm/lib/setup/setupBackup.js.map +1 -1
  168. package/build/esm/lib/setup/setupInstall.d.ts +66 -15
  169. package/build/esm/lib/setup/setupInstall.d.ts.map +1 -1
  170. package/build/esm/lib/setup/setupInstall.js +309 -23
  171. package/build/esm/lib/setup/setupInstall.js.map +1 -1
  172. package/build/esm/lib/setup/setupLicense.d.ts +13 -0
  173. package/build/esm/lib/setup/setupLicense.d.ts.map +1 -1
  174. package/build/esm/lib/setup/setupLicense.js +31 -1
  175. package/build/esm/lib/setup/setupLicense.js.map +1 -1
  176. package/build/esm/lib/setup/setupList.d.ts +55 -1
  177. package/build/esm/lib/setup/setupList.d.ts.map +1 -1
  178. package/build/esm/lib/setup/setupList.js +61 -8
  179. package/build/esm/lib/setup/setupList.js.map +1 -1
  180. package/build/esm/lib/setup/setupMultihost.d.ts +7 -0
  181. package/build/esm/lib/setup/setupMultihost.d.ts.map +1 -1
  182. package/build/esm/lib/setup/setupMultihost.js +85 -6
  183. package/build/esm/lib/setup/setupMultihost.js.map +1 -1
  184. package/build/esm/lib/setup/setupPacketManager.d.ts +10 -0
  185. package/build/esm/lib/setup/setupPacketManager.d.ts.map +1 -1
  186. package/build/esm/lib/setup/setupPacketManager.js +9 -0
  187. package/build/esm/lib/setup/setupPacketManager.js.map +1 -1
  188. package/build/esm/lib/setup/setupRepo.d.ts +19 -0
  189. package/build/esm/lib/setup/setupRepo.d.ts.map +1 -1
  190. package/build/esm/lib/setup/setupRepo.js +164 -14
  191. package/build/esm/lib/setup/setupRepo.js.map +1 -1
  192. package/build/esm/lib/setup/setupSetup.d.ts +34 -0
  193. package/build/esm/lib/setup/setupSetup.d.ts.map +1 -1
  194. package/build/esm/lib/setup/setupSetup.js +218 -21
  195. package/build/esm/lib/setup/setupSetup.js.map +1 -1
  196. package/build/esm/lib/setup/setupUpgrade.d.ts +13 -2
  197. package/build/esm/lib/setup/setupUpgrade.d.ts.map +1 -1
  198. package/build/esm/lib/setup/setupUpgrade.js +70 -6
  199. package/build/esm/lib/setup/setupUpgrade.js.map +1 -1
  200. package/build/esm/lib/setup/setupUpload.d.ts +77 -1
  201. package/build/esm/lib/setup/setupUpload.d.ts.map +1 -1
  202. package/build/esm/lib/setup/setupUpload.js +164 -7
  203. package/build/esm/lib/setup/setupUpload.js.map +1 -1
  204. package/build/esm/lib/setup/setupUsers.d.ts +44 -14
  205. package/build/esm/lib/setup/setupUsers.d.ts.map +1 -1
  206. package/build/esm/lib/setup/setupUsers.js +346 -14
  207. package/build/esm/lib/setup/setupUsers.js.map +1 -1
  208. package/build/esm/lib/setup/setupVendor.d.ts +14 -1
  209. package/build/esm/lib/setup/setupVendor.d.ts.map +1 -1
  210. package/build/esm/lib/setup/setupVendor.js +33 -2
  211. package/build/esm/lib/setup/setupVendor.js.map +1 -1
  212. package/build/esm/lib/setup/setupVisDebug.d.ts +16 -2
  213. package/build/esm/lib/setup/setupVisDebug.d.ts.map +1 -1
  214. package/build/esm/lib/setup/setupVisDebug.js +39 -14
  215. package/build/esm/lib/setup/setupVisDebug.js.map +1 -1
  216. package/build/esm/lib/setup/utils.d.ts +1 -1
  217. package/build/esm/lib/setup/utils.d.ts.map +1 -1
  218. package/build/esm/lib/setup/utils.js +2 -4
  219. package/build/esm/lib/setup/utils.js.map +1 -1
  220. package/build/esm/lib/setup.d.ts +1 -1
  221. package/build/esm/lib/setup.d.ts.map +1 -1
  222. package/build/esm/lib/setup.js +959 -1910
  223. package/build/esm/lib/setup.js.map +1 -1
  224. package/build/tsconfig.build.tsbuildinfo +1 -1
  225. package/package.json +14 -14
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/setup/setupMultihost.ts"],
4
- "sourcesContent": ["import fs from 'fs-extra';\nimport path from 'node:path';\nimport readline from 'node:readline';\nimport readlineSync from 'readline-sync';\nimport prompt from 'prompt';\n\nimport { tools } from '@iobroker/js-controller-common';\nimport { isLocalObjectsDbServer, isLocalStatesDbServer } from '@iobroker/js-controller-common';\nimport type { Client as ObjectsRedisClient } from '@iobroker/db-objects-redis';\nimport { MHClient, type BrowseResultEntry } from './multihostClient.js';\n\ninterface MHParams {\n secure?: boolean;\n persist?: boolean;\n debug?: boolean;\n}\n\n/** Options for Multihost CLI */\nexport interface CLIMultihostOptions {\n /** Redis client for objects DB */\n objects: ObjectsRedisClient;\n /** Additional parameters */\n params?: MHParams;\n}\n\n/**\n * Multihost CLI class\n * Handles multihost related commands\n */\nexport class Multihost {\n private readonly configName: string;\n private params: MHParams;\n private objects: ObjectsRedisClient;\n\n /**\n * Constructor\n *\n * @param options options for the Multihost CLI\n */\n constructor(options: CLIMultihostOptions) {\n this.configName = tools.getConfigFileName();\n this.params = options.params || {};\n this.objects = options.objects;\n }\n\n /**\n * Retrieve config (iobroker.json content)\n */\n getConfig(): ioBroker.IoBrokerJson {\n let config;\n // read actual configuration\n try {\n if (fs.existsSync(this.configName)) {\n config = fs.readJsonSync(this.configName);\n } else {\n config = fs.readJsonSync(\n path.join(tools.getControllerDir(), 'conf', `${tools.appName.toLowerCase()}-dist.json`),\n );\n }\n } catch {\n config = fs.readJsonSync(\n path.join(tools.getControllerDir(), 'conf', `${tools.appName.toLowerCase()}-dist.json`),\n );\n }\n return config;\n }\n\n /**\n * Show hosts on CLI\n *\n * @param list list of hosts\n */\n showHosts(list: BrowseResultEntry[]): void {\n if (!list || !list.length) {\n console.info(\n 'No Multihost server found. Make sure iobroker is running on the host where you enabled multihost discovery (and it is not this host)!',\n );\n } else {\n for (let i = 0; i < list.length; i++) {\n console.log(\n `${i + 1} | ${list[i].hostname!.padStart(20)} | ${list[i].slave ? 'slave' : ' host'} | ${list[\n i\n ].ip!.padStart(20)} | ${JSON.stringify(list[i].info)}`,\n );\n }\n }\n }\n\n /**\n * Start MH browsing\n */\n async browse(): Promise<BrowseResultEntry[]> {\n const mhClient = new MHClient();\n try {\n return await mhClient.browse(2_000, !!this.params.debug);\n } catch (e) {\n throw new Error(`Multihost discovery client: Cannot browse: ${e.message}`);\n }\n }\n\n /**\n * Show MH state on CLI\n *\n * @param config iob config\n * @param changed if config has changed\n */\n private async showMHState(config: ioBroker.IoBrokerJson, changed: boolean): Promise<void> {\n if (config.multihostService.enabled) {\n let warningShown = false;\n\n const hasLocalObjectsServer = await isLocalObjectsDbServer(config.objects.type, config.objects.host, true);\n\n if (hasLocalObjectsServer) {\n console.log('Changing objects server to accept connections on all IP addresses.');\n config.objects.host = tools.getListenAllAddress();\n changed = true;\n } else if (config.objects.type === 'redis') {\n warningShown = true;\n console.log(\n `Please check the binding of redis service. By default it is only local: http://download.redis.io/redis-stable/redis.conf\\nChange \"bind 127.0.0.1\" to \"bind ${tools.getListenAllAddress()}\" or to others.`,\n );\n } else {\n warningShown = true;\n console.log(\n `Please check the binding of the configured ${config.objects.type} server to allow remote connections.`,\n );\n }\n\n const hasLocalStatesServer = await isLocalStatesDbServer(config.states.type, config.states.host, true);\n\n if (hasLocalStatesServer) {\n console.log('Changing states server to accept connections on all IP addresses.');\n config.states.host = tools.getListenAllAddress();\n changed = true;\n } else if (config.states.type === 'redis') {\n !warningShown &&\n console.log(\n `Please check the binding of redis service. By default it is only local: http://download.redis.io/redis-stable/redis.conf\\nChange \"bind 127.0.0.1\" to \"bind ${tools.getListenAllAddress()}\" or to others.`,\n );\n } else {\n !warningShown &&\n console.log(\n `Please check the binding of the configured ${config.states.type} server to allow remote connections.`,\n );\n }\n }\n if (!changed) {\n console.log('No configuration change needed.');\n } else {\n fs.writeFileSync(this.configName, JSON.stringify(config, null, 2));\n console.log('Please restart ioBroker for the changes to take effect: \"iobroker restart\"');\n }\n console.log('\\n');\n console.log(`Multihost discovery server: ${config.multihostService.enabled ? 'enabled' : 'disabled'}`);\n console.log(`Discovery authentication: ${config.multihostService.secure ? 'enabled' : 'disabled'}`);\n console.log(\n `Persistent activation: ${\n config.multihostService.enabled && config.multihostService.persist ? 'enabled' : 'disabled'\n }`,\n );\n console.log(\n `Objects: ${config.objects.type} on ${Array.isArray(config.objects.host) ? config.objects.host.join(', ') : config.objects.host}`,\n );\n console.log(\n `States: ${config.states.type} on ${Array.isArray(config.states.host) ? config.states.host.join(', ') : config.states.host}`,\n );\n }\n\n /**\n * Enables or disables the multihost discovery server in the config json\n *\n * @param isEnable - if the server should be activated or deactivated\n * @param callback - callback function to be executed\n */\n enable(isEnable: boolean, callback: (err?: Error) => void): void {\n let changed = false;\n const config = this.getConfig();\n config.multihostService = config.multihostService || { enabled: false, secure: true };\n\n if (isEnable && !config.multihostService.enabled) {\n changed = true;\n config.multihostService.enabled = true;\n config.multihostService.password = '';\n console.log(\n 'Multihost discovery server activated on this host. If iobroker is currently not running please start before trying to discover this host.',\n );\n console.log(\n 'Important: Multihost discovery works with UDP packets. Make sure they are routed correctly in your network. If you use Docker you also need to configure this correctly.',\n );\n if (!this.params.persist) {\n console.log(\n 'Multihost discovery will be automatically deactivated after 15 minutes. If you want to activate it permanently use the --persist flag',\n );\n }\n } else if (!isEnable && config.multihostService.enabled) {\n changed = true;\n config.multihostService.enabled = false;\n config.multihostService.password = '';\n console.log('Multihost discovery server deactivated on this host.');\n }\n if (this.params.secure === undefined) {\n this.params.secure = true;\n }\n\n this.params.persist = !!this.params.persist;\n\n if (\n isEnable &&\n (config.multihostService.secure !== this.params.secure ||\n (config.multihostService.secure && !config.multihostService.password) ||\n config.multihostService.persist !== this.params.persist)\n ) {\n changed = true;\n config.multihostService.secure = this.params.secure;\n config.multihostService.persist = this.params.persist;\n console.log(`Discovery authentication ${this.params.secure ? 'activated' : 'deactivated'}.`);\n if (config.multihostService.secure) {\n prompt.message = '';\n prompt.delimiter = '';\n const schema = {\n properties: {\n password: {\n description: 'Enter secret phrase for connection:',\n pattern: /^[^'\"]+$/,\n message: 'No \" are allowed',\n hidden: true,\n },\n passwordRepeat: {\n description: 'Repeat secret phrase for connection:',\n pattern: /^[^'\"]+$/,\n message: 'No \" are allowed',\n hidden: true,\n },\n },\n };\n prompt.start();\n\n prompt.get(schema, (_err, password) => {\n if (password?.password) {\n if (password.password !== password.passwordRepeat) {\n callback(new Error('Secret phrases are not equal!'));\n } else {\n this.objects.getObject('system.config', (_err, obj) => {\n config.multihostService.password = tools.encrypt(\n obj!.native.secret,\n password.password as string,\n );\n this.showMHState(config, changed);\n callback();\n });\n }\n } else {\n callback(new Error('No secret phrase entered!'));\n }\n });\n } else {\n this.showMHState(config, changed);\n callback();\n }\n } else {\n this.showMHState(config, changed);\n callback();\n }\n }\n\n /**\n * Show the MH status\n */\n status(): void {\n const config = this.getConfig();\n config.multihostService = config.multihostService || { enabled: false, secure: true };\n this.showMHState(config, false);\n }\n\n /**\n * Read password from cli\n */\n readPassword(): string {\n return readlineSync.question('Enter secret phrase for connection: ', { hideEchoBack: true });\n }\n\n /**\n * Connect to given MH server\n *\n * @param mhClient MultiHost Client used for connection\n * @param ip IP address of server\n * @param pass password\n * @param callback callback\n */\n connectHelper(mhClient: MHClient, ip: string, pass: string, callback: (err?: Error) => void): void {\n mhClient.connect(ip, pass, async (err, oObjects, oStates, ipHost) => {\n if (err) {\n callback(new Error(`Cannot connect to \"${ip}\": ${err.message}`));\n } else if (oObjects && oStates) {\n const config = this.getConfig();\n config.objects = oObjects;\n config.states = oStates;\n\n const hasLocalObjectsServer = await isLocalObjectsDbServer(\n config.objects.type,\n config.objects.host,\n true,\n );\n const hasLocalStatesServer = await isLocalStatesDbServer(config.states.type, config.states.host, true);\n\n if (hasLocalObjectsServer || hasLocalStatesServer) {\n callback(\n new Error(\n `IP Address of the remote host is ${tools.getLocalAddress()}. Connections from this host will not be accepted. Please change the configuration of this host to accept remote connections.`,\n ),\n );\n } else if (\n (!Array.isArray(config.states.host) || config.states.host.length === 1) &&\n (!Array.isArray(config.objects.host) || config.objects.host.length === 1)\n ) {\n const sHost = Array.isArray(config.states.host) ? config.states.host[0] : config.states.host;\n // If server delivers 0.0.0.0 or ::, set to actual IP of the host\n if (tools.isListenAllAddress(sHost)) {\n config.states.host = ipHost ?? '';\n }\n const oHost = Array.isArray(config.objects.host) ? config.objects.host[0] : config.objects.host;\n // If server delivers 0.0.0.0 or ::, set to actual IP of the host\n if (tools.isListenAllAddress(oHost)) {\n config.objects.host = ipHost ?? '';\n }\n\n fs.writeFileSync(this.configName, JSON.stringify(config, null, 2));\n console.log('Config ok. Please restart ioBroker: \"iobroker restart\"');\n callback();\n } else {\n // Find if any of the hosts is \"listen all\" or reachable\n if (Array.isArray(config.states.host)) {\n config.states.host = config.states.host.map((sHost: string) =>\n tools.isListenAllAddress(sHost) ? (ipHost ?? '') : sHost,\n );\n }\n if (Array.isArray(config.objects.host)) {\n config.objects.host = config.objects.host.map((oHost: string) =>\n tools.isListenAllAddress(oHost) ? (ipHost ?? '') : oHost,\n );\n }\n\n fs.writeFileSync(this.configName, JSON.stringify(config, null, 2));\n console.log('Config ok. Please restart ioBroker: \"iobroker restart\"');\n callback();\n }\n } else {\n callback(new Error('No configuration received!'));\n }\n });\n }\n\n /**\n * Connect to MH Server\n *\n * @param index index of host to connect to\n * @param pass password\n * @param callback callback\n */\n async connect(\n index: number | null,\n pass: string | null,\n callback: (err?: Error, list?: BrowseResultEntry[]) => void,\n ): Promise<void> {\n if (typeof pass === 'function') {\n callback = pass;\n pass = null;\n }\n if (typeof index === 'function') {\n callback = index;\n index = null;\n }\n\n const mhClient = new MHClient();\n let list: BrowseResultEntry[];\n\n try {\n list = await mhClient.browse(2_000, !!this.params.debug);\n } catch (e) {\n callback(new Error(`Cannot browse: ${e.message}`));\n return;\n }\n\n this.showHosts(list);\n\n if (index !== null && index !== undefined && index > 0) {\n if (list && index < list.length + 1) {\n if (!pass) {\n callback(new Error('No password defined: please use \"multihost connect <NUMBER> <PASSWORD>\"'));\n } else {\n this.connectHelper(mhClient, list[index - 1].ip!, pass, callback);\n }\n } else {\n callback(new Error(`Invalid index: ${index}`));\n }\n } else if (list && list.length) {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n rl.question('Please select host [1]: ', answer => {\n if (answer === '' || answer === null || answer === undefined) {\n index = 1;\n }\n index = parseInt(answer, 10) - 1;\n const listEntry = list[index];\n if (!listEntry) {\n rl.close();\n callback(new Error(`Invalid index: ${answer}`));\n } else {\n if (listEntry.auth) {\n const password = this.readPassword();\n if (password) {\n this.connectHelper(mhClient, listEntry.ip!, password, callback);\n } else {\n callback(new Error('No password entered!'));\n }\n } else {\n this.connectHelper(mhClient, listEntry.ip!, '', callback);\n }\n }\n });\n } else {\n callback(undefined, list);\n }\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["import_js_controller_common", "fs", "path", "prompt", "_err", "readlineSync", "readline"]
4
+ "sourcesContent": ["import fs from 'fs-extra';\nimport path from 'node:path';\nimport readline from 'node:readline';\nimport readlineSync from 'readline-sync';\nimport prompt from 'prompt';\n\nimport { isLocalObjectsDbServer, isLocalStatesDbServer, tools, EXIT_CODES } from '@iobroker/js-controller-common';\nimport type { Client as ObjectsRedisClient } from '@iobroker/db-objects-redis';\nimport { MHClient, type BrowseResultEntry } from './multihostClient.js';\nimport type { ProcessCommandOptions } from '@/lib/cli/cliCommand.js';\nimport { dbConnect } from '@/lib/setup/dbConnection.js';\n\ninterface MHParams {\n secure?: boolean;\n persist?: boolean;\n debug?: boolean;\n}\n\n/** Options for Multihost CLI */\nexport interface CLIMultihostOptions {\n /** Redis client for objects DB */\n objects: ObjectsRedisClient;\n /** Additional parameters */\n params?: MHParams;\n}\n\n/**\n * Multihost CLI class\n * Handles multihost related commands\n */\nexport class Multihost {\n private readonly configName: string;\n private params: MHParams;\n private objects: ObjectsRedisClient;\n\n /**\n * Constructor\n *\n * @param options options for the Multihost CLI\n */\n constructor(options: CLIMultihostOptions) {\n this.configName = tools.getConfigFileName();\n this.params = options.params || {};\n this.objects = options.objects;\n }\n\n /**\n * Retrieve config (iobroker.json content)\n */\n getConfig(): ioBroker.IoBrokerJson {\n let config;\n // read actual configuration\n try {\n if (fs.existsSync(this.configName)) {\n config = fs.readJsonSync(this.configName);\n } else {\n config = fs.readJsonSync(\n path.join(tools.getControllerDir(), 'conf', `${tools.appName.toLowerCase()}-dist.json`),\n );\n }\n } catch {\n config = fs.readJsonSync(\n path.join(tools.getControllerDir(), 'conf', `${tools.appName.toLowerCase()}-dist.json`),\n );\n }\n return config;\n }\n\n /**\n * Show hosts on CLI\n *\n * @param list list of hosts\n */\n showHosts(list: BrowseResultEntry[]): void {\n if (!list || !list.length) {\n console.info(\n 'No Multihost server found. Make sure iobroker is running on the host where you enabled multihost discovery (and it is not this host)!',\n );\n } else {\n for (let i = 0; i < list.length; i++) {\n console.log(\n `${i + 1} | ${list[i].hostname!.padStart(20)} | ${list[i].slave ? 'slave' : ' host'} | ${list[\n i\n ].ip!.padStart(20)} | ${JSON.stringify(list[i].info)}`,\n );\n }\n }\n }\n\n /**\n * Start MH browsing\n */\n async browse(): Promise<BrowseResultEntry[]> {\n const mhClient = new MHClient();\n try {\n return await mhClient.browse(2_000, !!this.params.debug);\n } catch (e) {\n throw new Error(`Multihost discovery client: Cannot browse: ${e.message}`);\n }\n }\n\n /**\n * Show MH state on CLI\n *\n * @param config iob config\n * @param changed if config has changed\n */\n private async showMHState(config: ioBroker.IoBrokerJson, changed: boolean): Promise<void> {\n if (config.multihostService.enabled) {\n let warningShown = false;\n\n const hasLocalObjectsServer = await isLocalObjectsDbServer(config.objects.type, config.objects.host, true);\n\n if (hasLocalObjectsServer) {\n console.log('Changing objects server to accept connections on all IP addresses.');\n config.objects.host = tools.getListenAllAddress();\n changed = true;\n } else if (config.objects.type === 'redis') {\n warningShown = true;\n console.log(\n `Please check the binding of redis service. By default it is only local: http://download.redis.io/redis-stable/redis.conf\\nChange \"bind 127.0.0.1\" to \"bind ${tools.getListenAllAddress()}\" or to others.`,\n );\n } else {\n warningShown = true;\n console.log(\n `Please check the binding of the configured ${config.objects.type} server to allow remote connections.`,\n );\n }\n\n const hasLocalStatesServer = await isLocalStatesDbServer(config.states.type, config.states.host, true);\n\n if (hasLocalStatesServer) {\n console.log('Changing states server to accept connections on all IP addresses.');\n config.states.host = tools.getListenAllAddress();\n changed = true;\n } else if (config.states.type === 'redis') {\n !warningShown &&\n console.log(\n `Please check the binding of redis service. By default it is only local: http://download.redis.io/redis-stable/redis.conf\\nChange \"bind 127.0.0.1\" to \"bind ${tools.getListenAllAddress()}\" or to others.`,\n );\n } else {\n !warningShown &&\n console.log(\n `Please check the binding of the configured ${config.states.type} server to allow remote connections.`,\n );\n }\n }\n if (!changed) {\n console.log('No configuration change needed.');\n } else {\n fs.writeFileSync(this.configName, JSON.stringify(config, null, 2));\n console.log('Please restart ioBroker for the changes to take effect: \"iobroker restart\"');\n }\n console.log('\\n');\n console.log(`Multihost discovery server: ${config.multihostService.enabled ? 'enabled' : 'disabled'}`);\n console.log(`Discovery authentication: ${config.multihostService.secure ? 'enabled' : 'disabled'}`);\n console.log(\n `Persistent activation: ${\n config.multihostService.enabled && config.multihostService.persist ? 'enabled' : 'disabled'\n }`,\n );\n console.log(\n `Objects: ${config.objects.type} on ${Array.isArray(config.objects.host) ? config.objects.host.join(', ') : config.objects.host}`,\n );\n console.log(\n `States: ${config.states.type} on ${Array.isArray(config.states.host) ? config.states.host.join(', ') : config.states.host}`,\n );\n }\n\n /**\n * Enables or disables the multihost discovery server in the config json\n *\n * @param isEnable - if the server should be activated or deactivated\n * @param callback - callback function to be executed\n */\n enable(isEnable: boolean, callback: (err?: Error) => void): void {\n let changed = false;\n const config = this.getConfig();\n config.multihostService = config.multihostService || { enabled: false, secure: true };\n\n if (isEnable && !config.multihostService.enabled) {\n changed = true;\n config.multihostService.enabled = true;\n config.multihostService.password = '';\n console.log(\n 'Multihost discovery server activated on this host. If iobroker is currently not running please start before trying to discover this host.',\n );\n console.log(\n 'Important: Multihost discovery works with UDP packets. Make sure they are routed correctly in your network. If you use Docker you also need to configure this correctly.',\n );\n if (!this.params.persist) {\n console.log(\n 'Multihost discovery will be automatically deactivated after 15 minutes. If you want to activate it permanently use the --persist flag',\n );\n }\n } else if (!isEnable && config.multihostService.enabled) {\n changed = true;\n config.multihostService.enabled = false;\n config.multihostService.password = '';\n console.log('Multihost discovery server deactivated on this host.');\n }\n if (this.params.secure === undefined) {\n this.params.secure = true;\n }\n\n this.params.persist = !!this.params.persist;\n\n if (\n isEnable &&\n (config.multihostService.secure !== this.params.secure ||\n (config.multihostService.secure && !config.multihostService.password) ||\n config.multihostService.persist !== this.params.persist)\n ) {\n changed = true;\n config.multihostService.secure = this.params.secure;\n config.multihostService.persist = this.params.persist;\n console.log(`Discovery authentication ${this.params.secure ? 'activated' : 'deactivated'}.`);\n if (config.multihostService.secure) {\n prompt.message = '';\n prompt.delimiter = '';\n const schema = {\n properties: {\n password: {\n description: 'Enter secret phrase for connection:',\n pattern: /^[^'\"]+$/,\n message: 'No \" are allowed',\n hidden: true,\n },\n passwordRepeat: {\n description: 'Repeat secret phrase for connection:',\n pattern: /^[^'\"]+$/,\n message: 'No \" are allowed',\n hidden: true,\n },\n },\n };\n prompt.start();\n\n prompt.get(schema, (_err, password) => {\n if (password?.password) {\n if (password.password !== password.passwordRepeat) {\n callback(new Error('Secret phrases are not equal!'));\n } else {\n this.objects.getObject('system.config', (_err, obj) => {\n config.multihostService.password = tools.encrypt(\n obj!.native.secret,\n password.password as string,\n );\n this.showMHState(config, changed).catch(e =>\n console.error(`Cannot show multihost state: ${e.message}`),\n );\n callback();\n });\n }\n } else {\n callback(new Error('No secret phrase entered!'));\n }\n });\n } else {\n this.showMHState(config, changed).catch(e =>\n console.error(`Cannot show multihost state: ${e.message}`),\n );\n callback();\n }\n } else {\n this.showMHState(config, changed).catch(e => console.error(`Cannot show multihost state: ${e.message}`));\n callback();\n }\n }\n\n /**\n * Show the MH status\n */\n status(): void {\n const config = this.getConfig();\n config.multihostService = config.multihostService || { enabled: false, secure: true };\n this.showMHState(config, false).catch(e => console.error(`Cannot show multihost state: ${e.message}`));\n }\n\n /**\n * Read password from cli\n */\n readPassword(): string {\n return readlineSync.question('Enter secret phrase for connection: ', { hideEchoBack: true });\n }\n\n /**\n * Connect to given MH server\n *\n * @param mhClient MultiHost Client used for connection\n * @param ip IP address of server\n * @param pass password\n * @param callback callback\n */\n connectHelper(mhClient: MHClient, ip: string, pass: string, callback: (err?: Error) => void): void {\n mhClient.connect(ip, pass, async (err, oObjects, oStates, ipHost) => {\n if (err) {\n callback(new Error(`Cannot connect to \"${ip}\": ${err.message}`));\n } else if (oObjects && oStates) {\n const config = this.getConfig();\n config.objects = oObjects;\n config.states = oStates;\n\n const hasLocalObjectsServer = await isLocalObjectsDbServer(\n config.objects.type,\n config.objects.host,\n true,\n );\n const hasLocalStatesServer = await isLocalStatesDbServer(config.states.type, config.states.host, true);\n\n if (hasLocalObjectsServer || hasLocalStatesServer) {\n callback(\n new Error(\n `IP Address of the remote host is ${tools.getLocalAddress()}. Connections from this host will not be accepted. Please change the configuration of this host to accept remote connections.`,\n ),\n );\n } else if (\n (!Array.isArray(config.states.host) || config.states.host.length === 1) &&\n (!Array.isArray(config.objects.host) || config.objects.host.length === 1)\n ) {\n const sHost = Array.isArray(config.states.host) ? config.states.host[0] : config.states.host;\n // If server delivers 0.0.0.0 or ::, set to actual IP of the host\n if (tools.isListenAllAddress(sHost)) {\n config.states.host = ipHost ?? '';\n }\n const oHost = Array.isArray(config.objects.host) ? config.objects.host[0] : config.objects.host;\n // If server delivers 0.0.0.0 or ::, set to actual IP of the host\n if (tools.isListenAllAddress(oHost)) {\n config.objects.host = ipHost ?? '';\n }\n\n fs.writeFileSync(this.configName, JSON.stringify(config, null, 2));\n console.log('Config ok. Please restart ioBroker: \"iobroker restart\"');\n callback();\n } else {\n // Find if any of the hosts is \"listen all\" or reachable\n if (Array.isArray(config.states.host)) {\n config.states.host = config.states.host.map((sHost: string) =>\n tools.isListenAllAddress(sHost) ? (ipHost ?? '') : sHost,\n );\n }\n if (Array.isArray(config.objects.host)) {\n config.objects.host = config.objects.host.map((oHost: string) =>\n tools.isListenAllAddress(oHost) ? (ipHost ?? '') : oHost,\n );\n }\n\n fs.writeFileSync(this.configName, JSON.stringify(config, null, 2));\n console.log('Config ok. Please restart ioBroker: \"iobroker restart\"');\n callback();\n }\n } else {\n callback(new Error('No configuration received!'));\n }\n });\n }\n\n /**\n * Connect to MH Server\n *\n * @param index index of host to connect to\n * @param pass password\n * @param callback callback\n */\n async connect(\n index: number | null,\n pass: string | null,\n callback: (err?: Error, list?: BrowseResultEntry[]) => void,\n ): Promise<void> {\n if (typeof pass === 'function') {\n callback = pass;\n pass = null;\n }\n if (typeof index === 'function') {\n callback = index;\n index = null;\n }\n\n const mhClient = new MHClient();\n let list: BrowseResultEntry[];\n\n try {\n list = await mhClient.browse(2_000, !!this.params.debug);\n } catch (e) {\n callback(new Error(`Cannot browse: ${e.message}`));\n return;\n }\n\n this.showHosts(list);\n\n if (index !== null && index !== undefined && index > 0) {\n if (list && index < list.length + 1) {\n if (!pass) {\n callback(new Error('No password defined: please use \"multihost connect <NUMBER> <PASSWORD>\"'));\n } else {\n this.connectHelper(mhClient, list[index - 1].ip!, pass, callback);\n }\n } else {\n callback(new Error(`Invalid index: ${index}`));\n }\n } else if (list && list.length) {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n rl.question('Please select host [1]: ', answer => {\n if (answer === '' || answer === null || answer === undefined) {\n index = 1;\n }\n index = parseInt(answer, 10) - 1;\n const listEntry = list[index];\n if (!listEntry) {\n rl.close();\n callback(new Error(`Invalid index: ${answer}`));\n } else {\n if (listEntry.auth) {\n const password = this.readPassword();\n if (password) {\n this.connectHelper(mhClient, listEntry.ip!, password, callback);\n } else {\n callback(new Error('No password entered!'));\n }\n } else {\n this.connectHelper(mhClient, listEntry.ip!, '', callback);\n }\n }\n });\n } else {\n callback(undefined, list);\n }\n }\n}\n\n/**\n * Handles the `multihost` / `mh` CLI command.\n *\n * @param options the process command options\n */\nexport function processCommandMultihost(options: ProcessCommandOptions): void {\n const { args, params, callback } = options;\n\n const cmd = args[0];\n if (\n cmd !== 'c' &&\n cmd !== 'connect' &&\n cmd !== 's' &&\n cmd !== 'status' &&\n cmd !== 'b' &&\n cmd !== 'browse' &&\n cmd !== 'e' &&\n cmd !== 'enable' &&\n cmd !== 'd' &&\n cmd !== 'disable'\n ) {\n console.log('Invalid parameters. Following is possible: enable, browse, connect, status');\n return void callback(EXIT_CODES.INVALID_ARGUMENTS);\n }\n dbConnect(params, async ({ objects, states }) => {\n const mh = new Multihost({\n params,\n objects,\n });\n\n if (cmd === 's' || cmd === 'status') {\n mh.status();\n return void callback();\n } else if (cmd === 'b' || cmd === 'browse') {\n try {\n const list = await mh.browse();\n mh.showHosts(list);\n return void callback();\n } catch (e) {\n console.error(e.message);\n return void callback(EXIT_CODES.CANNOT_CREATE_USER_OR_GROUP);\n }\n } else if (cmd === 'e' || cmd === 'enable') {\n mh.enable(true, async (err: Error | null | undefined) => {\n if (err) {\n console.error(err);\n return void callback(EXIT_CODES.CANNOT_ENABLE_MULTIHOST);\n }\n await states.pushMessage(`system.host.${tools.getHostName()}`, {\n command: 'updateMultihost',\n message: null,\n from: 'setup',\n });\n\n callback();\n });\n } else if (cmd === 'd' || cmd === 'disable') {\n mh.enable(false, async (err: Error | null | undefined) => {\n if (err) {\n console.error(err);\n return void callback(EXIT_CODES.CANNOT_ENABLE_MULTIHOST);\n }\n await states.pushMessage(`system.host.${tools.getHostName()}`, {\n command: 'updateMultihost',\n message: null,\n from: 'setup',\n });\n\n callback();\n });\n } else if (cmd === 'c' || cmd === 'connect') {\n mh.connect(parseInt(args[1]), args[2], (err: Error | null | undefined) => {\n if (err) {\n console.error(err);\n }\n return void callback(err ? 1 : 0);\n }).catch(e => console.error(`Cannot connect multihost: ${e.message}`));\n }\n });\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["fs", "path", "prompt", "_err", "readlineSync", "readline"]
7
7
  }
@@ -16,12 +16,16 @@ interface PacketManagerOptions {
16
16
  manager?: Manager;
17
17
  logger?: Logger;
18
18
  }
19
+ /** Describes a system packet that should be upgraded */
19
20
  export interface UpgradePacket {
20
21
  /** Name of the packet which should be upgraded */
21
22
  name: string;
22
23
  /** Optional version */
23
24
  version?: string;
24
25
  }
26
+ /**
27
+ * Wrapper around the system packet manager (apt or yum) to query and upgrade system packages
28
+ */
25
29
  export declare class PacketManager {
26
30
  private manager;
27
31
  private readonly logger;
@@ -29,9 +33,15 @@ export declare class PacketManager {
29
33
  private sudo;
30
34
  private readonly _readyPromise;
31
35
  private readonly COMMANDS;
36
+ /**
37
+ * @param options The packet manager to use, a logger and the log level
38
+ */
32
39
  constructor(options?: PacketManagerOptions);
33
40
  /** Starts the initialization process */
34
41
  private _init;
42
+ /**
43
+ * Resolve once the packet manager has finished its asynchronous initialization
44
+ */
35
45
  ready(): Promise<void>;
36
46
  /**
37
47
  * Tests if the given command can be executed
@@ -3,6 +3,7 @@ var __defProp = Object.defineProperty;
3
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
6
7
  var __export = (target, all) => {
7
8
  for (var name in all)
8
9
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -32,6 +33,9 @@ var LOG_LEVELS;
32
33
  LOG_LEVELS2[LOG_LEVELS2["error"] = 0] = "error";
33
34
  })(LOG_LEVELS || (LOG_LEVELS = {}));
34
35
  class PacketManager {
36
+ static {
37
+ __name(this, "PacketManager");
38
+ }
35
39
  manager;
36
40
  logger;
37
41
  dpkg;
@@ -43,15 +47,18 @@ class PacketManager {
43
47
  yum: "check-update"
44
48
  }
45
49
  };
50
+ /**
51
+ * @param options The packet manager to use, a logger and the log level
52
+ */
46
53
  constructor(options = { logLevel: LOG_LEVELS.info }) {
47
54
  this.manager = options?.manager || "";
48
55
  this.logger = options?.logger || {
49
- silly: (text) => options.logLevel >= LOG_LEVELS.silly && console.log(text),
50
- info: (text) => options.logLevel >= LOG_LEVELS.info && console.log(text),
51
- log: (text) => options.logLevel >= LOG_LEVELS.log && console.log(text),
52
- warn: (text) => options.logLevel >= LOG_LEVELS.warn && console.warn(text),
53
- error: (text) => options.logLevel >= LOG_LEVELS.error && console.error(text),
54
- debug: (text) => options.logLevel >= LOG_LEVELS.debug && console.log(text)
56
+ silly: /* @__PURE__ */ __name((text) => options.logLevel >= LOG_LEVELS.silly && console.log(text), "silly"),
57
+ info: /* @__PURE__ */ __name((text) => options.logLevel >= LOG_LEVELS.info && console.log(text), "info"),
58
+ log: /* @__PURE__ */ __name((text) => options.logLevel >= LOG_LEVELS.log && console.log(text), "log"),
59
+ warn: /* @__PURE__ */ __name((text) => options.logLevel >= LOG_LEVELS.warn && console.warn(text), "warn"),
60
+ error: /* @__PURE__ */ __name((text) => options.logLevel >= LOG_LEVELS.error && console.error(text), "error"),
61
+ debug: /* @__PURE__ */ __name((text) => options.logLevel >= LOG_LEVELS.debug && console.log(text), "debug")
55
62
  };
56
63
  this.dpkg = false;
57
64
  this.sudo = false;
@@ -71,6 +78,9 @@ class PacketManager {
71
78
  this.logger.debug(`Detected dpkg: ${this.dpkg}`);
72
79
  }
73
80
  }
81
+ /**
82
+ * Resolve once the packet manager has finished its asynchronous initialization
83
+ */
74
84
  ready() {
75
85
  return this._readyPromise;
76
86
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/setup/setupPacketManager.ts"],
4
- "sourcesContent": ["import { execAsync, type InternalLogger } from '@iobroker/js-controller-common-db/tools';\n\nenum LOG_LEVELS {\n silly = 5,\n debug = 4,\n log = 3,\n info = 2,\n warn = 1,\n error = 0,\n}\n\ninterface Logger extends InternalLogger {\n log(message: string): void;\n}\n\ntype Manager = 'apt' | 'yum' | '';\n\ninterface PacketManagerOptions {\n logLevel: LOG_LEVELS;\n manager?: Manager;\n logger?: Logger;\n}\n\nexport interface UpgradePacket {\n /** Name of the packet which should be upgraded */\n name: string;\n /** Optional version */\n version?: string;\n}\n\nexport class PacketManager {\n private manager: Manager;\n private readonly logger: Logger;\n private dpkg: boolean;\n private sudo: boolean;\n private readonly _readyPromise: Promise<void>;\n private readonly COMMANDS = {\n listUpgradeable: {\n apt: 'list --upgradeable',\n yum: 'check-update',\n },\n } as const;\n\n constructor(options: PacketManagerOptions = { logLevel: LOG_LEVELS.info }) {\n // detect apt or yum\n this.manager = options?.manager || '';\n this.logger = options?.logger || {\n silly: text => options.logLevel >= LOG_LEVELS.silly && console.log(text),\n info: text => options.logLevel >= LOG_LEVELS.info && console.log(text),\n log: text => options.logLevel >= LOG_LEVELS.log && console.log(text),\n warn: text => options.logLevel >= LOG_LEVELS.warn && console.warn(text),\n error: text => options.logLevel >= LOG_LEVELS.error && console.error(text),\n debug: text => options.logLevel >= LOG_LEVELS.debug && console.log(text),\n };\n this.dpkg = false;\n this.sudo = false;\n this._readyPromise = this._init();\n }\n\n /** Starts the initialization process */\n private async _init(): Promise<void> {\n if (process.platform !== 'win32') {\n if (!this.manager) {\n const manager = await this._detectManager();\n if (manager) {\n this.logger.debug(`Detected packet manager: ${manager}`);\n // Check if sudo is available for packet manager and store information\n this.sudo = (await this._isSudoAvailable()) && (await this._isSudoAvailableForManager());\n }\n }\n\n // Check if dpkg is available\n this.dpkg = await this._isDpkgAvailable();\n this.logger.debug(`Detected dpkg: ${this.dpkg}`);\n }\n }\n\n ready(): Promise<void> {\n return this._readyPromise;\n }\n\n /**\n * Tests if the given command can be executed\n *\n * @param cmd The command to test\n * @returns True if the execution was successful, false otherwise\n */\n private async _isCmd(cmd: string): Promise<boolean> {\n try {\n const { stderr } = await execAsync(cmd);\n return !stderr;\n } catch (e) {\n // non zero exit code, however lets check if ok\n if (e.stderr === '') {\n return true;\n }\n console.error(e.stderr || e.stdout || e);\n return false;\n }\n }\n\n private async _isDpkgAvailable(): Promise<boolean> {\n try {\n const { stdout, stderr } = await execAsync('dpkg');\n return !!((stdout && stdout.includes('dpkg --help')) || (stderr && stderr.includes('dpkg --help')));\n } catch (err) {\n // non zero exit code, however lets check if ok\n if (\n (err.stdout && err.stdout.includes('dpkg --help')) ||\n (err.stderr && err.stderr.includes('dpkg --help'))\n ) {\n return true;\n }\n this.logger.error(`Cannot detect dpkg: ${err.stderr || err.stdout || err}`);\n return false;\n }\n }\n\n private async _isSudoAvailable(): Promise<boolean> {\n try {\n const { stdout, stderr } = await execAsync('sudo');\n return !!((stdout && stdout.includes('sudo -h')) || (stderr && stderr.includes('sudo -h')));\n } catch (err) {\n // non zero exit code, however lets check if ok\n if ((err.stdout && err.stdout.includes('sudo -h')) || (err.stderr && err.stderr.includes('sudo -h'))) {\n return true;\n }\n this.logger.error(`Cannot detect sudo: ${err.stderr || err.stdout || err}`);\n return false;\n }\n }\n\n private async _isSudoAvailableForManager(): Promise<boolean> {\n try {\n await execAsync(`sudo -n ${this.manager} -v`);\n return true;\n } catch (err) {\n this.logger.error(`Cannot detect \\\\\"sudo -n ${this.manager} -v\\\\\": ${err.stderr || err.stdout || err}`);\n return false;\n }\n }\n\n /**\n * Detects which package manager is installed. Throws if none can be found\n */\n private async _detectManager(): Promise<Manager | void> {\n for (const cmd of ['apt', 'yum'] as const) {\n if (await this._isCmd(cmd)) {\n this.manager = cmd;\n return cmd;\n }\n }\n this.logger.info('No supported packet manager found');\n }\n\n /**\n * Updates the sources if apt is used\n */\n async update(): Promise<void> {\n await this.ready();\n\n if (this.manager !== 'apt') {\n // ignore\n return;\n }\n\n try {\n await execAsync(`${(this.sudo ? 'sudo ' : '') + this.manager} update`);\n } catch (e) {\n this.logger.warn(`Cannot update apt sources: ${e.message}`);\n }\n }\n\n private async _listPackages(): Promise<string> {\n if (!this.dpkg) {\n throw new Error('No dpkg detected');\n }\n\n try {\n const { stdout } = await execAsync(`${this.sudo ? 'sudo ' : ''}dpkg -l`);\n const res = Buffer.isBuffer(stdout) ? stdout.toString('utf-8') : stdout;\n return res || '';\n } catch {\n // Ignore error\n return '';\n }\n }\n\n /**\n * Checks which packages are installed and returns them\n *\n * @param packets The packets to test\n */\n async checkInstalled(packets: string[] | string): Promise<string[]> {\n if (!(packets instanceof Array)) {\n packets = [packets];\n }\n\n const installed = await this._listPackages();\n return packets.filter(p => installed.includes(p));\n }\n\n /**\n * Installs a single packet using the configured manager and returns the stdout if there was any\n *\n * @param packet The packet to install\n */\n private async _installPacket(packet: string): Promise<void> {\n if (!this.manager) {\n // ignore\n return;\n }\n\n // if it fails, let it throw and get caught by _installPackets\n await execAsync(`${(this.sudo ? 'sudo ' : '') + this.manager} install ${packet} -y`);\n }\n\n /**\n * List all packages for which updates are available\n */\n async listUpgradeablePackages(): Promise<string[]> {\n if (!this.manager) {\n return [];\n }\n\n const { stdout } = await execAsync(\n `${(this.sudo ? 'sudo ' : '') + this.manager} ${this.COMMANDS.listUpgradeable[this.manager]}`,\n );\n\n const res = Buffer.isBuffer(stdout) ? stdout.toString('utf-8') : stdout;\n\n if (!res) {\n return [];\n }\n\n const packagesList = res.split('\\n').filter(packageInfo => packageInfo.trim() !== '');\n // first line is no package, just Listing...\n packagesList.shift();\n\n return packagesList;\n }\n\n /**\n * Installs multiple packets. The returned Promise contains the list of failed packets\n *\n * @param packets list of packets to install\n */\n private async _installPackets(packets: string[]): Promise<string[]> {\n const failed: string[] = [];\n\n if (packets?.length) {\n // Install all packets\n for (const packet of packets) {\n try {\n await this._installPacket(packet);\n } catch (err) {\n failed.push(packet);\n this.logger.error(`Cannot install \"${packet}\": ${err.stderr || err.stdout || err}`);\n // Continue with the next packet\n }\n }\n }\n return failed;\n }\n\n /**\n * Upgrade given OS packets to given version or newest available version\n *\n * @param packets the packet names and version information\n */\n async upgrade(packets: UpgradePacket[]): Promise<void> {\n await this.ready();\n\n if (!this.manager) {\n return;\n }\n\n for (const packet of packets) {\n let upgradeCmd = `upgrade -y ${packet.name}`;\n\n if (packet.version) {\n if (this.manager === 'apt') {\n upgradeCmd += `=${packet.version}`;\n } else {\n upgradeCmd = `install ${packet.name}-${packet.version}`;\n }\n }\n\n await execAsync(`${(this.sudo ? 'sudo ' : '') + this.manager} ${upgradeCmd}`);\n }\n }\n\n /**\n * Installs all given packets\n *\n * @param packets list of packets or single packet to upgrade\n */\n async install(packets: string[] | string): Promise<void> {\n packets = packets || [];\n if (!(packets instanceof Array)) {\n packets = [packets];\n }\n\n await this.ready();\n\n // Filter empty packets out\n packets = packets && packets.filter(p => p && p.trim());\n\n if (!packets || !packets.length) {\n // nothing must be installed\n return;\n }\n const installed = await this.checkInstalled(packets);\n const notInstalled = packets.filter(packet => !installed.includes(packet));\n // Install all non-installed packets\n const failed = await this._installPackets(notInstalled);\n if (this.logger) {\n if (failed.length > 0) {\n this.logger.warn(\n `The following ${this.manager || 'OS'} packages could not be installed: ${failed.join(\n ', ',\n )}. Please install them manually.`,\n );\n\n if (notInstalled.length) {\n this.logger.info(\n `Installed the following ${this.manager || 'OS'} packages: ${notInstalled.join(', ')}`,\n );\n }\n\n if (installed.length) {\n this.logger.info(\n `These ${this.manager || 'OS'} packages were already installed: ${installed.join(', ')}`,\n );\n }\n }\n }\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { execAsync, type InternalLogger } from '@iobroker/js-controller-common-db/tools';\n\nenum LOG_LEVELS {\n silly = 5,\n debug = 4,\n log = 3,\n info = 2,\n warn = 1,\n error = 0,\n}\n\ninterface Logger extends InternalLogger {\n log(message: string): void;\n}\n\ntype Manager = 'apt' | 'yum' | '';\n\ninterface PacketManagerOptions {\n logLevel: LOG_LEVELS;\n manager?: Manager;\n logger?: Logger;\n}\n\n/** Describes a system packet that should be upgraded */\nexport interface UpgradePacket {\n /** Name of the packet which should be upgraded */\n name: string;\n /** Optional version */\n version?: string;\n}\n\n/**\n * Wrapper around the system packet manager (apt or yum) to query and upgrade system packages\n */\nexport class PacketManager {\n private manager: Manager;\n private readonly logger: Logger;\n private dpkg: boolean;\n private sudo: boolean;\n private readonly _readyPromise: Promise<void>;\n private readonly COMMANDS = {\n listUpgradeable: {\n apt: 'list --upgradeable',\n yum: 'check-update',\n },\n } as const;\n\n /**\n * @param options The packet manager to use, a logger and the log level\n */\n constructor(options: PacketManagerOptions = { logLevel: LOG_LEVELS.info }) {\n // detect apt or yum\n this.manager = options?.manager || '';\n this.logger = options?.logger || {\n silly: text => options.logLevel >= LOG_LEVELS.silly && console.log(text),\n info: text => options.logLevel >= LOG_LEVELS.info && console.log(text),\n log: text => options.logLevel >= LOG_LEVELS.log && console.log(text),\n warn: text => options.logLevel >= LOG_LEVELS.warn && console.warn(text),\n error: text => options.logLevel >= LOG_LEVELS.error && console.error(text),\n debug: text => options.logLevel >= LOG_LEVELS.debug && console.log(text),\n };\n this.dpkg = false;\n this.sudo = false;\n this._readyPromise = this._init();\n }\n\n /** Starts the initialization process */\n private async _init(): Promise<void> {\n if (process.platform !== 'win32') {\n if (!this.manager) {\n const manager = await this._detectManager();\n if (manager) {\n this.logger.debug(`Detected packet manager: ${manager}`);\n // Check if sudo is available for packet manager and store information\n this.sudo = (await this._isSudoAvailable()) && (await this._isSudoAvailableForManager());\n }\n }\n\n // Check if dpkg is available\n this.dpkg = await this._isDpkgAvailable();\n this.logger.debug(`Detected dpkg: ${this.dpkg}`);\n }\n }\n\n /**\n * Resolve once the packet manager has finished its asynchronous initialization\n */\n ready(): Promise<void> {\n return this._readyPromise;\n }\n\n /**\n * Tests if the given command can be executed\n *\n * @param cmd The command to test\n * @returns True if the execution was successful, false otherwise\n */\n private async _isCmd(cmd: string): Promise<boolean> {\n try {\n const { stderr } = await execAsync(cmd);\n return !stderr;\n } catch (e) {\n // non zero exit code, however lets check if ok\n if (e.stderr === '') {\n return true;\n }\n console.error(e.stderr || e.stdout || e);\n return false;\n }\n }\n\n private async _isDpkgAvailable(): Promise<boolean> {\n try {\n const { stdout, stderr } = await execAsync('dpkg');\n return !!((stdout && stdout.includes('dpkg --help')) || (stderr && stderr.includes('dpkg --help')));\n } catch (err) {\n // non zero exit code, however lets check if ok\n if (\n (err.stdout && err.stdout.includes('dpkg --help')) ||\n (err.stderr && err.stderr.includes('dpkg --help'))\n ) {\n return true;\n }\n this.logger.error(`Cannot detect dpkg: ${err.stderr || err.stdout || err}`);\n return false;\n }\n }\n\n private async _isSudoAvailable(): Promise<boolean> {\n try {\n const { stdout, stderr } = await execAsync('sudo');\n return !!((stdout && stdout.includes('sudo -h')) || (stderr && stderr.includes('sudo -h')));\n } catch (err) {\n // non zero exit code, however lets check if ok\n if ((err.stdout && err.stdout.includes('sudo -h')) || (err.stderr && err.stderr.includes('sudo -h'))) {\n return true;\n }\n this.logger.error(`Cannot detect sudo: ${err.stderr || err.stdout || err}`);\n return false;\n }\n }\n\n private async _isSudoAvailableForManager(): Promise<boolean> {\n try {\n await execAsync(`sudo -n ${this.manager} -v`);\n return true;\n } catch (err) {\n this.logger.error(`Cannot detect \\\\\"sudo -n ${this.manager} -v\\\\\": ${err.stderr || err.stdout || err}`);\n return false;\n }\n }\n\n /**\n * Detects which package manager is installed. Throws if none can be found\n */\n private async _detectManager(): Promise<Manager | void> {\n for (const cmd of ['apt', 'yum'] as const) {\n if (await this._isCmd(cmd)) {\n this.manager = cmd;\n return cmd;\n }\n }\n this.logger.info('No supported packet manager found');\n }\n\n /**\n * Updates the sources if apt is used\n */\n async update(): Promise<void> {\n await this.ready();\n\n if (this.manager !== 'apt') {\n // ignore\n return;\n }\n\n try {\n await execAsync(`${(this.sudo ? 'sudo ' : '') + this.manager} update`);\n } catch (e) {\n this.logger.warn(`Cannot update apt sources: ${e.message}`);\n }\n }\n\n private async _listPackages(): Promise<string> {\n if (!this.dpkg) {\n throw new Error('No dpkg detected');\n }\n\n try {\n const { stdout } = await execAsync(`${this.sudo ? 'sudo ' : ''}dpkg -l`);\n const res = Buffer.isBuffer(stdout) ? stdout.toString('utf-8') : stdout;\n return res || '';\n } catch {\n // Ignore error\n return '';\n }\n }\n\n /**\n * Checks which packages are installed and returns them\n *\n * @param packets The packets to test\n */\n async checkInstalled(packets: string[] | string): Promise<string[]> {\n if (!(packets instanceof Array)) {\n packets = [packets];\n }\n\n const installed = await this._listPackages();\n return packets.filter(p => installed.includes(p));\n }\n\n /**\n * Installs a single packet using the configured manager and returns the stdout if there was any\n *\n * @param packet The packet to install\n */\n private async _installPacket(packet: string): Promise<void> {\n if (!this.manager) {\n // ignore\n return;\n }\n\n // if it fails, let it throw and get caught by _installPackets\n await execAsync(`${(this.sudo ? 'sudo ' : '') + this.manager} install ${packet} -y`);\n }\n\n /**\n * List all packages for which updates are available\n */\n async listUpgradeablePackages(): Promise<string[]> {\n if (!this.manager) {\n return [];\n }\n\n const { stdout } = await execAsync(\n `${(this.sudo ? 'sudo ' : '') + this.manager} ${this.COMMANDS.listUpgradeable[this.manager]}`,\n );\n\n const res = Buffer.isBuffer(stdout) ? stdout.toString('utf-8') : stdout;\n\n if (!res) {\n return [];\n }\n\n const packagesList = res.split('\\n').filter(packageInfo => packageInfo.trim() !== '');\n // first line is no package, just Listing...\n packagesList.shift();\n\n return packagesList;\n }\n\n /**\n * Installs multiple packets. The returned Promise contains the list of failed packets\n *\n * @param packets list of packets to install\n */\n private async _installPackets(packets: string[]): Promise<string[]> {\n const failed: string[] = [];\n\n if (packets?.length) {\n // Install all packets\n for (const packet of packets) {\n try {\n await this._installPacket(packet);\n } catch (err) {\n failed.push(packet);\n this.logger.error(`Cannot install \"${packet}\": ${err.stderr || err.stdout || err}`);\n // Continue with the next packet\n }\n }\n }\n return failed;\n }\n\n /**\n * Upgrade given OS packets to given version or newest available version\n *\n * @param packets the packet names and version information\n */\n async upgrade(packets: UpgradePacket[]): Promise<void> {\n await this.ready();\n\n if (!this.manager) {\n return;\n }\n\n for (const packet of packets) {\n let upgradeCmd = `upgrade -y ${packet.name}`;\n\n if (packet.version) {\n if (this.manager === 'apt') {\n upgradeCmd += `=${packet.version}`;\n } else {\n upgradeCmd = `install ${packet.name}-${packet.version}`;\n }\n }\n\n await execAsync(`${(this.sudo ? 'sudo ' : '') + this.manager} ${upgradeCmd}`);\n }\n }\n\n /**\n * Installs all given packets\n *\n * @param packets list of packets or single packet to upgrade\n */\n async install(packets: string[] | string): Promise<void> {\n packets = packets || [];\n if (!(packets instanceof Array)) {\n packets = [packets];\n }\n\n await this.ready();\n\n // Filter empty packets out\n packets = packets && packets.filter(p => p && p.trim());\n\n if (!packets || !packets.length) {\n // nothing must be installed\n return;\n }\n const installed = await this.checkInstalled(packets);\n const notInstalled = packets.filter(packet => !installed.includes(packet));\n // Install all non-installed packets\n const failed = await this._installPackets(notInstalled);\n if (this.logger) {\n if (failed.length > 0) {\n this.logger.warn(\n `The following ${this.manager || 'OS'} packages could not be installed: ${failed.join(\n ', ',\n )}. Please install them manually.`,\n );\n\n if (notInstalled.length) {\n this.logger.info(\n `Installed the following ${this.manager || 'OS'} packages: ${notInstalled.join(', ')}`,\n );\n }\n\n if (installed.length) {\n this.logger.info(\n `These ${this.manager || 'OS'} packages were already installed: ${installed.join(', ')}`,\n );\n }\n }\n }\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["LOG_LEVELS"]
7
7
  }
@@ -1,5 +1,6 @@
1
1
  import type { Client as ObjectsRedisClient } from '@iobroker/db-objects-redis';
2
2
  import type { Client as StatesRedisClient } from '@iobroker/db-states-redis';
3
+ import type { ProcessCommandOptions } from '../../lib/cli/cliCommand.js';
3
4
  /** The options passed to the Repo constructor */
4
5
  export interface CLIRepoOptions {
5
6
  /** Instance of objects DB */
@@ -24,11 +25,17 @@ export interface RepoFlags {
24
25
  /** Force update even if hash hasn't changed */
25
26
  force?: boolean;
26
27
  }
28
+ /**
29
+ * CLI command to manage the ioBroker repositories
30
+ */
27
31
  export declare class Repo {
28
32
  private readonly defaultSystemRepo;
29
33
  private readonly objects;
30
34
  private readonly states;
31
35
  private readonly controllerVersion;
36
+ /**
37
+ * @param options The objects/states clients and the controller version
38
+ */
32
39
  constructor(options: CLIRepoOptions);
33
40
  /**
34
41
  * Get the repository name by index
@@ -110,4 +117,16 @@ export declare class Repo {
110
117
  */
111
118
  rename(oldName: string, newName: string, repoUrl: string): Promise<void>;
112
119
  }
120
+ /**
121
+ * Handles the `update` CLI command
122
+ *
123
+ * @param options the process command options
124
+ */
125
+ export declare function processCommandUpdate(options: ProcessCommandOptions): void;
126
+ /**
127
+ * Handles the `repo` CLI command
128
+ *
129
+ * @param options the process command options
130
+ */
131
+ export declare function processCommandRepo(options: ProcessCommandOptions): Promise<void>;
113
132
  //# sourceMappingURL=setupRepo.d.ts.map
@@ -5,6 +5,7 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
8
9
  var __export = (target, all) => {
9
10
  for (var name in all)
10
11
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -28,20 +29,29 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
29
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
30
  var setupRepo_exports = {};
30
31
  __export(setupRepo_exports, {
31
- Repo: () => Repo
32
+ Repo: () => Repo,
33
+ processCommandRepo: () => processCommandRepo,
34
+ processCommandUpdate: () => processCommandUpdate
32
35
  });
33
36
  module.exports = __toCommonJS(setupRepo_exports);
34
- var import_js_controller_common = require("@iobroker/js-controller-common");
35
37
  var import_axios = __toESM(require("axios"), 1);
36
38
  var import_fs_extra = __toESM(require("fs-extra"), 1);
37
- var import_utils = require("../../lib/setup/utils.js");
38
39
  var import_node_path = __toESM(require("node:path"), 1);
40
+ var import_js_controller_common = require("@iobroker/js-controller-common");
39
41
  var import_constants = require("@iobroker/js-controller-common-db/constants");
42
+ var import_utils = require("../../lib/setup/utils.js");
43
+ var import_dbConnection = require("../../lib/setup/dbConnection.js");
40
44
  class Repo {
45
+ static {
46
+ __name(this, "Repo");
47
+ }
41
48
  defaultSystemRepo;
42
49
  objects;
43
50
  states;
44
51
  controllerVersion;
52
+ /**
53
+ * @param options The objects/states clients and the controller version
54
+ */
45
55
  constructor(options) {
46
56
  if (!options?.objects) {
47
57
  throw new Error("Invalid arguments: objects is missing");
@@ -207,7 +217,9 @@ class Repo {
207
217
  };
208
218
  }
209
219
  const sources = await this.updateRepo(url, flags.force || flags.f, systemConfig, systemRepos);
210
- sources && Object.assign(allSources, sources);
220
+ if (sources) {
221
+ Object.assign(allSources, sources);
222
+ }
211
223
  } else {
212
224
  console.error(`Error: unknown repository is active - "${url}". Known: ${Object.keys(systemRepos.native.repositories).join(", ")}`);
213
225
  }
@@ -230,11 +242,15 @@ class Repo {
230
242
  const adapters = Object.keys(sources).sort();
231
243
  for (const name of adapters) {
232
244
  let updatable = false;
233
- let text = sources[name].controller ? "Controller " : "Adapter ";
245
+ if (name === "repoInfo") {
246
+ continue;
247
+ }
248
+ const adapter = sources[name];
249
+ let text = adapter.controller ? "Controller " : "Adapter ";
234
250
  text += `"${name}"`;
235
251
  text = text.padEnd(11 + 15);
236
- if (sources[name].version) {
237
- text += `: ${sources[name].version}`;
252
+ if (adapter.version) {
253
+ text += `: ${adapter.version}`;
238
254
  }
239
255
  text = text.padEnd(11 + 15 + 11);
240
256
  if (!(flags.all || flags.a) && !installed[name]) {
@@ -243,13 +259,13 @@ class Repo {
243
259
  if (installed[name]?.version) {
244
260
  text += `, installed ${installed[name].version}`;
245
261
  try {
246
- if (sources[name].version !== installed[name].version && sources[name].version && !import_js_controller_common.tools.upToDate(sources[name].version, installed[name].version)) {
262
+ if (adapter.version !== installed[name].version && adapter.version && !import_js_controller_common.tools.upToDate(adapter.version, installed[name].version)) {
247
263
  updatable = true;
248
264
  text = text.padEnd(11 + 15 + 11 + 18);
249
265
  const isIgnored = await (0, import_utils.isVersionIgnored)({
250
266
  adapterName: name,
251
267
  objects: this.objects,
252
- version: sources[name].version
268
+ version: adapter.version
253
269
  });
254
270
  text += isIgnored ? " [Ignored]" : " [Updatable]";
255
271
  }
@@ -271,10 +287,14 @@ class Repo {
271
287
  async updateInfo(sources) {
272
288
  const installed = import_js_controller_common.tools.getInstalledInfo();
273
289
  const list = [];
274
- for (const name of Object.keys(sources)) {
275
- if (installed[name] && installed[name].version && sources[name].version) {
290
+ for (const name in sources) {
291
+ if (name === "repoInfo") {
292
+ continue;
293
+ }
294
+ const adapter = sources[name];
295
+ if (installed[name]?.version && adapter.version) {
276
296
  try {
277
- if (sources[name].version !== installed[name].version && !import_js_controller_common.tools.upToDate(sources[name].version, installed[name].version)) {
297
+ if (adapter.version !== installed[name].version && !import_js_controller_common.tools.upToDate(adapter.version, installed[name].version)) {
278
298
  const n = name.indexOf(".");
279
299
  list.push(n === -1 ? name : name.substring(n + 1));
280
300
  }
@@ -499,8 +519,116 @@ Active repo(s): ${activeRepo.join(", ")}`);
499
519
  }
500
520
  }
501
521
  }
522
+ function processCommandUpdate(options) {
523
+ const { args, params, callback } = options;
524
+ const repoUrl = args[0];
525
+ (0, import_dbConnection.dbConnect)(params, async ({ objects, states }) => {
526
+ const repo = new Repo({
527
+ objects,
528
+ states
529
+ });
530
+ await repo.showRepo(repoUrl, params);
531
+ setTimeout(callback, 1e3);
532
+ });
533
+ }
534
+ __name(processCommandUpdate, "processCommandUpdate");
535
+ async function processCommandRepo(options) {
536
+ const { args, params, callback } = options;
537
+ let repoUrlOrCommand = args[0];
538
+ let repoName = args[1];
539
+ let repoUrl = args[2];
540
+ if (repoUrlOrCommand !== "add" && repoUrlOrCommand !== "del" && repoUrlOrCommand !== "set" && repoUrlOrCommand !== "show" && repoUrlOrCommand !== "addset" && repoUrlOrCommand !== "unset") {
541
+ repoUrl = repoUrlOrCommand;
542
+ repoUrlOrCommand = "show";
543
+ }
544
+ const { objects, states } = await (0, import_dbConnection.dbConnectAsync)(false, params);
545
+ const repo = new Repo({
546
+ objects,
547
+ states
548
+ });
549
+ if (repoUrlOrCommand === "show") {
550
+ try {
551
+ await repo.showRepoStatus();
552
+ return void callback();
553
+ } catch (e) {
554
+ console.error(`Cannot show repository status: ${e.message}`);
555
+ return void callback(import_js_controller_common.EXIT_CODES.INVALID_REPO);
556
+ }
557
+ }
558
+ if (repoUrlOrCommand === "add" || repoUrlOrCommand === "del" || repoUrlOrCommand === "set" || repoUrlOrCommand === "addset" || repoUrlOrCommand === "unset") {
559
+ if (!repoName || !repoName.match(/[-_\w]+/)) {
560
+ console.error(`Invalid repository name: "${repoName}"`);
561
+ return void callback(import_js_controller_common.EXIT_CODES.INVALID_ARGUMENTS);
562
+ }
563
+ if ((0, import_utils.isIntegerLikeInput)(repoName)) {
564
+ try {
565
+ repoName = await repo.getNameByIndex(parseInt(repoName));
566
+ } catch (e) {
567
+ console.error(e.message);
568
+ return void callback(import_js_controller_common.EXIT_CODES.INVALID_ARGUMENTS);
569
+ }
570
+ }
571
+ if (repoUrlOrCommand === "add" || repoUrlOrCommand === "addset") {
572
+ if (!repoUrl) {
573
+ console.warn(`Please define repository URL or path: ${import_js_controller_common.tools.appName.toLowerCase()} add <repoName> <repoUrlOrPath>`);
574
+ return void callback(import_js_controller_common.EXIT_CODES.INVALID_ARGUMENTS);
575
+ }
576
+ try {
577
+ await repo.add(repoName, repoUrl);
578
+ if (repoUrlOrCommand === "addset") {
579
+ await repo.setActive(repoName);
580
+ console.log(`Repository "${repoName}" set as active: "${repoUrl}"`);
581
+ await repo.showRepoStatus();
582
+ return void callback();
583
+ }
584
+ console.log(`Repository "${repoName}" added as "${repoUrl}"`);
585
+ await repo.showRepoStatus();
586
+ return void callback();
587
+ } catch (e) {
588
+ console.error(`Cannot add repository location: ${e.message}`);
589
+ return void callback(import_js_controller_common.EXIT_CODES.INVALID_REPO);
590
+ }
591
+ } else if (repoUrlOrCommand === "set") {
592
+ try {
593
+ await repo.setActive(repoName);
594
+ console.log(`Repository "${repoName}" set as active.`);
595
+ await repo.showRepoStatus();
596
+ return void callback();
597
+ } catch (e) {
598
+ console.error(`Cannot activate repository: ${e.message}`);
599
+ return void callback(import_js_controller_common.EXIT_CODES.INVALID_REPO);
600
+ }
601
+ } else if (repoUrlOrCommand === "del") {
602
+ try {
603
+ await repo.del(repoName);
604
+ console.log(`Repository "${repoName}" deleted.`);
605
+ await repo.showRepoStatus();
606
+ return void callback();
607
+ } catch (e) {
608
+ console.error(`Cannot remove repository: ${e.message}`);
609
+ return void callback(import_js_controller_common.EXIT_CODES.INVALID_REPO);
610
+ }
611
+ } else if (repoUrlOrCommand === "unset") {
612
+ try {
613
+ await repo.setInactive(repoName);
614
+ console.log(`Repository "${repoName}" deactivated.`);
615
+ await repo.showRepoStatus();
616
+ return void callback();
617
+ } catch (e) {
618
+ console.error(`Cannot deactivate repository: ${e.message}`);
619
+ return void callback(import_js_controller_common.EXIT_CODES.INVALID_REPO);
620
+ }
621
+ } else {
622
+ console.warn(`Unknown repo command: ${repoUrlOrCommand}`);
623
+ return void callback(import_js_controller_common.EXIT_CODES.INVALID_ARGUMENTS);
624
+ }
625
+ }
626
+ }
627
+ __name(processCommandRepo, "processCommandRepo");
502
628
  // Annotate the CommonJS export names for ESM import in node:
503
629
  0 && (module.exports = {
504
- Repo
630
+ Repo,
631
+ processCommandRepo,
632
+ processCommandUpdate
505
633
  });
506
634
  //# sourceMappingURL=setupRepo.js.map