Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[typing] Added types to adapter.ts #2922

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion packages/adapter/src/lib/_Types.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
export interface AdapterOptions {

Check warning on line 1 in packages/adapter/src/lib/_Types.ts

View workflow job for this annotation

GitHub Actions / Eslint

Missing JSDoc comment
subscribesChange?: (

Check warning on line 2 in packages/adapter/src/lib/_Types.ts

View workflow job for this annotation

GitHub Actions / Eslint

Missing JSDoc comment
subs: Record<
string,
{
regex: RegExp;

Check warning on line 6 in packages/adapter/src/lib/_Types.ts

View workflow job for this annotation

GitHub Actions / Eslint

Missing JSDoc comment
}
>,
) => void;
Expand Down Expand Up @@ -70,10 +70,10 @@

type Invoice = 'free' | (string & {});

export interface SuitableLicense {

Check warning on line 73 in packages/adapter/src/lib/_Types.ts

View workflow job for this annotation

GitHub Actions / Eslint

Missing JSDoc comment
/** Name of the license type, not necessarily matching adapter */
product: string;
/** E-Mail of license owner */
/** E-Mail of a license owner */
email: string;
/** Unique id of this license */
id: string;
Expand All @@ -95,18 +95,18 @@
decoded: {
/** E-Mail of license owner */
email: string;
comment: string;

Check warning on line 98 in packages/adapter/src/lib/_Types.ts

View workflow job for this annotation

GitHub Actions / Eslint

Missing JSDoc comment
/** License type, eg private */
type: string;
/** Adapter name */
name: string;
/** Address of license owner */
address: {
Country: string;

Check warning on line 105 in packages/adapter/src/lib/_Types.ts

View workflow job for this annotation

GitHub Actions / Eslint

Missing JSDoc comment
Name: string;

Check warning on line 106 in packages/adapter/src/lib/_Types.ts

View workflow job for this annotation

GitHub Actions / Eslint

Missing JSDoc comment
AddressLine1: string;

Check warning on line 107 in packages/adapter/src/lib/_Types.ts

View workflow job for this annotation

GitHub Actions / Eslint

Missing JSDoc comment
AddressLine2: string;

Check warning on line 108 in packages/adapter/src/lib/_Types.ts

View workflow job for this annotation

GitHub Actions / Eslint

Missing JSDoc comment
ZIP: string;

Check warning on line 109 in packages/adapter/src/lib/_Types.ts

View workflow job for this annotation

GitHub Actions / Eslint

Missing JSDoc comment
City: string;
};
ltype: string;
Expand Down Expand Up @@ -149,6 +149,8 @@
accepted: boolean;
/** Optional heartbeat, if set, the client needs to re-subscribe every heartbeat interval */
heartbeat?: number;
/** Optional error if not accepted */
error?: string;
}

type UserInterfaceUnsubscribeInfoBaseObject = {
Expand Down
82 changes: 46 additions & 36 deletions packages/adapter/src/lib/adapter/adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -601,6 +601,20 @@ export interface AdapterClass {
getStatesOfAsync(parentDevice: string, parentChannel: string, options?: unknown): Promise<ioBroker.StateObject[]>;
}

/**
* Contents of iobroker.json plus some internal variables
*/
interface InternalAdapterJsonConfig extends ioBroker.IoBrokerJson {
/** Is instance started with the `--install` flag */
isInstall?: boolean;
/** If logs must be printed to stdout */
consoleOutput?: boolean;
/** Start instance even if it disabled in config */
forceIfDisabled?: boolean;
/** Instance number */
instance?: number;
}

/**
* Adapter class
*
Expand All @@ -620,7 +634,7 @@ export class AdapterClass extends EventEmitter {
/** Objects DB constructor */
private Objects?: typeof ObjectsInRedisClient;
/** Contents of iobroker.json */
private readonly _config: Record<string, any>;
private readonly _config: InternalAdapterJsonConfig;
private readonly _options: AdapterOptions;
private readonly startedInCompactMode: boolean;
/** List of instances which want our logs */
Expand Down Expand Up @@ -692,7 +706,7 @@ export class AdapterClass extends EventEmitter {
private _initializeTimeout?: NodeJS.Timeout | null;
private inited?: boolean;
/** contents of iobroker.json if required via AdapterOptions */
systemConfig?: Record<string, any>;
systemConfig?: InternalAdapterJsonConfig;
/** the configured date format of system.config, only available if requested via AdapterOptions `useFormatDate` */
dateFormat?: any;
/** if float comma instead of dot is used, only available if requested via AdapterOptions `useFormatDate` */
Expand Down Expand Up @@ -751,7 +765,7 @@ export class AdapterClass extends EventEmitter {
const configFileName = tools.getConfigFileName();

if (fs.pathExistsSync(configFileName)) {
this._config = fs.readJsonSync(configFileName);
this._config = fs.readJsonSync(configFileName) as InternalAdapterJsonConfig;
this._config.states = this._config.states || { type: 'jsonl' };
this._config.objects = this._config.objects || { type: 'jsonl' };
// Make sure the DB has enough time (5s). JsonL can take a bit longer if the process just crashed before
Expand All @@ -770,7 +784,10 @@ export class AdapterClass extends EventEmitter {
this._options.config.log = this._config.log;
}

this._config = this._options.config || this._config;
// this used in tests
if (this._options.config) {
this._config = this._options.config as ioBroker.IoBrokerJson;
}
this.startedInCompactMode = !!this._options.compact;

const parsedArgs = yargs(process.argv.slice(2))
Expand Down Expand Up @@ -811,7 +828,7 @@ export class AdapterClass extends EventEmitter {
.parseSync();

if (parsedArgs.loglevel && ['info', 'debug', 'error', 'warn', 'silly'].includes(parsedArgs.loglevel)) {
this._config.log.level = parsedArgs.loglevel;
this._config.log.level = parsedArgs.loglevel as ioBroker.LogLevel;
this.overwriteLogLevel = true;
}

Expand Down Expand Up @@ -853,11 +870,11 @@ export class AdapterClass extends EventEmitter {
}

const instance = parseInt(
this._options.compactInstance !== undefined
(this._options.compactInstance !== undefined
? this._options.compactInstance
: this._options.instance !== undefined
? this._options.instance
: this._config.instance || 0,
: this._config.instance || 0) as unknown as string,
10,
);

Expand Down Expand Up @@ -1437,8 +1454,7 @@ export class AdapterClass extends EventEmitter {
options?: Record<string, any> | null,
): Promise<(ioBroker.AnyObject | null)[]> {
try {
const res = await this.#objects!.getObjects(keys, options);
return res;
return this.#objects!.getObjects(keys, options);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will lead the catch not being functional anymore, can we please minimize PRs to the things we actually want to achieve with them. Personally I don't know what the goal of the adapter.ts changes is as none really rely on the added types.

} catch (e) {
this._logger.error(`Could not get objects by array: ${e.message}`);
return [];
Expand Down Expand Up @@ -1606,7 +1622,7 @@ export class AdapterClass extends EventEmitter {
* ...
* }
* ```

*
* @param featureName the name of the feature to check
* @returns true/false if the feature is in the list of supported features
*/
Expand Down Expand Up @@ -10462,15 +10478,15 @@ export class AdapterClass extends EventEmitter {
logs.push(`Actual Loglist - ${JSON.stringify(Array.from(this.logList))}`);

if (!this.#states) {
// if adapterState was destroyed, we can not continue
// if adapterState was destroyed, we cannot continue
return;
}

// Read current state of all log subscribers
// Read the current state of all log subscribers
this.#states.getKeys(`${SYSTEM_ADAPTER_PREFIX}*.logging`, (err, keys) => {
if (keys?.length) {
if (!this.#states) {
// if adapterState was destroyed, we can not continue
// if adapterState was destroyed, we cannot continue
return;
}

Expand Down Expand Up @@ -10516,7 +10532,7 @@ export class AdapterClass extends EventEmitter {
*/
private async _initLogging(): Promise<void> {
if (!this.#states) {
// if adapterState was destroyed, we can not continue
// if adapterState was destroyed, we cannot continue
return;
}

Expand All @@ -10540,13 +10556,13 @@ export class AdapterClass extends EventEmitter {
if (messages && !this._options.logTransporter) {
messages.push(info);

// do not let messages grow without limit
// do not let messages grow without a limit
if (messages.length > this._config.states.maxQueue) {
messages.splice(0, messages.length - this._config.states.maxQueue);
}
}
} else if (this.#states?.pushLog) {
// Send to all adapter, that required logs
// Send it to all adapters, that required logs
for (const instanceId of this.logList) {
this.#states.pushLog(instanceId, info);
}
Expand All @@ -10556,15 +10572,15 @@ export class AdapterClass extends EventEmitter {
const keys = await this.#states.getKeys(`${SYSTEM_ADAPTER_PREFIX}*.logging`);
if (keys?.length) {
if (!this.#states) {
// if adapterState was destroyed, we can not continue
// if adapterState was destroyed, we cannot continue
return;
}

const obj = await this.#states.getStates(keys);
if (obj) {
for (let i = 0; i < keys.length; i++) {
const objPart = obj[i];
// We can JSON.parse, but index is 16x faster
// We can JSON.parse, but the index is 16x faster
if (!objPart) {
continue;
}
Expand Down Expand Up @@ -10796,7 +10812,7 @@ export class AdapterClass extends EventEmitter {
['silly', 'debug', 'info', 'warn', 'error'].includes(state.val as string)
) {
this.overwriteLogLevel = true;
this._config.log.level = state.val;
this._config.log.level = state.val as ioBroker.LogLevel;
for (const transport in this._logger.transports) {
if (!Object.prototype.hasOwnProperty.call(this._logger.transports, transport)) {
continue;
Expand All @@ -10810,7 +10826,7 @@ export class AdapterClass extends EventEmitter {
this._logger.info(
`${this.namespaceLog} Loglevel changed from "${currentLevel}" to "${state.val}"`,
);
currentLevel = state.val;
currentLevel = state.val as ioBroker.LogLevel;
} else if (state.val && state.val !== currentLevel) {
this._logger.info(`${this.namespaceLog} Got invalid loglevel "${state.val}", ignoring`);
}
Expand Down Expand Up @@ -10944,7 +10960,7 @@ export class AdapterClass extends EventEmitter {
} else if (!this._stopInProgress && this.adapterReady && this.aliases.has(id)) {
// If adapter is ready and for this ID exist some alias links
const alias = this.aliases.get(id)!;
/** Prevent multiple publishes if multiple pattern contain this alias id */
/** Prevent multiple publishes if multiple patterns contain this alias id */
const uniqueTargets = new Set<string>();

for (const target of alias.targets) {
Expand Down Expand Up @@ -11306,8 +11322,7 @@ export class AdapterClass extends EventEmitter {
!this._config.forceIfDisabled &&
!this._config.isInstall &&
!this.startedInCompactMode &&
killRes &&
killRes.from?.startsWith('system.host.') &&
killRes?.from?.startsWith('system.host.') &&
killRes.ack &&
!isNaN(killRes.val as any) &&
killRes.val !== process.pid
Expand All @@ -11316,13 +11331,7 @@ export class AdapterClass extends EventEmitter {
`${this.namespaceLog} ${this.namespace} invalid process id scenario ${killRes.val} vs. own ID ${process.pid}. Stopping`,
);
this.terminate(EXIT_CODES.ADAPTER_REQUESTED_TERMINATION);
} else if (
!this._config.isInstall &&
resAlive &&
resAlive.val === true &&
resAlive.ack &&
!this._config.forceIfDisabled
) {
} else if (!this._config.isInstall && resAlive?.val === true && resAlive.ack && !this._config.forceIfDisabled) {
this._logger.error(`${this.namespaceLog} ${this.namespace} already running`);
this.terminate(EXIT_CODES.ADAPTER_ALREADY_RUNNING);
} else {
Expand Down Expand Up @@ -11358,7 +11367,7 @@ export class AdapterClass extends EventEmitter {
this.pluginHandler.setDatabaseForPlugins(this.#objects, this.#states);
await this.pluginHandler.initPlugins(adapterConfig || {});
if (!this.#states || !this.#objects || this.terminated) {
// if adapterState was destroyed,we should not continue
// if adapterState was destroyed, we should not continue
return;
}

Expand Down Expand Up @@ -11593,7 +11602,8 @@ export class AdapterClass extends EventEmitter {
}in ${this.adapterDir}, node: ${process.version}, js-controller: ${controllerVersion}`,
);
this._config.system = this._config.system || {};
this._config.system.statisticsInterval = parseInt(this._config.system.statisticsInterval, 10) || 15_000;
this._config.system.statisticsInterval =
parseInt(this._config.system.statisticsInterval as unknown as string, 10) || 15_000;
if (!this._config.isInstall) {
this._reportInterval = setInterval(() => this._reportStatus(), this._config.system.statisticsInterval);
this._reportStatus();
Expand Down Expand Up @@ -11774,7 +11784,7 @@ export class AdapterClass extends EventEmitter {
}

if (!obj._id.startsWith(this.namespace)) {
// instanceObjects are normally defined without namespace prefix
// instanceObjects are normally defined without a namespace prefix
obj._id = obj._id === '' ? this.namespace : `${this.namespace}.${obj._id}`;
}

Expand Down Expand Up @@ -12014,13 +12024,13 @@ export class AdapterClass extends EventEmitter {
if (this._options.systemConfig) {
this.systemConfig = this._config;
// Workaround for an admin 5 issue which could lead to deleting the dataDir folder
// TODO: remove it as soon as all adapters are fixed which use systemConfig.dataDir
// TODO: 08.2022 FR remove it as soon as all adapters are fixed which use systemConfig.dataDir
if (!Object.prototype.hasOwnProperty.call(this.systemConfig, 'dataDir')) {
this.systemConfig.dataDir = tools.getDefaultDataDir();
}
}

if (this._config.states && this._config.states.type) {
if (this._config.states?.type) {
try {
this.States = (await import(`@iobroker/db-states-${this._config.states.type}`)).Client;
} catch (e) {
Expand All @@ -12030,7 +12040,7 @@ export class AdapterClass extends EventEmitter {
this.States = await getStatesConstructor();
}

if (this._config.objects && this._config.objects.type) {
if (this._config.objects?.type) {
try {
this.Objects = (await import(`@iobroker/db-objects-${this._config.objects.type}`)).Client;
} catch (e) {
Expand Down
10 changes: 6 additions & 4 deletions packages/controller/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,7 @@ function createStates(onConnect: () => void): void {
state.val !== currentLevel &&
['silly', 'debug', 'info', 'warn', 'error'].includes(state.val)
) {
config.log.level = state.val;
config.log.level = state.val as ioBroker.LogLevel;
for (const transport in logger.transports) {
if (
logger.transports[transport].level === currentLevel &&
Expand All @@ -586,7 +586,7 @@ function createStates(onConnect: () => void): void {
}
}
logger.info(`${hostLogPrefix} Loglevel changed from "${currentLevel}" to "${state.val}"`);
currentLevel = state.val;
currentLevel = state.val as ioBroker.LogLevel;
} else if (state.val && state.val !== currentLevel) {
logger.info(`${hostLogPrefix} Got invalid loglevel "${state.val}", ignoring`);
}
Expand Down Expand Up @@ -5281,11 +5281,13 @@ export async function init(compactGroupId?: number): Promise<void> {
States = await getStatesConstructor();
}

// Detect if outputs to console are forced. By default, they are disabled and redirected to log file
// Detect if outputs to console are forced. By default, they are disabled and redirected to the log file
if (
config.log.noStdout &&
process.argv &&
(process.argv.indexOf('--console') !== -1 || process.argv.indexOf('--logs') !== -1)
(process.argv.indexOf('--console') !== -1 ||
process.argv.indexOf('--logs') !== -1 ||
process.argv.indexOf('--debug') !== -1)
) {
config.log.noStdout = false;
}
Expand Down
4 changes: 3 additions & 1 deletion packages/types-dev/config.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ export interface DatabaseOptions {
};
backup: DatabaseBackupOptions;
jsonlOptions: JsonlOptions;
/** do not let messages grow without a limit */
maxQueue: number;
}

export interface ObjectsDatabaseOptions extends DatabaseOptions {
Expand Down Expand Up @@ -121,7 +123,7 @@ export interface IoBJson {
objects: ObjectsDatabaseOptions;
states: DatabaseOptions;
log: {
level: string;
level: ioBroker.LogLevel;
maxDays: number;
noStdout: boolean;
transport: Record<string, any>;
Expand Down
23 changes: 18 additions & 5 deletions schemas/iobroker.json
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,14 @@
"type": "object",
"properties": {
"level": {
"type": "string"
"type": "string",
"enum": [
"silly",
"debug",
"info",
"warn",
"error"
]
},
"maxDays": {
"type": "number"
Expand Down Expand Up @@ -272,11 +279,12 @@
"jsonlOptions": {
"$ref": "#/definitions/JsonlOptions"
},
"maxQueue": {
"type": "number",
"description": "do not let messages grow without a limit"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

descriptions seem to start with an uppercase letter in general.

},
"noFileCache": {
"type": "boolean"
},
"maxQueue": {
"type": "number"
}
},
"required": [
Expand Down Expand Up @@ -513,6 +521,10 @@
},
"jsonlOptions": {
"$ref": "#/definitions/JsonlOptions"
},
"maxQueue": {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as used multiple times could be put into a definition

"type": "number",
"description": "do not let messages grow without a limit"
}
},
"required": [
Expand All @@ -525,7 +537,8 @@
"dataDir",
"options",
"backup",
"jsonlOptions"
"jsonlOptions",
"maxQueue"
],
"additionalProperties": false
}
Expand Down
Loading