@iobroker/js-controller-cli 8.0.0-alpha.1-20260921-e5941ca8a → 8.0.0-alpha.12-20261105-0aa407437
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/index.d.ts +2 -0
- package/build/cjs/index.js +6 -0
- package/build/cjs/index.js.map +2 -2
- package/build/cjs/lib/cli/cliLogs.d.ts +20 -0
- package/build/cjs/lib/cli/cliLogs.js +44 -3
- package/build/cjs/lib/cli/cliLogs.js.map +2 -2
- package/build/cjs/lib/setup/adapterCompatibility.d.ts +39 -0
- package/build/cjs/lib/setup/adapterCompatibility.js +74 -0
- package/build/cjs/lib/setup/adapterCompatibility.js.map +7 -0
- package/build/cjs/lib/setup/setupInstall.d.ts +53 -0
- package/build/cjs/lib/setup/setupInstall.js +164 -19
- package/build/cjs/lib/setup/setupInstall.js.map +2 -2
- package/build/cjs/lib/setup/setupMultihost.d.ts +1 -1
- package/build/cjs/lib/setup/setupMultihost.js +2 -3
- package/build/cjs/lib/setup/setupMultihost.js.map +2 -2
- package/build/cjs/lib/setup/setupSetup.js +1 -1
- package/build/cjs/lib/setup/setupSetup.js.map +2 -2
- package/build/cjs/lib/setup.js +4 -0
- package/build/cjs/lib/setup.js.map +2 -2
- package/build/esm/index.d.ts +2 -0
- package/build/esm/index.d.ts.map +1 -1
- package/build/esm/index.js +2 -0
- package/build/esm/index.js.map +1 -1
- package/build/esm/lib/cli/cliLogs.d.ts +20 -0
- package/build/esm/lib/cli/cliLogs.d.ts.map +1 -1
- package/build/esm/lib/cli/cliLogs.js +46 -4
- package/build/esm/lib/cli/cliLogs.js.map +1 -1
- package/build/esm/lib/setup/adapterCompatibility.d.ts +39 -0
- package/build/esm/lib/setup/adapterCompatibility.d.ts.map +1 -0
- package/build/esm/lib/setup/adapterCompatibility.js +45 -0
- package/build/esm/lib/setup/adapterCompatibility.js.map +1 -0
- package/build/esm/lib/setup/setupInstall.d.ts +53 -0
- package/build/esm/lib/setup/setupInstall.d.ts.map +1 -1
- package/build/esm/lib/setup/setupInstall.js +182 -23
- package/build/esm/lib/setup/setupInstall.js.map +1 -1
- package/build/esm/lib/setup/setupMultihost.d.ts +1 -1
- package/build/esm/lib/setup/setupMultihost.d.ts.map +1 -1
- package/build/esm/lib/setup/setupMultihost.js +1 -2
- package/build/esm/lib/setup/setupMultihost.js.map +1 -1
- package/build/esm/lib/setup/setupSetup.js +1 -1
- package/build/esm/lib/setup/setupSetup.js.map +1 -1
- package/build/esm/lib/setup.d.ts.map +1 -1
- package/build/esm/lib/setup.js +4 -0
- package/build/esm/lib/setup.js.map +1 -1
- package/build/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/build/cjs/lib/setup/multihostClient.d.ts +0 -96
- package/build/cjs/lib/setup/multihostClient.js +0 -252
- package/build/cjs/lib/setup/multihostClient.js.map +0 -7
- package/build/esm/lib/setup/multihostClient.d.ts +0 -96
- package/build/esm/lib/setup/multihostClient.d.ts.map +0 -1
- package/build/esm/lib/setup/multihostClient.js +0 -242
- package/build/esm/lib/setup/multihostClient.js.map +0 -1
package/build/cjs/index.d.ts
CHANGED
|
@@ -3,7 +3,9 @@ export { dbConnectAsync } from './lib/setup/dbConnection.js';
|
|
|
3
3
|
export { Vendor } from './lib/setup/setupVendor.js';
|
|
4
4
|
export { Upload } from './lib/setup/setupUpload.js';
|
|
5
5
|
export { Upgrade } from './lib/setup/setupUpgrade.js';
|
|
6
|
+
export { Install } from './lib/setup/setupInstall.js';
|
|
6
7
|
export { BackupRestore } from './lib/setup/setupBackup.js';
|
|
7
8
|
export { PacketManager, type UpgradePacket } from './lib/setup/setupPacketManager.js';
|
|
9
|
+
export { checkAdapterCompatibility, type AdapterCompatibilityInput, type AdapterCompatibilityProblem, } from './lib/setup/adapterCompatibility.js';
|
|
8
10
|
export type * from './lib/_Types.js';
|
|
9
11
|
//# sourceMappingURL=index.d.ts.map
|
package/build/cjs/index.js
CHANGED
|
@@ -19,10 +19,12 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
19
19
|
var index_exports = {};
|
|
20
20
|
__export(index_exports, {
|
|
21
21
|
BackupRestore: () => import_setupBackup.BackupRestore,
|
|
22
|
+
Install: () => import_setupInstall.Install,
|
|
22
23
|
PacketManager: () => import_setupPacketManager.PacketManager,
|
|
23
24
|
Upgrade: () => import_setupUpgrade.Upgrade,
|
|
24
25
|
Upload: () => import_setupUpload.Upload,
|
|
25
26
|
Vendor: () => import_setupVendor.Vendor,
|
|
27
|
+
checkAdapterCompatibility: () => import_adapterCompatibility.checkAdapterCompatibility,
|
|
26
28
|
dbConnectAsync: () => import_dbConnection.dbConnectAsync,
|
|
27
29
|
execute: () => import_setup.execute
|
|
28
30
|
});
|
|
@@ -32,15 +34,19 @@ var import_dbConnection = require("./lib/setup/dbConnection.js");
|
|
|
32
34
|
var import_setupVendor = require("./lib/setup/setupVendor.js");
|
|
33
35
|
var import_setupUpload = require("./lib/setup/setupUpload.js");
|
|
34
36
|
var import_setupUpgrade = require("./lib/setup/setupUpgrade.js");
|
|
37
|
+
var import_setupInstall = require("./lib/setup/setupInstall.js");
|
|
35
38
|
var import_setupBackup = require("./lib/setup/setupBackup.js");
|
|
36
39
|
var import_setupPacketManager = require("./lib/setup/setupPacketManager.js");
|
|
40
|
+
var import_adapterCompatibility = require("./lib/setup/adapterCompatibility.js");
|
|
37
41
|
// Annotate the CommonJS export names for ESM import in node:
|
|
38
42
|
0 && (module.exports = {
|
|
39
43
|
BackupRestore,
|
|
44
|
+
Install,
|
|
40
45
|
PacketManager,
|
|
41
46
|
Upgrade,
|
|
42
47
|
Upload,
|
|
43
48
|
Vendor,
|
|
49
|
+
checkAdapterCompatibility,
|
|
44
50
|
dbConnectAsync,
|
|
45
51
|
execute
|
|
46
52
|
});
|
package/build/cjs/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/index.ts"],
|
|
4
|
-
"sourcesContent": ["/// <reference types=\"@iobroker/types-dev\" />\nexport { execute } from '@/lib/setup.js';\nexport { dbConnectAsync } from '@/lib/setup/dbConnection.js';\nexport { Vendor } from '@/lib/setup/setupVendor.js';\nexport { Upload } from '@/lib/setup/setupUpload.js';\nexport { Upgrade } from '@/lib/setup/setupUpgrade.js';\nexport { BackupRestore } from '@/lib/setup/setupBackup.js';\nexport { PacketManager, type UpgradePacket } from '@/lib/setup/setupPacketManager.js';\nexport type * from '@/lib/_Types.js';\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA
|
|
4
|
+
"sourcesContent": ["/// <reference types=\"@iobroker/types-dev\" />\nexport { execute } from '@/lib/setup.js';\nexport { dbConnectAsync } from '@/lib/setup/dbConnection.js';\nexport { Vendor } from '@/lib/setup/setupVendor.js';\nexport { Upload } from '@/lib/setup/setupUpload.js';\nexport { Upgrade } from '@/lib/setup/setupUpgrade.js';\nexport { Install } from '@/lib/setup/setupInstall.js';\nexport { BackupRestore } from '@/lib/setup/setupBackup.js';\nexport { PacketManager, type UpgradePacket } from '@/lib/setup/setupPacketManager.js';\nexport {\n checkAdapterCompatibility,\n type AdapterCompatibilityInput,\n type AdapterCompatibilityProblem,\n} from '@/lib/setup/adapterCompatibility.js';\nexport type * from '@/lib/_Types.js';\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;;;;;AACA,mBAAwB;AACxB,0BAA+B;AAC/B,yBAAuB;AACvB,yBAAuB;AACvB,0BAAwB;AACxB,0BAAwB;AACxB,yBAA8B;AAC9B,gCAAkD;AAClD,kCAIO;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -4,6 +4,8 @@ interface CLILogsOptions {
|
|
|
4
4
|
complete?: boolean;
|
|
5
5
|
/** An optional RegExp to filter by */
|
|
6
6
|
regex?: RegExp;
|
|
7
|
+
/** The lowest level to still show, if the output is restricted to a severity */
|
|
8
|
+
minLevel?: ioBroker.LogLevel;
|
|
7
9
|
}
|
|
8
10
|
/** Command ioBroker state ... */
|
|
9
11
|
export declare class CLILogs extends CLICommand {
|
|
@@ -46,6 +48,24 @@ export declare class CLILogs extends CLICommand {
|
|
|
46
48
|
* @param options some options
|
|
47
49
|
*/
|
|
48
50
|
streamChange(path: string, start: number, options: CLILogsOptions): void;
|
|
51
|
+
/**
|
|
52
|
+
* Create the check of log lines against the active filters, for one read of a file
|
|
53
|
+
*
|
|
54
|
+
* A log entry can span several lines, e.g. a stack trace, and only its first line carries the
|
|
55
|
+
* level. Those follow-up lines inherit the decision made for the entry they belong to, so
|
|
56
|
+
* filtering by level does not cut a stack trace in half. Which lines start an entry is decided
|
|
57
|
+
* by the shared parser, the same one the host commands `getLogs` and `searchLogs` use: it takes
|
|
58
|
+
* a level only where the time stamp of an entry is, so a level quoted inside a message does not
|
|
59
|
+
* count as one.
|
|
60
|
+
*
|
|
61
|
+
* The decision belongs to one read and starts as "not shown". A read can begin with follow-up
|
|
62
|
+
* lines - the last lines of a file, or a stream from an offset - whose entry it does not know,
|
|
63
|
+
* and showing them would ignore the level. Files that are streamed at the same time do not
|
|
64
|
+
* share it either.
|
|
65
|
+
*
|
|
66
|
+
* @param options the active filters
|
|
67
|
+
*/
|
|
68
|
+
private createFilter;
|
|
49
69
|
}
|
|
50
70
|
export {};
|
|
51
71
|
//# sourceMappingURL=cliLogs.d.ts.map
|
|
@@ -67,6 +67,14 @@ class CLILogs extends import_cliCommand.CLICommand {
|
|
|
67
67
|
const options = {
|
|
68
68
|
complete: this.options.all
|
|
69
69
|
};
|
|
70
|
+
if (params.level !== void 0) {
|
|
71
|
+
const level = String(params.level).toLowerCase();
|
|
72
|
+
if (!import_js_controller_common.tools.isLogLevel(level)) {
|
|
73
|
+
console.error(`Unknown log level "${params.level}". Use one of: ${import_js_controller_common.LOG_LEVELS.join(", ")}`);
|
|
74
|
+
return void this.options.callback(import_js_controller_common.EXIT_CODES.INVALID_ARGUMENTS);
|
|
75
|
+
}
|
|
76
|
+
options.minLevel = level;
|
|
77
|
+
}
|
|
70
78
|
const config = import_fs_extra.default.readJSONSync(require2.resolve(getConfigFileName()));
|
|
71
79
|
const logger = (0, import_js_controller_common.logger)(config.log);
|
|
72
80
|
let fileName = logger.getFileName();
|
|
@@ -81,8 +89,9 @@ class CLILogs extends import_cliCommand.CLICommand {
|
|
|
81
89
|
regex = new RegExp(`: ${adapterName}\\.`);
|
|
82
90
|
options.regex = regex;
|
|
83
91
|
}
|
|
92
|
+
const matches = this.createFilter(options);
|
|
84
93
|
lines.forEach((line) => {
|
|
85
|
-
if (
|
|
94
|
+
if (!matches(line)) {
|
|
86
95
|
return;
|
|
87
96
|
}
|
|
88
97
|
console.log(line);
|
|
@@ -150,12 +159,44 @@ class CLILogs extends import_cliCommand.CLICommand {
|
|
|
150
159
|
start,
|
|
151
160
|
autoClose: true
|
|
152
161
|
});
|
|
153
|
-
if (options.regex) {
|
|
154
|
-
input.pipe(import_event_stream.default.split()).pipe(import_event_stream.default.filterSync((
|
|
162
|
+
if (options.regex || options.minLevel) {
|
|
163
|
+
input.pipe(import_event_stream.default.split()).pipe(import_event_stream.default.filterSync(this.createFilter(options))).pipe(import_event_stream.default.mapSync((line) => line + import_node_os.default.EOL)).pipe(process.stdout);
|
|
155
164
|
} else {
|
|
156
165
|
import_js_controller_common.tools.pipeLinewise(input, process.stdout);
|
|
157
166
|
}
|
|
158
167
|
}
|
|
168
|
+
/**
|
|
169
|
+
* Create the check of log lines against the active filters, for one read of a file
|
|
170
|
+
*
|
|
171
|
+
* A log entry can span several lines, e.g. a stack trace, and only its first line carries the
|
|
172
|
+
* level. Those follow-up lines inherit the decision made for the entry they belong to, so
|
|
173
|
+
* filtering by level does not cut a stack trace in half. Which lines start an entry is decided
|
|
174
|
+
* by the shared parser, the same one the host commands `getLogs` and `searchLogs` use: it takes
|
|
175
|
+
* a level only where the time stamp of an entry is, so a level quoted inside a message does not
|
|
176
|
+
* count as one.
|
|
177
|
+
*
|
|
178
|
+
* The decision belongs to one read and starts as "not shown". A read can begin with follow-up
|
|
179
|
+
* lines - the last lines of a file, or a stream from an offset - whose entry it does not know,
|
|
180
|
+
* and showing them would ignore the level. Files that are streamed at the same time do not
|
|
181
|
+
* share it either.
|
|
182
|
+
*
|
|
183
|
+
* @param options the active filters
|
|
184
|
+
*/
|
|
185
|
+
createFilter(options) {
|
|
186
|
+
let showEntry = false;
|
|
187
|
+
return (line) => {
|
|
188
|
+
if (options.minLevel) {
|
|
189
|
+
const header = (0, import_js_controller_common.parseLogEntryHeader)(line);
|
|
190
|
+
if (header) {
|
|
191
|
+
showEntry = (0, import_js_controller_common.isLogLevelAtLeast)(header.level, options.minLevel);
|
|
192
|
+
}
|
|
193
|
+
if (!showEntry) {
|
|
194
|
+
return false;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return !options.regex || options.regex.test(line);
|
|
198
|
+
};
|
|
199
|
+
}
|
|
159
200
|
}
|
|
160
201
|
// Annotate the CommonJS export names for ESM import in node:
|
|
161
202
|
0 && (module.exports = {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/lib/cli/cliLogs.ts", "../../../../../../node_modules/@alcalzone/esm2cjs/shims/import.meta.url/shim.js"],
|
|
4
|
-
"sourcesContent": ["import { CLICommand, type CLICommandOptions } from './cliCommand.js';\nimport {
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;ACAO,IAAM,oBACX,OAAO,aAAa,cAAc,KAAK,QAAQ,MAAM,QAAQ,IAAI,EAAE,CAAC,GAAE,IAAK,UAAU,UAAU,EAAE,OAC9F,SAAS,iBAAiB,SAAS,cAAc,OAAO,IAAI,IAAI,WAAW,SAAS,OAAO,EAAE;ADFlG,wBAAmD;AACnD,
|
|
4
|
+
"sourcesContent": ["import { CLICommand, type CLICommandOptions } from './cliCommand.js';\nimport {\n tools,\n logger as toolsLogger,\n EXIT_CODES,\n LOG_LEVELS,\n isLogLevelAtLeast,\n parseLogEntryHeader,\n} from '@iobroker/js-controller-common';\nimport chokidar from 'chokidar';\nimport fs from 'fs-extra';\nimport os from 'node:os';\nimport es from 'event-stream';\nimport { createRequire } from 'node:module';\n// eslint-disable-next-line unicorn/prefer-module\nconst require = createRequire(import.meta.url || `file://${__filename}`);\n\nconst { getConfigFileName } = tools;\n\ninterface CLILogsOptions {\n /** Whether to show today's full log */\n complete?: boolean;\n /** An optional RegExp to filter by */\n regex?: RegExp;\n /** The lowest level to still show, if the output is restricted to a severity */\n minLevel?: ioBroker.LogLevel;\n}\n\n/** Command ioBroker state ... */\nexport class CLILogs extends CLICommand {\n private readonly fileSizes = new Map<string, number>();\n private isReady = false;\n\n /**\n * @param options The command options including context and parameters\n */\n constructor(options: CLICommandOptions) {\n super(options);\n }\n\n /**\n * Executes a command\n *\n * @param args The command arguments (the first is the sub-command)\n * @param params additional parsed CLI parameters\n */\n execute(args: string[], params: Record<string, any>): void {\n const adapterName = args[0];\n const watch = params.watch || params.w;\n const count = params.lines || 1_000;\n\n const options: CLILogsOptions = {\n complete: this.options.all,\n };\n\n // Optional, so calls without a level keep showing everything as before\n if (params.level !== undefined) {\n const level = String(params.level).toLowerCase();\n\n if (!tools.isLogLevel(level)) {\n console.error(`Unknown log level \"${params.level}\". Use one of: ${LOG_LEVELS.join(', ')}`);\n return void this.options.callback(EXIT_CODES.INVALID_ARGUMENTS);\n }\n\n options.minLevel = level;\n }\n\n const config = fs.readJSONSync(require.resolve(getConfigFileName()));\n const logger = toolsLogger(config.log);\n // @ts-expect-error todo adjust logger type\n let fileName = logger.getFileName();\n if (fileName) {\n let lines = fs.readFileSync(fileName).toString('utf-8').split('\\n');\n lines = lines.filter(line => line);\n if (lines.length > count) {\n lines.splice(0, lines.length - count);\n }\n let regex: RegExp;\n if (adapterName) {\n //2019-03-02 13:26:54.698 - debug: iot.0 [ALEXA] Created ALEXA device: Bad.Hauptlicht.Aktor.STATE [\"turnOn\",\"turnOff\"]\n regex = new RegExp(`: ${adapterName}\\\\.`);\n options.regex = regex;\n }\n const matches = this.createFilter(options);\n lines.forEach(line => {\n if (!matches(line)) {\n return;\n }\n console.log(line);\n });\n\n if (watch) {\n fileName = fileName.replace(/\\\\/g, '/');\n const parts = fileName.split('/');\n parts.pop();\n chokidar\n .watch(`${parts.join('/')}/iobroker*`, {\n awaitWriteFinish: { stabilityThreshold: 500 },\n followSymlinks: false,\n })\n .on('all', this.watchHandler.bind(this, options))\n .on('ready', () => (this.isReady = true));\n }\n } else {\n console.log('No log file found');\n }\n }\n\n /**\n * Called by chokidar when watched files change\n *\n * @param options some options\n * @param event The type of change\n * @param path Which path has changed\n * @param stats Information about the file\n * @param stats.size The current size of the file in bytes\n */\n watchHandler(\n options: CLILogsOptions,\n event: string,\n path: string,\n stats?: {\n size: number;\n },\n ): void {\n if (!stats) {\n return;\n }\n if (event === 'add' || !this.fileSizes.has(path)) {\n this.fileSizes.set(path, stats.size);\n if (stats.size > 0 && (this.isReady || (options.complete && this.isTodaysLogfile(path)))) {\n this.streamChange(path, 0, options);\n }\n } else if (event === 'change') {\n const oldFileSize = this.fileSizes.get(path)!;\n this.fileSizes.set(path, stats.size);\n if (this.isReady && stats.size > oldFileSize) {\n this.streamChange(path, oldFileSize, options);\n }\n } else if (event === 'unlink') {\n this.fileSizes.delete(path);\n }\n }\n\n /**\n * If the log file belongs to today\n *\n * @param path The log file path\n */\n isTodaysLogfile(path: string): boolean {\n const YYYYMMDDDate = new Date().toJSON().slice(0, 10);\n return path.includes(YYYYMMDDDate);\n }\n\n /**\n * Streams a portion of a file to the console\n *\n * @param path The file to stream\n * @param start The offset in bytes where to start\n * @param options some options\n */\n streamChange(path: string, start: number, options: CLILogsOptions): void {\n const input = fs.createReadStream(path, {\n encoding: 'utf8',\n start,\n autoClose: true,\n });\n if (options.regex || options.minLevel) {\n // Read the input line by line and only include the lines matching the filter\n input\n .pipe(es.split())\n .pipe(es.filterSync(this.createFilter(options)))\n .pipe(es.mapSync((line: string) => line + os.EOL))\n .pipe(process.stdout);\n } else {\n // just pipe the input through\n tools.pipeLinewise(input, process.stdout);\n }\n }\n\n /**\n * Create the check of log lines against the active filters, for one read of a file\n *\n * A log entry can span several lines, e.g. a stack trace, and only its first line carries the\n * level. Those follow-up lines inherit the decision made for the entry they belong to, so\n * filtering by level does not cut a stack trace in half. Which lines start an entry is decided\n * by the shared parser, the same one the host commands `getLogs` and `searchLogs` use: it takes\n * a level only where the time stamp of an entry is, so a level quoted inside a message does not\n * count as one.\n *\n * The decision belongs to one read and starts as \"not shown\". A read can begin with follow-up\n * lines - the last lines of a file, or a stream from an offset - whose entry it does not know,\n * and showing them would ignore the level. Files that are streamed at the same time do not\n * share it either.\n *\n * @param options the active filters\n */\n private createFilter(options: CLILogsOptions): (line: string) => boolean {\n let showEntry = false;\n\n return line => {\n if (options.minLevel) {\n const header = parseLogEntryHeader(line);\n\n if (header) {\n showEntry = isLogLevelAtLeast(header.level, options.minLevel);\n }\n\n if (!showEntry) {\n return false;\n }\n }\n\n return !options.regex || options.regex.test(line);\n };\n }\n}\n", "export const __import_meta_url =\n typeof document === 'undefined' ? new (require('url'.replace('', '')).URL)('file:' + __filename).href :\n (document.currentScript && document.currentScript.src || new URL('main.js', document.baseURI).href)\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["require", "fs", "toolsLogger", "chokidar", "es", "os"]
|
|
7
7
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { EXIT_CODES } from '@iobroker/js-controller-common-db';
|
|
2
|
+
/** What is known about an adapter that is about to be installed */
|
|
3
|
+
export interface AdapterCompatibilityInput {
|
|
4
|
+
/** Content of its `io-package.json` */
|
|
5
|
+
ioPackage: {
|
|
6
|
+
common?: Partial<Pick<ioBroker.AdapterCommon, 'os' | 'nogit'>>;
|
|
7
|
+
} | null | undefined;
|
|
8
|
+
/** Content of its `package.json`, if known */
|
|
9
|
+
packageJson?: {
|
|
10
|
+
engines?: {
|
|
11
|
+
node?: string;
|
|
12
|
+
};
|
|
13
|
+
} | null;
|
|
14
|
+
/** Whether it is installed directly from GitHub (`iobroker url <github-url>`) */
|
|
15
|
+
fromGitHub?: boolean;
|
|
16
|
+
/** Operating system to check against, default `process.platform` */
|
|
17
|
+
platform?: string;
|
|
18
|
+
/** Node.js version to check against, default `process.version` */
|
|
19
|
+
nodeVersion?: string;
|
|
20
|
+
}
|
|
21
|
+
/** Why an adapter cannot be installed */
|
|
22
|
+
export interface AdapterCompatibilityProblem {
|
|
23
|
+
/** Exit code of the CLI */
|
|
24
|
+
exitCode: EXIT_CODES;
|
|
25
|
+
/** Message for the user */
|
|
26
|
+
message: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Check whether an adapter can be installed on this system: from GitHub only without `common.nogit`, only on a
|
|
30
|
+
* supported operating system (`common.os`) and only with a supported Node.js version (`engines.node`).
|
|
31
|
+
*
|
|
32
|
+
* The same checks run before a GitHub installation (with the files from GitHub) and before an adapter is set up
|
|
33
|
+
* (with the installed files).
|
|
34
|
+
*
|
|
35
|
+
* @param input the adapter files and the system to check against
|
|
36
|
+
* @returns the first problem found, or `null` if the adapter can be installed
|
|
37
|
+
*/
|
|
38
|
+
export declare function checkAdapterCompatibility(input: AdapterCompatibilityInput): AdapterCompatibilityProblem | null;
|
|
39
|
+
//# sourceMappingURL=adapterCompatibility.d.ts.map
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
9
|
+
var __export = (target, all) => {
|
|
10
|
+
for (var name in all)
|
|
11
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
12
|
+
};
|
|
13
|
+
var __copyProps = (to, from, except, desc) => {
|
|
14
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
15
|
+
for (let key of __getOwnPropNames(from))
|
|
16
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
17
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
18
|
+
}
|
|
19
|
+
return to;
|
|
20
|
+
};
|
|
21
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
22
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
23
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
24
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
25
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
26
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
27
|
+
mod
|
|
28
|
+
));
|
|
29
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
30
|
+
var adapterCompatibility_exports = {};
|
|
31
|
+
__export(adapterCompatibility_exports, {
|
|
32
|
+
checkAdapterCompatibility: () => checkAdapterCompatibility
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(adapterCompatibility_exports);
|
|
35
|
+
var import_semver = __toESM(require("semver"), 1);
|
|
36
|
+
var import_js_controller_common_db = require("@iobroker/js-controller-common-db");
|
|
37
|
+
function checkAdapterCompatibility(input) {
|
|
38
|
+
const common = input.ioPackage?.common;
|
|
39
|
+
const platform = input.platform ?? process.platform;
|
|
40
|
+
const nodeVersion = (input.nodeVersion ?? process.version).replace(/^v/, "");
|
|
41
|
+
if (input.fromGitHub && common?.nogit === true) {
|
|
42
|
+
return {
|
|
43
|
+
exitCode: import_js_controller_common_db.EXIT_CODES.CANNOT_INSTALL_NPM_PACKET,
|
|
44
|
+
message: 'Adapter cannot be installed from GitHub ("nogit" is set in io-package.json). Install it from the repository or from npm instead'
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
const os = common?.os;
|
|
48
|
+
if (typeof os === "string" && os !== platform) {
|
|
49
|
+
return {
|
|
50
|
+
exitCode: import_js_controller_common_db.EXIT_CODES.INVALID_OS,
|
|
51
|
+
message: `Adapter does not support current os. Required ${os}. Actual platform: ${platform}`
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
if (Array.isArray(os) && !os.includes(platform)) {
|
|
55
|
+
return {
|
|
56
|
+
exitCode: import_js_controller_common_db.EXIT_CODES.INVALID_OS,
|
|
57
|
+
message: `Adapter does not support current os. Required one of ${os.join(", ")}. Actual platform: ${platform}`
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
const engine = input.packageJson?.engines?.node;
|
|
61
|
+
if (engine && !import_semver.default.satisfies(nodeVersion, engine)) {
|
|
62
|
+
return {
|
|
63
|
+
exitCode: import_js_controller_common_db.EXIT_CODES.INVALID_NODE_VERSION,
|
|
64
|
+
message: `Adapter does not support current nodejs version. Required ${engine}. Actual version: v${nodeVersion}`
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
__name(checkAdapterCompatibility, "checkAdapterCompatibility");
|
|
70
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
71
|
+
0 && (module.exports = {
|
|
72
|
+
checkAdapterCompatibility
|
|
73
|
+
});
|
|
74
|
+
//# sourceMappingURL=adapterCompatibility.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/lib/setup/adapterCompatibility.ts"],
|
|
4
|
+
"sourcesContent": ["import semver from 'semver';\nimport { EXIT_CODES } from '@iobroker/js-controller-common-db';\n\n/** What is known about an adapter that is about to be installed */\nexport interface AdapterCompatibilityInput {\n /** Content of its `io-package.json` */\n ioPackage: { common?: Partial<Pick<ioBroker.AdapterCommon, 'os' | 'nogit'>> } | null | undefined;\n /** Content of its `package.json`, if known */\n packageJson?: { engines?: { node?: string } } | null;\n /** Whether it is installed directly from GitHub (`iobroker url <github-url>`) */\n fromGitHub?: boolean;\n /** Operating system to check against, default `process.platform` */\n platform?: string;\n /** Node.js version to check against, default `process.version` */\n nodeVersion?: string;\n}\n\n/** Why an adapter cannot be installed */\nexport interface AdapterCompatibilityProblem {\n /** Exit code of the CLI */\n exitCode: EXIT_CODES;\n /** Message for the user */\n message: string;\n}\n\n/**\n * Check whether an adapter can be installed on this system: from GitHub only without `common.nogit`, only on a\n * supported operating system (`common.os`) and only with a supported Node.js version (`engines.node`).\n *\n * The same checks run before a GitHub installation (with the files from GitHub) and before an adapter is set up\n * (with the installed files).\n *\n * @param input the adapter files and the system to check against\n * @returns the first problem found, or `null` if the adapter can be installed\n */\nexport function checkAdapterCompatibility(input: AdapterCompatibilityInput): AdapterCompatibilityProblem | null {\n const common = input.ioPackage?.common;\n const platform = input.platform ?? process.platform;\n const nodeVersion = (input.nodeVersion ?? process.version).replace(/^v/, '');\n\n if (input.fromGitHub && common?.nogit === true) {\n return {\n exitCode: EXIT_CODES.CANNOT_INSTALL_NPM_PACKET,\n message:\n 'Adapter cannot be installed from GitHub (\"nogit\" is set in io-package.json). Install it from the repository or from npm instead',\n };\n }\n\n const os = common?.os;\n if (typeof os === 'string' && os !== platform) {\n return {\n exitCode: EXIT_CODES.INVALID_OS,\n message: `Adapter does not support current os. Required ${os}. Actual platform: ${platform}`,\n };\n }\n if (Array.isArray(os) && !(os as string[]).includes(platform)) {\n return {\n exitCode: EXIT_CODES.INVALID_OS,\n message: `Adapter does not support current os. Required one of ${os.join(', ')}. Actual platform: ${platform}`,\n };\n }\n\n const engine = input.packageJson?.engines?.node;\n if (engine && !semver.satisfies(nodeVersion, engine)) {\n return {\n exitCode: EXIT_CODES.INVALID_NODE_VERSION,\n message: `Adapter does not support current nodejs version. Required ${engine}. Actual version: v${nodeVersion}`,\n };\n }\n\n return null;\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;AAAA,oBAAmB;AACnB,qCAA2B;AAkCrB,SAAU,0BAA0B,OAAgC;AACtE,QAAM,SAAS,MAAM,WAAW;AAChC,QAAM,WAAW,MAAM,YAAY,QAAQ;AAC3C,QAAM,eAAe,MAAM,eAAe,QAAQ,SAAS,QAAQ,MAAM,EAAE;AAE3E,MAAI,MAAM,cAAc,QAAQ,UAAU,MAAM;AAC5C,WAAO;MACH,UAAU,0CAAW;MACrB,SACI;;EAEZ;AAEA,QAAM,KAAK,QAAQ;AACnB,MAAI,OAAO,OAAO,YAAY,OAAO,UAAU;AAC3C,WAAO;MACH,UAAU,0CAAW;MACrB,SAAS,iDAAiD,EAAE,sBAAsB,QAAQ;;EAElG;AACA,MAAI,MAAM,QAAQ,EAAE,KAAK,CAAE,GAAgB,SAAS,QAAQ,GAAG;AAC3D,WAAO;MACH,UAAU,0CAAW;MACrB,SAAS,wDAAwD,GAAG,KAAK,IAAI,CAAC,sBAAsB,QAAQ;;EAEpH;AAEA,QAAM,SAAS,MAAM,aAAa,SAAS;AAC3C,MAAI,UAAU,CAAC,cAAAA,QAAO,UAAU,aAAa,MAAM,GAAG;AAClD,WAAO;MACH,UAAU,0CAAW;MACrB,SAAS,6DAA6D,MAAM,sBAAsB,WAAW;;EAErH;AAEA,SAAO;AACX;AApCgB;",
|
|
6
|
+
"names": ["semver"]
|
|
7
|
+
}
|
|
@@ -204,6 +204,21 @@ export declare class Install {
|
|
|
204
204
|
* @param adapter adapter name
|
|
205
205
|
*/
|
|
206
206
|
deleteAdapter(adapter: string): Promise<EXIT_CODES>;
|
|
207
|
+
/**
|
|
208
|
+
* Remove the virtual environment a Python adapter leaves behind in the data directory
|
|
209
|
+
*
|
|
210
|
+
* Host-local state like `node_modules` - rebuildable, but easily a few hundred megabytes - so it goes when
|
|
211
|
+
* the adapter goes. Deliberately not part of the npm uninstall: that one starts by resolving the adapter's
|
|
212
|
+
* `io-package.json`, so for a half-removed installation, where the package directory is already gone, it
|
|
213
|
+
* throws before ever getting here - and that is precisely the case which leaves the environment behind with
|
|
214
|
+
* nothing pointing at it.
|
|
215
|
+
*
|
|
216
|
+
* Removed without looking at `common.platform` for the same reason: the directory only exists for Python
|
|
217
|
+
* adapters, and the `io-package.json` that would say so may no longer be there.
|
|
218
|
+
*
|
|
219
|
+
* @param adapter adapter name, e.g. "pyexample"
|
|
220
|
+
*/
|
|
221
|
+
private _removePythonEnvironment;
|
|
207
222
|
/**
|
|
208
223
|
* Deletes given instance of an adapter
|
|
209
224
|
*
|
|
@@ -211,6 +226,21 @@ export declare class Install {
|
|
|
211
226
|
* @param instance e.g. 1, if undefined deletes all instances
|
|
212
227
|
*/
|
|
213
228
|
deleteInstance(adapter: string, instance?: number): Promise<void | EXIT_CODES.CANNOT_DELETE_DEPENDENCY>;
|
|
229
|
+
/**
|
|
230
|
+
* Free all exclusive resources (serial ports, TCP/UDP ports, ...) the given instance(s) had registered.
|
|
231
|
+
*
|
|
232
|
+
* This is needed because an instance can be deleted via the CLI while a js-controller is not running: it
|
|
233
|
+
* cannot notice that the instance object disappeared, so its `system.host.<host>.usedResources.<type>`
|
|
234
|
+
* states would keep listing the resources of an instance that no longer exists.
|
|
235
|
+
*
|
|
236
|
+
* Hosts that are running are deliberately skipped. Such a host cleans its own registry up when it sees the
|
|
237
|
+
* instance object being deleted, and it holds the registry in memory: it rewrites the state from that copy
|
|
238
|
+
* on its next change, which would silently undo a write made here.
|
|
239
|
+
*
|
|
240
|
+
* @param adapter adapter name, e.g. "mqtt"
|
|
241
|
+
* @param instance instance number; if undefined, all instances of the adapter are freed
|
|
242
|
+
*/
|
|
243
|
+
private _freeUsedResources;
|
|
214
244
|
/**
|
|
215
245
|
* Remove all node modules that has been installed by this instance
|
|
216
246
|
*
|
|
@@ -224,6 +254,29 @@ export declare class Install {
|
|
|
224
254
|
* @param ids - id of the adapter/instance to check for
|
|
225
255
|
*/
|
|
226
256
|
private _removeCustomFromObjects;
|
|
257
|
+
/**
|
|
258
|
+
* Read a JSON file of a GitHub repository at the given commit
|
|
259
|
+
*
|
|
260
|
+
* @param user GitHub user or organization
|
|
261
|
+
* @param repo repository name
|
|
262
|
+
* @param commit commit hash, branch or tag
|
|
263
|
+
* @param fileName file in the root of the repository
|
|
264
|
+
* @returns the parsed file, or `null` if it cannot be read
|
|
265
|
+
*/
|
|
266
|
+
private _readGitHubJson;
|
|
267
|
+
/**
|
|
268
|
+
* Check an adapter on GitHub before it is installed from there: `common.nogit`, the operating system and the
|
|
269
|
+
* Node.js version, from its `io-package.json` and `package.json` at the commit to be installed
|
|
270
|
+
*
|
|
271
|
+
* Without these checks the adapter would be installed first and fail later, e.g. because files that only the
|
|
272
|
+
* npm package contains are missing.
|
|
273
|
+
*
|
|
274
|
+
* @param user GitHub user or organization
|
|
275
|
+
* @param repo repository name
|
|
276
|
+
* @param commit commit hash, branch or tag; without it the default branch, which npm installs then as well
|
|
277
|
+
* @returns the problem that prevents the installation, or `null`
|
|
278
|
+
*/
|
|
279
|
+
private _checkGitHubAdapter;
|
|
227
280
|
/**
|
|
228
281
|
* Installs an adapter from given url
|
|
229
282
|
*
|