@jsonforms/core 2.5.2-alpha.0 → 3.0.0-alpha.2

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 (273) hide show
  1. package/README.md +1 -1
  2. package/docs/assets/js/search.json +1 -1
  3. package/docs/enums/ruleeffect.html +4 -4
  4. package/docs/globals.html +1061 -1120
  5. package/docs/index.html +64 -91
  6. package/docs/interfaces/addcellrendereraction.html +3 -3
  7. package/docs/interfaces/addrendereraction.html +3 -3
  8. package/docs/interfaces/adduischemaaction.html +3 -3
  9. package/docs/interfaces/andcondition.html +2 -2
  10. package/docs/interfaces/arraycontrolprops.html +22 -22
  11. package/docs/interfaces/arraylayoutprops.html +22 -22
  12. package/docs/interfaces/categorization.html +5 -5
  13. package/docs/interfaces/category.html +5 -5
  14. package/docs/interfaces/cellprops.html +14 -14
  15. package/docs/interfaces/combinatorrendererprops.html +13 -13
  16. package/docs/interfaces/combinatorsubschemarenderinfo.html +3 -3
  17. package/docs/interfaces/composablecondition.html +2 -2
  18. package/docs/interfaces/condition.html +1 -1
  19. package/docs/interfaces/controlelement.html +5 -5
  20. package/docs/interfaces/controlprops.html +17 -17
  21. package/docs/interfaces/controlstate.html +2 -2
  22. package/docs/interfaces/controlwithdetailprops.html +18 -18
  23. package/docs/interfaces/dispatchcellprops.html +13 -13
  24. package/docs/interfaces/dispatchcellstateprops.html +13 -13
  25. package/docs/interfaces/dispatchpropsofarraycontrol.html +4 -4
  26. package/docs/interfaces/dispatchpropsofcontrol.html +1 -1
  27. package/docs/interfaces/dispatchpropsofmultienumcontrol.html +2 -2
  28. package/docs/interfaces/enumcellprops.html +15 -15
  29. package/docs/interfaces/enumoption.html +2 -2
  30. package/docs/interfaces/formatted.html +2 -2
  31. package/docs/interfaces/grouplayout.html +5 -5
  32. package/docs/interfaces/horizontallayout.html +4 -4
  33. package/docs/interfaces/initaction.html +6 -6
  34. package/docs/interfaces/initactionoptions.html +3 -17
  35. package/docs/interfaces/jsonformscellrendererregistryentry.html +2 -2
  36. package/docs/interfaces/jsonformscore.html +7 -21
  37. package/docs/interfaces/jsonformsdefaultdataregistryentry.html +2 -2
  38. package/docs/interfaces/jsonformsextendedstate.html +1 -1
  39. package/docs/interfaces/{jsonformslocalestate.html → jsonformsi18nstate.html} +20 -20
  40. package/docs/interfaces/jsonformsprops.html +9 -24
  41. package/docs/interfaces/jsonformsrendererregistryentry.html +2 -2
  42. package/docs/interfaces/jsonformsstate.html +1 -1
  43. package/docs/interfaces/jsonformsstore.html +5 -5
  44. package/docs/interfaces/jsonformssubstates.html +18 -8
  45. package/docs/interfaces/jsonformsuischemaregistryentry.html +2 -2
  46. package/docs/interfaces/labeldescription.html +2 -2
  47. package/docs/interfaces/labelelement.html +4 -4
  48. package/docs/interfaces/layout.html +4 -4
  49. package/docs/interfaces/layoutprops.html +10 -10
  50. package/docs/interfaces/leafcondition.html +3 -3
  51. package/docs/interfaces/orcondition.html +2 -2
  52. package/docs/interfaces/ownpropsofcell.html +10 -10
  53. package/docs/interfaces/ownpropsofcontrol.html +9 -9
  54. package/docs/interfaces/ownpropsofenum.html +1 -1
  55. package/docs/interfaces/ownpropsofenumcell.html +11 -11
  56. package/docs/interfaces/ownpropsofjsonformsrenderer.html +8 -8
  57. package/docs/interfaces/ownpropsoflayout.html +9 -9
  58. package/docs/interfaces/ownpropsofmasterlistitem.html +6 -6
  59. package/docs/interfaces/ownpropsofrenderer.html +8 -8
  60. package/docs/interfaces/registerdefaultdataaction.html +3 -3
  61. package/docs/interfaces/removecellrendereraction.html +3 -3
  62. package/docs/interfaces/removerendereraction.html +3 -3
  63. package/docs/interfaces/removeuischemaaction.html +2 -2
  64. package/docs/interfaces/rendererprops.html +9 -9
  65. package/docs/interfaces/rule.html +2 -2
  66. package/docs/interfaces/schemabasedcondition.html +3 -3
  67. package/docs/interfaces/scopable.html +1 -1
  68. package/docs/interfaces/setajvaction.html +3 -3
  69. package/docs/interfaces/setconfigaction.html +2 -2
  70. package/docs/interfaces/setlocaleaction.html +3 -3
  71. package/docs/interfaces/setschemaaction.html +2 -2
  72. package/docs/interfaces/{setlocalizeduischemasaction.html → settranslatoraction.html} +29 -15
  73. package/docs/interfaces/setuischemaaction.html +2 -2
  74. package/docs/interfaces/setvalidationmodeaction.html +2 -2
  75. package/docs/interfaces/statepropsofarraycontrol.html +18 -18
  76. package/docs/interfaces/statepropsofarraylayout.html +18 -18
  77. package/docs/interfaces/statepropsofcell.html +13 -13
  78. package/docs/interfaces/statepropsofcombinator.html +12 -12
  79. package/docs/interfaces/statepropsofcontrol.html +16 -16
  80. package/docs/interfaces/statepropsofcontrolwithdetail.html +17 -17
  81. package/docs/interfaces/statepropsofenumcell.html +14 -14
  82. package/docs/interfaces/statepropsofjsonformsrenderer.html +9 -23
  83. package/docs/interfaces/statepropsoflayout.html +10 -10
  84. package/docs/interfaces/statepropsofmasteritem.html +7 -7
  85. package/docs/interfaces/statepropsofrenderer.html +9 -9
  86. package/docs/interfaces/statepropsofscopedrenderer.html +12 -12
  87. package/docs/interfaces/uischemaelement.html +3 -3
  88. package/docs/interfaces/unregisterdefaultdataaction.html +2 -2
  89. package/docs/interfaces/updateaction.html +3 -3
  90. package/docs/interfaces/updatecoreaction.html +6 -6
  91. package/docs/interfaces/updateerrorsaction.html +2 -2
  92. package/docs/interfaces/{setlocalizedschemasaction.html → updatei18naction.html} +43 -15
  93. package/docs/interfaces/verticallayout.html +4 -4
  94. package/docs/interfaces/withclassname.html +1 -1
  95. package/lib/Helpers.d.ts +5 -0
  96. package/lib/Helpers.js +33 -0
  97. package/lib/Helpers.js.map +1 -0
  98. package/lib/actions/actions.d.ts +181 -0
  99. package/lib/actions/actions.js +173 -0
  100. package/lib/actions/actions.js.map +1 -0
  101. package/lib/actions/index.d.ts +1 -180
  102. package/lib/actions/index.js +26 -122
  103. package/lib/actions/index.js.map +1 -1
  104. package/lib/configDefault.js +2 -1
  105. package/lib/configDefault.js.map +1 -1
  106. package/lib/generators/Generate.d.ts +6 -0
  107. package/lib/generators/Generate.js +35 -0
  108. package/lib/generators/Generate.js.map +1 -0
  109. package/lib/generators/index.d.ts +3 -10
  110. package/lib/generators/index.js +28 -9
  111. package/lib/generators/index.js.map +1 -1
  112. package/lib/generators/schema.d.ts +1 -1
  113. package/lib/generators/schema.js +3 -1
  114. package/lib/generators/schema.js.map +1 -1
  115. package/lib/generators/uischema.d.ts +1 -2
  116. package/lib/generators/uischema.js +12 -10
  117. package/lib/generators/uischema.js.map +1 -1
  118. package/lib/i18n/i18nTypes.d.ts +15 -0
  119. package/lib/i18n/i18nTypes.js +3 -0
  120. package/lib/i18n/i18nTypes.js.map +1 -0
  121. package/lib/i18n/i18nUtil.d.ts +11 -0
  122. package/lib/i18n/i18nUtil.js +58 -0
  123. package/lib/i18n/i18nUtil.js.map +1 -0
  124. package/lib/i18n/index.d.ts +2 -0
  125. package/lib/i18n/index.js +6 -0
  126. package/lib/i18n/index.js.map +1 -0
  127. package/lib/index.d.ts +6 -18
  128. package/lib/index.js +10 -15
  129. package/lib/index.js.map +1 -1
  130. package/lib/jsonforms-core.js +9 -12
  131. package/lib/jsonforms-core.js.map +1 -1
  132. package/lib/models/draft4.js +2 -1
  133. package/lib/models/draft4.js.map +1 -1
  134. package/lib/models/index.d.ts +5 -0
  135. package/lib/models/index.js +33 -0
  136. package/lib/models/index.js.map +1 -0
  137. package/lib/models/jsonSchema.js +24 -0
  138. package/lib/models/jsonSchema.js.map +1 -1
  139. package/lib/models/uischema.js +29 -2
  140. package/lib/models/uischema.js.map +1 -1
  141. package/lib/reducers/cells.d.ts +1 -1
  142. package/lib/reducers/cells.js +27 -1
  143. package/lib/reducers/cells.js.map +1 -1
  144. package/lib/reducers/config.d.ts +1 -1
  145. package/lib/reducers/config.js +5 -3
  146. package/lib/reducers/config.js.map +1 -1
  147. package/lib/reducers/core.d.ts +5 -7
  148. package/lib/reducers/core.js +78 -63
  149. package/lib/reducers/core.js.map +1 -1
  150. package/lib/reducers/default-data.d.ts +1 -1
  151. package/lib/reducers/default-data.js +6 -3
  152. package/lib/reducers/default-data.js.map +1 -1
  153. package/lib/reducers/i18n.d.ts +8 -11
  154. package/lib/reducers/i18n.js +40 -23
  155. package/lib/reducers/i18n.js.map +1 -1
  156. package/lib/reducers/index.d.ts +9 -49
  157. package/lib/reducers/index.js +33 -91
  158. package/lib/reducers/index.js.map +1 -1
  159. package/lib/reducers/reducers.d.ts +37 -0
  160. package/lib/reducers/reducers.js +107 -0
  161. package/lib/reducers/reducers.js.map +1 -0
  162. package/lib/reducers/renderers.d.ts +1 -1
  163. package/lib/reducers/renderers.js +27 -1
  164. package/lib/reducers/renderers.js.map +1 -1
  165. package/lib/reducers/selectors.d.ts +15 -0
  166. package/lib/reducers/selectors.js +56 -0
  167. package/lib/reducers/selectors.js.map +1 -0
  168. package/lib/reducers/uischemas.d.ts +2 -2
  169. package/lib/reducers/uischemas.js +9 -6
  170. package/lib/reducers/uischemas.js.map +1 -1
  171. package/lib/store.d.ts +5 -8
  172. package/lib/store.js +24 -0
  173. package/lib/store.js.map +1 -1
  174. package/lib/testers/index.d.ts +1 -204
  175. package/lib/testers/index.js +3 -376
  176. package/lib/testers/index.js.map +1 -1
  177. package/lib/testers/testers.d.ts +203 -0
  178. package/lib/testers/testers.js +421 -0
  179. package/lib/testers/testers.js.map +1 -0
  180. package/lib/util/Formatted.js +24 -0
  181. package/lib/util/Formatted.js.map +1 -1
  182. package/lib/util/array.js +25 -0
  183. package/lib/util/array.js.map +1 -1
  184. package/lib/util/cell.d.ts +11 -4
  185. package/lib/util/cell.js +61 -17
  186. package/lib/util/cell.js.map +1 -1
  187. package/lib/util/combinators.d.ts +2 -3
  188. package/lib/util/combinators.js +5 -2
  189. package/lib/util/combinators.js.map +1 -1
  190. package/lib/util/ids.js +8 -4
  191. package/lib/util/ids.js.map +1 -1
  192. package/lib/util/index.d.ts +11 -45
  193. package/lib/util/index.js +14 -104
  194. package/lib/util/index.js.map +1 -1
  195. package/lib/util/label.d.ts +1 -2
  196. package/lib/util/label.js +7 -4
  197. package/lib/util/label.js.map +1 -1
  198. package/lib/util/path.d.ts +2 -1
  199. package/lib/util/path.js +12 -6
  200. package/lib/util/path.js.map +1 -1
  201. package/lib/util/renderer.d.ts +17 -17
  202. package/lib/util/renderer.js +163 -76
  203. package/lib/util/renderer.js.map +1 -1
  204. package/lib/util/resolvers.d.ts +1 -14
  205. package/lib/util/resolvers.js +9 -215
  206. package/lib/util/resolvers.js.map +1 -1
  207. package/lib/util/runtime.d.ts +12 -2
  208. package/lib/util/runtime.js +59 -17
  209. package/lib/util/runtime.js.map +1 -1
  210. package/lib/util/schema.js +27 -1
  211. package/lib/util/schema.js.map +1 -1
  212. package/lib/util/uischema.d.ts +1 -1
  213. package/lib/util/uischema.js +11 -7
  214. package/lib/util/uischema.js.map +1 -1
  215. package/lib/util/util.d.ts +31 -0
  216. package/lib/util/util.js +112 -0
  217. package/lib/util/util.js.map +1 -0
  218. package/lib/util/validator.d.ts +3 -2
  219. package/lib/util/validator.js +6 -5
  220. package/lib/util/validator.js.map +1 -1
  221. package/package.json +7 -9
  222. package/src/Helpers.ts +38 -0
  223. package/src/actions/actions.ts +345 -0
  224. package/src/actions/index.ts +1 -312
  225. package/src/configDefault.ts +1 -0
  226. package/src/generators/Generate.ts +43 -0
  227. package/src/generators/index.ts +3 -21
  228. package/src/generators/schema.ts +1 -1
  229. package/src/generators/uischema.ts +4 -4
  230. package/src/i18n/i18nTypes.ts +17 -0
  231. package/src/i18n/i18nUtil.ts +76 -0
  232. package/src/i18n/index.ts +2 -0
  233. package/src/index.ts +7 -31
  234. package/src/models/draft4.ts +1 -0
  235. package/src/models/index.ts +30 -0
  236. package/src/models/jsonSchema.ts +1 -0
  237. package/src/models/uischema.ts +1 -0
  238. package/src/reducers/cells.ts +2 -1
  239. package/src/reducers/config.ts +2 -1
  240. package/src/reducers/core.ts +74 -81
  241. package/src/reducers/default-data.ts +2 -1
  242. package/src/reducers/i18n.ts +42 -35
  243. package/src/reducers/index.ts +9 -158
  244. package/src/reducers/reducers.ts +148 -0
  245. package/src/reducers/renderers.ts +2 -1
  246. package/src/reducers/selectors.ts +65 -0
  247. package/src/reducers/uischemas.ts +4 -2
  248. package/src/store.ts +11 -8
  249. package/src/testers/index.ts +1 -516
  250. package/src/testers/testers.ts +547 -0
  251. package/src/util/Formatted.ts +1 -0
  252. package/src/util/array.ts +25 -0
  253. package/src/util/cell.ts +91 -19
  254. package/src/util/combinators.ts +2 -4
  255. package/src/util/ids.ts +1 -0
  256. package/src/util/index.ts +11 -126
  257. package/src/util/label.ts +2 -2
  258. package/src/util/path.ts +4 -1
  259. package/src/util/renderer.ts +168 -85
  260. package/src/util/resolvers.ts +2 -261
  261. package/src/util/runtime.ts +46 -2
  262. package/src/util/schema.ts +26 -1
  263. package/src/util/uischema.ts +2 -1
  264. package/src/util/util.ts +127 -0
  265. package/src/util/validator.ts +5 -8
  266. package/test/reducers/core.test.ts +31 -223
  267. package/test/util/cell.test.ts +33 -2
  268. package/test/util/renderer.test.ts +483 -3
  269. package/test/util/resolvers.test.ts +1 -59
  270. package/test/util/runtime.test.ts +264 -4
  271. package/docs/interfaces/labels.html +0 -157
  272. package/docs/interfaces/schemaref.html +0 -160
  273. package/docs/interfaces/schemarefs.html +0 -138
@@ -0,0 +1,547 @@
1
+ /*
2
+ The MIT License
3
+
4
+ Copyright (c) 2017-2019 EclipseSource Munich
5
+ https://github.com/eclipsesource/jsonforms
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ of this software and associated documentation files (the "Software"), to deal
9
+ in the Software without restriction, including without limitation the rights
10
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ copies of the Software, and to permit persons to whom the Software is
12
+ furnished to do so, subject to the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be included in
15
+ all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ THE SOFTWARE.
24
+ */
25
+
26
+ import isEmpty from 'lodash/isEmpty';
27
+ import get from 'lodash/get';
28
+ import endsWith from 'lodash/endsWith';
29
+ import last from 'lodash/last';
30
+ import isArray from 'lodash/isArray';
31
+ import reduce from 'lodash/reduce';
32
+ import toPairs from 'lodash/toPairs';
33
+ import includes from 'lodash/includes';
34
+ import {
35
+ Categorization,
36
+ ControlElement,
37
+ JsonSchema,
38
+ UISchemaElement
39
+ } from '../models';
40
+ import { deriveTypes, hasType, resolveSchema } from '../util';
41
+
42
+ /**
43
+ * Constant that indicates that a tester is not capable of handling
44
+ * a combination of schema/data.
45
+ * @type {number}
46
+ */
47
+ export const NOT_APPLICABLE = -1;
48
+ /**
49
+ * A tester is a function that receives an UI schema and a JSON schema and returns a boolean.
50
+ */
51
+ export type Tester = (uischema: UISchemaElement, schema: JsonSchema) => boolean;
52
+
53
+ /**
54
+ * A ranked tester associates a tester with a number.
55
+ */
56
+ export type RankedTester = (
57
+ uischema: UISchemaElement,
58
+ schema: JsonSchema
59
+ ) => number;
60
+
61
+ export const isControl = (uischema: any): uischema is ControlElement =>
62
+ !isEmpty(uischema) && uischema.scope !== undefined;
63
+
64
+ /**
65
+ * Only applicable for Controls.
66
+ *
67
+ * This function checks whether the given UI schema is of type Control
68
+ * and if so, resolves the sub-schema referenced by the control and applies
69
+ * the given predicate
70
+ *
71
+ * @param {(JsonSchema) => boolean} predicate the predicate that should be
72
+ * applied to the resolved sub-schema
73
+ */
74
+ export const schemaMatches = (
75
+ predicate: (schema: JsonSchema) => boolean
76
+ ): Tester => (uischema: UISchemaElement, schema: JsonSchema): boolean => {
77
+ if (isEmpty(uischema) || !isControl(uischema)) {
78
+ return false;
79
+ }
80
+ if (isEmpty(schema)) {
81
+ return false;
82
+ }
83
+ const schemaPath = uischema.scope;
84
+ if (isEmpty(schemaPath)) {
85
+ return false;
86
+ }
87
+ let currentDataSchema = schema;
88
+ if (hasType(schema, 'object')) {
89
+ currentDataSchema = resolveSchema(schema, schemaPath);
90
+ }
91
+ if (currentDataSchema === undefined) {
92
+ return false;
93
+ }
94
+
95
+ return predicate(currentDataSchema);
96
+ };
97
+
98
+ export const schemaSubPathMatches = (
99
+ subPath: string,
100
+ predicate: (schema: JsonSchema) => boolean
101
+ ): Tester => (uischema: UISchemaElement, schema: JsonSchema): boolean => {
102
+ if (isEmpty(uischema) || !isControl(uischema)) {
103
+ return false;
104
+ }
105
+ const schemaPath = uischema.scope;
106
+ let currentDataSchema: JsonSchema = schema;
107
+ if (hasType(schema, 'object')) {
108
+ currentDataSchema = resolveSchema(schema, schemaPath);
109
+ }
110
+ currentDataSchema = get(currentDataSchema, subPath);
111
+
112
+ if (currentDataSchema === undefined) {
113
+ return false;
114
+ }
115
+
116
+ return predicate(currentDataSchema);
117
+ };
118
+
119
+ /**
120
+ * Only applicable for Controls.
121
+ *
122
+ * This function checks whether the given UI schema is of type Control
123
+ * and if so, resolves the sub-schema referenced by the control and checks
124
+ * whether the type of the sub-schema matches the expected one.
125
+ *
126
+ * @param {string} expectedType the expected type of the resolved sub-schema
127
+ */
128
+ export const schemaTypeIs = (expectedType: string): Tester =>
129
+ schemaMatches(schema => !isEmpty(schema) && hasType(schema, expectedType));
130
+
131
+ /**
132
+ * Only applicable for Controls.
133
+ *
134
+ * This function checks whether the given UI schema is of type Control
135
+ * and if so, resolves the sub-schema referenced by the control and checks
136
+ * whether the format of the sub-schema matches the expected one.
137
+ *
138
+ * @param {string} expectedFormat the expected format of the resolved sub-schema
139
+ */
140
+ export const formatIs = (expectedFormat: string): Tester =>
141
+ schemaMatches(
142
+ schema =>
143
+ !isEmpty(schema) &&
144
+ schema.format === expectedFormat &&
145
+ schema.type === 'string'
146
+ );
147
+
148
+ /**
149
+ * Checks whether the given UI schema has the expected type.
150
+ *
151
+ * @param {string} expected the expected UI schema type
152
+ */
153
+ export const uiTypeIs = (expected: string): Tester => (
154
+ uischema: UISchemaElement
155
+ ): boolean => !isEmpty(uischema) && uischema.type === expected;
156
+
157
+ /**
158
+ * Checks whether the given UI schema has an option with the given
159
+ * name and whether it has the expected value. If no options property
160
+ * is set, returns false.
161
+ *
162
+ * @param {string} optionName the name of the option to check
163
+ * @param {any} optionValue the expected value of the option
164
+ */
165
+ export const optionIs = (optionName: string, optionValue: any): Tester => (
166
+ uischema: UISchemaElement
167
+ ): boolean => {
168
+ if (isEmpty(uischema)) {
169
+ return false;
170
+ }
171
+
172
+ const options = uischema.options;
173
+ return !isEmpty(options) && options[optionName] === optionValue;
174
+ };
175
+
176
+ /**
177
+ * Only applicable for Controls.
178
+ *
179
+ * Checks whether the scope of a control ends with the expected string.
180
+ *
181
+ * @param {string} expected the expected ending of the reference
182
+ */
183
+ export const scopeEndsWith = (expected: string): Tester => (
184
+ uischema: UISchemaElement
185
+ ): boolean => {
186
+ if (isEmpty(expected) || !isControl(uischema)) {
187
+ return false;
188
+ }
189
+
190
+ return endsWith(uischema.scope, expected);
191
+ };
192
+
193
+ /**
194
+ * Only applicable for Controls.
195
+ *
196
+ * Checks whether the last segment of the scope matches the expected string.
197
+ *
198
+ * @param {string} expected the expected ending of the reference
199
+ */
200
+ export const scopeEndIs = (expected: string): Tester => (
201
+ uischema: UISchemaElement
202
+ ): boolean => {
203
+ if (isEmpty(expected) || !isControl(uischema)) {
204
+ return false;
205
+ }
206
+ const schemaPath = uischema.scope;
207
+
208
+ return !isEmpty(schemaPath) && last(schemaPath.split('/')) === expected;
209
+ };
210
+
211
+ /**
212
+ * A tester that allow composing other testers by && them.
213
+ *
214
+ * @param {Array<Tester>} testers the testers to be composed
215
+ */
216
+ export const and = (...testers: Tester[]): Tester => (
217
+ uischema: UISchemaElement,
218
+ schema: JsonSchema
219
+ ) => testers.reduce((acc, tester) => acc && tester(uischema, schema), true);
220
+
221
+ /**
222
+ * A tester that allow composing other testers by || them.
223
+ *
224
+ * @param {Array<Tester>} testers the testers to be composed
225
+ */
226
+ export const or = (...testers: Tester[]): Tester => (
227
+ uischema: UISchemaElement,
228
+ schema: JsonSchema
229
+ ) => testers.reduce((acc, tester) => acc || tester(uischema, schema), false);
230
+ /**
231
+ * Create a ranked tester that will associate a number with a given tester, if the
232
+ * latter returns true.
233
+ *
234
+ * @param {number} rank the rank to be returned in case the tester returns true
235
+ * @param {Tester} tester a tester
236
+ */
237
+ export const rankWith = (rank: number, tester: Tester) => (
238
+ uischema: UISchemaElement,
239
+ schema: JsonSchema
240
+ ): number => {
241
+ if (tester(uischema, schema)) {
242
+ return rank;
243
+ }
244
+
245
+ return NOT_APPLICABLE;
246
+ };
247
+
248
+ export const withIncreasedRank = (by: number, rankedTester: RankedTester) => (
249
+ uischema: UISchemaElement,
250
+ schema: JsonSchema
251
+ ): number => {
252
+ const rank = rankedTester(uischema, schema);
253
+ if (rank === NOT_APPLICABLE) {
254
+ return NOT_APPLICABLE;
255
+ }
256
+
257
+ return rank + by;
258
+ };
259
+
260
+ /**
261
+ * Default tester for boolean.
262
+ * @type {RankedTester}
263
+ */
264
+ export const isBooleanControl = and(
265
+ uiTypeIs('Control'),
266
+ schemaTypeIs('boolean')
267
+ );
268
+
269
+ // TODO: rather check for properties property
270
+ export const isObjectControl = and(uiTypeIs('Control'), schemaTypeIs('object'));
271
+
272
+ export const isAllOfControl = and(
273
+ uiTypeIs('Control'),
274
+ schemaMatches(schema => schema.hasOwnProperty('allOf'))
275
+ );
276
+
277
+ export const isAnyOfControl = and(
278
+ uiTypeIs('Control'),
279
+ schemaMatches(schema => schema.hasOwnProperty('anyOf'))
280
+ );
281
+
282
+ export const isOneOfControl = and(
283
+ uiTypeIs('Control'),
284
+ schemaMatches(schema => schema.hasOwnProperty('oneOf'))
285
+ );
286
+
287
+ /**
288
+ * Tests whether the given UI schema is of type Control and if the schema
289
+ * has an enum.
290
+ * @type {Tester}
291
+ */
292
+ export const isEnumControl = and(
293
+ uiTypeIs('Control'),
294
+ or(
295
+ schemaMatches(schema => schema.hasOwnProperty('enum')),
296
+ schemaMatches(schema => schema.hasOwnProperty('const'))
297
+ )
298
+ );
299
+
300
+ /**
301
+ * Tests whether the given UI schema is of type Control and if the schema
302
+ * has an enum based on oneOf.
303
+ * @type {Tester}
304
+ */
305
+ export const isOneOfEnumControl = and(
306
+ uiTypeIs('Control'),
307
+ schemaMatches(schema =>
308
+ schema.hasOwnProperty('oneOf') &&
309
+ (schema.oneOf as JsonSchema[]).every(s => s.const !== undefined)
310
+ )
311
+ );
312
+
313
+ /**
314
+ * Tests whether the given UI schema is of type Control and if the schema
315
+ * is of type integer
316
+ * @type {Tester}
317
+ */
318
+ export const isIntegerControl = and(
319
+ uiTypeIs('Control'),
320
+ schemaTypeIs('integer')
321
+ );
322
+
323
+ /**
324
+ * Tests whether the given UI schema is of type Control and if the schema
325
+ * is of type number
326
+ * @type {Tester}
327
+ */
328
+ export const isNumberControl = and(uiTypeIs('Control'), schemaTypeIs('number'));
329
+
330
+ /**
331
+ * Tests whether the given UI schema is of type Control and if the schema
332
+ * is of type string
333
+ * @type {Tester}
334
+ */
335
+ export const isStringControl = and(uiTypeIs('Control'), schemaTypeIs('string'));
336
+
337
+ /**
338
+ * Tests whether the given UI schema is of type Control and if is has
339
+ * a 'multi' option.
340
+ * @type {Tester}
341
+ */
342
+ export const isMultiLineControl = and(
343
+ uiTypeIs('Control'),
344
+ optionIs('multi', true)
345
+ );
346
+
347
+ /**
348
+ * Tests whether the given UI schema is of type Control and whether the schema
349
+ * or uischema options has a 'date' format.
350
+ * @type {Tester}
351
+ */
352
+ export const isDateControl = and(
353
+ uiTypeIs('Control'),
354
+ or(formatIs('date'), optionIs('format', 'date'))
355
+ );
356
+
357
+ /**
358
+ * Tests whether the given UI schema is of type Control and whether the schema
359
+ * or the uischema options has a 'time' format.
360
+ * @type {Tester}
361
+ */
362
+ export const isTimeControl = and(
363
+ uiTypeIs('Control'),
364
+ or(formatIs('time'), optionIs('format', 'time'))
365
+ );
366
+
367
+ /**
368
+ * Tests whether the given UI schema is of type Control and whether the schema
369
+ * or the uischema options has a 'date-time' format.
370
+ * @type {Tester}
371
+ */
372
+ export const isDateTimeControl = and(
373
+ uiTypeIs('Control'),
374
+ or(formatIs('date-time'), optionIs('format', 'date-time'))
375
+ );
376
+
377
+ /**
378
+ * Tests whether the given schema is an array of objects.
379
+ * @type {Tester}
380
+ */
381
+ export const isObjectArray = and(
382
+ schemaMatches(
383
+ schema => hasType(schema, 'array') && !Array.isArray(schema.items) // we don't care about tuples
384
+ ),
385
+ schemaSubPathMatches('items', schema => hasType(schema, 'object'))
386
+ );
387
+
388
+ /**
389
+ * Tests whether the given UI schema is of type Control and if the schema
390
+ * is an array of objects.
391
+ * @type {Tester}
392
+ */
393
+ export const isObjectArrayControl = and(uiTypeIs('Control'), isObjectArray);
394
+
395
+ const traverse = (
396
+ any: JsonSchema | JsonSchema[],
397
+ pred: (obj: JsonSchema) => boolean
398
+ ): boolean => {
399
+ if (isArray(any)) {
400
+ return reduce(any, (acc, el) => acc || traverse(el, pred), false);
401
+ }
402
+
403
+ if (pred(any)) {
404
+ return true;
405
+ }
406
+ if (any.items) {
407
+ return traverse(any.items, pred);
408
+ }
409
+ if (any.properties) {
410
+ return reduce(
411
+ toPairs(any.properties),
412
+ (acc, [_key, val]) => acc || traverse(val, pred),
413
+ false
414
+ );
415
+ }
416
+
417
+ return false;
418
+ };
419
+
420
+ export const isObjectArrayWithNesting = (
421
+ uischema: UISchemaElement,
422
+ schema: JsonSchema
423
+ ): boolean => {
424
+ if (!uiTypeIs('Control')(uischema, schema)) {
425
+ return false;
426
+ }
427
+ const schemaPath = (uischema as ControlElement).scope;
428
+ const resolvedSchema = resolveSchema(schema, schemaPath);
429
+ const wantedNestingByType: { [key: string]: number } = {
430
+ object: 2,
431
+ array: 1
432
+ };
433
+ if (resolvedSchema !== undefined && resolvedSchema.items !== undefined) {
434
+ // check if nested arrays
435
+ if (
436
+ traverse(resolvedSchema.items, val => {
437
+ if (val === schema) {
438
+ return false;
439
+ }
440
+ // we don't support multiple types
441
+ if (typeof val.type !== 'string') {
442
+ return true;
443
+ }
444
+ const typeCount = wantedNestingByType[val.type];
445
+ if (typeCount === undefined) {
446
+ return false;
447
+ }
448
+ wantedNestingByType[val.type] = typeCount - 1;
449
+ return wantedNestingByType[val.type] === 0;
450
+ })
451
+ ) {
452
+ return true;
453
+ }
454
+ // check if uischema options detail is set
455
+ if (uischema.options && uischema.options.detail) {
456
+ if (typeof uischema.options.detail === 'string') {
457
+ return uischema.options.detail.toUpperCase() !== 'DEFAULT';
458
+ } else if (
459
+ typeof uischema.options.detail === 'object' &&
460
+ uischema.options.detail.type
461
+ ) {
462
+ return true;
463
+ }
464
+ }
465
+ }
466
+ return false;
467
+ };
468
+
469
+ /**
470
+ * Synonym for isObjectArrayControl
471
+ */
472
+ export const isArrayObjectControl = isObjectArrayControl;
473
+
474
+ /**
475
+ * Tests whether the given UI schema is of type Control and if the schema
476
+ * is an array of a primitive type.
477
+ * @type {Tester}
478
+ */
479
+ export const isPrimitiveArrayControl = and(
480
+ uiTypeIs('Control'),
481
+ schemaMatches(
482
+ schema => deriveTypes(schema).length !== 0 && !Array.isArray(schema.items) // we don't care about tuples
483
+ ),
484
+ schemaSubPathMatches('items', schema => {
485
+ const types = deriveTypes(schema);
486
+ return (
487
+ types.length === 1 &&
488
+ includes(['integer', 'number', 'boolean', 'string'], types[0])
489
+ );
490
+ })
491
+ );
492
+
493
+ /**
494
+ * Tests whether a given UI schema is of type Control,
495
+ * if the schema is of type number or integer and
496
+ * whether the schema defines a numerical range with a default value.
497
+ * @type {Tester}
498
+ */
499
+ export const isRangeControl = and(
500
+ uiTypeIs('Control'),
501
+ or(schemaTypeIs('number'), schemaTypeIs('integer')),
502
+ schemaMatches(
503
+ schema =>
504
+ schema.hasOwnProperty('maximum') &&
505
+ schema.hasOwnProperty('minimum') &&
506
+ schema.hasOwnProperty('default')
507
+ ),
508
+ optionIs('slider', true)
509
+ );
510
+
511
+ /**
512
+ * Tests whether the given UI schema is of type Control, if the schema
513
+ * is of type string and has option format
514
+ * @type {Tester}
515
+ */
516
+ export const isNumberFormatControl = and(
517
+ uiTypeIs('Control'),
518
+ schemaTypeIs('integer'),
519
+ optionIs('format', true)
520
+ );
521
+
522
+ export const isCategorization = (
523
+ category: UISchemaElement
524
+ ): category is Categorization => category.type === 'Categorization';
525
+
526
+ export const isCategory = (uischema: UISchemaElement): boolean =>
527
+ uischema.type === 'Category';
528
+
529
+ export const hasCategory = (categorization: Categorization): boolean => {
530
+ if (isEmpty(categorization.elements)) {
531
+ return false;
532
+ }
533
+ // all children of the categorization have to be categories
534
+ return categorization.elements
535
+ .map(elem =>
536
+ isCategorization(elem) ? hasCategory(elem) : isCategory(elem)
537
+ )
538
+ .reduce((prev, curr) => prev && curr, true);
539
+ };
540
+
541
+ export const categorizationHasCategory = (uischema: UISchemaElement) =>
542
+ hasCategory(uischema as Categorization);
543
+
544
+ export const not = (tester: Tester): Tester => (
545
+ uischema: UISchemaElement,
546
+ schema: JsonSchema
547
+ ) => !tester(uischema, schema);
@@ -22,6 +22,7 @@
22
22
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
23
  THE SOFTWARE.
24
24
  */
25
+
25
26
  /**
26
27
  * Interface for mapping a given type to a formatted string and back.
27
28
  */
package/src/util/array.ts CHANGED
@@ -1,3 +1,28 @@
1
+ /*
2
+ The MIT License
3
+
4
+ Copyright (c) 2017-2019 EclipseSource Munich
5
+ https://github.com/eclipsesource/jsonforms
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ of this software and associated documentation files (the "Software"), to deal
9
+ in the Software without restriction, including without limitation the rights
10
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ copies of the Software, and to permit persons to whom the Software is
12
+ furnished to do so, subject to the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be included in
15
+ all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ THE SOFTWARE.
24
+ */
25
+
1
26
  const move = (array: any[], index: number, delta: number) => {
2
27
  const newIndex: number = index + delta;
3
28
  if (newIndex < 0 || newIndex >= array.length) {