mirta 0.1.2 → 0.2.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/dist/index.d.mts CHANGED
@@ -65,9 +65,9 @@ type StrictWhenSpecified<TObject, TKey extends keyof TObject, TReturn> = IsSpeci
65
65
  * Устанавливает указанное свойство в readonly при выполнении указанного условия.
66
66
  * @since 0.1.0
67
67
  **/
68
- type ReadonlyPropWhen<TObject, K extends keyof TObject, TCondition extends boolean | undefined> = TCondition extends true ? Omit<TObject, K> & {
68
+ type ReadonlyPropWhen<TObject, K extends keyof TObject, TCondition extends boolean | undefined> = TCondition extends true ? Expand<Omit<TObject, K> & {
69
69
  +readonly [P in K]-?: TObject[P];
70
- } : TObject;
70
+ }> : TObject;
71
71
  /**
72
72
  * Проверяет, что указанный тип объекта имеет хотя бы одно свойство заданного типа.
73
73
  * Применяется для работы с дженериками.
@@ -86,6 +86,58 @@ type HasPropertyOfType<TObject extends object, TProperty> = {
86
86
  [K in keyof TObject as TObject[K] extends TProperty ? K : never]: unknown;
87
87
  } extends infer R ? {} extends R ? false : true : never;
88
88
 
89
+ /**
90
+ * Набор политик, управляющих доступностью смены значения контрола.
91
+ *
92
+ * @since 0.2.0
93
+ *
94
+ **/
95
+ declare enum ChangePolicies {
96
+ /**
97
+ * Политика по умолчанию.
98
+ *
99
+ * - Применяет {@link Public} к контролам типа `switch`, `pushbutton`, `range` и `rgb`;
100
+ *
101
+ * - Применяет {@link Script} к остальным типам контролов.
102
+ *
103
+ **/
104
+ Default = "default",
105
+ /**
106
+ * Установка значения возможна как скриптами wb-rules, так и сторонними службами.
107
+ *
108
+ * Применимо к контролам виртуальных устройств.
109
+ *
110
+ **/
111
+ Public = "public",
112
+ /**
113
+ * Установка значения возможна только скриптами wb-rules.
114
+ *
115
+ * Применимо к контролам виртуальных устройств.
116
+ *
117
+ **/
118
+ Script = "script",
119
+ /**
120
+ * Полный запрет записи, значение доступно только для чтения.
121
+ *
122
+ * Применимо к контролам реальных устройств.
123
+ *
124
+ **/
125
+ ReadOnly = "read-only"
126
+ }
127
+ /**
128
+ * Определяет политику установки значений реальных устройств.
129
+ *
130
+ * @since 0.2.0
131
+ *
132
+ **/
133
+ type ChangePolicy = `${Exclude<ChangePolicies, ChangePolicies.Public | ChangePolicies.Script>}`;
134
+ /**
135
+ * Определяет политику установки значений контролов виртуальных устройств.
136
+ *
137
+ * @since 0.2.0
138
+ *
139
+ **/
140
+ type VirtualChangePolicy = `${Exclude<ChangePolicies, ChangePolicies.ReadOnly>}`;
89
141
  type ValueEventHandler<TValue> = (newValue: TValue, oldValue: TValue) => void;
90
142
  interface Control<TValue> {
91
143
  /** Актуальное значение контрола. */
@@ -117,8 +169,8 @@ type VirtualTypeMapper<K extends keyof WbRules.TypeMappings = keyof WbRules.Type
117
169
  interface BaseControlDef {
118
170
  /** Идентификатор контрола. Если не указан, используется название свойства. */
119
171
  controlId?: string;
120
- /** Если `true`, то значение доступно только для чтения. */
121
- isReadonly?: boolean;
172
+ /** Политика доступа на запись значения. */
173
+ changePolicy?: VirtualChangePolicy | ChangePolicy;
122
174
  }
123
175
  /**
124
176
  * Определения основных контролов.
@@ -166,7 +218,7 @@ type StrictVirtualControls<TControls extends VirtualControls> = TControls & Virt
166
218
  * при описании устройства в `defineDevice()`.
167
219
  **/
168
220
  type CreatedControls<TControls extends Controls | VirtualControls> = {
169
- [K in keyof TControls]: Expand<MaybeReadonlyControl<StrictWhenSpecified<TControls[K], 'defaultValue', WbRules.TypeMappings[TControls[K]['type']]>, TControls[K]['isReadonly']>>;
221
+ [K in keyof TControls]: Expand<MaybeReadonlyControl<StrictWhenSpecified<TControls[K], 'defaultValue', WbRules.TypeMappings[TControls[K]['type']]>, TControls[K]['changePolicy'] extends ChangePolicies.ReadOnly ? true : false>>;
170
222
  };
171
223
  /** Используется для извлечения типа значения из значения по умолчанию. */
172
224
  type InferDefaultType<TProp> = [TProp] extends [{
@@ -431,5 +483,5 @@ declare function getControlSafe(context: DeviceContext, controlId: string): Cont
431
483
  **/
432
484
  declare function getControlSafe(deviceId: string, controlId: string, isReadyFunc: () => boolean): ControlSafe;
433
485
 
434
- export { defineVirtualDevice, defineWiredDevice, defineZigbeeDevice, getControlSafe, getDeviceSafe };
486
+ export { ChangePolicies, defineVirtualDevice, defineWiredDevice, defineZigbeeDevice, getControlSafe, getDeviceSafe };
435
487
  export type { ControlSafe, DeviceContext, DeviceType, PropType, TrackCallback };
package/dist/index.mjs CHANGED
@@ -23,6 +23,45 @@ function getControlSafe(context, controlId, isReadyFunc = () => true) {
23
23
  };
24
24
  }
25
25
 
26
+ /**
27
+ * Набор политик, управляющих доступностью смены значения контрола.
28
+ *
29
+ * @since 0.2.0
30
+ *
31
+ **/
32
+ var ChangePolicies;
33
+ (function (ChangePolicies) {
34
+ /**
35
+ * Политика по умолчанию.
36
+ *
37
+ * - Применяет {@link Public} к контролам типа `switch`, `pushbutton`, `range` и `rgb`;
38
+ *
39
+ * - Применяет {@link Script} к остальным типам контролов.
40
+ *
41
+ **/
42
+ ChangePolicies["Default"] = "default";
43
+ /**
44
+ * Установка значения возможна как скриптами wb-rules, так и сторонними службами.
45
+ *
46
+ * Применимо к контролам виртуальных устройств.
47
+ *
48
+ **/
49
+ ChangePolicies["Public"] = "public";
50
+ /**
51
+ * Установка значения возможна только скриптами wb-rules.
52
+ *
53
+ * Применимо к контролам виртуальных устройств.
54
+ *
55
+ **/
56
+ ChangePolicies["Script"] = "script";
57
+ /**
58
+ * Полный запрет записи, значение доступно только для чтения.
59
+ *
60
+ * Применимо к контролам реальных устройств.
61
+ *
62
+ **/
63
+ ChangePolicies["ReadOnly"] = "read-only";
64
+ })(ChangePolicies || (ChangePolicies = {}));
26
65
  const typeMappings = {
27
66
  'text': 'string',
28
67
  'value': 'number',
@@ -35,10 +74,11 @@ const typeMappings = {
35
74
  /**
36
75
  * Создаёт контрол устройства.
37
76
  * @since 0.1.0
77
+ *
38
78
  **/
39
79
  function createControl(context, controlId, options) {
40
80
  const { deviceType, deviceId } = context;
41
- const { type, isReadonly } = options;
81
+ const { type, changePolicy = ChangePolicies.Default } = options;
42
82
  const defaultValue = 'defaultValue' in options
43
83
  ? options['defaultValue']
44
84
  : void 0;
@@ -61,6 +101,7 @@ function createControl(context, controlId, options) {
61
101
  * Устанавливает новое значение, если оно отличается от существующего.
62
102
  * @param newValue Устанавливаемое значение.
63
103
  * @param preventEmit Предотвращает отправку значения в устройство.
104
+ *
64
105
  **/
65
106
  function setValue(newValue, preventEmit = false) {
66
107
  const oldValue = localValue;
@@ -102,8 +143,8 @@ function createControl(context, controlId, options) {
102
143
  return localValue;
103
144
  },
104
145
  set value(newValue) {
105
- if (isReadonly) {
106
- log.warning(`Value of '${deviceId}/${controlId}' is readonly`);
146
+ if (changePolicy === ChangePolicies.ReadOnly) {
147
+ log.warning(`A new value of '${deviceId}/${controlId}' has been rejected: control is readonly.`);
107
148
  return;
108
149
  }
109
150
  setValue(newValue);
@@ -139,6 +180,9 @@ function createContext(deviceType, deviceId, state) {
139
180
  };
140
181
  return context;
141
182
  }
183
+ const extendWithReadonly = (changePolicy) => changePolicy && changePolicy !== ChangePolicies.Default
184
+ ? { readonly: changePolicy === ChangePolicies.Script || changePolicy === ChangePolicies.ReadOnly }
185
+ : {};
142
186
  function configureControls(deviceId, controls) {
143
187
  const device = getDevice(deviceId);
144
188
  if (!device)
@@ -152,8 +196,7 @@ function configureControls(deviceId, controls) {
152
196
  device.removeControl(controlId);
153
197
  device.addControl(controlId, assign({}, control, {
154
198
  value: control.defaultValue,
155
- readonly: control.isReadonly,
156
- }));
199
+ }, extendWithReadonly(control.changePolicy)));
157
200
  });
158
201
  }
159
202
  function configureContext(type, deviceId, controls, title) {
@@ -180,9 +223,10 @@ function configureContext(type, deviceId, controls, title) {
180
223
  if (type === 'virtual') {
181
224
  const cells = {};
182
225
  Object.keys(controls).forEach((key) => {
183
- const cell = assign({}, controls[key], {
184
- value: controls[key]['defaultValue'],
185
- }, controls[key]['isReadonly'] ? { readonly: true } : {});
226
+ const control = controls[key];
227
+ const cell = assign({}, control, {
228
+ value: control['defaultValue'],
229
+ }, extendWithReadonly(control['changePolicy']));
186
230
  cells[key] = cell;
187
231
  });
188
232
  global.defineVirtualDevice(deviceId, {
@@ -217,8 +261,8 @@ function createDevice(deviceType, deviceId, propDefs, props, options) {
217
261
  const controlId = controlDef.controlId ?? key;
218
262
  const control = createControl({ deviceType, deviceId, isReady: true }, controlId, {
219
263
  type: controlDef.type,
264
+ changePolicy: controlDef.changePolicy ?? ChangePolicies.Default,
220
265
  defaultValue: controlDef.defaultValue,
221
- isReadonly: controlDef.isReadonly,
222
266
  forceDefault: controlDef.forceDefault,
223
267
  lazyInit: controlDef.lazyInit,
224
268
  });
@@ -320,4 +364,4 @@ function getDeviceSafe(deviceId, isReadyFunc = () => true) {
320
364
  };
321
365
  }
322
366
 
323
- export { defineVirtualDevice, defineWiredDevice, defineZigbeeDevice, getControlSafe, getDeviceSafe };
367
+ export { ChangePolicies, defineVirtualDevice, defineWiredDevice, defineZigbeeDevice, getControlSafe, getDeviceSafe };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mirta",
3
3
  "description": "The powerful framework to write smart home automation scripts.",
4
- "version": "0.1.2",
4
+ "version": "0.2.0",
5
5
  "license": "Unlicense",
6
6
  "keywords": [
7
7
  "mirta",
@@ -36,9 +36,9 @@
36
36
  "url": "https://pay.cloudtips.ru/p/58512cca"
37
37
  },
38
38
  "dependencies": {
39
- "@mirta/globals": "0.1.2",
40
- "@mirta/polyfills": "0.1.2",
41
- "@mirta/basics": "0.1.2"
39
+ "@mirta/globals": "0.2.0",
40
+ "@mirta/basics": "0.2.0",
41
+ "@mirta/polyfills": "0.2.0"
42
42
  },
43
43
  "publishConfig": {
44
44
  "access": "public"