nayota-show-sdk 1.3.67 → 1.3.69
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/package.json
CHANGED
|
@@ -2,6 +2,17 @@ function isPlainObject(value) {
|
|
|
2
2
|
return Object.prototype.toString.call(value) === '[object Object]'
|
|
3
3
|
}
|
|
4
4
|
|
|
5
|
+
function stripResourceIdPrefix(value) {
|
|
6
|
+
if (value == null) {
|
|
7
|
+
return value
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const normalized = String(value)
|
|
11
|
+
const match = normalized.match(/^[a-z][a-z0-9-]*:([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$/i)
|
|
12
|
+
|
|
13
|
+
return match ? match[1] : normalized
|
|
14
|
+
}
|
|
15
|
+
|
|
5
16
|
export function removeUndefinedFields(value) {
|
|
6
17
|
if (!isPlainObject(value)) {
|
|
7
18
|
return value
|
|
@@ -35,7 +46,7 @@ export function getLegacyId(value) {
|
|
|
35
46
|
}
|
|
36
47
|
|
|
37
48
|
if (typeof value === 'string' || typeof value === 'number') {
|
|
38
|
-
return
|
|
49
|
+
return stripResourceIdPrefix(value)
|
|
39
50
|
}
|
|
40
51
|
|
|
41
52
|
if (Array.isArray(value)) {
|
|
@@ -44,10 +55,10 @@ export function getLegacyId(value) {
|
|
|
44
55
|
|
|
45
56
|
if (typeof value === 'object') {
|
|
46
57
|
if (value._id != null) {
|
|
47
|
-
return
|
|
58
|
+
return stripResourceIdPrefix(value._id)
|
|
48
59
|
}
|
|
49
60
|
if (value.id != null) {
|
|
50
|
-
return
|
|
61
|
+
return stripResourceIdPrefix(value.id)
|
|
51
62
|
}
|
|
52
63
|
}
|
|
53
64
|
|
|
@@ -89,6 +100,14 @@ export function withLegacyId(value) {
|
|
|
89
100
|
return acc
|
|
90
101
|
}, {})
|
|
91
102
|
|
|
103
|
+
if (next.id != null) {
|
|
104
|
+
next.id = stripResourceIdPrefix(next.id)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (next._id != null) {
|
|
108
|
+
next._id = stripResourceIdPrefix(next._id)
|
|
109
|
+
}
|
|
110
|
+
|
|
92
111
|
if (next.id != null && next._id == null) {
|
|
93
112
|
next._id = next.id
|
|
94
113
|
}
|
|
@@ -297,6 +297,71 @@ function mapDeviceEasyListRequest(data = {}) {
|
|
|
297
297
|
})
|
|
298
298
|
}
|
|
299
299
|
|
|
300
|
+
function hasOwn(value, key) {
|
|
301
|
+
return Object.prototype.hasOwnProperty.call(value || {}, key)
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
function getLegacyUiRelationId(relation = {}) {
|
|
305
|
+
if (relation.uiId != null) {
|
|
306
|
+
return getLegacyId(relation.uiId)
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
if (relation.ui != null) {
|
|
310
|
+
return getLegacyId(relation.ui)
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
if (relation.id != null || relation._id != null) {
|
|
314
|
+
return getLegacyId(relation)
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
return ''
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
function normalizeLegacyUiRelation(relation = {}, fallbackType = 'ba_card') {
|
|
321
|
+
const source = relation.ui && typeof relation.ui === 'object'
|
|
322
|
+
? relation.ui
|
|
323
|
+
: relation
|
|
324
|
+
const uiId = getLegacyUiRelationId(relation)
|
|
325
|
+
|
|
326
|
+
if (!uiId) {
|
|
327
|
+
return null
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
return removeUndefinedFields({
|
|
331
|
+
uiId,
|
|
332
|
+
uiName: relation.uiName || source.name,
|
|
333
|
+
uiCode: relation.uiCode || source.code,
|
|
334
|
+
type: relation.type || source.type || fallbackType,
|
|
335
|
+
props: relation.props,
|
|
336
|
+
attrs: Array.isArray(relation.attrs) ? relation.attrs : []
|
|
337
|
+
})
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
function resolveDigitalTwinTypeUiRelation(data = {}) {
|
|
341
|
+
if (hasOwn(data, 'uiId')) {
|
|
342
|
+
return data.uiId == null ? null : normalizeLegacyUiRelation({ uiId: data.uiId, ui: data.ui })
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
if (data.ui) {
|
|
346
|
+
return normalizeLegacyUiRelation(data.ui)
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
const relations = Array.isArray(data.uis) ? data.uis : []
|
|
350
|
+
return relations.find(item => item && item.type === 'ba_card') ||
|
|
351
|
+
relations.find(item => item && item.type === 'component') ||
|
|
352
|
+
relations[0] ||
|
|
353
|
+
null
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
function getDigitalTwinTypeUiId(data = {}) {
|
|
357
|
+
if (hasOwn(data, 'uiId')) {
|
|
358
|
+
return data.uiId == null ? null : getLegacyId(data.uiId)
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
const relation = resolveDigitalTwinTypeUiRelation(data)
|
|
362
|
+
return relation ? getLegacyUiRelationId(relation) : undefined
|
|
363
|
+
}
|
|
364
|
+
|
|
300
365
|
function mapDeviceClassToIotQuery(query = {}) {
|
|
301
366
|
return removeUndefinedFields({
|
|
302
367
|
...omitKeys(query, ['_id', 'code', 'sort']),
|
|
@@ -309,6 +374,8 @@ function mapDeviceClassToIotQuery(query = {}) {
|
|
|
309
374
|
}
|
|
310
375
|
|
|
311
376
|
function mapDeviceClassToIotBody(data = {}) {
|
|
377
|
+
const twinUiRelation = resolveDigitalTwinTypeUiRelation(data)
|
|
378
|
+
const uiId = getDigitalTwinTypeUiId(data)
|
|
312
379
|
const metadata = mergeMetadata(data.metadata, {
|
|
313
380
|
display: mergeMetadata(getNestedValue(data, 'metadata.display'), {
|
|
314
381
|
icon: data.icon
|
|
@@ -316,6 +383,7 @@ function mapDeviceClassToIotBody(data = {}) {
|
|
|
316
383
|
bms: mergeMetadata(getNestedValue(data, 'metadata.bms'), {
|
|
317
384
|
deviceUI: data.deviceUI,
|
|
318
385
|
uis: data.uis,
|
|
386
|
+
twinUi: twinUiRelation ? normalizeLegacyUiRelation(twinUiRelation) : undefined,
|
|
319
387
|
paramType: data.paramType,
|
|
320
388
|
departTag: data.departTag,
|
|
321
389
|
isSimulation: data.isSimulation,
|
|
@@ -329,6 +397,8 @@ function mapDeviceClassToIotBody(data = {}) {
|
|
|
329
397
|
'_id',
|
|
330
398
|
'id',
|
|
331
399
|
'code',
|
|
400
|
+
'ui',
|
|
401
|
+
'uiId',
|
|
332
402
|
'deviceUI',
|
|
333
403
|
'uis',
|
|
334
404
|
'paramType',
|
|
@@ -338,6 +408,7 @@ function mapDeviceClassToIotBody(data = {}) {
|
|
|
338
408
|
'icon'
|
|
339
409
|
]),
|
|
340
410
|
typeCode: data.typeCode || data.code || fallbackCode(data.name || data._id, 'TYPE'),
|
|
411
|
+
uiId,
|
|
341
412
|
metadata: Object.keys(metadata).length ? metadata : undefined
|
|
342
413
|
})
|
|
343
414
|
}
|
|
@@ -347,12 +418,22 @@ function mapIotDeviceClassToLegacy(item = {}) {
|
|
|
347
418
|
const metadata = getMetadata(entity.metadata)
|
|
348
419
|
const bms = getMetadata(metadata.bms)
|
|
349
420
|
const display = getMetadata(metadata.display)
|
|
421
|
+
const twinUiRelation = normalizeLegacyUiRelation({
|
|
422
|
+
uiId: entity.uiId,
|
|
423
|
+
ui: entity.ui,
|
|
424
|
+
type: entity.ui && entity.ui.type
|
|
425
|
+
})
|
|
426
|
+
const bmsUis = Array.isArray(bms.uis) ? bms.uis : undefined
|
|
427
|
+
const uis = bmsUis && bmsUis.length
|
|
428
|
+
? bmsUis
|
|
429
|
+
: twinUiRelation ? [twinUiRelation] : entity.uis
|
|
350
430
|
|
|
351
431
|
return removeUndefinedFields({
|
|
352
432
|
...entity,
|
|
353
433
|
code: entity.typeCode || entity.code,
|
|
354
434
|
deviceUI: bms.deviceUI || entity.deviceUI,
|
|
355
|
-
uis
|
|
435
|
+
uis,
|
|
436
|
+
uiCode: entity.uiCode || twinUiRelation?.uiCode,
|
|
356
437
|
paramType: bms.paramType || entity.paramType,
|
|
357
438
|
departTag: bms.departTag || entity.departTag,
|
|
358
439
|
isSimulation: bms.isSimulation != null ? bms.isSimulation : entity.isSimulation,
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
const { iotModuleSpecs } = require('./iot-module-specs')
|
|
2
|
+
|
|
3
|
+
describe('iotModuleSpecs deviceClass UI compatibility', () => {
|
|
4
|
+
const deviceClass = iotModuleSpecs.deviceClass.operations
|
|
5
|
+
|
|
6
|
+
test('maps legacy ba_card relation to digital twin type uiId', () => {
|
|
7
|
+
const request = deviceClass.updateOne.toRequest({
|
|
8
|
+
_id: 'type-1',
|
|
9
|
+
name: '照明',
|
|
10
|
+
code: 'LIGHT',
|
|
11
|
+
deviceUI: 'legacy-device-ui-1',
|
|
12
|
+
uis: [
|
|
13
|
+
{
|
|
14
|
+
uiId: 'legacy-device-ui-1',
|
|
15
|
+
uiName: '旧展示设备UI',
|
|
16
|
+
uiCode: 'LegacyDeviceUi',
|
|
17
|
+
type: 'device_ui',
|
|
18
|
+
attrs: []
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
uiId: 'card-ui-1',
|
|
22
|
+
uiName: '照明卡片',
|
|
23
|
+
uiCode: 'NaLightingCard',
|
|
24
|
+
type: 'ba_card',
|
|
25
|
+
attrs: [{ name: '名称' }]
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
expect(request.url).toBe('/digital-twin-types/type-1')
|
|
31
|
+
expect(request.method).toBe('patch')
|
|
32
|
+
expect(request.data.uiId).toBe('card-ui-1')
|
|
33
|
+
expect(request.data.metadata.bms.deviceUI).toBe('legacy-device-ui-1')
|
|
34
|
+
expect(request.data.metadata.bms.twinUi).toEqual({
|
|
35
|
+
uiId: 'card-ui-1',
|
|
36
|
+
uiName: '照明卡片',
|
|
37
|
+
uiCode: 'NaLightingCard',
|
|
38
|
+
type: 'ba_card',
|
|
39
|
+
attrs: [{ name: '名称' }]
|
|
40
|
+
})
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
test('does not treat legacy deviceUI as digital twin type uiId', () => {
|
|
44
|
+
const request = deviceClass.create.toRequest({
|
|
45
|
+
name: '空调',
|
|
46
|
+
code: 'AIR',
|
|
47
|
+
deviceUI: 'legacy-device-ui-2'
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
expect(request.data.uiId).toBeUndefined()
|
|
51
|
+
expect(request.data.metadata.bms.deviceUI).toBe('legacy-device-ui-2')
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
test('expands digital twin type ui relation back to legacy uis', () => {
|
|
55
|
+
const response = deviceClass.list.fromResponse({
|
|
56
|
+
code: 0,
|
|
57
|
+
data: {
|
|
58
|
+
total: 1,
|
|
59
|
+
items: [
|
|
60
|
+
{
|
|
61
|
+
id: 'type-1',
|
|
62
|
+
typeCode: 'LIGHT',
|
|
63
|
+
name: '照明',
|
|
64
|
+
uiId: 'card-ui-1',
|
|
65
|
+
ui: {
|
|
66
|
+
id: 'card-ui-1',
|
|
67
|
+
name: '照明卡片',
|
|
68
|
+
code: 'NaLightingCard',
|
|
69
|
+
type: 'ba_card'
|
|
70
|
+
},
|
|
71
|
+
metadata: {
|
|
72
|
+
bms: {
|
|
73
|
+
deviceUI: 'legacy-device-ui-1'
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
]
|
|
78
|
+
}
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
expect(response.data.rows[0]._id).toBe('type-1')
|
|
82
|
+
expect(response.data.rows[0].code).toBe('LIGHT')
|
|
83
|
+
expect(response.data.rows[0].deviceUI).toBe('legacy-device-ui-1')
|
|
84
|
+
expect(response.data.rows[0].uiCode).toBe('NaLightingCard')
|
|
85
|
+
expect(response.data.rows[0].uis).toEqual([
|
|
86
|
+
{
|
|
87
|
+
uiId: 'card-ui-1',
|
|
88
|
+
uiName: '照明卡片',
|
|
89
|
+
uiCode: 'NaLightingCard',
|
|
90
|
+
type: 'ba_card',
|
|
91
|
+
attrs: []
|
|
92
|
+
}
|
|
93
|
+
])
|
|
94
|
+
})
|
|
95
|
+
})
|