@sakibcoolz/core 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.
Files changed (142) hide show
  1. package/README.md +67 -7
  2. package/dist/acquisition.d.ts +29 -0
  3. package/dist/acquisition.d.ts.map +1 -0
  4. package/dist/acquisition.js +30 -0
  5. package/dist/acquisition.js.map +1 -0
  6. package/dist/assembly.d.ts +5 -2
  7. package/dist/assembly.d.ts.map +1 -1
  8. package/dist/assembly.js +7 -4
  9. package/dist/assembly.js.map +1 -1
  10. package/dist/attach.d.ts +4 -2
  11. package/dist/attach.d.ts.map +1 -1
  12. package/dist/attach.js +5 -3
  13. package/dist/attach.js.map +1 -1
  14. package/dist/clipboard.d.ts +6 -4
  15. package/dist/clipboard.d.ts.map +1 -1
  16. package/dist/clipboard.js +25 -4
  17. package/dist/clipboard.js.map +1 -1
  18. package/dist/collision.d.ts +2 -2
  19. package/dist/collision.js.map +1 -1
  20. package/dist/digest.d.ts +9 -0
  21. package/dist/digest.d.ts.map +1 -0
  22. package/dist/digest.js +68 -0
  23. package/dist/digest.js.map +1 -0
  24. package/dist/flow.d.ts +3 -2
  25. package/dist/flow.d.ts.map +1 -1
  26. package/dist/flow.js.map +1 -1
  27. package/dist/graph.d.ts +67 -7
  28. package/dist/graph.d.ts.map +1 -1
  29. package/dist/graph.js +195 -10
  30. package/dist/graph.js.map +1 -1
  31. package/dist/index.d.ts +13 -6
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +7 -3
  34. package/dist/index.js.map +1 -1
  35. package/dist/observation.d.ts +1 -1
  36. package/dist/observation.d.ts.map +1 -1
  37. package/dist/observation.js +4 -1
  38. package/dist/observation.js.map +1 -1
  39. package/dist/routing.d.ts +6 -3
  40. package/dist/routing.d.ts.map +1 -1
  41. package/dist/routing.js +12 -2
  42. package/dist/routing.js.map +1 -1
  43. package/dist/scene.d.ts +245 -5
  44. package/dist/scene.d.ts.map +1 -1
  45. package/dist/scene.js +94 -3
  46. package/dist/scene.js.map +1 -1
  47. package/dist/serialization.d.ts +7 -7
  48. package/dist/serialization.d.ts.map +1 -1
  49. package/dist/serialization.js +120 -8
  50. package/dist/serialization.js.map +1 -1
  51. package/dist/snapping.d.ts +2 -2
  52. package/dist/snapping.d.ts.map +1 -1
  53. package/dist/snapping.js +10 -7
  54. package/dist/snapping.js.map +1 -1
  55. package/dist/status.d.ts +56 -0
  56. package/dist/status.d.ts.map +1 -0
  57. package/dist/status.js +114 -0
  58. package/dist/status.js.map +1 -0
  59. package/dist/tags.d.ts +52 -0
  60. package/dist/tags.d.ts.map +1 -0
  61. package/dist/tags.js +103 -0
  62. package/dist/tags.js.map +1 -0
  63. package/dist/telemetry.d.ts +42 -4
  64. package/dist/telemetry.d.ts.map +1 -1
  65. package/dist/telemetry.js +84 -8
  66. package/dist/telemetry.js.map +1 -1
  67. package/dist/touching.d.ts +2 -2
  68. package/dist/touching.d.ts.map +1 -1
  69. package/dist/touching.js +7 -4
  70. package/dist/touching.js.map +1 -1
  71. package/dist/units.js +1 -1
  72. package/dist/units.js.map +1 -1
  73. package/dist/upgrade.d.ts +2 -2
  74. package/dist/upgrade.js.map +1 -1
  75. package/dist/validation.d.ts +33 -6
  76. package/dist/validation.d.ts.map +1 -1
  77. package/dist/validation.js +806 -39
  78. package/dist/validation.js.map +1 -1
  79. package/package.json +4 -2
  80. package/schema/fixtures/invalid/association-without-relationship.scene.json +69 -0
  81. package/schema/fixtures/invalid/binding-kind.scene.json +14 -0
  82. package/schema/fixtures/invalid/command-zero-step.scene.json +105 -0
  83. package/schema/fixtures/invalid/empty-name.scene.json +30 -0
  84. package/schema/fixtures/invalid/expected.json +70 -0
  85. package/schema/fixtures/invalid/extension-not-namespaced.scene.json +10 -0
  86. package/schema/fixtures/invalid/extension-prototype-key.scene.json +12 -0
  87. package/schema/fixtures/invalid/missing-document-type.scene.json +6 -0
  88. package/schema/fixtures/invalid/non-string-label.scene.json +32 -0
  89. package/schema/fixtures/invalid/underlay-opacity.scene.json +17 -0
  90. package/schema/fixtures/invalid/unknown-component-kind.scene.json +29 -0
  91. package/schema/fixtures/invalid/unknown-relationship.scene.json +63 -0
  92. package/schema/fixtures/invalid/unknown-root-field.scene.json +8 -0
  93. package/schema/fixtures/invalid/unsupported-version.scene.json +7 -0
  94. package/schema/fixtures/invalid/view-rotation.scene.json +139 -0
  95. package/schema/fixtures/invalid/writable-string.scene.json +93 -0
  96. package/schema/fixtures/invalid/writable-without-limits.scene.json +100 -0
  97. package/schema/fixtures/invalid/zero-scale.scene.json +29 -0
  98. package/schema/fixtures/migration/README.md +18 -0
  99. package/schema/fixtures/migration/v1-demo.scene.json +160 -0
  100. package/schema/fixtures/migration/v1-demo.v4.json +198 -0
  101. package/schema/fixtures/migration/v2-demo.scene.json +244 -0
  102. package/schema/fixtures/migration/v2-demo.v4.json +245 -0
  103. package/schema/fixtures/migration/v2-generated-12.scene.json +473 -0
  104. package/schema/fixtures/migration/v2-generated-12.v4.json +474 -0
  105. package/schema/fixtures/migration/v3-demo.scene.json +244 -0
  106. package/schema/fixtures/migration/v3-demo.v4.json +245 -0
  107. package/schema/fixtures/migration/v3-generated-12.scene.json +473 -0
  108. package/schema/fixtures/migration/v3-generated-12.v4.json +474 -0
  109. package/schema/fixtures/migration/v3-mostly-connected-plant.scene.json +386 -0
  110. package/schema/fixtures/migration/v3-mostly-connected-plant.v4.json +387 -0
  111. package/schema/fixtures/migration/v3-open-joints-plant.scene.json +288 -0
  112. package/schema/fixtures/migration/v3-open-joints-plant.v4.json +289 -0
  113. package/schema/fixtures/migration/v3-unconnected-plant.scene.json +14 -0
  114. package/schema/fixtures/migration/v3-unconnected-plant.v4.json +276 -0
  115. package/schema/fixtures/projection/acquisition.plan.json +50 -0
  116. package/schema/fixtures/projection/control-line.plan.json +86 -0
  117. package/schema/fixtures/valid/acquisition.scene.json +117 -0
  118. package/schema/fixtures/valid/associations.scene.json +79 -0
  119. package/schema/fixtures/valid/commands.scene.json +155 -0
  120. package/schema/fixtures/valid/control-line.scene.json +210 -0
  121. package/schema/fixtures/valid/empty.scene.json +7 -0
  122. package/schema/fixtures/valid/identity-and-extensions.scene.json +96 -0
  123. package/schema/fixtures/valid/tank-valve-line.scene.json +89 -0
  124. package/schema/fixtures/valid/views.scene.json +139 -0
  125. package/schema/fixtures/validator-only/association-id-reuses-connection.scene.json +70 -0
  126. package/schema/fixtures/validator-only/association-unknown-component.scene.json +70 -0
  127. package/schema/fixtures/validator-only/command-max-below-min.scene.json +104 -0
  128. package/schema/fixtures/validator-only/command-out-of-type-range.scene.json +97 -0
  129. package/schema/fixtures/validator-only/connection-domain-mismatch.scene.json +63 -0
  130. package/schema/fixtures/validator-only/credential-in-connection.scene.json +66 -0
  131. package/schema/fixtures/validator-only/credential-in-extension.scene.json +14 -0
  132. package/schema/fixtures/validator-only/credential-label.scene.json +32 -0
  133. package/schema/fixtures/validator-only/duplicate-component-id.scene.json +50 -0
  134. package/schema/fixtures/validator-only/endpoint-with-credentials.scene.json +74 -0
  135. package/schema/fixtures/validator-only/expected.json +66 -0
  136. package/schema/fixtures/validator-only/modbus-coil-float.scene.json +100 -0
  137. package/schema/fixtures/validator-only/non-unit-rotation.scene.json +29 -0
  138. package/schema/fixtures/validator-only/unknown-data-source.scene.json +100 -0
  139. package/schema/fixtures/validator-only/unknown-port.scene.json +62 -0
  140. package/schema/fixtures/validator-only/unregistered-host-type.scene.json +29 -0
  141. package/schema/fixtures/validator-only/view-unknown-component.scene.json +143 -0
  142. package/schema/industrial-scene.v4.schema.json +365 -0
@@ -0,0 +1,143 @@
1
+ {
2
+ "schemaVersion": 4,
3
+ "documentType": "industrial.scene",
4
+ "units": "m",
5
+ "components": [
6
+ {
7
+ "id": "T1",
8
+ "type": "tank",
9
+ "position": {
10
+ "x": 0,
11
+ "y": 0.5,
12
+ "z": 0
13
+ },
14
+ "rotation": {
15
+ "x": 0,
16
+ "y": 0,
17
+ "z": 0,
18
+ "w": 1
19
+ },
20
+ "scale": {
21
+ "x": 1,
22
+ "y": 1,
23
+ "z": 1
24
+ },
25
+ "properties": {}
26
+ },
27
+ {
28
+ "id": "V1",
29
+ "type": "valve",
30
+ "position": {
31
+ "x": 2,
32
+ "y": 0.5,
33
+ "z": 0
34
+ },
35
+ "rotation": {
36
+ "x": 0,
37
+ "y": 0,
38
+ "z": 0,
39
+ "w": 1
40
+ },
41
+ "scale": {
42
+ "x": 1,
43
+ "y": 1,
44
+ "z": 1
45
+ },
46
+ "properties": {}
47
+ }
48
+ ],
49
+ "connections": [
50
+ {
51
+ "id": "c",
52
+ "from": {
53
+ "instanceId": "T1",
54
+ "portId": "outlet"
55
+ },
56
+ "to": {
57
+ "instanceId": "V1",
58
+ "portId": "in"
59
+ }
60
+ }
61
+ ],
62
+ "associations": [
63
+ {
64
+ "id": "a1",
65
+ "relationship": "feeds",
66
+ "from": "T1",
67
+ "to": "V1",
68
+ "properties": {
69
+ "note": "gravity feed"
70
+ }
71
+ },
72
+ {
73
+ "id": "a2",
74
+ "relationship": "com.example.supervises",
75
+ "from": "V1",
76
+ "to": "T1"
77
+ }
78
+ ],
79
+ "views": {
80
+ "process": {
81
+ "symbols": {
82
+ "T1": {
83
+ "x": 40,
84
+ "y": 120
85
+ },
86
+ "V1": {
87
+ "x": 160,
88
+ "y": 120,
89
+ "rotation": 90
90
+ },
91
+ "P9": {
92
+ "x": 0,
93
+ "y": 0
94
+ }
95
+ },
96
+ "routes": {
97
+ "c": {
98
+ "points": [
99
+ [
100
+ 60,
101
+ 120
102
+ ],
103
+ [
104
+ 110,
105
+ 120
106
+ ],
107
+ [
108
+ 110,
109
+ 130
110
+ ],
111
+ [
112
+ 150,
113
+ 130
114
+ ]
115
+ ]
116
+ }
117
+ }
118
+ },
119
+ "electrical": {
120
+ "symbols": {
121
+ "V1": {
122
+ "x": 0,
123
+ "y": 0,
124
+ "hidden": true
125
+ }
126
+ },
127
+ "routes": {
128
+ "a1": {
129
+ "points": [
130
+ [
131
+ 0,
132
+ 0
133
+ ],
134
+ [
135
+ 10,
136
+ 0
137
+ ]
138
+ ]
139
+ }
140
+ }
141
+ }
142
+ }
143
+ }
@@ -0,0 +1,365 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "urn:sakibcoolz:3d-scada-sdk:industrial-scene:4",
4
+ "title": "Industrial scene document, schema version 4",
5
+ "description": "Structure of a scene file written by @sakibcoolz/core serializeScene (ADR-0021). The TypeScript validateScene is authoritative and also checks what JSON Schema cannot express: unit-length rotations, references between components, ports, connections and bindings, port compatibility and occupancy, scale policy, assembly cycles, units per quantity, credential-like key names (SECRET_FIELD), and the extension depth (16) and value (10,000 per document) budgets. Anything validateScene accepts with the default limits (defaultSceneLimits) also passes this schema; hosts that raise the limits must not rely on it. Older files (versions 1 to 3) are accepted by validateScene and migrated; this schema describes version 4 only.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": ["schemaVersion", "documentType", "units", "components", "connections"],
9
+ "properties": {
10
+ "schemaVersion": { "const": 4 },
11
+ "documentType": { "const": "industrial.scene" },
12
+ "units": { "const": "m", "description": "Lengths are metres; right-handed, Y-up." },
13
+ "project": { "$ref": "#/$defs/project" },
14
+ "components": { "type": "array", "maxItems": 10000, "items": { "$ref": "#/$defs/component" } },
15
+ "connections": { "type": "array", "maxItems": 20000, "items": { "$ref": "#/$defs/connection" } },
16
+ "associations": {
17
+ "description": "Port-less logical links between components, such as a PLC that controls a drive (ADR-0023). Never drawn as wiring.",
18
+ "type": "array",
19
+ "maxItems": 20000,
20
+ "items": { "$ref": "#/$defs/association" }
21
+ },
22
+ "dataSources": {
23
+ "description": "Where values come from: a PLC, drive or gateway the host reaches (ADR-0024). Never credentials.",
24
+ "type": "array",
25
+ "maxItems": 1000,
26
+ "items": { "$ref": "#/$defs/dataSource" }
27
+ },
28
+ "runtimeVariables": {
29
+ "description": "Typed tags: data type, unit, read-only access and a protocol-typed address (ADR-0024). Values arrive as observations, never in the document.",
30
+ "type": "array",
31
+ "maxItems": 20000,
32
+ "items": { "$ref": "#/$defs/runtimeVariable" }
33
+ },
34
+ "tagBindings": { "type": "array", "maxItems": 20000, "items": { "$ref": "#/$defs/tagBinding" } },
35
+ "underlay": { "$ref": "#/$defs/underlay" },
36
+ "views": {
37
+ "description": "2D layouts per view (ADR-0026): symbol placements by component id and routes by connection or association id, in drawing units (1 mm, x right, y down). Layout only; the model stays in components and connections.",
38
+ "type": "object",
39
+ "additionalProperties": false,
40
+ "properties": { "process": { "$ref": "#/$defs/viewLayout" }, "electrical": { "$ref": "#/$defs/viewLayout" } }
41
+ },
42
+ "extensions": { "$ref": "#/$defs/extensions" }
43
+ },
44
+ "$defs": {
45
+ "id": { "type": "string", "minLength": 1, "maxLength": 128 },
46
+ "text": { "type": "string", "minLength": 1, "maxLength": 1024 },
47
+ "vector3": {
48
+ "type": "object",
49
+ "additionalProperties": false,
50
+ "required": ["x", "y", "z"],
51
+ "properties": { "x": { "type": "number" }, "y": { "type": "number" }, "z": { "type": "number" } }
52
+ },
53
+ "positiveVector3": {
54
+ "type": "object",
55
+ "additionalProperties": false,
56
+ "required": ["x", "y", "z"],
57
+ "properties": {
58
+ "x": { "type": "number", "exclusiveMinimum": 0 },
59
+ "y": { "type": "number", "exclusiveMinimum": 0 },
60
+ "z": { "type": "number", "exclusiveMinimum": 0 }
61
+ }
62
+ },
63
+ "quaternion": {
64
+ "description": "Unit quaternion (length 1 within 1e-6, checked by validateScene).",
65
+ "type": "object",
66
+ "additionalProperties": false,
67
+ "required": ["x", "y", "z", "w"],
68
+ "properties": {
69
+ "x": { "type": "number" },
70
+ "y": { "type": "number" },
71
+ "z": { "type": "number" },
72
+ "w": { "type": "number" }
73
+ }
74
+ },
75
+ "project": {
76
+ "type": "object",
77
+ "additionalProperties": false,
78
+ "properties": {
79
+ "id": { "$ref": "#/$defs/id" },
80
+ "name": { "$ref": "#/$defs/text" },
81
+ "revision": { "$ref": "#/$defs/text" },
82
+ "description": { "$ref": "#/$defs/text" }
83
+ }
84
+ },
85
+ "componentKind": {
86
+ "description": "A built-in kind, or a namespaced host type such as com.example.press (ADR-0022). Whether a host type is registered is checked by validateScene (resolveType).",
87
+ "anyOf": [
88
+ { "enum": ["tank", "conicalTank", "horizontalTank", "sphericalTank", "pool", "pipe", "elbow", "tee", "valve", "reducer", "coupler", "pump", "sensor", "motor"] },
89
+ { "type": "string", "maxLength": 128, "pattern": "^[A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?(\\.[A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?)+$" }
90
+ ]
91
+ },
92
+ "component": {
93
+ "type": "object",
94
+ "additionalProperties": false,
95
+ "required": ["id", "type", "position", "rotation", "scale", "properties"],
96
+ "properties": {
97
+ "id": { "$ref": "#/$defs/id" },
98
+ "name": { "$ref": "#/$defs/text" },
99
+ "type": { "$ref": "#/$defs/componentKind" },
100
+ "typeVersion": { "$ref": "#/$defs/text" },
101
+ "manufacturer": { "$ref": "#/$defs/text" },
102
+ "model": { "$ref": "#/$defs/text" },
103
+ "parentId": { "$ref": "#/$defs/id", "description": "Assembly parent (ADR-0008)." },
104
+ "position": { "$ref": "#/$defs/vector3", "description": "Metres, world space." },
105
+ "rotation": { "$ref": "#/$defs/quaternion" },
106
+ "scale": { "$ref": "#/$defs/positiveVector3", "description": "Components with ports keep 1, 1, 1 (checked by validateScene)." },
107
+ "properties": {
108
+ "description": "Engineering and display properties; the component definition validates names and ranges.",
109
+ "type": "object",
110
+ "maxProperties": 64,
111
+ "additionalProperties": { "anyOf": [{ "type": "string", "maxLength": 1024 }, { "type": "number" }, { "type": "boolean" }] }
112
+ },
113
+ "labels": {
114
+ "description": "Identification and metadata tags. Never credentials and never live values.",
115
+ "type": "object",
116
+ "maxProperties": 64,
117
+ "propertyNames": { "minLength": 1, "maxLength": 128 },
118
+ "additionalProperties": { "type": "string", "maxLength": 1024 }
119
+ },
120
+ "extensions": { "$ref": "#/$defs/extensions" }
121
+ }
122
+ },
123
+ "endpoint": {
124
+ "type": "object",
125
+ "additionalProperties": false,
126
+ "required": ["instanceId", "portId"],
127
+ "properties": { "instanceId": { "$ref": "#/$defs/id" }, "portId": { "$ref": "#/$defs/id" } }
128
+ },
129
+ "relationship": {
130
+ "description": "A built-in relationship, or a namespaced host relationship such as com.example.supervises (ADR-0023).",
131
+ "anyOf": [
132
+ { "enum": ["controls", "drives", "measures", "feeds", "communicates", "wired", "associated"] },
133
+ { "type": "string", "maxLength": 128, "pattern": "^[A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?(\\.[A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?)+$" }
134
+ ]
135
+ },
136
+ "edgeProperties": {
137
+ "description": "Edge data such as cable type, cross-section or length (ADR-0023). Credential-like names are rejected by validateScene.",
138
+ "type": "object",
139
+ "maxProperties": 64,
140
+ "additionalProperties": { "anyOf": [{ "type": "string", "maxLength": 1024 }, { "type": "number" }, { "type": "boolean" }] }
141
+ },
142
+ "connection": {
143
+ "type": "object",
144
+ "additionalProperties": false,
145
+ "required": ["id", "from", "to"],
146
+ "properties": {
147
+ "id": { "$ref": "#/$defs/id" },
148
+ "domain": {
149
+ "description": "The ports' domain (ADR-0023); validateScene checks that it matches them. Derived from the ports when absent.",
150
+ "enum": ["fluid", "mechanical", "power", "signal", "network", "electrical"]
151
+ },
152
+ "relationship": { "$ref": "#/$defs/relationship" },
153
+ "from": { "$ref": "#/$defs/endpoint" },
154
+ "to": { "$ref": "#/$defs/endpoint" },
155
+ "properties": { "$ref": "#/$defs/edgeProperties" }
156
+ }
157
+ },
158
+ "dataSource": {
159
+ "type": "object",
160
+ "additionalProperties": false,
161
+ "required": ["id", "protocol"],
162
+ "properties": {
163
+ "id": { "$ref": "#/$defs/id" },
164
+ "name": { "$ref": "#/$defs/text" },
165
+ "protocol": {
166
+ "description": "A built-in protocol, or a namespaced host protocol such as com.vendor.bus.",
167
+ "anyOf": [
168
+ { "enum": ["opcua", "modbus-tcp", "modbus-rtu", "host"] },
169
+ { "type": "string", "maxLength": 128, "pattern": "^[A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?(\\.[A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?)+$" }
170
+ ]
171
+ },
172
+ "deviceId": { "$ref": "#/$defs/id" },
173
+ "endpointRef": { "description": "Opaque reference the host resolves. validateScene rejects URLs with user info.", "$ref": "#/$defs/text" },
174
+ "properties": { "$ref": "#/$defs/edgeProperties" }
175
+ }
176
+ },
177
+ "runtimeVariable": {
178
+ "type": "object",
179
+ "additionalProperties": false,
180
+ "required": ["id", "dataType", "access"],
181
+ "properties": {
182
+ "id": { "description": "The tag id observations and bindings carry.", "$ref": "#/$defs/id" },
183
+ "name": { "$ref": "#/$defs/text" },
184
+ "componentId": { "$ref": "#/$defs/id" },
185
+ "dataType": { "enum": ["bool", "int16", "uint16", "int32", "uint32", "float32", "float64", "string"] },
186
+ "unit": { "type": "string", "maxLength": 32 },
187
+ "access": { "description": "\"readWrite\" allows a confirmed command request to the host (ADR-0029); the SDK never writes.", "enum": ["read", "readWrite"] },
188
+ "source": {
189
+ "type": "object",
190
+ "additionalProperties": false,
191
+ "required": ["dataSourceId"],
192
+ "properties": {
193
+ "dataSourceId": { "$ref": "#/$defs/id" },
194
+ "variable": { "$ref": "#/$defs/text" },
195
+ "address": {
196
+ "description": "Typed by the data source's protocol (OPC UA nodeId, Modbus area/address/unitId…); validateScene checks it against that protocol.",
197
+ "type": "object"
198
+ }
199
+ }
200
+ },
201
+ "scaling": {
202
+ "description": "How the host converts raw values; descriptive only.",
203
+ "type": "object",
204
+ "additionalProperties": false,
205
+ "required": ["kind", "rawMin", "rawMax", "min", "max"],
206
+ "properties": {
207
+ "kind": { "const": "linear" },
208
+ "rawMin": { "type": "number" },
209
+ "rawMax": { "type": "number" },
210
+ "min": { "type": "number" },
211
+ "max": { "type": "number" }
212
+ }
213
+ },
214
+ "command": {
215
+ "description": "Limits of a readWrite variable (ADR-0029); the host's gateway must enforce them too. validateScene also checks min < max and that both fit the data type.",
216
+ "type": "object",
217
+ "additionalProperties": false,
218
+ "properties": {
219
+ "min": { "type": "number" },
220
+ "max": { "type": "number" },
221
+ "step": { "type": "number", "exclusiveMinimum": 0 },
222
+ "confirm": { "$ref": "#/$defs/text" }
223
+ }
224
+ }
225
+ },
226
+ "allOf": [
227
+ {
228
+ "if": { "required": ["access"], "properties": { "access": { "const": "readWrite" } } },
229
+ "then": { "required": ["command", "source"], "properties": { "command": true, "source": true, "dataType": { "not": { "const": "string" } } } },
230
+ "else": { "not": { "required": ["command"], "properties": { "command": true } } }
231
+ },
232
+ {
233
+ "if": { "required": ["access", "dataType"], "properties": { "access": { "const": "readWrite" }, "dataType": { "not": { "const": "bool" } } } },
234
+ "then": { "properties": { "command": { "type": "object", "required": ["min", "max"], "properties": { "min": true, "max": true } } } }
235
+ },
236
+ {
237
+ "if": { "required": ["dataType"], "properties": { "dataType": { "const": "bool" } } },
238
+ "then": { "properties": { "command": { "not": { "anyOf": [{ "type": "object", "required": ["min"], "properties": { "min": true } }, { "type": "object", "required": ["max"], "properties": { "max": true } }] } } } }
239
+ }
240
+ ]
241
+ },
242
+ "association": {
243
+ "type": "object",
244
+ "additionalProperties": false,
245
+ "required": ["id", "relationship", "from", "to"],
246
+ "properties": {
247
+ "id": { "$ref": "#/$defs/id" },
248
+ "relationship": { "$ref": "#/$defs/relationship" },
249
+ "from": { "$ref": "#/$defs/id" },
250
+ "to": { "$ref": "#/$defs/id" },
251
+ "properties": { "$ref": "#/$defs/edgeProperties" }
252
+ }
253
+ },
254
+ "tagBinding": {
255
+ "description": "Authored link from a host tag to a component property or a connection's flow (ADR-0006).",
256
+ "oneOf": [
257
+ {
258
+ "type": "object",
259
+ "additionalProperties": false,
260
+ "required": ["id", "tagId", "kind", "instanceId", "property"],
261
+ "properties": {
262
+ "id": { "$ref": "#/$defs/id" },
263
+ "tagId": { "$ref": "#/$defs/id" },
264
+ "kind": { "const": "property" },
265
+ "instanceId": { "$ref": "#/$defs/id" },
266
+ "property": { "$ref": "#/$defs/id" },
267
+ "unit": { "type": "string" }
268
+ }
269
+ },
270
+ {
271
+ "type": "object",
272
+ "additionalProperties": false,
273
+ "required": ["id", "tagId", "kind", "connectionId"],
274
+ "properties": {
275
+ "id": { "$ref": "#/$defs/id" },
276
+ "tagId": { "$ref": "#/$defs/id" },
277
+ "kind": { "const": "flow" },
278
+ "connectionId": { "$ref": "#/$defs/id" },
279
+ "unit": { "type": "string" }
280
+ }
281
+ }
282
+ ]
283
+ },
284
+ "viewCoordinate": { "type": "number", "minimum": -1000000, "maximum": 1000000 },
285
+ "viewLayout": {
286
+ "type": "object",
287
+ "additionalProperties": false,
288
+ "properties": {
289
+ "symbols": {
290
+ "type": "object",
291
+ "maxProperties": 10000,
292
+ "propertyNames": { "$ref": "#/$defs/id" },
293
+ "additionalProperties": {
294
+ "type": "object",
295
+ "additionalProperties": false,
296
+ "required": ["x", "y"],
297
+ "properties": {
298
+ "x": { "$ref": "#/$defs/viewCoordinate" },
299
+ "y": { "$ref": "#/$defs/viewCoordinate" },
300
+ "rotation": { "enum": [0, 90, 180, 270] },
301
+ "hidden": { "const": true }
302
+ }
303
+ }
304
+ },
305
+ "routes": {
306
+ "type": "object",
307
+ "maxProperties": 40000,
308
+ "propertyNames": { "$ref": "#/$defs/id" },
309
+ "additionalProperties": {
310
+ "type": "object",
311
+ "additionalProperties": false,
312
+ "required": ["points"],
313
+ "properties": {
314
+ "points": {
315
+ "type": "array",
316
+ "minItems": 2,
317
+ "maxItems": 1000,
318
+ "items": { "type": "array", "prefixItems": [{ "$ref": "#/$defs/viewCoordinate" }, { "$ref": "#/$defs/viewCoordinate" }], "items": false, "minItems": 2 }
319
+ }
320
+ }
321
+ }
322
+ }
323
+ }
324
+ },
325
+ "underlay": {
326
+ "description": "Sanitized SVG reference drawing on the ground (ADR-0012); at most 512 KiB of UTF-8.",
327
+ "type": "object",
328
+ "additionalProperties": false,
329
+ "required": ["svg", "position", "width", "rotation", "opacity"],
330
+ "properties": {
331
+ "svg": { "type": "string", "maxLength": 524288 },
332
+ "position": {
333
+ "type": "object",
334
+ "additionalProperties": false,
335
+ "required": ["x", "z"],
336
+ "properties": { "x": { "type": "number" }, "z": { "type": "number" } }
337
+ },
338
+ "width": { "type": "number", "exclusiveMinimum": 0, "maximum": 1000 },
339
+ "rotation": { "type": "number", "description": "Degrees about +Y." },
340
+ "opacity": { "type": "number", "minimum": 0, "maximum": 1 }
341
+ }
342
+ },
343
+ "extensions": {
344
+ "description": "Host or library data keyed by reverse-DNS namespace, preserved and never interpreted by core.",
345
+ "type": "object",
346
+ "propertyNames": { "pattern": "^[A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?(\\.[A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?)+$" },
347
+ "additionalProperties": { "$ref": "#/$defs/json" }
348
+ },
349
+ "json": {
350
+ "description": "Plain JSON with strings of at most 1024 characters and no prototype keys.",
351
+ "anyOf": [
352
+ { "type": "null" },
353
+ { "type": "boolean" },
354
+ { "type": "number" },
355
+ { "type": "string", "maxLength": 1024 },
356
+ { "type": "array", "items": { "$ref": "#/$defs/json" } },
357
+ {
358
+ "type": "object",
359
+ "propertyNames": { "not": { "enum": ["__proto__", "constructor", "prototype"] } },
360
+ "additionalProperties": { "$ref": "#/$defs/json" }
361
+ }
362
+ ]
363
+ }
364
+ }
365
+ }