mirror of
https://github.com/chenasraf/DefinitelyTyped.git
synced 2026-05-18 01:49:01 +00:00
964 lines
33 KiB
TypeScript
964 lines
33 KiB
TypeScript
declare function assertNever(val: never): never;
|
|
|
|
// Let the tests begin
|
|
declare let adapter: ioBroker.Adapter;
|
|
|
|
// Test EventEmitter definitions
|
|
adapter
|
|
.on('ready', readyHandler)
|
|
.on('stateChange', stateChangeHandler)
|
|
.on('objectChange', objectChangeHandler)
|
|
.on('message', messageHandler)
|
|
.on('unload', unloadHandler);
|
|
adapter
|
|
.removeListener('ready', readyHandler)
|
|
.removeListener('stateChange', stateChangeHandler)
|
|
.removeListener('objectChange', objectChangeHandler)
|
|
.removeListener('message', messageHandler)
|
|
.removeListener('unload', unloadHandler);
|
|
adapter.removeAllListeners();
|
|
// @ts-expect-error
|
|
adapter.removeListener('unload', messageHandler);
|
|
|
|
// Test adapter constructor options
|
|
let adapterOptions: ioBroker.AdapterOptions = {
|
|
name: 'foo',
|
|
ready: readyHandler,
|
|
stateChange: stateChangeHandler,
|
|
objectChange: objectChangeHandler,
|
|
message: messageHandler,
|
|
unload: unloadHandler,
|
|
error: err => {
|
|
console.log(err);
|
|
return true;
|
|
},
|
|
};
|
|
|
|
function readyHandler() {}
|
|
|
|
function stateChangeHandler(id: string, state: ioBroker.State | null | undefined) {
|
|
// Test State properties
|
|
if (state) {
|
|
state.ack;
|
|
state.c && state.c.toLowerCase();
|
|
state.expire && state.expire.toFixed();
|
|
state.from.toLowerCase();
|
|
state.lc.toFixed();
|
|
state.q && state.q.toFixed();
|
|
state.user && state.user.toLowerCase();
|
|
state.ts.toFixed();
|
|
state.val;
|
|
}
|
|
}
|
|
|
|
function objectChangeHandler(id: string, object: ioBroker.Object | null | undefined) {
|
|
// Test properties of all objects
|
|
if (object) {
|
|
object._id.toLowerCase();
|
|
const name = object.common.name;
|
|
if (typeof name !== 'string') {
|
|
name.de; // $ExpectType string | undefined
|
|
}
|
|
object.common.role && object.common.role.toLowerCase();
|
|
object.common.icon && object.common.icon.toLowerCase();
|
|
object.native.toString();
|
|
object.enums && object.enums.toString();
|
|
if (object.acl) {
|
|
object.acl.object.toFixed();
|
|
object.acl.owner.toLowerCase();
|
|
object.acl.ownerGroup.toLowerCase();
|
|
}
|
|
// Test different object kinds
|
|
switch (object.type) {
|
|
case 'adapter':
|
|
case 'config':
|
|
case 'enum':
|
|
case 'group':
|
|
case 'host':
|
|
case 'instance':
|
|
case 'meta':
|
|
case 'script':
|
|
case 'user':
|
|
// nothing special here, update these tests when we have specialized definitions
|
|
break;
|
|
|
|
case 'state':
|
|
if (object.acl) object.acl.state.toFixed();
|
|
object.common.def;
|
|
typeof object.common.desc === 'string' && object.common.desc.toLowerCase();
|
|
object.common.history;
|
|
object.common.max && object.common.max.toFixed();
|
|
object.common.min && object.common.min.toFixed();
|
|
object.common.read.valueOf();
|
|
object.common.states && object.common.states.toString();
|
|
object.common.type && object.common.type.toLowerCase();
|
|
object.common.unit && object.common.unit.toLowerCase();
|
|
object.common.workingID && object.common.workingID.toLowerCase();
|
|
object.common.write.valueOf();
|
|
break;
|
|
|
|
case 'channel':
|
|
object.common.desc && object.common.desc.toLowerCase();
|
|
break;
|
|
|
|
case 'device':
|
|
// nothing special here, update these tests when we have specialized definitions
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
function messageHandler(msg: ioBroker.Message) {
|
|
msg._id.toFixed();
|
|
msg.callback.ack.valueOf();
|
|
msg.callback.id.toFixed();
|
|
msg.callback.message.toString();
|
|
msg.callback.time.toFixed();
|
|
msg.command.toLowerCase();
|
|
msg.from.toLowerCase();
|
|
typeof msg.message === 'object' && msg.message.anything;
|
|
typeof msg.message === 'string' && msg.message.toLowerCase();
|
|
}
|
|
|
|
function unloadHandler(callback: ioBroker.EmptyCallback) {
|
|
adapter.log.info('shutting down');
|
|
callback();
|
|
}
|
|
|
|
// Test the most important methods
|
|
adapter.setState('state.name', 'value');
|
|
adapter.setState('state.name', 'value', true);
|
|
adapter.setState('state.name', 'value', (err, id) => {});
|
|
adapter.setState('state.name', { val: 'value', ack: true });
|
|
adapter.setState('state.name', { val: 'value', ack: true }, (err, id) => {});
|
|
|
|
adapter.setStateAsync('state.name', 'value').then(id => id.toLowerCase());
|
|
adapter.setStateAsync('state.name', 'value', true).then(id => id.toLowerCase());
|
|
adapter.setStateAsync('state.name', { val: 'value', ack: true }).then(id => id.toLowerCase());
|
|
|
|
adapter.setStateChanged('state.name', 'value');
|
|
adapter.setStateChanged('state.name', 'value', true);
|
|
adapter.setStateChanged('state.name', 'value', (err, id) => {});
|
|
adapter.setStateChanged('state.name', { val: 'value', ack: true });
|
|
adapter.setStateChanged('state.name', { val: 'value', ack: true }, (err, id) => {});
|
|
|
|
adapter.setStateChangedAsync('state.name', 'value').then(id => id.toLowerCase());
|
|
adapter.setStateChangedAsync('state.name', 'value', true).then(id => id.toLowerCase());
|
|
adapter.setStateChangedAsync('state.name', { val: 'value', ack: true }).then(id => id.toLowerCase());
|
|
|
|
adapter.setForeignState('state.name', 'value');
|
|
adapter.setForeignState('state.name', 'value', true);
|
|
adapter.setForeignState('state.name', 'value', (err, id) => {});
|
|
adapter.setForeignState('state.name', { val: 'value', ack: true });
|
|
adapter.setForeignState('state.name', { val: 'value', ack: true }, (err, id) => {});
|
|
|
|
adapter.setForeignStateAsync('state.name', 'value').then(id => id.toLowerCase());
|
|
adapter.setForeignStateAsync('state.name', 'value', true).then(id => id.toLowerCase());
|
|
adapter.setForeignStateAsync('state.name', { val: 'value', ack: true }).then(id => id.toLowerCase());
|
|
|
|
adapter.setForeignStateChanged('state.name', 'value');
|
|
adapter.setForeignStateChanged('state.name', 'value', true);
|
|
adapter.setForeignStateChanged('state.name', 'value', (err, id) => {});
|
|
adapter.setForeignStateChanged('state.name', { val: 'value', ack: true });
|
|
adapter.setForeignStateChanged('state.name', { val: 'value', ack: true }, (err, id) => {});
|
|
|
|
adapter.setForeignStateChangedAsync('state.name', 'value').then(id => id.toLowerCase());
|
|
adapter.setForeignStateChangedAsync('state.name', 'value', true).then(id => id.toLowerCase());
|
|
adapter.setForeignStateChangedAsync('state.name', { val: 'value', ack: true }).then(id => id.toLowerCase());
|
|
|
|
adapter.getState('state.id', (err, state) => state && state.from.toLowerCase());
|
|
adapter.getStateAsync('state.id').then(state => state && state.from.toLowerCase());
|
|
adapter.getForeignState('state.id', (err, state) => state && state.from.toLowerCase());
|
|
adapter.getForeignStateAsync('state.id').then(state => state && state.from.toLowerCase());
|
|
adapter.getBinaryState('state.id', (err, state) => state && state.writeUInt16BE(0, 0));
|
|
adapter.getBinaryStateAsync('state.id').then(state => state && state.writeUInt16BE(0, 0));
|
|
adapter.getForeignBinaryState('state.id', (err, state) => state && state.writeUInt16BE(0, 0));
|
|
adapter.getForeignBinaryStateAsync('state.id').then(state => state && state.writeUInt16BE(0, 0));
|
|
|
|
adapter.setObject('obj.id', { type: 'device', common: { name: 'foo' }, native: {} });
|
|
adapter.setObject('obj.id', { type: 'device', common: { name: 'foo' }, native: {} }, (err, id) => {});
|
|
adapter.setForeignObject('obj.id', { type: 'device', common: { name: 'foo' }, native: {} });
|
|
adapter.setForeignObject('obj.id', { type: 'device', common: { name: 'foo' }, native: {} }, (err, id) => {});
|
|
|
|
adapter
|
|
.setObjectAsync('obj.id', { type: 'device', common: { name: 'foo' }, native: {} })
|
|
.then(({ id }) => id.toLowerCase());
|
|
adapter
|
|
.setForeignObjectAsync('obj.id', { type: 'device', common: { name: 'foo' }, native: {} })
|
|
.then(({ id }) => id.toLowerCase());
|
|
|
|
adapter.setObjectNotExists('obj.id', { type: 'device', common: { name: 'foo' }, native: {} });
|
|
adapter.setObjectNotExists('obj.id', { type: 'device', common: { name: 'foo' }, native: {} }, (err, id) => {});
|
|
adapter.setForeignObjectNotExists('obj.id', { type: 'device', common: { name: 'foo' }, native: {} });
|
|
adapter.setForeignObjectNotExists('obj.id', { type: 'device', common: { name: 'foo' }, native: {} }, (err, id) => {});
|
|
|
|
adapter
|
|
.setObjectNotExistsAsync('obj.id', { type: 'device', common: { name: 'foo' }, native: {} })
|
|
.then(({ id }) => id.toLowerCase());
|
|
adapter
|
|
.setForeignObjectNotExistsAsync('obj.id', { type: 'device', common: { name: 'foo' }, native: {} })
|
|
.then(({ id }) => id.toLowerCase());
|
|
|
|
adapter.getObject('obj.id', (err, obj) => {});
|
|
adapter.getForeignObject('obj.id', (err, obj) => {});
|
|
|
|
adapter.getObjectAsync('obj.id').then(obj => obj && obj._id.toLowerCase());
|
|
adapter.getForeignObjectAsync('obj.id').then(obj => obj && obj._id.toLowerCase());
|
|
|
|
adapter.getForeignObjects('*', (err, objs) => objs!['foo']._id.toLowerCase());
|
|
// getForeignObjectsAsync always returns a Record when it doesn't throw
|
|
adapter.getForeignObjectsAsync('*').then(objs => objs['foo']._id.toLowerCase());
|
|
// If an object type was specified, the returned objects have the correct type
|
|
adapter.getForeignObjectsAsync('*', 'adapter').then(objs => {
|
|
objs[0].type; // $ExpectType "adapter"
|
|
});
|
|
|
|
// Check that required properties are enforced
|
|
// OK:
|
|
adapter.setObject('id', {
|
|
_id: 'id',
|
|
type: 'state',
|
|
common: {
|
|
type: 'array',
|
|
name: 'foo',
|
|
read: true,
|
|
write: false,
|
|
role: 'some role',
|
|
def: [],
|
|
defAck: false,
|
|
},
|
|
native: {},
|
|
from: 'me',
|
|
user: 'also me',
|
|
ts: Date.now(),
|
|
});
|
|
|
|
adapter.setObject(
|
|
'id',
|
|
// missing property type
|
|
// @ts-expect-error
|
|
{
|
|
common: {
|
|
type: 'array',
|
|
name: 'foo',
|
|
read: true,
|
|
write: false,
|
|
role: 'some role',
|
|
},
|
|
native: {},
|
|
protectedNative: ['none'],
|
|
encryptedNative: ['none'],
|
|
from: 'me',
|
|
ts: Date.now(),
|
|
},
|
|
);
|
|
|
|
adapter.setObject(
|
|
'id',
|
|
// missing property common
|
|
// @ts-expect-error
|
|
{
|
|
type: 'state',
|
|
native: {},
|
|
from: 'me',
|
|
ts: Date.now(),
|
|
},
|
|
);
|
|
|
|
adapter.setObject(
|
|
'id',
|
|
// missing property common.role
|
|
// @ts-expect-error
|
|
{
|
|
type: 'state',
|
|
common: {
|
|
name: 'foo',
|
|
read: true,
|
|
write: false,
|
|
},
|
|
native: {},
|
|
},
|
|
);
|
|
|
|
// TODO: Cannot enforce this without making it impossible to use interfaces to describe the shape of `native`
|
|
// adapter.setObject('id', {
|
|
// type: 'device',
|
|
// common: {
|
|
// name: 'foo',
|
|
// },
|
|
// native: {
|
|
// // Date is not allowed here
|
|
// // @ts-expect-error
|
|
// date: new Date(),
|
|
// },
|
|
// });
|
|
|
|
// Check that name as object is okay:
|
|
adapter.extendForeignObject('id', {
|
|
common: {
|
|
name: {
|
|
en: 'foobar',
|
|
fr: 'le foo de bar',
|
|
},
|
|
},
|
|
});
|
|
|
|
// Check that `preserve` is typed correctly
|
|
adapter.extendObject(
|
|
'id',
|
|
{},
|
|
{
|
|
preserve: { common: ['name'] },
|
|
// And that undocumented options are allowed
|
|
undocumented: true,
|
|
},
|
|
);
|
|
adapter.extendObject(
|
|
'id',
|
|
{},
|
|
{
|
|
preserve: { common: { name: true } },
|
|
},
|
|
);
|
|
adapter.extendForeignObject(
|
|
'id',
|
|
{},
|
|
{
|
|
preserve: { common: { name: { en: true } } },
|
|
},
|
|
);
|
|
|
|
// Make sure the return type of getObjectView is inferred correctly
|
|
adapter.getObjectView('system', 'admin', { startkey: 'foo', endkey: 'bar' }, (err, docs) => {
|
|
docs!.rows[0].id; // $ExpectType string
|
|
// FIXME: This should check for ioBroker.Object | null instead, but dtslint with TS4.7 is broken
|
|
// https://github.com/microsoft/dtslint/issues/352
|
|
docs!.rows[0].value?._id; // $ExpectType string | undefined
|
|
});
|
|
adapter.getObjectViewAsync('system', 'admin', { startkey: 'foo', endkey: 'bar' }).then(docs => {
|
|
docs.rows[0].id; // $ExpectType string
|
|
// FIXME: This should check for ioBroker.Object | null instead, but dtslint with TS4.7 is broken
|
|
// https://github.com/microsoft/dtslint/issues/352
|
|
docs.rows[0].value?._id; // $ExpectType string | undefined
|
|
});
|
|
adapter.getObjectView('system', 'admin', { startkey: 'foo', endkey: 'bar' }, (err, docs) => {
|
|
docs!.rows[0].id; // $ExpectType string
|
|
// FIXME: This should check for ioBroker.Object | null instead, but dtslint with TS4.7 is broken
|
|
// https://github.com/microsoft/dtslint/issues/352
|
|
docs!.rows[0].value?._id; // $ExpectType string | undefined
|
|
});
|
|
adapter.getObjectViewAsync('system', 'admin', { startkey: 'foo', endkey: 'bar' }).then(docs => {
|
|
docs.rows[0].id; // $ExpectType string
|
|
// FIXME: This should check for ioBroker.Object | null instead, but dtslint with TS4.7 is broken
|
|
// https://github.com/microsoft/dtslint/issues/352
|
|
docs.rows[0].value?._id; // $ExpectType string | undefined
|
|
});
|
|
adapter.getObjectView('hm-rpc', 'foo', { startkey: 'foo', endkey: 'bar' }, (err, docs) => {
|
|
docs!.rows[0].id; // $ExpectType string
|
|
docs!.rows[0].value; // $ExpectType any
|
|
});
|
|
adapter.getObjectViewAsync('hm-rpc', 'admin', { startkey: 'foo', endkey: 'bar' }).then(docs => {
|
|
docs.rows[0].id; // $ExpectType string
|
|
docs.rows[0].value; // $ExpectType any
|
|
});
|
|
// And without repetition some of the special ones:
|
|
adapter.getObjectViewAsync('system', 'instance', { startkey: 'foo', endkey: 'bar' }).then(docs => {
|
|
docs.rows[0].value!.type; // $ExpectType "instance"
|
|
});
|
|
adapter.getObjectViewAsync('system', 'state', { startkey: 'foo', endkey: 'bar' }).then(docs => {
|
|
docs.rows[0].value!.type; // $ExpectType "state"
|
|
});
|
|
adapter.getObjectViewAsync('system', 'custom', { startkey: 'foo', endkey: 'bar' }).then(docs => {
|
|
docs.rows[0].value; // $ExpectType Record<string, any> | null
|
|
});
|
|
|
|
adapter.getObjectList({ startkey: 'foo', endkey: 'bar' }, {}, (err, result) => {
|
|
result && result.rows[0] && result.rows[0].id.toLowerCase();
|
|
});
|
|
adapter.getObjectList({ startkey: 'foo', endkey: 'bar' }, (err, result) => {
|
|
result && result.rows[0] && result.rows[0].id.toLowerCase();
|
|
});
|
|
adapter.getObjectListAsync({ startkey: 'foo', endkey: 'bar' }, {}).then(result => {
|
|
result && result.rows[0] && result.rows[0].id.toLowerCase();
|
|
});
|
|
adapter.getObjectListAsync({ startkey: 'foo', endkey: 'bar' }).then(result => {
|
|
result && result.rows[0] && result.rows[0].id.toLowerCase();
|
|
});
|
|
|
|
adapter.delObject('foo');
|
|
adapter.delObject('foo', { recursive: true });
|
|
adapter.delObject('foo', { someWeirdOption: 1 });
|
|
|
|
adapter.subscribeObjects('*');
|
|
adapter.subscribeStates('*');
|
|
adapter.subscribeForeignObjects('*');
|
|
adapter.subscribeForeignStates('*');
|
|
adapter.unsubscribeObjects('*');
|
|
adapter.unsubscribeStates('*');
|
|
adapter.unsubscribeForeignObjects('*');
|
|
adapter.unsubscribeForeignStates('*');
|
|
|
|
adapter.encrypt('top secret').toLocaleLowerCase();
|
|
adapter.decrypt('garbled nonsense').toLocaleLowerCase();
|
|
|
|
adapter.log.info('msg');
|
|
adapter.log.debug('msg');
|
|
adapter.log.warn('msg');
|
|
adapter.log.error('msg');
|
|
adapter.log.silly('msg');
|
|
|
|
switch (adapter.log.level) {
|
|
case 'debug':
|
|
case 'error':
|
|
case 'info':
|
|
case 'silly':
|
|
case 'warn':
|
|
break;
|
|
default:
|
|
assertNever(adapter.log.level);
|
|
}
|
|
|
|
adapter.sendTo('foo.0', 'command', 'message');
|
|
adapter.sendTo('foo.0', 'message');
|
|
adapter.sendTo('foo.0', 'command', { msg: 'message' });
|
|
adapter.sendTo('foo.0', { msg: 'message' });
|
|
|
|
function handleMessageResponse(response?: ioBroker.Message) {
|
|
if (!response) return;
|
|
response._id.toFixed();
|
|
response.callback.ack.valueOf();
|
|
response.callback.id.toFixed();
|
|
response.callback.message.toString();
|
|
response.callback.time.toFixed();
|
|
response.command.toLowerCase();
|
|
response.from.toLowerCase();
|
|
typeof response.message === 'object' && response.message.anything;
|
|
typeof response.message === 'string' && response.message.toLowerCase();
|
|
}
|
|
adapter.sendTo('foo.0', 'command', 'message', handleMessageResponse);
|
|
adapter.sendTo('foo.0', 'message', handleMessageResponse);
|
|
adapter.sendTo('foo.0', 'command', { msg: 'message' }, handleMessageResponse);
|
|
adapter.sendTo('foo.0', { msg: 'message' }, handleMessageResponse);
|
|
|
|
adapter.sendToAsync('foo.0', 'command', 'message').then(handleMessageResponse);
|
|
adapter.sendToAsync('foo.0', 'message').then(handleMessageResponse);
|
|
adapter.sendToAsync('foo.0', 'command', { msg: 'message' }).then(handleMessageResponse);
|
|
adapter.sendToAsync('foo.0', { msg: 'message' }).then(handleMessageResponse);
|
|
|
|
adapter.sendToHost('host-foo', 'command', 'message');
|
|
adapter.sendToHost('host-foo', 'message');
|
|
adapter.sendToHost('host-foo', 'command', { msg: 'message' });
|
|
adapter.sendToHost('host-foo', { msg: 'message' });
|
|
|
|
adapter.sendToHost('host-foo', 'command', 'message', handleMessageResponse);
|
|
adapter.sendToHost('host-foo', 'message', handleMessageResponse);
|
|
adapter.sendToHost('host-foo', 'command', { msg: 'message' }, handleMessageResponse);
|
|
adapter.sendToHost('host-foo', { msg: 'message' }, handleMessageResponse);
|
|
|
|
adapter.sendToHostAsync('host-foo', 'command', 'message').then(handleMessageResponse);
|
|
adapter.sendToHostAsync('host-foo', 'message').then(handleMessageResponse);
|
|
adapter.sendToHostAsync('host-foo', 'command', { msg: 'message' }).then(handleMessageResponse);
|
|
adapter.sendToHostAsync('host-foo', { msg: 'message' }).then(handleMessageResponse);
|
|
|
|
function handleError(err?: string) {}
|
|
adapter.subscribeStates('*', handleError);
|
|
adapter.subscribeForeignStates('*', handleError);
|
|
adapter.unsubscribeStates('*', handleError);
|
|
adapter.unsubscribeForeignStates('*', handleError);
|
|
|
|
adapter.subscribeStatesAsync('*').catch(handleError);
|
|
adapter.subscribeForeignStatesAsync('*').catch(handleError);
|
|
adapter.unsubscribeStatesAsync('*').catch(handleError);
|
|
adapter.unsubscribeForeignStatesAsync('*').catch(handleError);
|
|
adapter.subscribeObjectsAsync('*').catch(handleError);
|
|
adapter.subscribeForeignObjectsAsync('*').catch(handleError);
|
|
adapter.unsubscribeObjectsAsync('*').catch(handleError);
|
|
adapter.unsubscribeForeignObjectsAsync('*').catch(handleError);
|
|
|
|
adapter.getHistory('state.id', {}, (err, result?: ioBroker.GetHistoryResult) => {});
|
|
|
|
(() => adapter.terminate())();
|
|
(() => adapter.terminate(1))();
|
|
(() => adapter.terminate('Reason'))();
|
|
(() => adapter.terminate('Reason', 4))();
|
|
|
|
adapter.supportsFeature && !!adapter.supportsFeature('foo');
|
|
() => {
|
|
const instance = adapter.getPluginInstance('my-plugin');
|
|
instance && instance.someMethod();
|
|
const config = adapter.getPluginConfig('my-plugin');
|
|
config && config.x;
|
|
};
|
|
|
|
// @ts-expect-error
|
|
adapter.states.getStates();
|
|
// @ts-expect-error
|
|
adapter.objects.getObjectView();
|
|
|
|
adapter.oObjects && adapter.oObjects['foo'] && adapter.oObjects['foo']._id.toString();
|
|
adapter.oStates && adapter.oStates['foo'] && adapter.oStates['foo'].val;
|
|
|
|
// Repro from https://github.com/ioBroker/adapter-core/issues/3
|
|
const repro1: ioBroker.ObjectChangeHandler = (id, obj) => {
|
|
if (!obj || !obj.common) return;
|
|
if (obj.common.custom) {
|
|
const test1: ioBroker.StateCommon = obj.common;
|
|
}
|
|
obj && obj.common && obj.common.custom && obj.common.custom['adapter.0'] && obj.common.custom['adapter.0'].enabled;
|
|
};
|
|
|
|
// Repro from https://github.com/ioBroker/adapter-core/issues/4
|
|
function repro2() {
|
|
// Prepare custom object
|
|
const obj = {
|
|
common: {
|
|
custom: {
|
|
'adapter.namespace': { start_day: null as any },
|
|
},
|
|
},
|
|
};
|
|
adapter.extendForeignObject('obj.id', obj, err => {});
|
|
}
|
|
|
|
// repro from https://github.com/ioBroker/adapter-core/issues/6
|
|
function repro3() {
|
|
adapter.getDevices((error, deviceList) => {
|
|
if (deviceList) {
|
|
deviceList; // $ExpectType DeviceObject[]
|
|
}
|
|
});
|
|
adapter.getDevicesAsync().then(list => {
|
|
list; // $ExpectType DeviceObject[]
|
|
});
|
|
adapter.getChannels((error, channelList) => {
|
|
if (channelList) {
|
|
channelList; // $ExpectType ChannelObject[]
|
|
}
|
|
});
|
|
adapter.getChannelsAsync().then(list => {
|
|
list; // $ExpectType ChannelObject[]
|
|
});
|
|
adapter.getChannelsOfAsync().then(list => {
|
|
list; // $ExpectType ChannelObject[]
|
|
});
|
|
adapter.getStatesOf((error, stateList) => {
|
|
if (stateList) {
|
|
stateList; // $ExpectType StateObject[]
|
|
}
|
|
});
|
|
adapter.getStatesOfAsync().then(list => {
|
|
list; // $ExpectType StateObject[]
|
|
});
|
|
}
|
|
|
|
const folderObj: ioBroker.FolderObject = {
|
|
_id: 'id',
|
|
type: 'folder',
|
|
common: {
|
|
name: 'something',
|
|
// any property is allowed
|
|
foo: 'bar',
|
|
},
|
|
native: {},
|
|
};
|
|
|
|
// This used to be an error: https://github.com/ioBroker/ioBroker.js-controller/issues/782
|
|
// With JS-Controller 3.3 it no longer is.
|
|
adapter.setState('id', { ack: false });
|
|
// @ts-expect-error
|
|
adapter.setState('id', {});
|
|
|
|
// null is a valid state value
|
|
adapter.setState('id', null);
|
|
adapter.setForeignState('id', null);
|
|
adapter.setStateAsync('id', null);
|
|
adapter.setForeignStateAsync('id', null);
|
|
adapter.setStateChanged('id', null);
|
|
adapter.setForeignStateChanged('id', null);
|
|
adapter.setStateChangedAsync('id', null);
|
|
adapter.setForeignStateChangedAsync('id', null);
|
|
adapter.delBinaryState('id');
|
|
adapter.delBinaryStateAsync('id').then(() => null);
|
|
adapter.delForeignBinaryState('id');
|
|
adapter.delForeignBinaryStateAsync('id').then(() => null);
|
|
|
|
// Objects and arrays are not valid state values
|
|
// @ts-expect-error
|
|
adapter.setState('id', { an: 'object' });
|
|
// @ts-expect-error
|
|
adapter.setForeignState('id', { an: 'object' });
|
|
// @ts-expect-error
|
|
adapter.setStateAsync('id', { an: 'object' });
|
|
// @ts-expect-error
|
|
adapter.setForeignStateAsync('id', { an: 'object' });
|
|
// @ts-expect-error
|
|
adapter.setStateChanged('id', { an: 'object' });
|
|
// @ts-expect-error
|
|
adapter.setForeignStateChanged('id', { an: 'object' });
|
|
// @ts-expect-error
|
|
adapter.setStateChangedAsync('id', { an: 'object' });
|
|
// @ts-expect-error
|
|
adapter.setForeignStateChangedAsync('id', { an: 'object' });
|
|
// @ts-expect-error
|
|
adapter.setState('id', ['an', 'array']);
|
|
// @ts-expect-error
|
|
adapter.setForeignState('id', ['an', 'array']);
|
|
// @ts-expect-error
|
|
adapter.setStateAsync('id', ['an', 'array']);
|
|
// @ts-expect-error
|
|
adapter.setForeignStateAsync('id', ['an', 'array']);
|
|
// @ts-expect-error
|
|
adapter.setStateChanged('id', ['an', 'array']);
|
|
// @ts-expect-error
|
|
adapter.setForeignStateChanged('id', ['an', 'array']);
|
|
// @ts-expect-error
|
|
adapter.setStateChangedAsync('id', ['an', 'array']);
|
|
// @ts-expect-error
|
|
adapter.setForeignStateChangedAsync('id', ['an', 'array']);
|
|
// @ts-expect-error
|
|
adapter.setState('id', { val: { an: 'object' } });
|
|
// @ts-expect-error
|
|
adapter.setForeignState('id', { val: { an: 'object' } });
|
|
// @ts-expect-error
|
|
adapter.setStateAsync('id', { val: { an: 'object' } });
|
|
// @ts-expect-error
|
|
adapter.setForeignStateAsync('id', { val: { an: 'object' } });
|
|
// @ts-expect-error
|
|
adapter.setStateChanged('id', { val: { an: 'object' } });
|
|
// @ts-expect-error
|
|
adapter.setForeignStateChanged('id', { val: { an: 'object' } });
|
|
// @ts-expect-error
|
|
adapter.setStateChangedAsync('id', { val: { an: 'object' } });
|
|
// @ts-expect-error
|
|
adapter.setForeignStateChangedAsync('id', { val: { an: 'object' } });
|
|
// @ts-expect-error
|
|
adapter.setState('id', { val: ['an', 'array'] });
|
|
// @ts-expect-error
|
|
adapter.setForeignState('id', { val: ['an', 'array'] });
|
|
// @ts-expect-error
|
|
adapter.setStateAsync('id', { val: ['an', 'array'] });
|
|
// @ts-expect-error
|
|
adapter.setForeignStateAsync('id', { val: ['an', 'array'] });
|
|
// @ts-expect-error
|
|
adapter.setStateChanged('id', { val: ['an', 'array'] });
|
|
// @ts-expect-error
|
|
adapter.setForeignStateChanged('id', { val: ['an', 'array'] });
|
|
// @ts-expect-error
|
|
adapter.setStateChangedAsync('id', { val: ['an', 'array'] });
|
|
// @ts-expect-error
|
|
adapter.setForeignStateChangedAsync('id', { val: ['an', 'array'] });
|
|
|
|
// Allow alias states
|
|
adapter
|
|
.getForeignObjectAsync('adapter.0.stateId')
|
|
.then(
|
|
obj =>
|
|
obj &&
|
|
obj.type === 'state' &&
|
|
(typeof obj.common.alias?.id === 'string' || typeof obj.common.alias?.id.read === 'string'),
|
|
);
|
|
|
|
adapter.getObjectAsync('id').then(obj => {
|
|
// Allow accessing unknown properties - the user is on its own here
|
|
obj && obj.common && obj.common.alias && obj.common.alias.id;
|
|
obj && obj.common && obj.common.unit && obj.common.workingID;
|
|
});
|
|
|
|
declare let state: ioBroker.StateObject;
|
|
if (typeof state.common.smartName === 'object') {
|
|
state.common.smartName.de && state.common.smartName.de.toUpperCase();
|
|
state.common.smartName.byOn && state.common.smartName.byOn.toUpperCase();
|
|
}
|
|
|
|
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));
|
|
// @ts-expect-error
|
|
clearTimeout(adapter.setTimeout(() => {}, 10));
|
|
// @ts-expect-error
|
|
clearInterval(adapter.setInterval(() => {}, 10));
|
|
// @ts-expect-error
|
|
adapter.clearTimeout(setTimeout(() => {}, 10));
|
|
// @ts-expect-error
|
|
adapter.clearInterval(setInterval(() => {}, 10));
|
|
// And they must not be switched
|
|
// @ts-expect-error
|
|
adapter.clearInterval(adapter.setTimeout(() => {}, 10));
|
|
// @ts-expect-error
|
|
adapter.clearTimeout(adapter.setInterval(() => {}, 10));
|
|
|
|
// Error callbacks were changed to Error objects
|
|
adapter.delFile(null, 'foo', err => {
|
|
if (err) {
|
|
// And the fs-specific ones now contain the code
|
|
err.code;
|
|
err.message;
|
|
err.syscall;
|
|
}
|
|
});
|
|
|
|
adapter.FORBIDDEN_CHARS.test('foo');
|
|
// @ts-expect-error
|
|
adapter.FORBIDDEN_CHARS = /_/;
|
|
|
|
// Repro from ioBroker.i2c
|
|
{
|
|
interface PCF8574Config {
|
|
pollingInterval: number;
|
|
interrupt?: string;
|
|
pins: PinConfig[];
|
|
}
|
|
|
|
interface PinConfig {
|
|
dir: 'in' | 'out';
|
|
inv?: boolean;
|
|
}
|
|
|
|
const config: PCF8574Config = undefined as any;
|
|
|
|
adapter.extendObject(`some state`, {
|
|
type: 'state',
|
|
common: {
|
|
name: `some name`,
|
|
read: true,
|
|
write: false,
|
|
type: 'boolean',
|
|
role: 'indicator',
|
|
},
|
|
native: config,
|
|
});
|
|
}
|
|
|
|
// Test some of the more uncommon object types
|
|
const adapterObject: ioBroker.AdapterObject = {
|
|
_id: '',
|
|
type: 'adapter',
|
|
native: {},
|
|
common: {
|
|
enabled: true,
|
|
installedVersion: '1.2.3',
|
|
materialize: false,
|
|
materializeTab: false,
|
|
mode: 'daemon',
|
|
name: 'test',
|
|
platform: 'Javascript/Node.js',
|
|
titleLang: {
|
|
de: 'foo',
|
|
es: 'foo',
|
|
fr: 'foo',
|
|
it: 'foo',
|
|
nl: 'foo',
|
|
pl: 'foo',
|
|
pt: 'foo',
|
|
ru: 'foo',
|
|
en: 'foo',
|
|
uk: 'foo',
|
|
'zh-cn': 'foo',
|
|
},
|
|
version: '1.2.3',
|
|
},
|
|
};
|
|
|
|
const folderObject: ioBroker.FolderObject = {
|
|
_id: '',
|
|
type: 'folder',
|
|
common: { name: 'My Folder' },
|
|
native: {},
|
|
};
|
|
|
|
const enumObject: ioBroker.EnumObject = {
|
|
_id: '',
|
|
type: 'enum',
|
|
common: { name: 'My Enum', members: [] },
|
|
native: {},
|
|
};
|
|
|
|
const metaObject: ioBroker.MetaObject = {
|
|
_id: '',
|
|
type: 'meta',
|
|
common: { type: 'meta.folder', name: 'foobar' },
|
|
native: {},
|
|
};
|
|
|
|
const instanceObject: ioBroker.InstanceObject = {
|
|
_id: '',
|
|
type: 'instance',
|
|
common: { enabled: true, host: 'my host', mode: 'daemon', name: 'instance 1' },
|
|
native: {},
|
|
};
|
|
|
|
const userObject: ioBroker.UserObject = {
|
|
_id: '',
|
|
type: 'user',
|
|
common: { name: 'me', password: '*****', enabled: true },
|
|
native: {},
|
|
};
|
|
|
|
// Ensure that getForeignObject tries to resolve a specific object type
|
|
async () => {
|
|
let inst: ioBroker.InstanceObject | null | undefined;
|
|
inst = await adapter.getForeignObjectAsync('system.adapter.admin.0');
|
|
|
|
let adptr: ioBroker.AdapterObject | null | undefined;
|
|
adptr = await adapter.getForeignObjectAsync('system.adapter.admin');
|
|
|
|
let meta: ioBroker.MetaObject | null | undefined;
|
|
meta = await adapter.getForeignObjectAsync('admin.0');
|
|
meta = await adapter.getForeignObjectAsync('admin.admin');
|
|
meta = await adapter.getForeignObjectAsync('admin.meta');
|
|
meta = await adapter.getForeignObjectAsync('admin.meta.foobar');
|
|
meta = await adapter.getForeignObjectAsync('admin.0.meta.blub');
|
|
|
|
let chnl: ioBroker.ChannelObject | null | undefined;
|
|
chnl = await adapter.getForeignObjectAsync('script.js.common');
|
|
chnl = await adapter.getForeignObjectAsync('script.js.global');
|
|
chnl = await adapter.getForeignObjectAsync('admin.777.info');
|
|
|
|
let state: ioBroker.StateObject | null | undefined;
|
|
state = await adapter.getForeignObjectAsync('system.adapter.admin.0.foobar');
|
|
|
|
let scrChnl: ioBroker.ChannelObject | ioBroker.ScriptObject | null | undefined;
|
|
scrChnl = await adapter.getForeignObjectAsync('script.js.my-script');
|
|
scrChnl = await adapter.getForeignObjectAsync('script.js.my-script.foobar');
|
|
|
|
let enm: ioBroker.EnumObject | null | undefined;
|
|
enm = await adapter.getForeignObjectAsync('enum.functions');
|
|
enm = await adapter.getForeignObjectAsync('enum.functions.light');
|
|
|
|
let group: ioBroker.GroupObject | null | undefined;
|
|
group = await adapter.getForeignObjectAsync('system.group.admin.faz');
|
|
|
|
let user: ioBroker.UserObject | null | undefined;
|
|
user = await adapter.getForeignObjectAsync('system.user.admin.faz');
|
|
|
|
let host: ioBroker.HostObject | null | undefined;
|
|
host = await adapter.getForeignObjectAsync('system.host.my-hostname');
|
|
|
|
let config: (ioBroker.OtherObject & { type: 'config' }) | null | undefined;
|
|
config = await adapter.getForeignObjectAsync('system.repositories');
|
|
config = await adapter.getForeignObjectAsync('system.config');
|
|
config = await adapter.getForeignObjectAsync('system.certificates');
|
|
|
|
let misc:
|
|
| ioBroker.FolderObject
|
|
| ioBroker.DeviceObject
|
|
| ioBroker.ChannelObject
|
|
| ioBroker.StateObject
|
|
| null
|
|
| undefined;
|
|
misc = await adapter.getForeignObjectAsync('system.host.hostname.foobar');
|
|
misc = await adapter.getForeignObjectAsync('adapter-name.0.foo');
|
|
misc = await adapter.getForeignObjectAsync('adapter-name.0.foo.bar');
|
|
misc = await adapter.getForeignObjectAsync('adapter-name.0.foo.bar.baz');
|
|
|
|
// combined
|
|
const idCombined = '' as 'enum.functions' | 'script.js.global';
|
|
let combined: ioBroker.ChannelObject | ioBroker.EnumObject | null | undefined;
|
|
combined = await adapter.getForeignObjectAsync(idCombined);
|
|
|
|
// unknown id
|
|
let unknown: ioBroker.Object | null | undefined;
|
|
unknown = await adapter.getForeignObjectAsync('');
|
|
};
|
|
|
|
// Ensure that setForeignObject tries to resolve a specific object type
|
|
async () => {
|
|
adapter.setForeignObject('system.host.my-hostname', {
|
|
// @ts-expect-error
|
|
type: 'not-host',
|
|
});
|
|
|
|
adapter.setForeignObject('admin.0.maybe-channel', {
|
|
type: 'channel',
|
|
common: {
|
|
name: 'A channel',
|
|
},
|
|
native: {},
|
|
});
|
|
|
|
adapter.setForeignObject(null! as string, null! as ioBroker.Object);
|
|
};
|
|
|
|
// Test convenience types for subsets of SettableObject
|
|
{
|
|
// Should be OK
|
|
const stateObj: ioBroker.SettableStateObject = {
|
|
type: 'state',
|
|
common: {
|
|
name: 'Dummy name',
|
|
role: 'value',
|
|
read: true,
|
|
write: false,
|
|
unit: '%',
|
|
},
|
|
native: {},
|
|
};
|
|
}
|
|
{
|
|
const stateObj: ioBroker.SettableDeviceObject = {
|
|
// @ts-expect-error
|
|
type: 'state',
|
|
common: {
|
|
name: 'Dummy name',
|
|
},
|
|
native: {},
|
|
};
|
|
}
|
|
|
|
// Repro for https://github.com/ioBroker/adapter-core/issues/334
|
|
async () => {
|
|
const states = await adapter.getStatesAsync('foo');
|
|
// This should not error
|
|
states['foo'];
|
|
};
|
|
|
|
// Test registerNotification
|
|
// @ts-expect-error
|
|
adapter.registerNotification('foobar', 'accessErrors', 'This is a problem!');
|
|
adapter.registerNotification('system', 'accessErrors', 'This is a problem!');
|
|
adapter.registerNotification('system', null, 'This is a problem!');
|
|
|
|
// https://github.com/ioBroker/adapter-core/issues/429
|
|
adapter.namespace === 'foo-bar.0';
|
|
adapter.namespace === 'foooooo.10';
|
|
// @ts-expect-error
|
|
adapter.namespace === 'foo.bar.0';
|
|
// @ts-expect-error
|
|
adapter.namespace === 'foo-bar.a';
|
|
adapter.getForeignObjectAsync(`system.adapter.${adapter.namespace}`).then(o => {
|
|
// $ExpectType InstanceObject
|
|
o!;
|
|
});
|
|
|
|
// https://github.com/ioBroker/adapter-core/issues/378
|
|
adapter.performStrictObjectChecks = true;
|
|
|
|
// Ensure narrowing of SettableState works correctly
|
|
function testSettableState(arg: ioBroker.SettableState): void {
|
|
if (arg.val !== undefined && arg.val !== null) {
|
|
arg.val.toString(); // OK
|
|
// @ts-expect-error
|
|
arg.ts.toString();
|
|
if (arg.ts !== undefined && arg.ts !== null) {
|
|
arg.ts.toString(); // OK
|
|
}
|
|
}
|
|
// $ExpectType number | undefined
|
|
arg.ts;
|
|
}
|
|
|
|
// https://github.com/ioBroker/adapter-core/issues/455
|
|
adapter.findForeignObjectAsync('foo', 'bar').then(ret => {
|
|
// $ExpectType ioBroker.StringOrTranslated | undefined || StringOrTranslated | undefined
|
|
ret.name;
|
|
if (typeof ret.name === 'object') {
|
|
// $ExpectType string
|
|
ret.name.en;
|
|
// $ExpectType string | undefined
|
|
ret.name.de;
|
|
}
|
|
});
|