Skip to content

Commit

Permalink
optimize some types and trim read docker version string (#2375)
Browse files Browse the repository at this point in the history
* optimize some types and trim read docker version string

* back to node timeout

* specify adapter interval and timeout as return types for the according methods

* fix some of the ugly path handling

* path must be relative

* Update tools.ts

* correct type to match implementation and allow undefined to be passed to clear methods for convinience like for internal timeout methods

* add undefined guard

* adapter _logger is always defined
  • Loading branch information
foxriver76 authored Aug 4, 2023
1 parent 27720a0 commit 9011054
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 65 deletions.
85 changes: 46 additions & 39 deletions packages/adapter/src/lib/adapter/adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1619,19 +1619,19 @@ export class AdapterClass extends EventEmitter {
}

// external signature
getUserID(username: string): Promise<string | void>;
getUserID(username: string): Promise<string | undefined>;
/**
* Return ID of given username
*
* @param username - name of the user
*/
getUserID(username: unknown): Promise<string | void> {
getUserID(username: unknown): Promise<string | undefined> {
Validator.assertString(username, 'username');

return this._getUserID({ username });
}

private async _getUserID(options: InternalGetUserIDOptions): Promise<void | string> {
private async _getUserID(options: InternalGetUserIDOptions): Promise<string | undefined> {
if (!this.usernames[options.username]) {
try {
// did not find username, we should have a look in the cache
Expand Down Expand Up @@ -2492,7 +2492,7 @@ export class AdapterClass extends EventEmitter {
}

// external signature
setTimeout(cb: TimeoutCallback, timeout: number, ...args: any[]): NodeJS.Timeout | void;
setTimeout(cb: TimeoutCallback, timeout: number, ...args: any[]): ioBroker.Timeout | undefined;
/**
* Same as setTimeout
* but it clears the running timers on unload
Expand All @@ -2503,7 +2503,7 @@ export class AdapterClass extends EventEmitter {
* @param args - as many arguments as needed, which will be passed to setTimeout
* @returns timer id
*/
setTimeout(cb: unknown, timeout: unknown, ...args: unknown[]): NodeJS.Timeout | void {
setTimeout(cb: unknown, timeout: unknown, ...args: unknown[]): ioBroker.Timeout | undefined {
if (typeof cb !== 'function') {
this._logger.warn(
`${this.namespaceLog} setTimeout expected callback to be of type "function", but got "${typeof cb}"`
Expand All @@ -2529,10 +2529,10 @@ export class AdapterClass extends EventEmitter {
);
this._timers.add(timer);

return timer;
return timer as unknown as ioBroker.Timeout;
}

clearTimeout(timer: NodeJS.Timeout): void;
clearTimeout(timer: ioBroker.Timeout | undefined): void;

/**
* Same as clearTimeout
Expand All @@ -2541,9 +2541,13 @@ export class AdapterClass extends EventEmitter {
* @param timer - the timer object
*/
clearTimeout(timer: unknown): void {
// should we validate this?
clearTimeout(timer as any);
this._timers.delete(timer as any);
if (timer === undefined) {
return;
}

// should we further validate this?
clearTimeout(timer as NodeJS.Timeout);
this._timers.delete(timer as NodeJS.Timeout);
}

// external signature
Expand Down Expand Up @@ -2575,7 +2579,7 @@ export class AdapterClass extends EventEmitter {
}

// external signature
setInterval(cb: TimeoutCallback, timeout: number, ...args: any[]): NodeJS.Timeout | void;
setInterval(cb: TimeoutCallback, timeout: number, ...args: any[]): ioBroker.Interval | undefined;

/**
* Same as setInterval
Expand All @@ -2587,7 +2591,7 @@ export class AdapterClass extends EventEmitter {
* @param args - as many arguments as needed, which will be passed to setTimeout
* @returns interval interval object
*/
setInterval(cb: unknown, timeout: unknown, ...args: unknown[]): NodeJS.Timeout | void {
setInterval(cb: unknown, timeout: unknown, ...args: unknown[]): ioBroker.Interval | undefined {
if (typeof cb !== 'function') {
this._logger.error(
`${this.namespaceLog} setInterval expected callback to be of type "function", but got "${typeof cb}"`
Expand All @@ -2606,11 +2610,11 @@ export class AdapterClass extends EventEmitter {
const id = setInterval(() => cb(...args), timeout);
this._intervals.add(id);

return id;
return id as unknown as ioBroker.Interval;
}

// external signature
clearInterval(interval: NodeJS.Timeout): void;
clearInterval(interval: ioBroker.Interval | undefined): void;

/**
* Same as clearInterval
Expand All @@ -2619,9 +2623,13 @@ export class AdapterClass extends EventEmitter {
* @param interval - interval object
*/
clearInterval(interval: unknown): void {
// should we validate it is a valid interval?
clearInterval(interval as any);
this._intervals.delete(interval as any);
if (interval === undefined) {
return;
}

// should we further validate it is a valid interval?
clearInterval(interval as NodeJS.Timeout);
this._intervals.delete(interval as NodeJS.Timeout);
}

setObject(id: string, obj: ioBroker.SettableObject, callback?: ioBroker.SetObjectCallback): Promise<void>;
Expand Down Expand Up @@ -2660,7 +2668,7 @@ export class AdapterClass extends EventEmitter {
* }
* ```
*/
setObject(id: unknown, obj: unknown, options: unknown, callback?: unknown): Promise<void> {
setObject(id: unknown, obj: unknown, options: unknown, callback?: unknown): Promise<void> | void {
if (typeof options === 'function') {
callback = options;
options = null;
Expand Down Expand Up @@ -7372,26 +7380,26 @@ export class AdapterClass extends EventEmitter {
id: string | ioBroker.IdObject,
state: ioBroker.State | ioBroker.StateValue | ioBroker.SettableState,
callback?: T
): T extends ioBroker.SetStateCallback ? Promise<void> : ioBroker.SetStatePromise;
): T extends ioBroker.SetStateCallback ? void : ioBroker.SetStatePromise;
setState<T extends ioBroker.SetStateCallback>(
id: string | ioBroker.IdObject,
state: ioBroker.State | ioBroker.StateValue | ioBroker.SettableState,
ack: boolean,
callback?: T
): T extends ioBroker.SetStateCallback ? Promise<void> : ioBroker.SetStatePromise;
): T extends ioBroker.SetStateCallback ? void : ioBroker.SetStatePromise;
setState<T extends ioBroker.SetStateCallback>(
id: string | ioBroker.IdObject,
state: ioBroker.State | ioBroker.StateValue | ioBroker.SettableState,
options?: Partial<GetUserGroupsOptions> | null,
callback?: T
): T extends ioBroker.SetStateCallback ? Promise<void> : ioBroker.SetStatePromise;
): T extends ioBroker.SetStateCallback ? void : ioBroker.SetStatePromise;
setState<T extends ioBroker.SetStateCallback>(
id: string | ioBroker.IdObject,
state: ioBroker.State | ioBroker.StateValue | ioBroker.SettableState,
ack: boolean,
options?: Partial<GetUserGroupsOptions> | null,
callback?: T
): T extends ioBroker.SetStateCallback ? Promise<void> : ioBroker.SetStatePromise;
): T extends ioBroker.SetStateCallback ? void : ioBroker.SetStatePromise;

/**
* Writes value into states DB.
Expand Down Expand Up @@ -7424,7 +7432,13 @@ export class AdapterClass extends EventEmitter {
* }
* ```
*/
setState(id: unknown, state: unknown, ack: unknown, options?: unknown, callback?: unknown): Promise<void | string> {
setState(
id: unknown,
state: unknown,
ack: unknown,
options?: unknown,
callback?: unknown
): Promise<void | string> | void {
if (typeof state === 'object' && typeof ack !== 'boolean') {
callback = options;
options = ack;
Expand Down Expand Up @@ -10782,11 +10796,10 @@ export class AdapterClass extends EventEmitter {
this._initializeTimeout = setTimeout(() => {
this._initializeTimeout = null;
if (this._config.isInstall) {
this._logger && this._logger.warn(`${this.namespaceLog} no connection to states DB. Terminating.`);
this._logger.warn(`${this.namespaceLog} no connection to states DB. Terminating.`);
this.terminate(EXIT_CODES.NO_ERROR);
} else {
this._logger &&
this._logger.warn(`${this.namespaceLog} slow connection to states DB. Still waiting ...`);
this._logger.warn(`${this.namespaceLog} slow connection to states DB. Still waiting ...`);
}
}, this._config.states.connectTimeout || 2_000);

Expand Down Expand Up @@ -10946,8 +10959,8 @@ export class AdapterClass extends EventEmitter {
// If someone want to have log messages
if (id.endsWith('.logging')) {
const instance = id.substring(0, id.length - '.logging'.length);
this._logger &&
this._logger.silly(`${this.namespaceLog} ${instance}: logging ${state ? state.val : false}`);

this._logger.silly(`${this.namespaceLog} ${instance}: logging ${state ? state.val : false}`);
this.logRedirect!(state ? !!state.val : false, instance);
} else if (id === `log.system.adapter.${this.namespace}`) {
this._options.logTransporter && this.processLog && this.processLog(state);
Expand Down Expand Up @@ -11087,10 +11100,7 @@ export class AdapterClass extends EventEmitter {
if (this.connected) {
return;
} // If reconnected in the meantime, do not terminate
this._logger &&
this._logger.warn(
`${this.namespaceLog} Cannot connect/reconnect to states DB. Terminating`
);
this._logger.warn(`${this.namespaceLog} Cannot connect/reconnect to states DB. Terminating`);
this.terminate(EXIT_CODES.NO_ERROR);
}, 5000);
}
Expand All @@ -11101,11 +11111,10 @@ export class AdapterClass extends EventEmitter {
this._initializeTimeout = setTimeout(() => {
this._initializeTimeout = null;
if (this._config.isInstall) {
this._logger && this._logger.warn(`${this.namespaceLog} no connection to objects DB. Terminating`);
this._logger.warn(`${this.namespaceLog} no connection to objects DB. Terminating`);
this.terminate(EXIT_CODES.NO_ERROR);
} else {
this._logger &&
this._logger.warn(`${this.namespaceLog} slow connection to objects DB. Still waiting ...`);
this._logger.warn(`${this.namespaceLog} slow connection to objects DB. Still waiting ...`);
}
}, this._config.objects.connectTimeout * 2); // Because we do not connect only anymore, give it a bit more time

Expand Down Expand Up @@ -11158,10 +11167,8 @@ export class AdapterClass extends EventEmitter {
if (this.connected) {
return;
} // If reconnected in the meantime, do not terminate
this._logger &&
this._logger.warn(
`${this.namespaceLog} Cannot connect/reconnect to objects DB. Terminating`
);

this._logger.warn(`${this.namespaceLog} Cannot connect/reconnect to objects DB. Terminating`);
this.terminate(EXIT_CODES.NO_ERROR);
}, 4000);
},
Expand Down
34 changes: 12 additions & 22 deletions packages/common/src/lib/common/tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ function getMac(callback: (e?: Error | null, mac?: string) => void): void {
*/
export function getDockerInformation(): DockerInformation {
try {
const versionString = fs.readFileSync(OFFICIAL_DOCKER_FILE, { encoding: 'utf-8' });
const versionString = fs.readFileSync(OFFICIAL_DOCKER_FILE, { encoding: 'utf-8' }).trim();
return { isDocker: true, isOfficial: true, officialVersion: versionString };
} catch {
// ignore error
Expand Down Expand Up @@ -2239,30 +2239,20 @@ export function getDefaultDataDir(): string {
return './data/';
}

const _appName = appName.toLowerCase();

// if debugging with npm5
if (fs.existsSync(`${__dirname}/../../../node_modules/${_appName}.js-controller`)) {
return `../${_appName}-data/`;
} else {
// If installed with npm
return `../../${_appName}-data/`;
}
return path.join('..', '..', `${appNameLowerCase}-data/`);
}

/**
* Returns the path of the config file
*/
export function getConfigFileName(): string {
const _appName = appName.toLowerCase();

// Allow overriding the config file location with an environment variable
let envDataDir = process.env[`${appName.toUpperCase()}_DATA_DIR`];
if (envDataDir) {
if (!path.isAbsolute(envDataDir)) {
envDataDir = path.join(getControllerDir(), envDataDir);
}
return path.join(envDataDir, `${_appName}.json`);
return path.join(envDataDir, `${appNameLowerCase}.json`);
}

let devConfigDir;
Expand All @@ -2275,10 +2265,10 @@ export function getConfigFileName(): string {
devConfigParts.splice(devConfigParts.length - 4, 4);
devConfigDir = devConfigParts.join('/');
devConfigDir += '/controller'; // go inside controller dir
if (fs.existsSync(`${devConfigDir}/conf/${_appName}.json`)) {
return `${devConfigDir}/conf/${_appName}.json`;
} else if (fs.existsSync(`${devConfigDir}/data/${_appName}.json`)) {
return `${devConfigDir}/data/${_appName}.json`;
if (fs.existsSync(`${devConfigDir}/conf/${appNameLowerCase}.json`)) {
return `${devConfigDir}/conf/${appNameLowerCase}.json`;
} else if (fs.existsSync(`${devConfigDir}/data/${appNameLowerCase}.json`)) {
return `${devConfigDir}/data/${appNameLowerCase}.json`;
}
}

Expand All @@ -2287,8 +2277,8 @@ export function getConfigFileName(): string {

// if debugging with npm5 -> node_modules on e.g. /opt/node_modules
if (
fs.existsSync(`${__dirname}/../../../../../../../../node_modules/${_appName.toLowerCase()}.js-controller`) ||
fs.existsSync(`${__dirname}/../../../../../../../../node_modules/${_appName}.js-controller`)
fs.existsSync(`${__dirname}/../../../../../../../../node_modules/${appNameLowerCase}.js-controller`) ||
fs.existsSync(`${__dirname}/../../../../../../../../node_modules/${appName}.js-controller`)
) {
// remove /node_modules/' + appName + '.js-controller/lib
configParts.splice(configParts.length - 8, 8);
Expand All @@ -2299,11 +2289,11 @@ export function getConfigFileName(): string {
configDir = configParts.join('/');
}

if (!fs.existsSync(`${configDir}/${_appName}-data/${_appName}.json`) && devConfigDir) {
return `${devConfigDir}/data/${_appName}.json`;
if (!fs.existsSync(`${configDir}/${appNameLowerCase}-data/${appNameLowerCase}.json`) && devConfigDir) {
return `${devConfigDir}/data/${appNameLowerCase}.json`;
}

return `${configDir}/${_appName}-data/${_appName}.json`;
return `${configDir}/${appNameLowerCase}-data/${appNameLowerCase}.json`;
}

/**
Expand Down
12 changes: 8 additions & 4 deletions packages/types-public/index.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -688,15 +688,19 @@ declare let enumObj: ioBroker.EnumObject;
enumObj.common.members && enumObj.common.members.map(() => 1);

// Adapter.clearTimeout and clearInterval are not compatible with the builtins
adapter.clearTimeout(adapter.setTimeout(() => {}, 10)!);
adapter.clearInterval(adapter.setInterval(() => {}, 10)!);
adapter.clearTimeout(adapter.setTimeout(() => {}, 10));
adapter.clearInterval(adapter.setInterval(() => {}, 10));
// @ts-expect-error
adapter.clearInterval(adapter.setTimeout(() => {}, 10));
// @ts-expect-error
adapter.clearTimeout(adapter.setInterval(() => {}, 10));
// @ts-expect-error
clearTimeout(adapter.setTimeout(() => {}, 10));
// @ts-expect-error
clearInterval(adapter.setInterval(() => {}, 10));
// todo types need to be implemented to not allow interchanging between nodejs and iob timers @ts-expect-error
// @ts-expect-error
adapter.clearTimeout(setTimeout(() => {}, 10));
// todo types need to be implemented to not allow interchanging between nodejs and iob timers @ts-expect-error
// @ts-expect-error
adapter.clearInterval(setInterval(() => {}, 10));
// And they must not be switched
// @ts-expect-error
Expand Down

0 comments on commit 9011054

Please sign in to comment.