@iobroker/js-controller-cli 7.2.2 → 7.2.3-alpha.1-20260621-61726ea22
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.
- package/build/cjs/lib/_Types.d.ts +7 -0
- package/build/cjs/lib/cli/cliCert.d.ts +5 -2
- package/build/cjs/lib/cli/cliCert.js +5 -2
- package/build/cjs/lib/cli/cliCert.js.map +2 -2
- package/build/cjs/lib/cli/cliCommand.d.ts +32 -1
- package/build/cjs/lib/cli/cliCommand.js +4 -1
- package/build/cjs/lib/cli/cliCommand.js.map +2 -2
- package/build/cjs/lib/cli/cliCompact.d.ts +4 -1
- package/build/cjs/lib/cli/cliCompact.js +4 -1
- package/build/cjs/lib/cli/cliCompact.js.map +2 -2
- package/build/cjs/lib/cli/cliDebug.d.ts +4 -1
- package/build/cjs/lib/cli/cliDebug.js +4 -1
- package/build/cjs/lib/cli/cliDebug.js.map +2 -2
- package/build/cjs/lib/cli/cliHost.d.ts +8 -5
- package/build/cjs/lib/cli/cliHost.js +8 -5
- package/build/cjs/lib/cli/cliHost.js.map +2 -2
- package/build/cjs/lib/cli/cliLogs.d.ts +4 -1
- package/build/cjs/lib/cli/cliLogs.js +4 -1
- package/build/cjs/lib/cli/cliLogs.js.map +2 -2
- package/build/cjs/lib/cli/cliMessage.d.ts +1 -0
- package/build/cjs/lib/cli/cliMessage.js.map +2 -2
- package/build/cjs/lib/cli/cliObjects.d.ts +12 -9
- package/build/cjs/lib/cli/cliObjects.js +12 -9
- package/build/cjs/lib/cli/cliObjects.js.map +2 -2
- package/build/cjs/lib/cli/cliPlugin.js.map +1 -1
- package/build/cjs/lib/cli/cliProcess.d.ts +4 -0
- package/build/cjs/lib/cli/cliProcess.js +3 -0
- package/build/cjs/lib/cli/cliProcess.js.map +2 -2
- package/build/cjs/lib/cli/cliStates.d.ts +3 -0
- package/build/cjs/lib/cli/cliStates.js +3 -0
- package/build/cjs/lib/cli/cliStates.js.map +2 -2
- package/build/cjs/lib/setup/customError.d.ts +4 -0
- package/build/cjs/lib/setup/customError.js +3 -0
- package/build/cjs/lib/setup/customError.js.map +2 -2
- package/build/cjs/lib/setup/formatters.d.ts +4 -4
- package/build/cjs/lib/setup/formatters.js.map +1 -1
- package/build/cjs/lib/setup/pluginInfos.d.ts +5 -0
- package/build/cjs/lib/setup/pluginInfos.js.map +2 -2
- package/build/cjs/lib/setup/setupBackup.d.ts +34 -0
- package/build/cjs/lib/setup/setupBackup.js +22 -0
- package/build/cjs/lib/setup/setupBackup.js.map +2 -2
- package/build/cjs/lib/setup/setupInstall.d.ts +37 -14
- package/build/cjs/lib/setup/setupInstall.js +28 -14
- package/build/cjs/lib/setup/setupInstall.js.map +2 -2
- package/build/cjs/lib/setup/setupLicense.d.ts +8 -0
- package/build/cjs/lib/setup/setupLicense.js +3 -0
- package/build/cjs/lib/setup/setupLicense.js.map +2 -2
- package/build/cjs/lib/setup/setupList.d.ts +54 -0
- package/build/cjs/lib/setup/setupList.js +51 -0
- package/build/cjs/lib/setup/setupList.js.map +2 -2
- package/build/cjs/lib/setup/setupPacketManager.d.ts +10 -0
- package/build/cjs/lib/setup/setupPacketManager.js +6 -0
- package/build/cjs/lib/setup/setupPacketManager.js.map +2 -2
- package/build/cjs/lib/setup/setupRepo.d.ts +6 -0
- package/build/cjs/lib/setup/setupRepo.js +3 -0
- package/build/cjs/lib/setup/setupRepo.js.map +2 -2
- package/build/cjs/lib/setup/setupSetup.d.ts +27 -0
- package/build/cjs/lib/setup/setupSetup.js +18 -0
- package/build/cjs/lib/setup/setupSetup.js.map +2 -2
- package/build/cjs/lib/setup/setupUpgrade.d.ts +6 -0
- package/build/cjs/lib/setup/setupUpgrade.js +3 -0
- package/build/cjs/lib/setup/setupUpgrade.js.map +2 -2
- package/build/cjs/lib/setup/setupUpload.d.ts +71 -0
- package/build/cjs/lib/setup/setupUpload.js +65 -1
- package/build/cjs/lib/setup/setupUpload.js.map +2 -2
- package/build/cjs/lib/setup/setupUsers.d.ts +23 -14
- package/build/cjs/lib/setup/setupUsers.js +17 -14
- package/build/cjs/lib/setup/setupUsers.js.map +2 -2
- package/build/cjs/lib/setup/setupVendor.d.ts +9 -1
- package/build/cjs/lib/setup/setupVendor.js +4 -1
- package/build/cjs/lib/setup/setupVendor.js.map +2 -2
- package/build/cjs/lib/setup/setupVisDebug.d.ts +9 -0
- package/build/cjs/lib/setup/setupVisDebug.js +3 -0
- package/build/cjs/lib/setup/setupVisDebug.js.map +2 -2
- package/build/esm/lib/_Types.d.ts +7 -0
- package/build/esm/lib/_Types.d.ts.map +1 -1
- package/build/esm/lib/cli/cliCert.d.ts +5 -2
- package/build/esm/lib/cli/cliCert.d.ts.map +1 -1
- package/build/esm/lib/cli/cliCert.js +5 -2
- package/build/esm/lib/cli/cliCert.js.map +1 -1
- package/build/esm/lib/cli/cliCommand.d.ts +32 -1
- package/build/esm/lib/cli/cliCommand.d.ts.map +1 -1
- package/build/esm/lib/cli/cliCommand.js +4 -1
- package/build/esm/lib/cli/cliCommand.js.map +1 -1
- package/build/esm/lib/cli/cliCompact.d.ts +4 -1
- package/build/esm/lib/cli/cliCompact.d.ts.map +1 -1
- package/build/esm/lib/cli/cliCompact.js +4 -1
- package/build/esm/lib/cli/cliCompact.js.map +1 -1
- package/build/esm/lib/cli/cliDebug.d.ts +4 -1
- package/build/esm/lib/cli/cliDebug.d.ts.map +1 -1
- package/build/esm/lib/cli/cliDebug.js +4 -1
- package/build/esm/lib/cli/cliDebug.js.map +1 -1
- package/build/esm/lib/cli/cliHost.d.ts +8 -5
- package/build/esm/lib/cli/cliHost.d.ts.map +1 -1
- package/build/esm/lib/cli/cliHost.js +8 -5
- package/build/esm/lib/cli/cliHost.js.map +1 -1
- package/build/esm/lib/cli/cliLogs.d.ts +4 -1
- package/build/esm/lib/cli/cliLogs.d.ts.map +1 -1
- package/build/esm/lib/cli/cliLogs.js +4 -1
- package/build/esm/lib/cli/cliLogs.js.map +1 -1
- package/build/esm/lib/cli/cliMessage.d.ts +1 -0
- package/build/esm/lib/cli/cliMessage.d.ts.map +1 -1
- package/build/esm/lib/cli/cliMessage.js +1 -0
- package/build/esm/lib/cli/cliMessage.js.map +1 -1
- package/build/esm/lib/cli/cliObjects.d.ts +12 -9
- package/build/esm/lib/cli/cliObjects.d.ts.map +1 -1
- package/build/esm/lib/cli/cliObjects.js +17 -14
- package/build/esm/lib/cli/cliObjects.js.map +1 -1
- package/build/esm/lib/cli/cliPlugin.js +1 -1
- package/build/esm/lib/cli/cliProcess.d.ts +4 -0
- package/build/esm/lib/cli/cliProcess.d.ts.map +1 -1
- package/build/esm/lib/cli/cliProcess.js +5 -1
- package/build/esm/lib/cli/cliProcess.js.map +1 -1
- package/build/esm/lib/cli/cliStates.d.ts +3 -0
- package/build/esm/lib/cli/cliStates.d.ts.map +1 -1
- package/build/esm/lib/cli/cliStates.js +3 -0
- package/build/esm/lib/cli/cliStates.js.map +1 -1
- package/build/esm/lib/setup/customError.d.ts +4 -0
- package/build/esm/lib/setup/customError.d.ts.map +1 -1
- package/build/esm/lib/setup/customError.js +3 -0
- package/build/esm/lib/setup/customError.js.map +1 -1
- package/build/esm/lib/setup/formatters.d.ts +4 -4
- package/build/esm/lib/setup/formatters.js +4 -4
- package/build/esm/lib/setup/pluginInfos.d.ts +5 -0
- package/build/esm/lib/setup/pluginInfos.d.ts.map +1 -1
- package/build/esm/lib/setup/pluginInfos.js +5 -0
- package/build/esm/lib/setup/pluginInfos.js.map +1 -1
- package/build/esm/lib/setup/setupBackup.d.ts +34 -0
- package/build/esm/lib/setup/setupBackup.d.ts.map +1 -1
- package/build/esm/lib/setup/setupBackup.js +25 -0
- package/build/esm/lib/setup/setupBackup.js.map +1 -1
- package/build/esm/lib/setup/setupInstall.d.ts +37 -14
- package/build/esm/lib/setup/setupInstall.d.ts.map +1 -1
- package/build/esm/lib/setup/setupInstall.js +31 -14
- package/build/esm/lib/setup/setupInstall.js.map +1 -1
- package/build/esm/lib/setup/setupLicense.d.ts +8 -0
- package/build/esm/lib/setup/setupLicense.d.ts.map +1 -1
- package/build/esm/lib/setup/setupLicense.js +6 -0
- package/build/esm/lib/setup/setupLicense.js.map +1 -1
- package/build/esm/lib/setup/setupList.d.ts +54 -0
- package/build/esm/lib/setup/setupList.d.ts.map +1 -1
- package/build/esm/lib/setup/setupList.js +54 -0
- package/build/esm/lib/setup/setupList.js.map +1 -1
- package/build/esm/lib/setup/setupPacketManager.d.ts +10 -0
- package/build/esm/lib/setup/setupPacketManager.d.ts.map +1 -1
- package/build/esm/lib/setup/setupPacketManager.js +9 -0
- package/build/esm/lib/setup/setupPacketManager.js.map +1 -1
- package/build/esm/lib/setup/setupRepo.d.ts +6 -0
- package/build/esm/lib/setup/setupRepo.d.ts.map +1 -1
- package/build/esm/lib/setup/setupRepo.js +6 -0
- package/build/esm/lib/setup/setupRepo.js.map +1 -1
- package/build/esm/lib/setup/setupSetup.d.ts +27 -0
- package/build/esm/lib/setup/setupSetup.d.ts.map +1 -1
- package/build/esm/lib/setup/setupSetup.js +21 -0
- package/build/esm/lib/setup/setupSetup.js.map +1 -1
- package/build/esm/lib/setup/setupUpgrade.d.ts +6 -0
- package/build/esm/lib/setup/setupUpgrade.d.ts.map +1 -1
- package/build/esm/lib/setup/setupUpgrade.js +6 -0
- package/build/esm/lib/setup/setupUpgrade.js.map +1 -1
- package/build/esm/lib/setup/setupUpload.d.ts +71 -0
- package/build/esm/lib/setup/setupUpload.d.ts.map +1 -1
- package/build/esm/lib/setup/setupUpload.js +68 -1
- package/build/esm/lib/setup/setupUpload.js.map +1 -1
- package/build/esm/lib/setup/setupUsers.d.ts +23 -14
- package/build/esm/lib/setup/setupUsers.d.ts.map +1 -1
- package/build/esm/lib/setup/setupUsers.js +20 -14
- package/build/esm/lib/setup/setupUsers.js.map +1 -1
- package/build/esm/lib/setup/setupVendor.d.ts +9 -1
- package/build/esm/lib/setup/setupVendor.d.ts.map +1 -1
- package/build/esm/lib/setup/setupVendor.js +7 -1
- package/build/esm/lib/setup/setupVendor.js.map +1 -1
- package/build/esm/lib/setup/setupVisDebug.d.ts +9 -0
- package/build/esm/lib/setup/setupVisDebug.d.ts.map +1 -1
- package/build/esm/lib/setup/setupVisDebug.js +6 -0
- package/build/esm/lib/setup/setupVisDebug.js.map +1 -1
- package/build/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +4 -4
|
@@ -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": ";;;;;;;;;;;;;;;;;;AAAA;;;;;AAAA,mBAA+C;AAE/C,IAAK;CAAL,SAAKA,aAAU;AACX,EAAAA,YAAAA,YAAA,OAAA,IAAA,CAAA,IAAA;AACA,EAAAA,YAAAA,YAAA,OAAA,IAAA,CAAA,IAAA;AACA,EAAAA,YAAAA,YAAA,KAAA,IAAA,CAAA,IAAA;AACA,EAAAA,YAAAA,YAAA,MAAA,IAAA,CAAA,IAAA;AACA,EAAAA,YAAAA,YAAA,MAAA,IAAA,CAAA,IAAA;AACA,EAAAA,YAAAA,YAAA,OAAA,IAAA,CAAA,IAAA;AACJ,GAPK,eAAA,aAAU,CAAA,EAAA;
|
|
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": ";;;;;;;;;;;;;;;;;;AAAA;;;;;AAAA,mBAA+C;AAE/C,IAAK;CAAL,SAAKA,aAAU;AACX,EAAAA,YAAAA,YAAA,OAAA,IAAA,CAAA,IAAA;AACA,EAAAA,YAAAA,YAAA,OAAA,IAAA,CAAA,IAAA;AACA,EAAAA,YAAAA,YAAA,KAAA,IAAA,CAAA,IAAA;AACA,EAAAA,YAAAA,YAAA,MAAA,IAAA,CAAA,IAAA;AACA,EAAAA,YAAAA,YAAA,MAAA,IAAA,CAAA,IAAA;AACA,EAAAA,YAAAA,YAAA,OAAA,IAAA,CAAA,IAAA;AACJ,GAPK,eAAA,aAAU,CAAA,EAAA;AAgCT,MAAO,cAAa;EACd;EACS;EACT;EACA;EACS;EACA,WAAW;IACxB,iBAAiB;MACb,KAAK;MACL,KAAK;;;;;;EAOb,YAAY,UAAgC,EAAE,UAAU,WAAW,KAAI,GAAE;AAErE,SAAK,UAAU,SAAS,WAAW;AACnC,SAAK,SAAS,SAAS,UAAU;MAC7B,OAAO,UAAQ,QAAQ,YAAY,WAAW,SAAS,QAAQ,IAAI,IAAI;MACvE,MAAM,UAAQ,QAAQ,YAAY,WAAW,QAAQ,QAAQ,IAAI,IAAI;MACrE,KAAK,UAAQ,QAAQ,YAAY,WAAW,OAAO,QAAQ,IAAI,IAAI;MACnE,MAAM,UAAQ,QAAQ,YAAY,WAAW,QAAQ,QAAQ,KAAK,IAAI;MACtE,OAAO,UAAQ,QAAQ,YAAY,WAAW,SAAS,QAAQ,MAAM,IAAI;MACzE,OAAO,UAAQ,QAAQ,YAAY,WAAW,SAAS,QAAQ,IAAI,IAAI;;AAE3E,SAAK,OAAO;AACZ,SAAK,OAAO;AACZ,SAAK,gBAAgB,KAAK,MAAK;EACnC;;EAGQ,MAAM,QAAK;AACf,QAAI,QAAQ,aAAa,SAAS;AAC9B,UAAI,CAAC,KAAK,SAAS;AACf,cAAM,UAAU,MAAM,KAAK,eAAc;AACzC,YAAI,SAAS;AACT,eAAK,OAAO,MAAM,4BAA4B,OAAO,EAAE;AAEvD,eAAK,OAAQ,MAAM,KAAK,iBAAgB,KAAQ,MAAM,KAAK,2BAA0B;QACzF;MACJ;AAGA,WAAK,OAAO,MAAM,KAAK,iBAAgB;AACvC,WAAK,OAAO,MAAM,kBAAkB,KAAK,IAAI,EAAE;IACnD;EACJ;;;;EAKA,QAAK;AACD,WAAO,KAAK;EAChB;;;;;;;EAQQ,MAAM,OAAO,KAAW;AAC5B,QAAI;AACA,YAAM,EAAE,OAAM,IAAK,UAAM,wBAAU,GAAG;AACtC,aAAO,CAAC;IACZ,SAAS,GAAG;AAER,UAAI,EAAE,WAAW,IAAI;AACjB,eAAO;MACX;AACA,cAAQ,MAAM,EAAE,UAAU,EAAE,UAAU,CAAC;AACvC,aAAO;IACX;EACJ;EAEQ,MAAM,mBAAgB;AAC1B,QAAI;AACA,YAAM,EAAE,QAAQ,OAAM,IAAK,UAAM,wBAAU,MAAM;AACjD,aAAO,CAAC,EAAG,UAAU,OAAO,SAAS,aAAa,KAAO,UAAU,OAAO,SAAS,aAAa;IACpG,SAAS,KAAK;AAEV,UACK,IAAI,UAAU,IAAI,OAAO,SAAS,aAAa,KAC/C,IAAI,UAAU,IAAI,OAAO,SAAS,aAAa,GAClD;AACE,eAAO;MACX;AACA,WAAK,OAAO,MAAM,uBAAuB,IAAI,UAAU,IAAI,UAAU,GAAG,EAAE;AAC1E,aAAO;IACX;EACJ;EAEQ,MAAM,mBAAgB;AAC1B,QAAI;AACA,YAAM,EAAE,QAAQ,OAAM,IAAK,UAAM,wBAAU,MAAM;AACjD,aAAO,CAAC,EAAG,UAAU,OAAO,SAAS,SAAS,KAAO,UAAU,OAAO,SAAS,SAAS;IAC5F,SAAS,KAAK;AAEV,UAAK,IAAI,UAAU,IAAI,OAAO,SAAS,SAAS,KAAO,IAAI,UAAU,IAAI,OAAO,SAAS,SAAS,GAAI;AAClG,eAAO;MACX;AACA,WAAK,OAAO,MAAM,uBAAuB,IAAI,UAAU,IAAI,UAAU,GAAG,EAAE;AAC1E,aAAO;IACX;EACJ;EAEQ,MAAM,6BAA0B;AACpC,QAAI;AACA,gBAAM,wBAAU,WAAW,KAAK,OAAO,KAAK;AAC5C,aAAO;IACX,SAAS,KAAK;AACV,WAAK,OAAO,MAAM,4BAA4B,KAAK,OAAO,WAAW,IAAI,UAAU,IAAI,UAAU,GAAG,EAAE;AACtG,aAAO;IACX;EACJ;;;;EAKQ,MAAM,iBAAc;AACxB,eAAW,OAAO,CAAC,OAAO,KAAK,GAAY;AACvC,UAAI,MAAM,KAAK,OAAO,GAAG,GAAG;AACxB,aAAK,UAAU;AACf,eAAO;MACX;IACJ;AACA,SAAK,OAAO,KAAK,mCAAmC;EACxD;;;;EAKA,MAAM,SAAM;AACR,UAAM,KAAK,MAAK;AAEhB,QAAI,KAAK,YAAY,OAAO;AAExB;IACJ;AAEA,QAAI;AACA,gBAAM,wBAAU,IAAI,KAAK,OAAO,UAAU,MAAM,KAAK,OAAO,SAAS;IACzE,SAAS,GAAG;AACR,WAAK,OAAO,KAAK,8BAA8B,EAAE,OAAO,EAAE;IAC9D;EACJ;EAEQ,MAAM,gBAAa;AACvB,QAAI,CAAC,KAAK,MAAM;AACZ,YAAM,IAAI,MAAM,kBAAkB;IACtC;AAEA,QAAI;AACA,YAAM,EAAE,OAAM,IAAK,UAAM,wBAAU,GAAG,KAAK,OAAO,UAAU,EAAE,SAAS;AACvE,YAAM,MAAM,OAAO,SAAS,MAAM,IAAI,OAAO,SAAS,OAAO,IAAI;AACjE,aAAO,OAAO;IAClB,QAAQ;AAEJ,aAAO;IACX;EACJ;;;;;;EAOA,MAAM,eAAe,SAA0B;AAC3C,QAAI,EAAE,mBAAmB,QAAQ;AAC7B,gBAAU,CAAC,OAAO;IACtB;AAEA,UAAM,YAAY,MAAM,KAAK,cAAa;AAC1C,WAAO,QAAQ,OAAO,OAAK,UAAU,SAAS,CAAC,CAAC;EACpD;;;;;;EAOQ,MAAM,eAAe,QAAc;AACvC,QAAI,CAAC,KAAK,SAAS;AAEf;IACJ;AAGA,cAAM,wBAAU,IAAI,KAAK,OAAO,UAAU,MAAM,KAAK,OAAO,YAAY,MAAM,KAAK;EACvF;;;;EAKA,MAAM,0BAAuB;AACzB,QAAI,CAAC,KAAK,SAAS;AACf,aAAO,CAAA;IACX;AAEA,UAAM,EAAE,OAAM,IAAK,UAAM,wBACrB,IAAI,KAAK,OAAO,UAAU,MAAM,KAAK,OAAO,IAAI,KAAK,SAAS,gBAAgB,KAAK,OAAO,CAAC,EAAE;AAGjG,UAAM,MAAM,OAAO,SAAS,MAAM,IAAI,OAAO,SAAS,OAAO,IAAI;AAEjE,QAAI,CAAC,KAAK;AACN,aAAO,CAAA;IACX;AAEA,UAAM,eAAe,IAAI,MAAM,IAAI,EAAE,OAAO,iBAAe,YAAY,KAAI,MAAO,EAAE;AAEpF,iBAAa,MAAK;AAElB,WAAO;EACX;;;;;;EAOQ,MAAM,gBAAgB,SAAiB;AAC3C,UAAM,SAAmB,CAAA;AAEzB,QAAI,SAAS,QAAQ;AAEjB,iBAAW,UAAU,SAAS;AAC1B,YAAI;AACA,gBAAM,KAAK,eAAe,MAAM;QACpC,SAAS,KAAK;AACV,iBAAO,KAAK,MAAM;AAClB,eAAK,OAAO,MAAM,mBAAmB,MAAM,MAAM,IAAI,UAAU,IAAI,UAAU,GAAG,EAAE;QAEtF;MACJ;IACJ;AACA,WAAO;EACX;;;;;;EAOA,MAAM,QAAQ,SAAwB;AAClC,UAAM,KAAK,MAAK;AAEhB,QAAI,CAAC,KAAK,SAAS;AACf;IACJ;AAEA,eAAW,UAAU,SAAS;AAC1B,UAAI,aAAa,cAAc,OAAO,IAAI;AAE1C,UAAI,OAAO,SAAS;AAChB,YAAI,KAAK,YAAY,OAAO;AACxB,wBAAc,IAAI,OAAO,OAAO;QACpC,OAAO;AACH,uBAAa,WAAW,OAAO,IAAI,IAAI,OAAO,OAAO;QACzD;MACJ;AAEA,gBAAM,wBAAU,IAAI,KAAK,OAAO,UAAU,MAAM,KAAK,OAAO,IAAI,UAAU,EAAE;IAChF;EACJ;;;;;;EAOA,MAAM,QAAQ,SAA0B;AACpC,cAAU,WAAW,CAAA;AACrB,QAAI,EAAE,mBAAmB,QAAQ;AAC7B,gBAAU,CAAC,OAAO;IACtB;AAEA,UAAM,KAAK,MAAK;AAGhB,cAAU,WAAW,QAAQ,OAAO,OAAK,KAAK,EAAE,KAAI,CAAE;AAEtD,QAAI,CAAC,WAAW,CAAC,QAAQ,QAAQ;AAE7B;IACJ;AACA,UAAM,YAAY,MAAM,KAAK,eAAe,OAAO;AACnD,UAAM,eAAe,QAAQ,OAAO,YAAU,CAAC,UAAU,SAAS,MAAM,CAAC;AAEzE,UAAM,SAAS,MAAM,KAAK,gBAAgB,YAAY;AACtD,QAAI,KAAK,QAAQ;AACb,UAAI,OAAO,SAAS,GAAG;AACnB,aAAK,OAAO,KACR,iBAAiB,KAAK,WAAW,IAAI,qCAAqC,OAAO,KAC7E,IAAI,CACP,iCAAiC;AAGtC,YAAI,aAAa,QAAQ;AACrB,eAAK,OAAO,KACR,2BAA2B,KAAK,WAAW,IAAI,cAAc,aAAa,KAAK,IAAI,CAAC,EAAE;QAE9F;AAEA,YAAI,UAAU,QAAQ;AAClB,eAAK,OAAO,KACR,SAAS,KAAK,WAAW,IAAI,qCAAqC,UAAU,KAAK,IAAI,CAAC,EAAE;QAEhG;MACJ;IACJ;EACJ;;",
|
|
6
6
|
"names": ["LOG_LEVELS"]
|
|
7
7
|
}
|
|
@@ -24,11 +24,17 @@ export interface RepoFlags {
|
|
|
24
24
|
/** Force update even if hash hasn't changed */
|
|
25
25
|
force?: boolean;
|
|
26
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* CLI command to manage the ioBroker repositories
|
|
29
|
+
*/
|
|
27
30
|
export declare class Repo {
|
|
28
31
|
private readonly defaultSystemRepo;
|
|
29
32
|
private readonly objects;
|
|
30
33
|
private readonly states;
|
|
31
34
|
private readonly controllerVersion;
|
|
35
|
+
/**
|
|
36
|
+
* @param options The objects/states clients and the controller version
|
|
37
|
+
*/
|
|
32
38
|
constructor(options: CLIRepoOptions);
|
|
33
39
|
/**
|
|
34
40
|
* Get the repository name by index
|
|
@@ -42,6 +42,9 @@ class Repo {
|
|
|
42
42
|
objects;
|
|
43
43
|
states;
|
|
44
44
|
controllerVersion;
|
|
45
|
+
/**
|
|
46
|
+
* @param options The objects/states clients and the controller version
|
|
47
|
+
*/
|
|
45
48
|
constructor(options) {
|
|
46
49
|
if (!options?.objects) {
|
|
47
50
|
throw new Error("Invalid arguments: objects is missing");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/lib/setup/setupRepo.ts"],
|
|
4
|
-
"sourcesContent": ["import { tools, EXIT_CODES } from '@iobroker/js-controller-common';\nimport axios from 'axios';\nimport fs from 'fs-extra';\nimport type { Client as ObjectsRedisClient } from '@iobroker/db-objects-redis';\nimport type { Client as StatesRedisClient } from '@iobroker/db-states-redis';\nimport { BETA_REPO_URL, isIntegerLikeInput, isVersionIgnored, STABLE_REPO_URL } from '@/lib/setup/utils.js';\nimport path from 'node:path';\nimport { SYSTEM_CONFIG_ID, SYSTEM_REPOSITORIES_ID } from '@iobroker/js-controller-common-db/constants';\n\n/** The options passed to the Repo constructor */\nexport interface CLIRepoOptions {\n /** Instance of objects DB */\n objects: ObjectsRedisClient;\n /** Instance of states DB */\n states: StatesRedisClient;\n}\n\n/**\n * All possible Repo Flags which can be passed to the `show` method\n */\nexport interface RepoFlags {\n /** Also list not installed adapters */\n a?: boolean;\n /** Also list not installed adapters */\n all?: boolean;\n /** Only list updatable adapters */\n u?: boolean;\n /** Only list updatable adapters */\n updatable?: boolean;\n /** Force update even if hash hasn't changed */\n f?: boolean;\n /** Force update even if hash hasn't changed */\n force?: boolean;\n}\n\ntype RepoActiveInfo =\n | {\n /** If the repo is active */\n isActive: true;\n /** Name of the repository */\n name: string;\n }\n | {\n /** If the repo is active */\n isActive: false;\n };\n\ninterface RepoActiveOptions {\n /** Url to check if active */\n url: string;\n /** System config object */\n sysConfObj: ioBroker.SystemConfigObject;\n /** Repository object */\n repoObj: ioBroker.RepositoryObject;\n}\n\nexport class Repo {\n private readonly defaultSystemRepo: ioBroker.RepositoryObject;\n private readonly objects: ObjectsRedisClient;\n private readonly states: StatesRedisClient;\n private readonly controllerVersion: string;\n\n constructor(options: CLIRepoOptions) {\n if (!options?.objects) {\n throw new Error('Invalid arguments: objects is missing');\n }\n if (!options?.states) {\n throw new Error('Invalid arguments: states is missing');\n }\n\n const ioPackage = fs.readJSONSync(path.join(tools.getControllerDir(), 'io-package.json'));\n this.controllerVersion = ioPackage.common.version;\n\n this.objects = options.objects;\n this.states = options.states;\n\n this.defaultSystemRepo = {\n common: {\n name: 'System repositories',\n dontDelete: true,\n },\n native: {\n repositories: {\n stable: {\n link: STABLE_REPO_URL,\n json: null,\n },\n beta: {\n link: BETA_REPO_URL,\n json: null,\n },\n },\n },\n _id: SYSTEM_REPOSITORIES_ID,\n type: 'config',\n };\n }\n\n /**\n * Get the repository name by index\n * Throws if the index does not exist\n *\n * @param repoIndex repo name or index\n */\n async getNameByIndex(repoIndex: number): Promise<string> {\n const obj = await this.objects.getObject(SYSTEM_REPOSITORIES_ID);\n if (!obj?.native?.repositories) {\n throw new Error('No repositories setup!');\n }\n\n const repoNames = Object.keys(obj.native.repositories);\n if (!repoNames[repoIndex]) {\n throw new Error(`No repository for index \"${repoIndex}\" found`);\n }\n\n return repoNames[repoIndex];\n }\n\n /**\n * Update the given repository and returns new repo content\n *\n * @param repoName name of the repository\n * @param force force update even if same hash\n * @param systemConfig content of `system.config` object\n * @param systemRepos content of `system.repositories` object\n */\n private async updateRepo(\n repoName: string,\n force: boolean | undefined,\n systemConfig?: ioBroker.OtherObject,\n systemRepos?: ioBroker.RepositoryObject,\n ): Promise<null | ioBroker.RepositoryJson> {\n if (!repoName) {\n const sysConfig = systemConfig || (await this.objects.getObject(SYSTEM_CONFIG_ID));\n repoName = sysConfig!.common.activeRepo;\n }\n\n const oldRepos = systemRepos || (await this.objects.getObject(SYSTEM_REPOSITORIES_ID));\n if (!oldRepos?.native.repositories?.[repoName]) {\n console.log(`Error: repository \"${repoName}\" not found in the \"${SYSTEM_REPOSITORIES_ID}\"`);\n return null;\n }\n\n const urlOrPath = oldRepos.native.repositories[repoName].link;\n const hashUrl = urlOrPath.replace(/\\.json$/, '-hash.json');\n let hash;\n\n if (\n !force &&\n oldRepos.native.repositories[repoName].hash &&\n oldRepos.native.repositories[repoName].json &&\n (urlOrPath.startsWith('http://') || urlOrPath.startsWith('https://'))\n ) {\n try {\n hash = await axios({ url: hashUrl, timeout: 10_000 });\n } catch (e) {\n console.error(`Cannot download repository hash file from \"${hashUrl}\": ${e.message}`);\n }\n if (hash?.data && oldRepos.native.repositories[repoName].hash === hash.data.hash) {\n return oldRepos.native.repositories[repoName].json;\n }\n }\n\n let data;\n\n if (urlOrPath.startsWith('http://') || urlOrPath.startsWith('https://')) {\n if (!hash) {\n try {\n hash = await axios({ url: hashUrl, timeout: 10000 });\n } catch (e) {\n console.error(`Cannot download repository hash file from \"${hashUrl}\": ${e.message}`);\n }\n }\n\n const agent = `${tools.appName}, RND: CLI, Node:${process.version}, V:${this.controllerVersion}`;\n try {\n data = await axios({\n url: urlOrPath,\n timeout: 10_000,\n headers: { 'User-Agent': agent },\n });\n if (data.data) {\n data = data.data;\n } else {\n data = null;\n }\n } catch (e) {\n console.error(`Cannot download repository file from \"${urlOrPath}\": ${e.message}`);\n data = null;\n }\n } else {\n if (fs.existsSync(urlOrPath)) {\n try {\n data = JSON.parse(fs.readFileSync(urlOrPath).toString('utf8'));\n } catch (err) {\n console.error(`Error: Cannot read or parse file \"${urlOrPath}\": ${err.message}`);\n }\n } else {\n console.error(`Error: Cannot find file \"${urlOrPath}\"`);\n }\n }\n\n let changed;\n if (data) {\n oldRepos.native.repositories[repoName].json = data;\n changed = true;\n }\n if (hash?.data) {\n oldRepos.native.repositories[repoName].hash = hash.data.hash;\n changed = true;\n }\n if (changed) {\n oldRepos.from = `system.host.${tools.getHostName()}.cli`;\n oldRepos.ts = Date.now();\n await this.objects.setObject(SYSTEM_REPOSITORIES_ID, oldRepos);\n }\n\n return oldRepos.native.repositories[repoName].json;\n }\n\n /**\n * Show repo on CLI\n *\n * @param repoUrl url of the repository\n * @param flags CLI flags\n */\n async showRepo(repoUrl: string | string[], flags: RepoFlags): Promise<void> {\n // Get the repositories\n const systemConfig = await this.objects.getObject(SYSTEM_CONFIG_ID);\n const systemRepos = await this.objects.getObject(SYSTEM_REPOSITORIES_ID);\n if (!systemConfig) {\n console.error(`Error: Object \"${SYSTEM_CONFIG_ID}\" not found`);\n } else if (!systemRepos) {\n console.error(`Error: Object \"${SYSTEM_REPOSITORIES_ID}\" not found`);\n } else if (!systemRepos.native || !systemRepos.native.repositories) {\n console.error(`Error: no repositories found in the \"${SYSTEM_REPOSITORIES_ID}\"`);\n } else {\n repoUrl = repoUrl || systemConfig.common.activeRepo;\n\n if (!Array.isArray(repoUrl)) {\n repoUrl = [repoUrl];\n }\n\n console.log(`Used ${repoUrl.length > 1 ? 'repositories' : 'repository'}: ${repoUrl.join(', ')}`);\n\n const allSources = {};\n\n for (const url of repoUrl) {\n const repo = systemRepos.native.repositories[url];\n // If known repository\n if (repo) {\n if (typeof repo === 'string') {\n systemRepos.native.repositories[url] = {\n link: repo,\n json: null,\n hash: '',\n };\n }\n\n const sources = await this.updateRepo(url, flags.force || flags.f, systemConfig, systemRepos);\n sources && Object.assign(allSources, sources);\n } else {\n console.error(\n `Error: unknown repository is active - \"${url}\". Known: ${Object.keys(\n systemRepos.native.repositories,\n ).join(', ')}`,\n );\n }\n }\n\n try {\n // update variables of every admin instance\n await this.updateInfo(allSources);\n } catch {\n // not important if fails\n }\n\n return this.showRepoResult(allSources, flags);\n }\n }\n\n /**\n * Show the repo result on CLI\n *\n * @param sources Repo JSON sources\n * @param flags CLI flags\n */\n private async showRepoResult(sources: Record<string, any>, flags: RepoFlags): Promise<void> {\n const installed = tools.getInstalledInfo();\n const adapters = Object.keys(sources).sort();\n\n for (const name of adapters) {\n let updatable = false;\n let text = sources[name].controller ? 'Controller ' : 'Adapter ';\n text += `\"${name}\"`;\n text = text.padEnd(11 + 15);\n\n if (sources[name].version) {\n text += `: ${sources[name].version}`;\n }\n text = text.padEnd(11 + 15 + 11);\n\n if (!(flags.all || flags.a) && !installed[name]) {\n continue;\n }\n\n if (installed[name]?.version) {\n text += `, installed ${installed[name].version}`;\n try {\n // tools.upToDate can throw if a version is invalid\n if (\n sources[name].version !== installed[name].version &&\n sources[name].version &&\n !tools.upToDate(sources[name].version, installed[name].version)\n ) {\n updatable = true;\n text = text.padEnd(11 + 15 + 11 + 18);\n const isIgnored = await isVersionIgnored({\n adapterName: name,\n objects: this.objects,\n version: sources[name].version,\n });\n\n text += isIgnored ? ' [Ignored]' : ' [Updatable]';\n }\n } catch (e) {\n console.error(`Cannot determine update info of \"${name}\": ${e.message}`);\n }\n }\n if ((flags.updatable || flags.u) && !updatable) {\n continue;\n }\n console.log(text);\n }\n }\n\n /**\n * Update Admin info states with number of updates\n *\n * @param sources the repository object\n */\n private async updateInfo(sources: Record<string, any>): Promise<void> {\n const installed = tools.getInstalledInfo();\n const list: string[] = [];\n\n for (const name of Object.keys(sources)) {\n if (installed[name] && installed[name].version && sources[name].version) {\n try {\n // tools.upToDate can throw if a version is invalid\n if (\n sources[name].version !== installed[name].version &&\n !tools.upToDate(sources[name].version, installed[name].version)\n ) {\n // remove the first part of the name\n const n = name.indexOf('.');\n list.push(n === -1 ? name : name.substring(n + 1));\n }\n } catch (e) {\n console.error(`Cannot determine update info of \"${name}\": ${e.message}`);\n }\n }\n }\n\n const objs = await this.objects.getObjectViewAsync('system', 'instance', {\n startkey: 'system.adapter.admin',\n endkey: 'system.adapter.admin\\u9999',\n });\n\n if (objs?.rows?.length) {\n const listStr = list.join(', ');\n for (const row of objs.rows) {\n if (row?.value?.type === 'instance') {\n await this.states.setState(`${row.id}.info.updatesNumber`, { val: list.length, ack: true });\n await this.states.setState(`${row.id}.info.updatesList`, { val: listStr, ack: true });\n }\n }\n }\n }\n\n /**\n * Show the current status of Repo on CLI\n */\n async showRepoStatus(): Promise<number> {\n try {\n const obj = await this.objects.getObject(SYSTEM_REPOSITORIES_ID);\n const objCfg = await this.objects.getObject(SYSTEM_CONFIG_ID);\n\n if (!obj) {\n console.error('List is empty');\n return EXIT_CODES.CANNOT_GET_REPO_LIST;\n } else if (obj.native.repositories) {\n console.table(\n Object.entries(obj.native.repositories).map(([key, value]) => {\n return {\n name: key,\n url: value.link,\n 'auto upgrade': objCfg?.common.adapterAutoUpgrade?.repositories[key] ?? false,\n };\n }),\n );\n\n if (objCfg?.common) {\n let activeRepo = objCfg.common.activeRepo;\n if (typeof activeRepo === 'string') {\n activeRepo = [activeRepo];\n }\n console.log(`\\nActive repo(s): ${activeRepo.join(', ')}`);\n console.log(`Upgrade policy: ${objCfg.common.adapterAutoUpgrade?.defaultPolicy ?? 'none'}`);\n }\n } else {\n console.error('List is empty');\n return EXIT_CODES.CANNOT_GET_REPO_LIST;\n }\n } catch (err) {\n console.error(`Cannot get list: ${err}`);\n }\n return EXIT_CODES.CANNOT_GET_REPO_LIST;\n }\n\n /**\n * Add new repo\n *\n * @param repoName name of new repo\n * @param repoUrl url of new repo\n */\n async add(repoName: string, repoUrl: string): Promise<void> {\n const sysRepoObj = await this.objects.getObject(SYSTEM_REPOSITORIES_ID);\n const obj = sysRepoObj || this.defaultSystemRepo;\n\n if (obj.native.repositories[repoName]) {\n throw new Error(`Repository \"${repoName}\" yet exists: ${obj.native.repositories[repoName].link}`);\n } else {\n if (isIntegerLikeInput(repoName)) {\n throw new Error(\n `Invalid name \"${repoName}\"! A repository name is not allowed to contain only numbers.`,\n );\n }\n\n obj.native.repositories[repoName] = {\n link: repoUrl,\n json: null,\n };\n obj.from = `system.host.${tools.getHostName()}.cli`;\n obj.ts = Date.now();\n await this.objects.setObject(SYSTEM_REPOSITORIES_ID, obj);\n }\n }\n\n /**\n * Remove repository from sources\n *\n * @param repoName name of repository to remove\n */\n async del(repoName: string): Promise<void> {\n const obj = await this.objects.getObject(SYSTEM_CONFIG_ID);\n if (\n (obj?.common.activeRepo &&\n typeof obj.common.activeRepo === 'string' &&\n obj.common.activeRepo === repoName) ||\n (obj?.common.activeRepo && Array.isArray(obj.common.activeRepo) && obj.common.activeRepo.includes(repoName))\n ) {\n throw new Error(`Cannot delete active repository: ${repoName}`);\n } else {\n const repoObj = await this.objects.getObject(SYSTEM_REPOSITORIES_ID);\n if (repoObj) {\n if (!repoObj.native.repositories[repoName]) {\n throw new Error(`Repository \"${repoName}\" not found.`);\n } else {\n delete repoObj.native.repositories[repoName];\n repoObj.from = `system.host.${tools.getHostName()}.cli`;\n repoObj.ts = Date.now();\n await this.objects.setObject(SYSTEM_REPOSITORIES_ID, repoObj);\n }\n }\n }\n }\n\n /**\n * Checks if stable repo is active\n *\n * @param options the system config object and the repository object\n */\n private getRepoActiveInfo(options: RepoActiveOptions): RepoActiveInfo {\n const { repoObj, sysConfObj, url } = options;\n\n const name = sysConfObj.common.activeRepo.find(\n activeRepo => repoObj.native.repositories[activeRepo].link === url,\n );\n\n return name ? { isActive: true, name } : { isActive: false };\n }\n\n /**\n * Set specific repo as active one\n *\n * @param repoName name of the repository to activate\n */\n async setActive(repoName: string): Promise<void> {\n const sysRepoObj = await this.objects.getObject(SYSTEM_REPOSITORIES_ID);\n const obj = sysRepoObj || this.defaultSystemRepo;\n\n if (!obj.native.repositories[repoName]) {\n throw new Error(`Repository \"${repoName}\" not found.`);\n }\n\n const confObj = await this.objects.getObject(SYSTEM_CONFIG_ID);\n if (typeof confObj?.common.activeRepo === 'string') {\n confObj.common.activeRepo = [confObj.common.activeRepo];\n }\n\n if (!confObj || confObj.common.activeRepo.includes(repoName)) {\n return;\n }\n\n confObj.common.activeRepo.push(repoName);\n\n const stableInfo = this.getRepoActiveInfo({\n url: STABLE_REPO_URL,\n sysConfObj: confObj,\n repoObj: obj,\n });\n\n const betaInfo = this.getRepoActiveInfo({\n url: BETA_REPO_URL,\n sysConfObj: confObj,\n repoObj: obj,\n });\n\n if (stableInfo.isActive && betaInfo.isActive) {\n const posStable = confObj.common.activeRepo.indexOf(stableInfo.name);\n const posBeta = confObj.common.activeRepo.indexOf(betaInfo.name);\n\n if (posStable < posBeta) {\n // put beta in front of stable, so stable will override adapters\n confObj.common.activeRepo.splice(posBeta, 1);\n confObj.common.activeRepo.splice(posStable, 0, betaInfo.name);\n console.info(\n `Ensured that stable repository \"${stableInfo.name}\" has priority over beta repository \"${betaInfo.name}\"`,\n );\n }\n }\n\n if (confObj.common.activeRepo.length > 1) {\n console.info('More than one repository is active. Please be sure, that this is a desired constellation!');\n }\n\n confObj.from = `system.host.${tools.getHostName()}.cli`;\n confObj.ts = Date.now();\n await this.objects.setObject(SYSTEM_CONFIG_ID, confObj);\n }\n\n /**\n * Set given repo as inactive\n *\n * @param repoName name of the repository\n */\n async setInactive(repoName: string): Promise<void> {\n const confObj = (await this.objects.getObject(SYSTEM_CONFIG_ID))!;\n if (typeof confObj?.common.activeRepo === 'string') {\n confObj.common.activeRepo = [confObj.common.activeRepo];\n }\n\n const pos = confObj.common.activeRepo.indexOf(repoName);\n if (pos !== -1) {\n confObj.common.activeRepo.splice(pos, 1);\n confObj.from = `system.host.${tools.getHostName()}.cli`;\n confObj.ts = Date.now();\n await this.objects.setObject(SYSTEM_CONFIG_ID, confObj);\n }\n }\n\n /**\n * Renames existing repository if old name and link matches, renaming will not be performed if a repo with the new name already exists\n *\n * @param oldName - name of the current repository\n * @param newName - target name\n * @param repoUrl - hyperlink of the repository\n */\n async rename(oldName: string, newName: string, repoUrl: string): Promise<void> {\n let repoObj;\n let sysConfigObj;\n try {\n sysConfigObj = await this.objects.getObject(SYSTEM_CONFIG_ID);\n repoObj = await this.objects.getObject(SYSTEM_REPOSITORIES_ID);\n } catch (err) {\n throw new Error(`Could not rename repository \"${oldName}\" to \"${newName}\": ${err.message}`);\n }\n\n if (isIntegerLikeInput(newName)) {\n throw new Error(`Invalid name \"${newName}\"! A repository name is not allowed to contain only numbers.`);\n }\n\n if (!repoObj) {\n return;\n }\n\n if (\n repoObj.native.repositories[oldName] &&\n repoObj.native.repositories[oldName].link === repoUrl &&\n !repoObj.native.repositories[newName]\n ) {\n repoObj.native.repositories[newName] = repoObj.native.repositories[oldName];\n delete repoObj.native.repositories[oldName];\n\n try {\n await this.objects.setObject(SYSTEM_REPOSITORIES_ID, repoObj);\n console.log(`Renamed repository \"${oldName} to \"${newName}\"`);\n } catch (e) {\n throw new Error(`Could not rename repository \"${oldName}\" to \"${newName}\": ${e.message}`);\n }\n\n // if we changed the name of the activeRepo, we should set newName as active repo\n if (\n sysConfigObj?.common &&\n ((typeof sysConfigObj.common.activeRepo === 'string' && sysConfigObj.common.activeRepo === oldName) ||\n (Array.isArray(sysConfigObj.common.activeRepo) && sysConfigObj.common.activeRepo.includes(oldName)))\n ) {\n if (typeof sysConfigObj.common.activeRepo === 'string') {\n sysConfigObj.common.activeRepo = [sysConfigObj.common.activeRepo];\n }\n const pos = sysConfigObj.common.activeRepo.indexOf(oldName);\n sysConfigObj.common.activeRepo.splice(pos, 1, newName);\n\n try {\n await this.objects.setObject(SYSTEM_CONFIG_ID, sysConfigObj);\n } catch (e) {\n throw new Error(`Could not set \"${newName}\" as active repository: ${e.message}`);\n }\n }\n }\n }\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;AAAA,kCAAkC;AAClC,mBAAkB;AAClB,sBAAe;AAGf,mBAAqF;AACrF,uBAAiB;AACjB,uBAAyD;
|
|
4
|
+
"sourcesContent": ["import { tools, EXIT_CODES } from '@iobroker/js-controller-common';\nimport axios from 'axios';\nimport fs from 'fs-extra';\nimport type { Client as ObjectsRedisClient } from '@iobroker/db-objects-redis';\nimport type { Client as StatesRedisClient } from '@iobroker/db-states-redis';\nimport { BETA_REPO_URL, isIntegerLikeInput, isVersionIgnored, STABLE_REPO_URL } from '@/lib/setup/utils.js';\nimport path from 'node:path';\nimport { SYSTEM_CONFIG_ID, SYSTEM_REPOSITORIES_ID } from '@iobroker/js-controller-common-db/constants';\n\n/** The options passed to the Repo constructor */\nexport interface CLIRepoOptions {\n /** Instance of objects DB */\n objects: ObjectsRedisClient;\n /** Instance of states DB */\n states: StatesRedisClient;\n}\n\n/**\n * All possible Repo Flags which can be passed to the `show` method\n */\nexport interface RepoFlags {\n /** Also list not installed adapters */\n a?: boolean;\n /** Also list not installed adapters */\n all?: boolean;\n /** Only list updatable adapters */\n u?: boolean;\n /** Only list updatable adapters */\n updatable?: boolean;\n /** Force update even if hash hasn't changed */\n f?: boolean;\n /** Force update even if hash hasn't changed */\n force?: boolean;\n}\n\ntype RepoActiveInfo =\n | {\n /** If the repo is active */\n isActive: true;\n /** Name of the repository */\n name: string;\n }\n | {\n /** If the repo is active */\n isActive: false;\n };\n\ninterface RepoActiveOptions {\n /** Url to check if active */\n url: string;\n /** System config object */\n sysConfObj: ioBroker.SystemConfigObject;\n /** Repository object */\n repoObj: ioBroker.RepositoryObject;\n}\n\n/**\n * CLI command to manage the ioBroker repositories\n */\nexport class Repo {\n private readonly defaultSystemRepo: ioBroker.RepositoryObject;\n private readonly objects: ObjectsRedisClient;\n private readonly states: StatesRedisClient;\n private readonly controllerVersion: string;\n\n /**\n * @param options The objects/states clients and the controller version\n */\n constructor(options: CLIRepoOptions) {\n if (!options?.objects) {\n throw new Error('Invalid arguments: objects is missing');\n }\n if (!options?.states) {\n throw new Error('Invalid arguments: states is missing');\n }\n\n const ioPackage = fs.readJSONSync(path.join(tools.getControllerDir(), 'io-package.json'));\n this.controllerVersion = ioPackage.common.version;\n\n this.objects = options.objects;\n this.states = options.states;\n\n this.defaultSystemRepo = {\n common: {\n name: 'System repositories',\n dontDelete: true,\n },\n native: {\n repositories: {\n stable: {\n link: STABLE_REPO_URL,\n json: null,\n },\n beta: {\n link: BETA_REPO_URL,\n json: null,\n },\n },\n },\n _id: SYSTEM_REPOSITORIES_ID,\n type: 'config',\n };\n }\n\n /**\n * Get the repository name by index\n * Throws if the index does not exist\n *\n * @param repoIndex repo name or index\n */\n async getNameByIndex(repoIndex: number): Promise<string> {\n const obj = await this.objects.getObject(SYSTEM_REPOSITORIES_ID);\n if (!obj?.native?.repositories) {\n throw new Error('No repositories setup!');\n }\n\n const repoNames = Object.keys(obj.native.repositories);\n if (!repoNames[repoIndex]) {\n throw new Error(`No repository for index \"${repoIndex}\" found`);\n }\n\n return repoNames[repoIndex];\n }\n\n /**\n * Update the given repository and returns new repo content\n *\n * @param repoName name of the repository\n * @param force force update even if same hash\n * @param systemConfig content of `system.config` object\n * @param systemRepos content of `system.repositories` object\n */\n private async updateRepo(\n repoName: string,\n force: boolean | undefined,\n systemConfig?: ioBroker.OtherObject,\n systemRepos?: ioBroker.RepositoryObject,\n ): Promise<null | ioBroker.RepositoryJson> {\n if (!repoName) {\n const sysConfig = systemConfig || (await this.objects.getObject(SYSTEM_CONFIG_ID));\n repoName = sysConfig!.common.activeRepo;\n }\n\n const oldRepos = systemRepos || (await this.objects.getObject(SYSTEM_REPOSITORIES_ID));\n if (!oldRepos?.native.repositories?.[repoName]) {\n console.log(`Error: repository \"${repoName}\" not found in the \"${SYSTEM_REPOSITORIES_ID}\"`);\n return null;\n }\n\n const urlOrPath = oldRepos.native.repositories[repoName].link;\n const hashUrl = urlOrPath.replace(/\\.json$/, '-hash.json');\n let hash;\n\n if (\n !force &&\n oldRepos.native.repositories[repoName].hash &&\n oldRepos.native.repositories[repoName].json &&\n (urlOrPath.startsWith('http://') || urlOrPath.startsWith('https://'))\n ) {\n try {\n hash = await axios({ url: hashUrl, timeout: 10_000 });\n } catch (e) {\n console.error(`Cannot download repository hash file from \"${hashUrl}\": ${e.message}`);\n }\n if (hash?.data && oldRepos.native.repositories[repoName].hash === hash.data.hash) {\n return oldRepos.native.repositories[repoName].json;\n }\n }\n\n let data;\n\n if (urlOrPath.startsWith('http://') || urlOrPath.startsWith('https://')) {\n if (!hash) {\n try {\n hash = await axios({ url: hashUrl, timeout: 10000 });\n } catch (e) {\n console.error(`Cannot download repository hash file from \"${hashUrl}\": ${e.message}`);\n }\n }\n\n const agent = `${tools.appName}, RND: CLI, Node:${process.version}, V:${this.controllerVersion}`;\n try {\n data = await axios({\n url: urlOrPath,\n timeout: 10_000,\n headers: { 'User-Agent': agent },\n });\n if (data.data) {\n data = data.data;\n } else {\n data = null;\n }\n } catch (e) {\n console.error(`Cannot download repository file from \"${urlOrPath}\": ${e.message}`);\n data = null;\n }\n } else {\n if (fs.existsSync(urlOrPath)) {\n try {\n data = JSON.parse(fs.readFileSync(urlOrPath).toString('utf8'));\n } catch (err) {\n console.error(`Error: Cannot read or parse file \"${urlOrPath}\": ${err.message}`);\n }\n } else {\n console.error(`Error: Cannot find file \"${urlOrPath}\"`);\n }\n }\n\n let changed;\n if (data) {\n oldRepos.native.repositories[repoName].json = data;\n changed = true;\n }\n if (hash?.data) {\n oldRepos.native.repositories[repoName].hash = hash.data.hash;\n changed = true;\n }\n if (changed) {\n oldRepos.from = `system.host.${tools.getHostName()}.cli`;\n oldRepos.ts = Date.now();\n await this.objects.setObject(SYSTEM_REPOSITORIES_ID, oldRepos);\n }\n\n return oldRepos.native.repositories[repoName].json;\n }\n\n /**\n * Show repo on CLI\n *\n * @param repoUrl url of the repository\n * @param flags CLI flags\n */\n async showRepo(repoUrl: string | string[], flags: RepoFlags): Promise<void> {\n // Get the repositories\n const systemConfig = await this.objects.getObject(SYSTEM_CONFIG_ID);\n const systemRepos = await this.objects.getObject(SYSTEM_REPOSITORIES_ID);\n if (!systemConfig) {\n console.error(`Error: Object \"${SYSTEM_CONFIG_ID}\" not found`);\n } else if (!systemRepos) {\n console.error(`Error: Object \"${SYSTEM_REPOSITORIES_ID}\" not found`);\n } else if (!systemRepos.native || !systemRepos.native.repositories) {\n console.error(`Error: no repositories found in the \"${SYSTEM_REPOSITORIES_ID}\"`);\n } else {\n repoUrl = repoUrl || systemConfig.common.activeRepo;\n\n if (!Array.isArray(repoUrl)) {\n repoUrl = [repoUrl];\n }\n\n console.log(`Used ${repoUrl.length > 1 ? 'repositories' : 'repository'}: ${repoUrl.join(', ')}`);\n\n const allSources = {};\n\n for (const url of repoUrl) {\n const repo = systemRepos.native.repositories[url];\n // If known repository\n if (repo) {\n if (typeof repo === 'string') {\n systemRepos.native.repositories[url] = {\n link: repo,\n json: null,\n hash: '',\n };\n }\n\n const sources = await this.updateRepo(url, flags.force || flags.f, systemConfig, systemRepos);\n sources && Object.assign(allSources, sources);\n } else {\n console.error(\n `Error: unknown repository is active - \"${url}\". Known: ${Object.keys(\n systemRepos.native.repositories,\n ).join(', ')}`,\n );\n }\n }\n\n try {\n // update variables of every admin instance\n await this.updateInfo(allSources);\n } catch {\n // not important if fails\n }\n\n return this.showRepoResult(allSources, flags);\n }\n }\n\n /**\n * Show the repo result on CLI\n *\n * @param sources Repo JSON sources\n * @param flags CLI flags\n */\n private async showRepoResult(sources: Record<string, any>, flags: RepoFlags): Promise<void> {\n const installed = tools.getInstalledInfo();\n const adapters = Object.keys(sources).sort();\n\n for (const name of adapters) {\n let updatable = false;\n let text = sources[name].controller ? 'Controller ' : 'Adapter ';\n text += `\"${name}\"`;\n text = text.padEnd(11 + 15);\n\n if (sources[name].version) {\n text += `: ${sources[name].version}`;\n }\n text = text.padEnd(11 + 15 + 11);\n\n if (!(flags.all || flags.a) && !installed[name]) {\n continue;\n }\n\n if (installed[name]?.version) {\n text += `, installed ${installed[name].version}`;\n try {\n // tools.upToDate can throw if a version is invalid\n if (\n sources[name].version !== installed[name].version &&\n sources[name].version &&\n !tools.upToDate(sources[name].version, installed[name].version)\n ) {\n updatable = true;\n text = text.padEnd(11 + 15 + 11 + 18);\n const isIgnored = await isVersionIgnored({\n adapterName: name,\n objects: this.objects,\n version: sources[name].version,\n });\n\n text += isIgnored ? ' [Ignored]' : ' [Updatable]';\n }\n } catch (e) {\n console.error(`Cannot determine update info of \"${name}\": ${e.message}`);\n }\n }\n if ((flags.updatable || flags.u) && !updatable) {\n continue;\n }\n console.log(text);\n }\n }\n\n /**\n * Update Admin info states with number of updates\n *\n * @param sources the repository object\n */\n private async updateInfo(sources: Record<string, any>): Promise<void> {\n const installed = tools.getInstalledInfo();\n const list: string[] = [];\n\n for (const name of Object.keys(sources)) {\n if (installed[name] && installed[name].version && sources[name].version) {\n try {\n // tools.upToDate can throw if a version is invalid\n if (\n sources[name].version !== installed[name].version &&\n !tools.upToDate(sources[name].version, installed[name].version)\n ) {\n // remove the first part of the name\n const n = name.indexOf('.');\n list.push(n === -1 ? name : name.substring(n + 1));\n }\n } catch (e) {\n console.error(`Cannot determine update info of \"${name}\": ${e.message}`);\n }\n }\n }\n\n const objs = await this.objects.getObjectViewAsync('system', 'instance', {\n startkey: 'system.adapter.admin',\n endkey: 'system.adapter.admin\\u9999',\n });\n\n if (objs?.rows?.length) {\n const listStr = list.join(', ');\n for (const row of objs.rows) {\n if (row?.value?.type === 'instance') {\n await this.states.setState(`${row.id}.info.updatesNumber`, { val: list.length, ack: true });\n await this.states.setState(`${row.id}.info.updatesList`, { val: listStr, ack: true });\n }\n }\n }\n }\n\n /**\n * Show the current status of Repo on CLI\n */\n async showRepoStatus(): Promise<number> {\n try {\n const obj = await this.objects.getObject(SYSTEM_REPOSITORIES_ID);\n const objCfg = await this.objects.getObject(SYSTEM_CONFIG_ID);\n\n if (!obj) {\n console.error('List is empty');\n return EXIT_CODES.CANNOT_GET_REPO_LIST;\n } else if (obj.native.repositories) {\n console.table(\n Object.entries(obj.native.repositories).map(([key, value]) => {\n return {\n name: key,\n url: value.link,\n 'auto upgrade': objCfg?.common.adapterAutoUpgrade?.repositories[key] ?? false,\n };\n }),\n );\n\n if (objCfg?.common) {\n let activeRepo = objCfg.common.activeRepo;\n if (typeof activeRepo === 'string') {\n activeRepo = [activeRepo];\n }\n console.log(`\\nActive repo(s): ${activeRepo.join(', ')}`);\n console.log(`Upgrade policy: ${objCfg.common.adapterAutoUpgrade?.defaultPolicy ?? 'none'}`);\n }\n } else {\n console.error('List is empty');\n return EXIT_CODES.CANNOT_GET_REPO_LIST;\n }\n } catch (err) {\n console.error(`Cannot get list: ${err}`);\n }\n return EXIT_CODES.CANNOT_GET_REPO_LIST;\n }\n\n /**\n * Add new repo\n *\n * @param repoName name of new repo\n * @param repoUrl url of new repo\n */\n async add(repoName: string, repoUrl: string): Promise<void> {\n const sysRepoObj = await this.objects.getObject(SYSTEM_REPOSITORIES_ID);\n const obj = sysRepoObj || this.defaultSystemRepo;\n\n if (obj.native.repositories[repoName]) {\n throw new Error(`Repository \"${repoName}\" yet exists: ${obj.native.repositories[repoName].link}`);\n } else {\n if (isIntegerLikeInput(repoName)) {\n throw new Error(\n `Invalid name \"${repoName}\"! A repository name is not allowed to contain only numbers.`,\n );\n }\n\n obj.native.repositories[repoName] = {\n link: repoUrl,\n json: null,\n };\n obj.from = `system.host.${tools.getHostName()}.cli`;\n obj.ts = Date.now();\n await this.objects.setObject(SYSTEM_REPOSITORIES_ID, obj);\n }\n }\n\n /**\n * Remove repository from sources\n *\n * @param repoName name of repository to remove\n */\n async del(repoName: string): Promise<void> {\n const obj = await this.objects.getObject(SYSTEM_CONFIG_ID);\n if (\n (obj?.common.activeRepo &&\n typeof obj.common.activeRepo === 'string' &&\n obj.common.activeRepo === repoName) ||\n (obj?.common.activeRepo && Array.isArray(obj.common.activeRepo) && obj.common.activeRepo.includes(repoName))\n ) {\n throw new Error(`Cannot delete active repository: ${repoName}`);\n } else {\n const repoObj = await this.objects.getObject(SYSTEM_REPOSITORIES_ID);\n if (repoObj) {\n if (!repoObj.native.repositories[repoName]) {\n throw new Error(`Repository \"${repoName}\" not found.`);\n } else {\n delete repoObj.native.repositories[repoName];\n repoObj.from = `system.host.${tools.getHostName()}.cli`;\n repoObj.ts = Date.now();\n await this.objects.setObject(SYSTEM_REPOSITORIES_ID, repoObj);\n }\n }\n }\n }\n\n /**\n * Checks if stable repo is active\n *\n * @param options the system config object and the repository object\n */\n private getRepoActiveInfo(options: RepoActiveOptions): RepoActiveInfo {\n const { repoObj, sysConfObj, url } = options;\n\n const name = sysConfObj.common.activeRepo.find(\n activeRepo => repoObj.native.repositories[activeRepo].link === url,\n );\n\n return name ? { isActive: true, name } : { isActive: false };\n }\n\n /**\n * Set specific repo as active one\n *\n * @param repoName name of the repository to activate\n */\n async setActive(repoName: string): Promise<void> {\n const sysRepoObj = await this.objects.getObject(SYSTEM_REPOSITORIES_ID);\n const obj = sysRepoObj || this.defaultSystemRepo;\n\n if (!obj.native.repositories[repoName]) {\n throw new Error(`Repository \"${repoName}\" not found.`);\n }\n\n const confObj = await this.objects.getObject(SYSTEM_CONFIG_ID);\n if (typeof confObj?.common.activeRepo === 'string') {\n confObj.common.activeRepo = [confObj.common.activeRepo];\n }\n\n if (!confObj || confObj.common.activeRepo.includes(repoName)) {\n return;\n }\n\n confObj.common.activeRepo.push(repoName);\n\n const stableInfo = this.getRepoActiveInfo({\n url: STABLE_REPO_URL,\n sysConfObj: confObj,\n repoObj: obj,\n });\n\n const betaInfo = this.getRepoActiveInfo({\n url: BETA_REPO_URL,\n sysConfObj: confObj,\n repoObj: obj,\n });\n\n if (stableInfo.isActive && betaInfo.isActive) {\n const posStable = confObj.common.activeRepo.indexOf(stableInfo.name);\n const posBeta = confObj.common.activeRepo.indexOf(betaInfo.name);\n\n if (posStable < posBeta) {\n // put beta in front of stable, so stable will override adapters\n confObj.common.activeRepo.splice(posBeta, 1);\n confObj.common.activeRepo.splice(posStable, 0, betaInfo.name);\n console.info(\n `Ensured that stable repository \"${stableInfo.name}\" has priority over beta repository \"${betaInfo.name}\"`,\n );\n }\n }\n\n if (confObj.common.activeRepo.length > 1) {\n console.info('More than one repository is active. Please be sure, that this is a desired constellation!');\n }\n\n confObj.from = `system.host.${tools.getHostName()}.cli`;\n confObj.ts = Date.now();\n await this.objects.setObject(SYSTEM_CONFIG_ID, confObj);\n }\n\n /**\n * Set given repo as inactive\n *\n * @param repoName name of the repository\n */\n async setInactive(repoName: string): Promise<void> {\n const confObj = (await this.objects.getObject(SYSTEM_CONFIG_ID))!;\n if (typeof confObj?.common.activeRepo === 'string') {\n confObj.common.activeRepo = [confObj.common.activeRepo];\n }\n\n const pos = confObj.common.activeRepo.indexOf(repoName);\n if (pos !== -1) {\n confObj.common.activeRepo.splice(pos, 1);\n confObj.from = `system.host.${tools.getHostName()}.cli`;\n confObj.ts = Date.now();\n await this.objects.setObject(SYSTEM_CONFIG_ID, confObj);\n }\n }\n\n /**\n * Renames existing repository if old name and link matches, renaming will not be performed if a repo with the new name already exists\n *\n * @param oldName - name of the current repository\n * @param newName - target name\n * @param repoUrl - hyperlink of the repository\n */\n async rename(oldName: string, newName: string, repoUrl: string): Promise<void> {\n let repoObj;\n let sysConfigObj;\n try {\n sysConfigObj = await this.objects.getObject(SYSTEM_CONFIG_ID);\n repoObj = await this.objects.getObject(SYSTEM_REPOSITORIES_ID);\n } catch (err) {\n throw new Error(`Could not rename repository \"${oldName}\" to \"${newName}\": ${err.message}`);\n }\n\n if (isIntegerLikeInput(newName)) {\n throw new Error(`Invalid name \"${newName}\"! A repository name is not allowed to contain only numbers.`);\n }\n\n if (!repoObj) {\n return;\n }\n\n if (\n repoObj.native.repositories[oldName] &&\n repoObj.native.repositories[oldName].link === repoUrl &&\n !repoObj.native.repositories[newName]\n ) {\n repoObj.native.repositories[newName] = repoObj.native.repositories[oldName];\n delete repoObj.native.repositories[oldName];\n\n try {\n await this.objects.setObject(SYSTEM_REPOSITORIES_ID, repoObj);\n console.log(`Renamed repository \"${oldName} to \"${newName}\"`);\n } catch (e) {\n throw new Error(`Could not rename repository \"${oldName}\" to \"${newName}\": ${e.message}`);\n }\n\n // if we changed the name of the activeRepo, we should set newName as active repo\n if (\n sysConfigObj?.common &&\n ((typeof sysConfigObj.common.activeRepo === 'string' && sysConfigObj.common.activeRepo === oldName) ||\n (Array.isArray(sysConfigObj.common.activeRepo) && sysConfigObj.common.activeRepo.includes(oldName)))\n ) {\n if (typeof sysConfigObj.common.activeRepo === 'string') {\n sysConfigObj.common.activeRepo = [sysConfigObj.common.activeRepo];\n }\n const pos = sysConfigObj.common.activeRepo.indexOf(oldName);\n sysConfigObj.common.activeRepo.splice(pos, 1, newName);\n\n try {\n await this.objects.setObject(SYSTEM_CONFIG_ID, sysConfigObj);\n } catch (e) {\n throw new Error(`Could not set \"${newName}\" as active repository: ${e.message}`);\n }\n }\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["fs", "path", "axios"]
|
|
7
7
|
}
|
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
import type { CleanDatabaseHandler, IoPackage, ProcessExitCallback, RestartController } from '../../lib/_Types.js';
|
|
2
2
|
import { EXIT_CODES } from '@iobroker/js-controller-common';
|
|
3
|
+
/** Options for the setup command */
|
|
3
4
|
export interface CLISetupOptions {
|
|
5
|
+
/** Handler to clean the database */
|
|
4
6
|
cleanDatabase: CleanDatabaseHandler;
|
|
7
|
+
/** Callback to exit the process with an exit code */
|
|
5
8
|
processExit: ProcessExitCallback;
|
|
9
|
+
/** Parsed CLI parameters */
|
|
6
10
|
params: Record<string, any>;
|
|
11
|
+
/** Handler to restart the controller */
|
|
7
12
|
restartController: RestartController;
|
|
8
13
|
}
|
|
14
|
+
/** Options for running the setup command */
|
|
9
15
|
export interface SetupCommandOptions {
|
|
10
16
|
/** Callback called afterward */
|
|
11
17
|
callback: (isCreated?: boolean) => void;
|
|
@@ -14,6 +20,9 @@ export interface SetupCommandOptions {
|
|
|
14
20
|
/** If redis should be setup */
|
|
15
21
|
useRedis: boolean;
|
|
16
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* CLI command that performs the initial ioBroker setup (databases, config and objects)
|
|
25
|
+
*/
|
|
17
26
|
export declare class Setup {
|
|
18
27
|
/** Object IDs which are not allowed to exist but could be generated due to errors in the past */
|
|
19
28
|
private readonly KNOWN_GARBAGE_OBJECT_IDS;
|
|
@@ -25,7 +34,15 @@ export declare class Setup {
|
|
|
25
34
|
private readonly params;
|
|
26
35
|
private readonly cleanDatabase;
|
|
27
36
|
private readonly restartController;
|
|
37
|
+
/**
|
|
38
|
+
* @param options Handlers for cleaning the DB, exiting and restarting, plus the CLI parameters
|
|
39
|
+
*/
|
|
28
40
|
constructor(options: CLISetupOptions);
|
|
41
|
+
/**
|
|
42
|
+
* Print information about the plugins configured for the controller
|
|
43
|
+
*
|
|
44
|
+
* @param systemConfig The system.config object, used to read the active repository
|
|
45
|
+
*/
|
|
29
46
|
informAboutPlugins(systemConfig?: ioBroker.SystemConfigObject | null): Promise<void>;
|
|
30
47
|
/**
|
|
31
48
|
* Called after io-package objects are created (hence object view functionalities are now available)
|
|
@@ -34,6 +51,13 @@ export declare class Setup {
|
|
|
34
51
|
* @param callback callback function
|
|
35
52
|
*/
|
|
36
53
|
setupReady(systemConfig: ioBroker.SystemConfigObject | undefined | null, callback: () => void): Promise<void>;
|
|
54
|
+
/**
|
|
55
|
+
* Create the initial set of objects and design documents in the database
|
|
56
|
+
*
|
|
57
|
+
* @param iopkg The io-package.json of the controller
|
|
58
|
+
* @param ignoreExisting Whether to proceed even if the config already exists
|
|
59
|
+
* @param callback Called once the database has been set up
|
|
60
|
+
*/
|
|
37
61
|
dbSetup(iopkg: IoPackage, ignoreExisting: boolean, callback: () => void): Promise<void>;
|
|
38
62
|
/**
|
|
39
63
|
* Fix the config object if existing
|
|
@@ -55,6 +79,9 @@ export declare class Setup {
|
|
|
55
79
|
* @param oldConfig - previous config
|
|
56
80
|
*/
|
|
57
81
|
migrateObjects(newConfig: ioBroker.IoBrokerJson, oldConfig: ioBroker.IoBrokerJson): Promise<EXIT_CODES>;
|
|
82
|
+
/**
|
|
83
|
+
* Interactively configure the databases and write the configuration file
|
|
84
|
+
*/
|
|
58
85
|
setupCustom(): Promise<EXIT_CODES>;
|
|
59
86
|
/**
|
|
60
87
|
* Checks if single host setup and if so migrates and activates Redis Sets Usage
|
|
@@ -66,6 +66,9 @@ class Setup {
|
|
|
66
66
|
params;
|
|
67
67
|
cleanDatabase;
|
|
68
68
|
restartController;
|
|
69
|
+
/**
|
|
70
|
+
* @param options Handlers for cleaning the DB, exiting and restarting, plus the CLI parameters
|
|
71
|
+
*/
|
|
69
72
|
constructor(options) {
|
|
70
73
|
this.processExit = options.processExit;
|
|
71
74
|
this.params = options.params;
|
|
@@ -73,6 +76,11 @@ class Setup {
|
|
|
73
76
|
this.restartController = options.restartController;
|
|
74
77
|
this.dbSetup = this.dbSetup.bind(this);
|
|
75
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* Print information about the plugins configured for the controller
|
|
81
|
+
*
|
|
82
|
+
* @param systemConfig The system.config object, used to read the active repository
|
|
83
|
+
*/
|
|
76
84
|
async informAboutPlugins(systemConfig) {
|
|
77
85
|
if (!this.states) {
|
|
78
86
|
throw new Error("States not set up, call setupObjects first");
|
|
@@ -204,6 +212,13 @@ Please DO NOT copy files manually into ioBroker storage directories!`);
|
|
|
204
212
|
return void callback();
|
|
205
213
|
}
|
|
206
214
|
}
|
|
215
|
+
/**
|
|
216
|
+
* Create the initial set of objects and design documents in the database
|
|
217
|
+
*
|
|
218
|
+
* @param iopkg The io-package.json of the controller
|
|
219
|
+
* @param ignoreExisting Whether to proceed even if the config already exists
|
|
220
|
+
* @param callback Called once the database has been set up
|
|
221
|
+
*/
|
|
207
222
|
async dbSetup(iopkg, ignoreExisting, callback) {
|
|
208
223
|
if (!this.objects) {
|
|
209
224
|
throw new Error("Objects not set up, call setupObjects first");
|
|
@@ -525,6 +540,9 @@ Please DO NOT copy files manually into ioBroker storage directories!`);
|
|
|
525
540
|
import_fs_extra.default.writeFileSync(import_js_controller_common.tools.getConfigFileName(), JSON.stringify(newConfig, null, 2));
|
|
526
541
|
return import_js_controller_common.EXIT_CODES.NO_ERROR;
|
|
527
542
|
}
|
|
543
|
+
/**
|
|
544
|
+
* Interactively configure the databases and write the configuration file
|
|
545
|
+
*/
|
|
528
546
|
async setupCustom() {
|
|
529
547
|
let config;
|
|
530
548
|
try {
|