@lakutata/dbus 2.3.1 → 3.0.0-beta.0
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/LICENSE +23 -0
- package/README.md +253 -25
- package/dist/cjs/adapters/DBusEntrypoint.d.ts +89 -0
- package/dist/cjs/adapters/DBusEntrypoint.js +280 -0
- package/dist/cjs/channel/DBusChannel.d.ts +36 -0
- package/dist/cjs/channel/DBusChannel.js +70 -0
- package/dist/cjs/components/DBusClientComponent.d.ts +494 -0
- package/dist/cjs/components/DBusClientComponent.js +272 -0
- package/dist/cjs/components/DBusObjectManager.d.ts +164 -0
- package/dist/cjs/components/DBusObjectManager.js +200 -0
- package/dist/cjs/context/DBusContext.d.ts +52 -0
- package/dist/cjs/context/DBusContext.js +68 -0
- package/dist/cjs/decorators/DBusInterface.d.ts +74 -0
- package/dist/cjs/decorators/DBusInterface.js +63 -0
- package/dist/cjs/decorators/DBusMethod.d.ts +115 -0
- package/dist/cjs/decorators/DBusMethod.js +20 -0
- package/dist/cjs/exports/DBus.d.ts +11 -0
- package/dist/cjs/exports/DBus.js +42 -0
- package/dist/cjs/lib/DBusClientOptions.d.ts +30 -0
- package/dist/cjs/lib/Declarations.d.ts +187 -0
- package/dist/cjs/lib/Declarations.js +113 -0
- package/dist/cjs/lib/Names.d.ts +35 -0
- package/dist/cjs/lib/Names.js +80 -0
- package/dist/cjs/lib/Signature.d.ts +14 -0
- package/dist/cjs/lib/Signature.js +53 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/types/DBusContextParams.d.ts +22 -0
- package/dist/cjs/types/DBusContextParams.js +2 -0
- package/dist/esm/adapters/DBusEntrypoint.js +274 -0
- package/dist/esm/channel/DBusChannel.js +67 -0
- package/dist/esm/components/DBusClientComponent.js +267 -0
- package/dist/esm/components/DBusObjectManager.js +197 -0
- package/dist/esm/context/DBusContext.js +64 -0
- package/dist/esm/decorators/DBusInterface.js +60 -0
- package/dist/esm/decorators/DBusMethod.js +17 -0
- package/dist/esm/exports/DBus.js +12 -0
- package/dist/esm/lib/DBusClientOptions.js +1 -0
- package/dist/esm/lib/Declarations.js +107 -0
- package/dist/esm/lib/Names.js +73 -0
- package/dist/esm/lib/Signature.js +49 -0
- package/dist/esm/types/DBusContextParams.js +1 -0
- package/dist/types/adapters/DBusEntrypoint.d.ts +89 -0
- package/dist/types/channel/DBusChannel.d.ts +36 -0
- package/dist/types/components/DBusClientComponent.d.ts +494 -0
- package/dist/types/components/DBusObjectManager.d.ts +164 -0
- package/dist/types/context/DBusContext.d.ts +52 -0
- package/dist/types/decorators/DBusInterface.d.ts +74 -0
- package/dist/types/decorators/DBusMethod.d.ts +115 -0
- package/dist/types/exports/DBus.d.ts +11 -0
- package/dist/types/lib/DBusClientOptions.d.ts +30 -0
- package/dist/types/lib/Declarations.d.ts +187 -0
- package/dist/types/lib/Names.d.ts +35 -0
- package/dist/types/lib/Signature.d.ts +14 -0
- package/dist/types/types/DBusContextParams.d.ts +22 -0
- package/package.json +38 -39
- package/CHANGELOG.md +0 -153
- package/dist/CommonExports.d.ts +0 -2
- package/dist/CommonExports.d.ts.map +0 -1
- package/dist/CommonExports.js +0 -44
- package/dist/ComponentExports.d.ts +0 -2
- package/dist/ComponentExports.d.ts.map +0 -1
- package/dist/ComponentExports.js +0 -5
- package/dist/ProviderExports.d.ts +0 -2
- package/dist/ProviderExports.d.ts.map +0 -1
- package/dist/ProviderExports.js +0 -5
- package/dist/components/DBusClientComponent.d.ts +0 -75
- package/dist/components/DBusClientComponent.d.ts.map +0 -1
- package/dist/components/DBusClientComponent.js +0 -125
- package/dist/interfaces/DBusClientOptions.d.ts +0 -7
- package/dist/interfaces/DBusClientOptions.d.ts.map +0 -1
- package/dist/providers/DBusClientProvider.d.ts +0 -75
- package/dist/providers/DBusClientProvider.d.ts.map +0 -1
- package/dist/providers/DBusClientProvider.js +0 -125
- package/dist/tests/DBusTest.spec.d.ts +0 -2
- package/dist/tests/DBusTest.spec.d.ts.map +0 -1
- package/dist/tests/DBusTest.spec.js +0 -26
- package/dist/tests/Test.d.ts +0 -9
- package/dist/tests/Test.d.ts.map +0 -1
- package/dist/tests/Test.js +0 -80
- package/tsconfig.json +0 -7
- /package/dist/{interfaces → cjs/lib}/DBusClientOptions.js +0 -0
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { DTO, type Schema } from '@lakutata/core';
|
|
2
|
+
/**
|
|
3
|
+
* A D-Bus signal, built by {@link defineDBusSignal}: list it in the `signals` of `@DBusInterface`, and emit it with
|
|
4
|
+
* {@link DBusObjectManager.emitSignal}. The definition itself identifies the signal: two definitions with the same
|
|
5
|
+
* name are two signals.
|
|
6
|
+
* @typeParam T The data the signal carries.
|
|
7
|
+
*/
|
|
8
|
+
export type DBusSignalDefinition<T = unknown> = {
|
|
9
|
+
/**
|
|
10
|
+
* Always `'signal'`.
|
|
11
|
+
*/
|
|
12
|
+
readonly kind: 'signal';
|
|
13
|
+
/**
|
|
14
|
+
* The member name of the signal (`'Changed'`).
|
|
15
|
+
*/
|
|
16
|
+
readonly name: string;
|
|
17
|
+
/**
|
|
18
|
+
* The D-Bus signature of the signal's one argument: `a{sv}` for a DTO, or the signature given.
|
|
19
|
+
*/
|
|
20
|
+
readonly type: string;
|
|
21
|
+
/**
|
|
22
|
+
* Validate the data of an emission: with the DTO when the signal has one, returning the validated data; as it is
|
|
23
|
+
* otherwise.
|
|
24
|
+
* @param data The data to emit.
|
|
25
|
+
* @returns The data validated.
|
|
26
|
+
* @throws {InvalidValueException} When the data does not match the signal's DTO.
|
|
27
|
+
*/
|
|
28
|
+
readonly validate: (data: T) => T;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* A D-Bus property, built by {@link defineDBusProperty}: list it in the `properties` of `@DBusInterface`. Its values
|
|
32
|
+
* are kept by {@link DBusObjectManager}, one per object path: the application sets them with
|
|
33
|
+
* {@link DBusObjectManager.setPropertyValue}, the clients read them, and write them when the property is writable. The
|
|
34
|
+
* definition itself identifies the property.
|
|
35
|
+
* @typeParam T The values of the property.
|
|
36
|
+
*/
|
|
37
|
+
export type DBusPropertyDefinition<T = unknown> = {
|
|
38
|
+
/**
|
|
39
|
+
* Always `'property'`.
|
|
40
|
+
*/
|
|
41
|
+
readonly kind: 'property';
|
|
42
|
+
/**
|
|
43
|
+
* The member name of the property (`'State'`).
|
|
44
|
+
*/
|
|
45
|
+
readonly name: string;
|
|
46
|
+
/**
|
|
47
|
+
* The D-Bus signature of the property's values (`'s'`, `'i'`, `'a{sv}'`…).
|
|
48
|
+
*/
|
|
49
|
+
readonly type: string;
|
|
50
|
+
/**
|
|
51
|
+
* Whether the clients may write the property (`org.freedesktop.DBus.Properties.Set`); a read-only property refuses
|
|
52
|
+
* their writes with a D-Bus error.
|
|
53
|
+
*/
|
|
54
|
+
readonly writable: boolean;
|
|
55
|
+
/**
|
|
56
|
+
* The value of the property on every object until it is set.
|
|
57
|
+
*/
|
|
58
|
+
readonly initial?: T;
|
|
59
|
+
/**
|
|
60
|
+
* Validate a value of the property, synchronously, with its `schema` (the value as it is without a schema).
|
|
61
|
+
* @param value The value set by the application or written by a client.
|
|
62
|
+
* @returns The value validated.
|
|
63
|
+
* @throws {InvalidValueException} When the value does not match the schema; a client writing it gets a D-Bus error.
|
|
64
|
+
*/
|
|
65
|
+
readonly validate: (value: T) => T;
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* The options of {@link defineDBusProperty}.
|
|
69
|
+
* @typeParam T The values of the property.
|
|
70
|
+
*/
|
|
71
|
+
export type DBusPropertyOptions<T> = {
|
|
72
|
+
/**
|
|
73
|
+
* Whether the clients may write the property. A value written is validated with `schema`, kept, and announced by
|
|
74
|
+
* `DBusObjectManager` with a `propertyWritten` event and to the clients with `PropertiesChanged`.
|
|
75
|
+
* @default false
|
|
76
|
+
*/
|
|
77
|
+
writable?: boolean;
|
|
78
|
+
/**
|
|
79
|
+
* The value of the property on every object until it is set; it is not validated.
|
|
80
|
+
* @default undefined
|
|
81
|
+
*/
|
|
82
|
+
initial?: T;
|
|
83
|
+
/**
|
|
84
|
+
* The schema validating the values of the property (`DTO.Number().integer().min(0)`), the ones set by the
|
|
85
|
+
* application and the ones written by the clients.
|
|
86
|
+
* @default none: every value is accepted
|
|
87
|
+
*/
|
|
88
|
+
schema?: Schema;
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* The declaration of a D-Bus interface served by a controller, as `@DBusInterface` records it.
|
|
92
|
+
*/
|
|
93
|
+
export type DBusInterfaceDeclaration = {
|
|
94
|
+
/**
|
|
95
|
+
* The name of the interface (`'com.example.Device'`).
|
|
96
|
+
*/
|
|
97
|
+
readonly interface: string;
|
|
98
|
+
/**
|
|
99
|
+
* The object path, or path template, of the interface (`'/com/example/Devices/{sn}'`).
|
|
100
|
+
*/
|
|
101
|
+
readonly path: string;
|
|
102
|
+
/**
|
|
103
|
+
* The signals of the interface.
|
|
104
|
+
*/
|
|
105
|
+
readonly signals: DBusSignalDefinition<any>[];
|
|
106
|
+
/**
|
|
107
|
+
* The properties of the interface.
|
|
108
|
+
*/
|
|
109
|
+
readonly properties: DBusPropertyDefinition<any>[];
|
|
110
|
+
};
|
|
111
|
+
/**
|
|
112
|
+
* Declare a D-Bus signal, to list in the `signals` of one or more `@DBusInterface`. The signal has one argument: a
|
|
113
|
+
* dictionary of variants (`a{sv}`) holding a DTO, or a value of the signature given. Its data is validated by its DTO
|
|
114
|
+
* when it is emitted.
|
|
115
|
+
* @typeParam T The data the signal carries.
|
|
116
|
+
* @param name The member name of the signal (`'Changed'`): letters, digits and `_`, not starting with a digit; 255
|
|
117
|
+
* characters at most.
|
|
118
|
+
* @param data The DTO of the signal's data, or the D-Bus signature of its argument (`'s'`, `'a{sv}'`…); with a
|
|
119
|
+
* signature, the data is not validated. `'a{sv}'` by default.
|
|
120
|
+
* @returns The signal's definition.
|
|
121
|
+
* @throws {TypeError} When the name is invalid.
|
|
122
|
+
* @example
|
|
123
|
+
* ```typescript
|
|
124
|
+
* import {DTO} from 'lakutata'
|
|
125
|
+
* import {Expect} from 'lakutata/decorator/dto'
|
|
126
|
+
* import {defineDBusSignal, type DBusObjectManager} from '@lakutata/dbus'
|
|
127
|
+
*
|
|
128
|
+
* class StatusDTO extends DTO {
|
|
129
|
+
* @Expect(DTO.String().required())
|
|
130
|
+
* public sn: string
|
|
131
|
+
*
|
|
132
|
+
* @Expect(DTO.Boolean().required())
|
|
133
|
+
* public online: boolean
|
|
134
|
+
* }
|
|
135
|
+
*
|
|
136
|
+
* //A dictionary of variants a{sv}, validated by StatusDTO
|
|
137
|
+
* export const DeviceChanged = defineDBusSignal<StatusDTO>('Changed', StatusDTO)
|
|
138
|
+
* //A string s
|
|
139
|
+
* export const DeviceMessage = defineDBusSignal<string>('Message', 's')
|
|
140
|
+
*
|
|
141
|
+
* declare const manager: DBusObjectManager
|
|
142
|
+
* manager.emitSignal('/com/example/Devices/A1', DeviceChanged, {sn: 'A1', online: true} as StatusDTO)
|
|
143
|
+
* manager.emitSignal('/com/example/Devices/A1', DeviceMessage, 'Rebooted')
|
|
144
|
+
* ```
|
|
145
|
+
*/
|
|
146
|
+
export declare function defineDBusSignal<T = Record<string, unknown>>(name: string, data?: typeof DTO | string): DBusSignalDefinition<T>;
|
|
147
|
+
/**
|
|
148
|
+
* Declare a D-Bus property, to list in the `properties` of one or more `@DBusInterface`. Its values are kept by
|
|
149
|
+
* `DBusObjectManager`, one per object: the application sets them, the clients read them (`Get`, `GetAll`) and are told
|
|
150
|
+
* of their changes (`PropertiesChanged`), and write them when the property is writable.
|
|
151
|
+
* @typeParam T The values of the property.
|
|
152
|
+
* @param name The member name of the property (`'State'`): letters, digits and `_`, not starting with a digit; 255
|
|
153
|
+
* characters at most.
|
|
154
|
+
* @param type The D-Bus signature of its values (`'s'`, `'i'`, `'b'`, `'a{sv}'`…); it is not checked against `schema`.
|
|
155
|
+
* @param options Whether the clients may write it, its initial value and the schema of its values; none by default
|
|
156
|
+
* (read-only, no initial value, every value accepted).
|
|
157
|
+
* @returns The property's definition.
|
|
158
|
+
* @throws {TypeError} When the name is invalid.
|
|
159
|
+
* @example
|
|
160
|
+
* ```typescript
|
|
161
|
+
* import {DTO} from 'lakutata'
|
|
162
|
+
* import {defineDBusProperty, type DBusObjectManager, type DBusPropertyWrite} from '@lakutata/dbus'
|
|
163
|
+
*
|
|
164
|
+
* //Read-only, "idle" until it is set
|
|
165
|
+
* export const DeviceState = defineDBusProperty<string>('State', 's', {initial: 'idle'})
|
|
166
|
+
* //Written by the clients, from 0 to 10
|
|
167
|
+
* export const DeviceLevel = defineDBusProperty<number>('Level', 'i', {writable: true, initial: 1, schema: DTO.Number().integer().min(0).max(10)})
|
|
168
|
+
*
|
|
169
|
+
* declare const manager: DBusObjectManager
|
|
170
|
+
* manager.setPropertyValue('/com/example/Devices/A1', DeviceState, 'running')
|
|
171
|
+
* manager.on('propertyWritten', (write: DBusPropertyWrite): void => {
|
|
172
|
+
* if (write.property === DeviceLevel) console.log(`${write.path}: level ${write.value}`)
|
|
173
|
+
* })
|
|
174
|
+
* ```
|
|
175
|
+
*/
|
|
176
|
+
export declare function defineDBusProperty<T = unknown>(name: string, type: string, options?: DBusPropertyOptions<T>): DBusPropertyDefinition<T>;
|
|
177
|
+
/**
|
|
178
|
+
* Keep the declaration of the interface of a controller
|
|
179
|
+
* @param controller
|
|
180
|
+
* @param declaration
|
|
181
|
+
*/
|
|
182
|
+
export declare function setDBusInterfaceDeclaration(controller: Function, declaration: DBusInterfaceDeclaration): void;
|
|
183
|
+
/**
|
|
184
|
+
* The declaration of the interface of a controller, or of its nearest parent class declaring one
|
|
185
|
+
* @param controller
|
|
186
|
+
*/
|
|
187
|
+
export declare function getDBusInterfaceDeclaration(controller: Function): DBusInterfaceDeclaration | undefined;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.defineDBusSignal = defineDBusSignal;
|
|
4
|
+
exports.defineDBusProperty = defineDBusProperty;
|
|
5
|
+
exports.setDBusInterfaceDeclaration = setDBusInterfaceDeclaration;
|
|
6
|
+
exports.getDBusInterfaceDeclaration = getDBusInterfaceDeclaration;
|
|
7
|
+
const core_1 = require("@lakutata/core");
|
|
8
|
+
const Names_js_1 = require("./Names.js");
|
|
9
|
+
const Signature_js_1 = require("./Signature.js");
|
|
10
|
+
/**
|
|
11
|
+
* Declare a D-Bus signal, to list in the `signals` of one or more `@DBusInterface`. The signal has one argument: a
|
|
12
|
+
* dictionary of variants (`a{sv}`) holding a DTO, or a value of the signature given. Its data is validated by its DTO
|
|
13
|
+
* when it is emitted.
|
|
14
|
+
* @typeParam T The data the signal carries.
|
|
15
|
+
* @param name The member name of the signal (`'Changed'`): letters, digits and `_`, not starting with a digit; 255
|
|
16
|
+
* characters at most.
|
|
17
|
+
* @param data The DTO of the signal's data, or the D-Bus signature of its argument (`'s'`, `'a{sv}'`…); with a
|
|
18
|
+
* signature, the data is not validated. `'a{sv}'` by default.
|
|
19
|
+
* @returns The signal's definition.
|
|
20
|
+
* @throws {TypeError} When the name is invalid.
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* import {DTO} from 'lakutata'
|
|
24
|
+
* import {Expect} from 'lakutata/decorator/dto'
|
|
25
|
+
* import {defineDBusSignal, type DBusObjectManager} from '@lakutata/dbus'
|
|
26
|
+
*
|
|
27
|
+
* class StatusDTO extends DTO {
|
|
28
|
+
* @Expect(DTO.String().required())
|
|
29
|
+
* public sn: string
|
|
30
|
+
*
|
|
31
|
+
* @Expect(DTO.Boolean().required())
|
|
32
|
+
* public online: boolean
|
|
33
|
+
* }
|
|
34
|
+
*
|
|
35
|
+
* //A dictionary of variants a{sv}, validated by StatusDTO
|
|
36
|
+
* export const DeviceChanged = defineDBusSignal<StatusDTO>('Changed', StatusDTO)
|
|
37
|
+
* //A string s
|
|
38
|
+
* export const DeviceMessage = defineDBusSignal<string>('Message', 's')
|
|
39
|
+
*
|
|
40
|
+
* declare const manager: DBusObjectManager
|
|
41
|
+
* manager.emitSignal('/com/example/Devices/A1', DeviceChanged, {sn: 'A1', online: true} as StatusDTO)
|
|
42
|
+
* manager.emitSignal('/com/example/Devices/A1', DeviceMessage, 'Rebooted')
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
function defineDBusSignal(name, data = 'a{sv}') {
|
|
46
|
+
(0, Names_js_1.checkMemberName)(name, 'signal');
|
|
47
|
+
const isDTO = typeof data === 'function';
|
|
48
|
+
return {
|
|
49
|
+
kind: 'signal',
|
|
50
|
+
name: name,
|
|
51
|
+
type: isDTO ? (0, Signature_js_1.schemaSignature)(data) : data,
|
|
52
|
+
validate: (value) => isDTO ? data.validate(value) : value
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Declare a D-Bus property, to list in the `properties` of one or more `@DBusInterface`. Its values are kept by
|
|
57
|
+
* `DBusObjectManager`, one per object: the application sets them, the clients read them (`Get`, `GetAll`) and are told
|
|
58
|
+
* of their changes (`PropertiesChanged`), and write them when the property is writable.
|
|
59
|
+
* @typeParam T The values of the property.
|
|
60
|
+
* @param name The member name of the property (`'State'`): letters, digits and `_`, not starting with a digit; 255
|
|
61
|
+
* characters at most.
|
|
62
|
+
* @param type The D-Bus signature of its values (`'s'`, `'i'`, `'b'`, `'a{sv}'`…); it is not checked against `schema`.
|
|
63
|
+
* @param options Whether the clients may write it, its initial value and the schema of its values; none by default
|
|
64
|
+
* (read-only, no initial value, every value accepted).
|
|
65
|
+
* @returns The property's definition.
|
|
66
|
+
* @throws {TypeError} When the name is invalid.
|
|
67
|
+
* @example
|
|
68
|
+
* ```typescript
|
|
69
|
+
* import {DTO} from 'lakutata'
|
|
70
|
+
* import {defineDBusProperty, type DBusObjectManager, type DBusPropertyWrite} from '@lakutata/dbus'
|
|
71
|
+
*
|
|
72
|
+
* //Read-only, "idle" until it is set
|
|
73
|
+
* export const DeviceState = defineDBusProperty<string>('State', 's', {initial: 'idle'})
|
|
74
|
+
* //Written by the clients, from 0 to 10
|
|
75
|
+
* export const DeviceLevel = defineDBusProperty<number>('Level', 'i', {writable: true, initial: 1, schema: DTO.Number().integer().min(0).max(10)})
|
|
76
|
+
*
|
|
77
|
+
* declare const manager: DBusObjectManager
|
|
78
|
+
* manager.setPropertyValue('/com/example/Devices/A1', DeviceState, 'running')
|
|
79
|
+
* manager.on('propertyWritten', (write: DBusPropertyWrite): void => {
|
|
80
|
+
* if (write.property === DeviceLevel) console.log(`${write.path}: level ${write.value}`)
|
|
81
|
+
* })
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
function defineDBusProperty(name, type, options = {}) {
|
|
85
|
+
(0, Names_js_1.checkMemberName)(name, 'property');
|
|
86
|
+
const schema = options.schema;
|
|
87
|
+
return {
|
|
88
|
+
kind: 'property',
|
|
89
|
+
name: name,
|
|
90
|
+
type: type,
|
|
91
|
+
writable: options.writable === true,
|
|
92
|
+
initial: options.initial,
|
|
93
|
+
validate: (value) => schema ? core_1.DTO.validate(value, schema) : value
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
const DBUS_INTERFACE = Symbol('DBUS.INTERFACE');
|
|
97
|
+
/**
|
|
98
|
+
* Keep the declaration of the interface of a controller
|
|
99
|
+
* @param controller
|
|
100
|
+
* @param declaration
|
|
101
|
+
*/
|
|
102
|
+
function setDBusInterfaceDeclaration(controller, declaration) {
|
|
103
|
+
(0, Names_js_1.checkInterfaceName)(declaration.interface);
|
|
104
|
+
(0, Names_js_1.checkPathTemplate)(declaration.path);
|
|
105
|
+
Reflect.defineMetadata(DBUS_INTERFACE, declaration, controller);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* The declaration of the interface of a controller, or of its nearest parent class declaring one
|
|
109
|
+
* @param controller
|
|
110
|
+
*/
|
|
111
|
+
function getDBusInterfaceDeclaration(controller) {
|
|
112
|
+
return Reflect.getMetadata(DBUS_INTERFACE, controller);
|
|
113
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check the name of an interface
|
|
3
|
+
* @param name
|
|
4
|
+
*/
|
|
5
|
+
export declare function checkInterfaceName(name: string): string;
|
|
6
|
+
/**
|
|
7
|
+
* Check the name of a member
|
|
8
|
+
* @param name
|
|
9
|
+
* @param kind
|
|
10
|
+
*/
|
|
11
|
+
export declare function checkMemberName(name: string, kind: string): string;
|
|
12
|
+
/**
|
|
13
|
+
* Check an object path, or a template of object paths
|
|
14
|
+
* @param path
|
|
15
|
+
*/
|
|
16
|
+
export declare function checkPathTemplate(path: string): string;
|
|
17
|
+
/**
|
|
18
|
+
* A template of object paths
|
|
19
|
+
*/
|
|
20
|
+
export type PathTemplate = {
|
|
21
|
+
readonly template: string;
|
|
22
|
+
readonly variables: string[];
|
|
23
|
+
readonly static: boolean;
|
|
24
|
+
match(path: string): Record<string, string> | undefined;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Compile a template of object paths
|
|
28
|
+
* @param template
|
|
29
|
+
*/
|
|
30
|
+
export declare function compilePathTemplate(template: string): PathTemplate;
|
|
31
|
+
/**
|
|
32
|
+
* The name of the DBus error of an exception: its errno, or its name
|
|
33
|
+
* @param error
|
|
34
|
+
*/
|
|
35
|
+
export declare function errorName(error: unknown): string;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.checkInterfaceName = checkInterfaceName;
|
|
4
|
+
exports.checkMemberName = checkMemberName;
|
|
5
|
+
exports.checkPathTemplate = checkPathTemplate;
|
|
6
|
+
exports.compilePathTemplate = compilePathTemplate;
|
|
7
|
+
exports.errorName = errorName;
|
|
8
|
+
/**
|
|
9
|
+
* The names of the interfaces and of the errors: dot-separated elements
|
|
10
|
+
*/
|
|
11
|
+
const INTERFACE_NAME = /^[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)+$/;
|
|
12
|
+
/**
|
|
13
|
+
* The names of the members: the methods, the properties and the signals
|
|
14
|
+
*/
|
|
15
|
+
const MEMBER_NAME = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
16
|
+
/**
|
|
17
|
+
* The object paths, their elements may be variables of a template ("/com/example/Devices/{sn}")
|
|
18
|
+
*/
|
|
19
|
+
const PATH_TEMPLATE = /^\/$|^(\/([A-Za-z0-9_]+|\{[A-Za-z_][A-Za-z0-9_]*}))+$/;
|
|
20
|
+
/**
|
|
21
|
+
* Check the name of an interface
|
|
22
|
+
* @param name
|
|
23
|
+
*/
|
|
24
|
+
function checkInterfaceName(name) {
|
|
25
|
+
if (typeof name !== 'string' || name.length > 255 || !INTERFACE_NAME.test(name))
|
|
26
|
+
throw new TypeError(`Invalid DBus interface name "${name}": dot-separated elements of letters, digits and "_", such as "com.example.Device"`);
|
|
27
|
+
return name;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Check the name of a member
|
|
31
|
+
* @param name
|
|
32
|
+
* @param kind
|
|
33
|
+
*/
|
|
34
|
+
function checkMemberName(name, kind) {
|
|
35
|
+
if (typeof name !== 'string' || name.length > 255 || !MEMBER_NAME.test(name))
|
|
36
|
+
throw new TypeError(`Invalid DBus ${kind} name "${name}": letters, digits and "_", not starting with a digit`);
|
|
37
|
+
return name;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Check an object path, or a template of object paths
|
|
41
|
+
* @param path
|
|
42
|
+
*/
|
|
43
|
+
function checkPathTemplate(path) {
|
|
44
|
+
if (typeof path !== 'string' || !PATH_TEMPLATE.test(path))
|
|
45
|
+
throw new TypeError(`Invalid DBus object path "${path}": "/" separated elements of letters, digits and "_", or variables such as "{sn}"`);
|
|
46
|
+
return path;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Compile a template of object paths
|
|
50
|
+
* @param template
|
|
51
|
+
*/
|
|
52
|
+
function compilePathTemplate(template) {
|
|
53
|
+
const variables = [];
|
|
54
|
+
const expression = new RegExp(`^${checkPathTemplate(template).replace(/\{([A-Za-z_][A-Za-z0-9_]*)}/g, (matched, name) => {
|
|
55
|
+
variables.push(name);
|
|
56
|
+
return '([A-Za-z0-9_]+)';
|
|
57
|
+
})}$`);
|
|
58
|
+
return {
|
|
59
|
+
template: template,
|
|
60
|
+
variables: variables,
|
|
61
|
+
static: !variables.length,
|
|
62
|
+
match: (path) => {
|
|
63
|
+
const matched = expression.exec(path);
|
|
64
|
+
return matched ? Object.fromEntries(variables.map((name, index) => [name, matched[index + 1]])) : undefined;
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* The name of the DBus error of an exception: its errno, or its name
|
|
70
|
+
* @param error
|
|
71
|
+
*/
|
|
72
|
+
function errorName(error) {
|
|
73
|
+
const { errno, name } = (error && typeof error === 'object' ? error : {});
|
|
74
|
+
const candidate = String(errno ?? name ?? 'Error');
|
|
75
|
+
//A dotted name is a full DBus error name, the others are prefixed by the service name
|
|
76
|
+
if (INTERFACE_NAME.test(candidate))
|
|
77
|
+
return candidate;
|
|
78
|
+
const element = candidate.replace(/[^A-Za-z0-9_]/g, '_');
|
|
79
|
+
return /^[A-Za-z_]/.test(element) ? element : `E${element}`;
|
|
80
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { DTO, type Schema } from '@lakutata/core';
|
|
2
|
+
/**
|
|
3
|
+
* The DBus signature of the values of a schema: an object is a dictionary of variants,
|
|
4
|
+
* the scalars have their own types, the other values are variants
|
|
5
|
+
* @param schema
|
|
6
|
+
*/
|
|
7
|
+
export declare function schemaSignature(schema: Schema | typeof DTO): string;
|
|
8
|
+
/**
|
|
9
|
+
* A value ready to be encoded: the dates are ISO strings, the undefined and null values are removed (a variant has no null);
|
|
10
|
+
* the typed values of dbus-sdk (`DBusUInt32`, `DBusVariant`…) are kept as they are, a Map keeps its entries (its keys
|
|
11
|
+
* keep their types)
|
|
12
|
+
* @param value
|
|
13
|
+
*/
|
|
14
|
+
export declare function toEncodable(value: unknown): unknown;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.schemaSignature = schemaSignature;
|
|
4
|
+
exports.toEncodable = toEncodable;
|
|
5
|
+
const dbus_sdk_1 = require("dbus-sdk");
|
|
6
|
+
/**
|
|
7
|
+
* The DBus signature of the values of a schema: an object is a dictionary of variants,
|
|
8
|
+
* the scalars have their own types, the other values are variants
|
|
9
|
+
* @param schema
|
|
10
|
+
*/
|
|
11
|
+
function schemaSignature(schema) {
|
|
12
|
+
const target = typeof schema === 'function' ? schema.Schema() : schema;
|
|
13
|
+
switch (target?.type) {
|
|
14
|
+
case 'object':
|
|
15
|
+
return 'a{sv}';
|
|
16
|
+
case 'string':
|
|
17
|
+
return 's';
|
|
18
|
+
case 'boolean':
|
|
19
|
+
return 'b';
|
|
20
|
+
case 'number':
|
|
21
|
+
return (target._rules ?? []).some((rule) => rule.name === 'integer') ? 'x' : 'd';
|
|
22
|
+
case 'bigint':
|
|
23
|
+
return 'x';
|
|
24
|
+
case 'array':
|
|
25
|
+
return 'av';
|
|
26
|
+
default:
|
|
27
|
+
return 'v';
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* A value ready to be encoded: the dates are ISO strings, the undefined and null values are removed (a variant has no null);
|
|
32
|
+
* the typed values of dbus-sdk (`DBusUInt32`, `DBusVariant`…) are kept as they are, a Map keeps its entries (its keys
|
|
33
|
+
* keep their types)
|
|
34
|
+
* @param value
|
|
35
|
+
*/
|
|
36
|
+
function toEncodable(value) {
|
|
37
|
+
if (value instanceof Date)
|
|
38
|
+
return value.toISOString();
|
|
39
|
+
if (value instanceof dbus_sdk_1.DBusSignedValue)
|
|
40
|
+
return value;
|
|
41
|
+
if (Array.isArray(value))
|
|
42
|
+
return value.filter((item) => item !== undefined && item !== null).map(toEncodable);
|
|
43
|
+
if (value instanceof Map)
|
|
44
|
+
return new Map([...value].filter(([, item]) => item !== undefined && item !== null).map(([key, item]) => [key, toEncodable(item)]));
|
|
45
|
+
if (value && typeof value === 'object' && !Buffer.isBuffer(value) && !(value instanceof Uint8Array)) {
|
|
46
|
+
const encodable = {};
|
|
47
|
+
for (const [key, item] of Object.entries(value))
|
|
48
|
+
if (item !== undefined && item !== null)
|
|
49
|
+
encodable[key] = toEncodable(item);
|
|
50
|
+
return encodable;
|
|
51
|
+
}
|
|
52
|
+
return value;
|
|
53
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"commonjs"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The parameters of a {@link DBusContext}: the adapter builds them for each method call it receives. An application
|
|
3
|
+
* builds them only to create a context itself, in a test of a controller.
|
|
4
|
+
*/
|
|
5
|
+
export type DBusContextParams = {
|
|
6
|
+
/**
|
|
7
|
+
* The object path of the method call (`'/com/example/Devices/A1'`), the variables of its template resolved.
|
|
8
|
+
*/
|
|
9
|
+
readonly path: string;
|
|
10
|
+
/**
|
|
11
|
+
* The name of the interface called (`'com.example.Device'`).
|
|
12
|
+
*/
|
|
13
|
+
readonly interface: string;
|
|
14
|
+
/**
|
|
15
|
+
* The name of the method called (`'Status'`).
|
|
16
|
+
*/
|
|
17
|
+
readonly member: string;
|
|
18
|
+
/**
|
|
19
|
+
* The input of the call: the entries of its `a{sv}` dictionary, an empty object for a method without input.
|
|
20
|
+
*/
|
|
21
|
+
readonly data: Record<string, any>;
|
|
22
|
+
};
|