Skip to content

Commit

Permalink
Working on typescript
Browse files Browse the repository at this point in the history
  • Loading branch information
GermanBluefox committed Nov 13, 2024
1 parent db00c1d commit 0fc78c4
Show file tree
Hide file tree
Showing 33 changed files with 5,215 additions and 4,742 deletions.
13 changes: 11 additions & 2 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,23 @@ export default [
languageOptions: {
parserOptions: {
projectService: {
allowDefaultProject: ['eslint.config.mjs'],
allowDefaultProject: ['*.mjs'],
},
tsconfigRootDir: import.meta.dirname,
project: './tsconfig.json',
},
},
},
{
ignores: ['src-admin/**/*', 'src/**/*', 'admin/**/*'],
ignores: [
'src-admin/**/*',
'admin/**/*',
'admin-config/**/*',
'detection/*',
'lib/**/*',
'node_modules/**/*',
'test/**/*',
],
},
{
// disable temporary the rule 'jsdoc/require-param' and enable 'jsdoc/require-jsdoc'
Expand Down
81 changes: 34 additions & 47 deletions install/installTypings.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';

// The adapter includes typings for the lowest supported NodeJS version.
// The adapter includes typings for the lowest supported Node.js version.
// This script updates them to the installed version

const { spawn } = require('node:child_process');
Expand All @@ -16,29 +16,6 @@ function fail(reason) {

// Find the latest version on npm
console.log('Installing NodeJS typings...');
npmCommand('view', ['@types/node', 'version'], {stdout: 'pipe', stderr: 'pipe'})
.then(cmdResult => {
if (cmdResult.exitCode !== 0) {
return fail(cmdResult.stderr);
}
const latestVersion = semver.coerce(cmdResult.stdout).major;
console.log(`latest @types: ${latestVersion}, installed node: ${installedNodeVersion}`);
return semver.gt(`${installedNodeVersion}.0.0`, `${latestVersion}.0.0`)
? 'latest' // The installed version is too new, install latest
: installedNodeVersion.toString()
;
})
.then(targetVersion => {
// Install the desired version
return npmCommand('i', [`@types/node@${targetVersion}`], {stdout: 'ignore', stderr: 'pipe'});
})
.then(cmdResult => {
if (cmdResult.exitCode !== 0) {
return fail(cmdResult.stderr);
} else {
process.exit(0);
}
});

// TODO: the following code is copied from a js-controller fork
// It should be moved to the core and referenced from there in a future version
Expand All @@ -60,7 +37,7 @@ npmCommand('view', ['@types/node', 'version'], {stdout: 'pipe', stderr: 'pipe'})
*/

/**
* Executes an npm command (e.g. install) and returns the exit code and (if requested) the stdout
* Executes a npm command (e.g., install) and returns the exit code and (if requested) the stdout
* @param {string} command The npm command to execute
* @param {string[]} [npmArgs] The command line arguments for the npm command
* @param {Partial<NpmCommandOptions>} [options] (optional) Some options for the command execution
Expand All @@ -78,50 +55,39 @@ function npmCommand(command, npmArgs, options) {
const npmBinary = /^win/.test(process.platform) ? 'npm.cmd' : 'npm';
/** @type {import("child_process").SpawnOptions} */
const spawnOptions = {
stdio: [
options.stdin || process.stdin,
options.stdout || process.stdout,
options.stderr || process.stderr,
],
stdio: [options.stdin || process.stdin, options.stdout || process.stdout, options.stderr || process.stderr],
// @ts-ignore This option exists starting with NodeJS 8
windowsHide: true,
};
if (options.cwd != null) spawnOptions.cwd = options.cwd;

// Now execute the npm process and avoid throwing errors
return new Promise((resolve) => {
return new Promise(resolve => {
try {
/** @type {string} */
let bufferedStdout;
/** @type {string} */
let bufferedStderr;
const cmd = spawn(npmBinary, [command].concat(npmArgs), spawnOptions)
.on('close', (code, signal) => {
resolve({
exitCode: code,
signal,
stdout: bufferedStdout,
stderr: bufferedStderr
});
const cmd = spawn(npmBinary, [command].concat(npmArgs), spawnOptions).on('close', (code, signal) => {
resolve({
exitCode: code,
signal,
stdout: bufferedStdout,
stderr: bufferedStderr,
});
});
// Capture stdout/stderr if requested
if (options.stdout === 'pipe') {
bufferedStdout = '';
cmd.stdout.on('data', chunk => {
const buffer = Buffer.isBuffer(chunk)
? chunk
: new Buffer(chunk, 'utf8')
;
const buffer = Buffer.isBuffer(chunk) ? chunk : new Buffer(chunk, 'utf8');
bufferedStdout += buffer;
});
}
if (options.stderr === 'pipe') {
bufferedStderr = '';
cmd.stderr.on('data', chunk => {
const buffer = Buffer.isBuffer(chunk)
? chunk
: new Buffer(chunk, 'utf8')
;
const buffer = Buffer.isBuffer(chunk) ? chunk : new Buffer(chunk, 'utf8');
bufferedStderr += buffer;
});
}
Expand All @@ -130,3 +96,24 @@ function npmCommand(command, npmArgs, options) {
}
});
}

npmCommand('view', ['@types/node', 'version'], { stdout: 'pipe', stderr: 'pipe' })
.then(cmdResult => {
if (cmdResult.exitCode !== 0) {
return fail(cmdResult.stderr);
}
const latestVersion = semver.coerce(cmdResult.stdout).major;
console.log(`latest @types: ${latestVersion}, installed node: ${installedNodeVersion}`);
return semver.gt(`${installedNodeVersion}.0.0`, `${latestVersion}.0.0`)
? 'latest' // The installed version is too new, install latest
: installedNodeVersion.toString();
})
// Install the desired version
.then(targetVersion => npmCommand('i', [`@types/node@${targetVersion}`], { stdout: 'ignore', stderr: 'pipe' }))
.then(cmdResult => {
if (cmdResult.exitCode !== 0) {
fail(cmdResult.stderr);
} else {
process.exit(0);
}
});
16 changes: 15 additions & 1 deletion src/lib/consts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,21 @@ export const monthShort: Record<ioBroker.Languages, string[]> = {
'zh-cn': ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
};

export type AstroEvent = 'sunrise' | 'sunset' | 'sunriseEnd' | 'sunsetStart' | 'dawn' | 'dusk' | 'nauticalDawn' | 'nauticalDusk' | 'nadir' | 'nightEnd' | 'night' | 'goldenHourEnd' | 'goldenHour' | 'solarNoon';
export type AstroEvent =
| 'sunrise'
| 'sunset'
| 'sunriseEnd'
| 'sunsetStart'
| 'dawn'
| 'dusk'
| 'nauticalDawn'
| 'nauticalDusk'
| 'nadir'
| 'nightEnd'
| 'night'
| 'goldenHourEnd'
| 'goldenHour'
| 'solarNoon';

export const astroList: AstroEvent[] = [
'sunrise',
Expand Down
20 changes: 13 additions & 7 deletions src/lib/convert.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// controller uses this file when build uploads
export function stringify(data: { data: ioBroker.ScriptObject | ioBroker.ChannelObject, id: string }): { id: string; data: string | undefined } {
let obj = data.data;
export function stringify(data: { data: ioBroker.ScriptObject | ioBroker.ChannelObject; id: string }): {
id: string;
data: string | undefined;
} {
const obj = data.data;
let id = data.id;
let result: string | undefined;
if (data.data.type === 'channel') {
Expand Down Expand Up @@ -39,7 +42,10 @@ export function stringify(data: { data: ioBroker.ScriptObject | ioBroker.Channel
return { id, data: result };
}

export function parse(data: { data: string, id: string }): { id: string; data: ioBroker.ScriptObject; error: string | undefined } | null {
export function parse(data: {
data: string;
id: string;
}): { id: string; data: ioBroker.ScriptObject; error: string | undefined } | null {
let obj: string = data.data;
let id = data.id;
let error: string | undefined;
Expand All @@ -58,8 +64,8 @@ export function parse(data: { data: string, id: string }): { id: string; data: i

try {
result = JSON.parse(obj);
} catch (e) {
error = `Cannot parse object "${name}": ${e}`;
} catch (err: unknown) {
error = `Cannot parse object "${name}": ${err as Error}`;
result = {
common: {
name: name.split('.').pop() || name,
Expand Down Expand Up @@ -92,8 +98,8 @@ export function parse(data: { data: string, id: string }): { id: string; data: i
result = {} as ioBroker.Object;
result.common = JSON.parse(stringObj);
result.common.source = source;
} catch (e) {
error = `Cannot parse object "${id}": ${e}`;
} catch (err: unknown) {
error = `Cannot parse object "${id}": ${err as Error}`;
}
} else {
source = obj;
Expand Down
52 changes: 27 additions & 25 deletions src/lib/debug.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { fork, type ForkOptions } from 'node:child_process';
import type { DebugState } from '../types';

const adapter = {
log: {
Expand All @@ -7,7 +8,7 @@ const adapter = {
warn: (text: string) => console.warn(text),
debug: (text: string) => console.log(text),
},
setState: (id:string, val: any): void => {
setState: (id: string, val: any): void => {
try {
val = JSON.parse(val);
} catch (e) {
Expand All @@ -18,56 +19,54 @@ const adapter = {
extendForeignObjectAsync: (id: string, obj: Partial<ioBroker.ScriptObject>) => {
console.log(`EXTEND: ${id} ${JSON.stringify(obj)}`);
return Promise.resolve();
}
},
};
const context: {
objects: Record<string, ioBroker.Object>;
} = {
objects: {},
};

const debugState: {
scriptName: string;
child: any;
promiseOnEnd: any;
paused: boolean;
endTimeout: NodeJS.Timeout | null;
running: boolean;
breakOnStart: boolean;
} = {
const debugState: DebugState = {
scriptName: '',
child: null,
promiseOnEnd: null,
paused: false,
endTimeout: null,
running: false,
breakOnStart: false,
started: 0,
};

function stopDebug() {
function stopDebug(): Promise<void> {
if (debugState.child) {
sendToInspector({ cmd: 'end' });
debugState.endTimeout = setTimeout(() => {
debugState.endTimeout = null;
debugState.child.kill('SIGTERM');
debugState.child?.kill('SIGTERM');
});
debugState.promiseOnEnd = debugState.promiseOnEnd || Promise.resolve(0);
} else {
debugState.promiseOnEnd = Promise.resolve();
debugState.promiseOnEnd = Promise.resolve(0);
}

return debugState.promiseOnEnd.then(() => {
debugState.child = null;
debugState.running = false;
debugState.scriptName = '';
debugState.endTimeout && clearTimeout(debugState.endTimeout);
debugState.endTimeout = null;
if (debugState.endTimeout) {
clearTimeout(debugState.endTimeout);
debugState.endTimeout = null;
}
});
}

function disableScript(id) {
function disableScript(id: string): Promise<void> {
const obj = context.objects[id];
if (obj?.common?.enabled) {
return adapter.extendForeignObjectAsync(obj._id, { common: { enabled: false } } as Partial<ioBroker.ScriptObject>);
return adapter.extendForeignObjectAsync(obj._id, {
common: { enabled: false },
} as Partial<ioBroker.ScriptObject>);
}
return Promise.resolve();
}
Expand All @@ -76,8 +75,8 @@ function sendToInspector(message: string | Record<string, any>): void {
if (typeof message === 'string') {
try {
message = JSON.parse(message);
} catch (e) {
adapter.log.error(`Cannot parse message to inspector: ${message}`);
} catch {
adapter.log.error(`Cannot parse message to inspector: ${JSON.stringify(message)}`);
return adapter.setState('debug.from', JSON.stringify({ error: 'Cannot parse message to inspector' }));
}
}
Expand All @@ -89,7 +88,7 @@ function sendToInspector(message: string | Record<string, any>): void {
return adapter.setState('debug.from', JSON.stringify({ error: `Cannot send command to terminated inspector` }));
}
}

/*
function childPrint(text: string): void {
console.log(
text
Expand All @@ -100,8 +99,9 @@ function childPrint(text: string): void {
.join('\n'),
);
}
*/

function debugScript(data): Promise<void> {
function debugScript(data: { breakOnStart?: boolean; scriptName: string }): Promise<void> {
// stop a script if it is running

return disableScript(data.scriptName)
Expand Down Expand Up @@ -133,15 +133,15 @@ function debugScript(data): Promise<void> {
};
try {
debugMessage = JSON.parse(message);
} catch (e) {
} catch {
return adapter.log.error(`Cannot parse message from inspector: ${message}`);
}

adapter.setState('debug.from', JSON.stringify(debugMessage));

switch (debugMessage.cmd) {
case 'ready': {
debugState.child.send(JSON.stringify({ cmd: 'start', scriptName: debugState.scriptName }));
debugState.child?.send(JSON.stringify({ cmd: 'start', scriptName: debugState.scriptName }));
break;
}

Expand All @@ -168,7 +168,9 @@ function debugScript(data): Promise<void> {
}

case 'readyToDebug': {
console.log(`readyToDebug (set breakpoints): [${debugMessage.scriptId}] ${debugMessage.script}`);
console.log(
`readyToDebug (set breakpoints): [${debugMessage.scriptId}] ${debugMessage.script}`,
);
break;
}
}
Expand Down
Loading

0 comments on commit 0fc78c4

Please sign in to comment.