@defra/forms-model 3.0.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 (336) hide show
  1. package/LICENCE +8 -0
  2. package/README.md +22 -0
  3. package/dist/browser/components/component-types.d.ts +3 -0
  4. package/dist/browser/components/component-types.d.ts.map +1 -0
  5. package/dist/browser/components/component-types.js +220 -0
  6. package/dist/browser/components/component-types.js.map +1 -0
  7. package/dist/browser/components/conditional-component-types.d.ts +3 -0
  8. package/dist/browser/components/conditional-component-types.d.ts.map +1 -0
  9. package/dist/browser/components/conditional-component-types.js +28 -0
  10. package/dist/browser/components/conditional-component-types.js.map +1 -0
  11. package/dist/browser/components/index.d.ts +4 -0
  12. package/dist/browser/components/index.d.ts.map +1 -0
  13. package/dist/browser/components/index.js +45 -0
  14. package/dist/browser/components/index.js.map +1 -0
  15. package/dist/browser/components/types.d.ts +244 -0
  16. package/dist/browser/components/types.d.ts.map +1 -0
  17. package/dist/browser/components/types.js +56 -0
  18. package/dist/browser/components/types.js.map +1 -0
  19. package/dist/browser/conditions/condition-abstract.d.ts +16 -0
  20. package/dist/browser/conditions/condition-abstract.d.ts.map +1 -0
  21. package/dist/browser/conditions/condition-abstract.js +62 -0
  22. package/dist/browser/conditions/condition-abstract.js.map +1 -0
  23. package/dist/browser/conditions/condition-field.d.ts +13 -0
  24. package/dist/browser/conditions/condition-field.d.ts.map +1 -0
  25. package/dist/browser/conditions/condition-field.js +45 -0
  26. package/dist/browser/conditions/condition-field.js.map +1 -0
  27. package/dist/browser/conditions/condition-group-def.d.ts +10 -0
  28. package/dist/browser/conditions/condition-group-def.d.ts.map +1 -0
  29. package/dist/browser/conditions/condition-group-def.js +45 -0
  30. package/dist/browser/conditions/condition-group-def.js.map +1 -0
  31. package/dist/browser/conditions/condition-group.d.ts +15 -0
  32. package/dist/browser/conditions/condition-group.d.ts.map +1 -0
  33. package/dist/browser/conditions/condition-group.js +64 -0
  34. package/dist/browser/conditions/condition-group.js.map +1 -0
  35. package/dist/browser/conditions/condition-model.d.ts +41 -0
  36. package/dist/browser/conditions/condition-model.d.ts.map +1 -0
  37. package/dist/browser/conditions/condition-model.js +214 -0
  38. package/dist/browser/conditions/condition-model.js.map +1 -0
  39. package/dist/browser/conditions/condition-operators.d.ts +248 -0
  40. package/dist/browser/conditions/condition-operators.d.ts.map +1 -0
  41. package/dist/browser/conditions/condition-operators.js +132 -0
  42. package/dist/browser/conditions/condition-operators.js.map +1 -0
  43. package/dist/browser/conditions/condition-ref.d.ts +12 -0
  44. package/dist/browser/conditions/condition-ref.d.ts.map +1 -0
  45. package/dist/browser/conditions/condition-ref.js +51 -0
  46. package/dist/browser/conditions/condition-ref.js.map +1 -0
  47. package/dist/browser/conditions/condition-value-abstract.d.ts +8 -0
  48. package/dist/browser/conditions/condition-value-abstract.d.ts.map +1 -0
  49. package/dist/browser/conditions/condition-value-abstract.js +41 -0
  50. package/dist/browser/conditions/condition-value-abstract.js.map +1 -0
  51. package/dist/browser/conditions/condition-value-registration.d.ts +10 -0
  52. package/dist/browser/conditions/condition-value-registration.d.ts.map +1 -0
  53. package/dist/browser/conditions/condition-value-registration.js +37 -0
  54. package/dist/browser/conditions/condition-value-registration.js.map +1 -0
  55. package/dist/browser/conditions/condition-values.d.ts +38 -0
  56. package/dist/browser/conditions/condition-values.d.ts.map +1 -0
  57. package/dist/browser/conditions/condition-values.js +127 -0
  58. package/dist/browser/conditions/condition-values.js.map +1 -0
  59. package/dist/browser/conditions/condition.d.ts +15 -0
  60. package/dist/browser/conditions/condition.d.ts.map +1 -0
  61. package/dist/browser/conditions/condition.js +56 -0
  62. package/dist/browser/conditions/condition.js.map +1 -0
  63. package/dist/browser/conditions/helpers.d.ts +3 -0
  64. package/dist/browser/conditions/helpers.d.ts.map +1 -0
  65. package/dist/browser/conditions/helpers.js +26 -0
  66. package/dist/browser/conditions/helpers.js.map +1 -0
  67. package/dist/browser/conditions/index.d.ts +11 -0
  68. package/dist/browser/conditions/index.d.ts.map +1 -0
  69. package/dist/browser/conditions/index.js +144 -0
  70. package/dist/browser/conditions/index.js.map +1 -0
  71. package/dist/browser/conditions/inline-condition-model.d.ts +86 -0
  72. package/dist/browser/conditions/inline-condition-model.d.ts.map +1 -0
  73. package/dist/browser/conditions/inline-condition-model.js +418 -0
  74. package/dist/browser/conditions/inline-condition-model.js.map +1 -0
  75. package/dist/browser/conditions/inline-condition-operators.d.ts +175 -0
  76. package/dist/browser/conditions/inline-condition-operators.d.ts.map +1 -0
  77. package/dist/browser/conditions/inline-condition-operators.js +132 -0
  78. package/dist/browser/conditions/inline-condition-operators.js.map +1 -0
  79. package/dist/browser/conditions/inline-condition-values.d.ts +93 -0
  80. package/dist/browser/conditions/inline-condition-values.d.ts.map +1 -0
  81. package/dist/browser/conditions/inline-condition-values.js +159 -0
  82. package/dist/browser/conditions/inline-condition-values.js.map +1 -0
  83. package/dist/browser/conditions/types.d.ts +38 -0
  84. package/dist/browser/conditions/types.d.ts.map +1 -0
  85. package/dist/browser/conditions/types.js +24 -0
  86. package/dist/browser/conditions/types.js.map +1 -0
  87. package/dist/browser/data-model/conditions-wrapper.d.ts +19 -0
  88. package/dist/browser/data-model/conditions-wrapper.d.ts.map +1 -0
  89. package/dist/browser/data-model/conditions-wrapper.js +49 -0
  90. package/dist/browser/data-model/conditions-wrapper.js.map +1 -0
  91. package/dist/browser/data-model/index.d.ts +4 -0
  92. package/dist/browser/data-model/index.d.ts.map +1 -0
  93. package/dist/browser/data-model/index.js +66 -0
  94. package/dist/browser/data-model/index.js.map +1 -0
  95. package/dist/browser/data-model/input-wrapper.d.ts +16 -0
  96. package/dist/browser/data-model/input-wrapper.d.ts.map +1 -0
  97. package/dist/browser/data-model/input-wrapper.js +49 -0
  98. package/dist/browser/data-model/input-wrapper.js.map +1 -0
  99. package/dist/browser/data-model/types.d.ts +153 -0
  100. package/dist/browser/data-model/types.d.ts.map +1 -0
  101. package/dist/browser/data-model/types.js +34 -0
  102. package/dist/browser/data-model/types.js.map +1 -0
  103. package/dist/browser/form/form-configuration.d.ts +8 -0
  104. package/dist/browser/form/form-configuration.d.ts.map +1 -0
  105. package/dist/browser/form/form-configuration.js +38 -0
  106. package/dist/browser/form/form-configuration.js.map +1 -0
  107. package/dist/browser/form/index.d.ts +2 -0
  108. package/dist/browser/form/index.d.ts.map +1 -0
  109. package/dist/browser/form/index.js +24 -0
  110. package/dist/browser/form/index.js.map +1 -0
  111. package/dist/browser/index.d.ts +12 -0
  112. package/dist/browser/index.d.ts.map +1 -0
  113. package/dist/browser/index.js +138 -0
  114. package/dist/browser/index.js.map +1 -0
  115. package/dist/browser/migration/index.d.ts +2 -0
  116. package/dist/browser/migration/index.d.ts.map +1 -0
  117. package/dist/browser/migration/index.js +24 -0
  118. package/dist/browser/migration/index.js.map +1 -0
  119. package/dist/browser/migration/migration.0-2.d.ts +3 -0
  120. package/dist/browser/migration/migration.0-2.d.ts.map +1 -0
  121. package/dist/browser/migration/migration.0-2.js +65 -0
  122. package/dist/browser/migration/migration.0-2.js.map +1 -0
  123. package/dist/browser/migration/migration.1-2.d.ts +3 -0
  124. package/dist/browser/migration/migration.1-2.d.ts.map +1 -0
  125. package/dist/browser/migration/migration.1-2.js +108 -0
  126. package/dist/browser/migration/migration.1-2.js.map +1 -0
  127. package/dist/browser/migration/types.d.ts +2 -0
  128. package/dist/browser/migration/types.d.ts.map +1 -0
  129. package/dist/browser/migration/types.js +16 -0
  130. package/dist/browser/migration/types.js.map +1 -0
  131. package/dist/browser/migration/whichMigrations.d.ts +7 -0
  132. package/dist/browser/migration/whichMigrations.d.ts.map +1 -0
  133. package/dist/browser/migration/whichMigrations.js +38 -0
  134. package/dist/browser/migration/whichMigrations.js.map +1 -0
  135. package/dist/browser/schema/index.d.ts +2 -0
  136. package/dist/browser/schema/index.d.ts.map +1 -0
  137. package/dist/browser/schema/index.js +30 -0
  138. package/dist/browser/schema/index.js.map +1 -0
  139. package/dist/browser/schema/schema.d.ts +20 -0
  140. package/dist/browser/schema/schema.d.ts.map +1 -0
  141. package/dist/browser/schema/schema.js +255 -0
  142. package/dist/browser/schema/schema.js.map +1 -0
  143. package/dist/browser/utils/helpers.d.ts +9 -0
  144. package/dist/browser/utils/helpers.d.ts.map +1 -0
  145. package/dist/browser/utils/helpers.js +48 -0
  146. package/dist/browser/utils/helpers.js.map +1 -0
  147. package/dist/browser/utils/logger.d.ts +11 -0
  148. package/dist/browser/utils/logger.d.ts.map +1 -0
  149. package/dist/browser/utils/logger.js +46 -0
  150. package/dist/browser/utils/logger.js.map +1 -0
  151. package/dist/module/components/component-types.d.ts +3 -0
  152. package/dist/module/components/component-types.d.ts.map +1 -0
  153. package/dist/module/components/component-types.js +206 -0
  154. package/dist/module/components/component-types.js.map +1 -0
  155. package/dist/module/components/conditional-component-types.d.ts +3 -0
  156. package/dist/module/components/conditional-component-types.d.ts.map +1 -0
  157. package/dist/module/components/conditional-component-types.js +14 -0
  158. package/dist/module/components/conditional-component-types.js.map +1 -0
  159. package/dist/module/components/index.d.ts +4 -0
  160. package/dist/module/components/index.d.ts.map +1 -0
  161. package/dist/module/components/index.js +34 -0
  162. package/dist/module/components/index.js.map +1 -0
  163. package/dist/module/components/types.d.ts +244 -0
  164. package/dist/module/components/types.d.ts.map +1 -0
  165. package/dist/module/components/types.js +42 -0
  166. package/dist/module/components/types.js.map +1 -0
  167. package/dist/module/conditions/condition-abstract.d.ts +16 -0
  168. package/dist/module/conditions/condition-abstract.d.ts.map +1 -0
  169. package/dist/module/conditions/condition-abstract.js +45 -0
  170. package/dist/module/conditions/condition-abstract.js.map +1 -0
  171. package/dist/module/conditions/condition-field.d.ts +13 -0
  172. package/dist/module/conditions/condition-field.d.ts.map +1 -0
  173. package/dist/module/conditions/condition-field.js +26 -0
  174. package/dist/module/conditions/condition-field.js.map +1 -0
  175. package/dist/module/conditions/condition-group-def.d.ts +10 -0
  176. package/dist/module/conditions/condition-group-def.d.ts.map +1 -0
  177. package/dist/module/conditions/condition-group-def.js +26 -0
  178. package/dist/module/conditions/condition-group-def.js.map +1 -0
  179. package/dist/module/conditions/condition-group.d.ts +15 -0
  180. package/dist/module/conditions/condition-group.d.ts.map +1 -0
  181. package/dist/module/conditions/condition-group.js +47 -0
  182. package/dist/module/conditions/condition-group.js.map +1 -0
  183. package/dist/module/conditions/condition-model.d.ts +41 -0
  184. package/dist/module/conditions/condition-model.d.ts.map +1 -0
  185. package/dist/module/conditions/condition-model.js +199 -0
  186. package/dist/module/conditions/condition-model.js.map +1 -0
  187. package/dist/module/conditions/condition-operators.d.ts +248 -0
  188. package/dist/module/conditions/condition-operators.d.ts.map +1 -0
  189. package/dist/module/conditions/condition-operators.js +119 -0
  190. package/dist/module/conditions/condition-operators.js.map +1 -0
  191. package/dist/module/conditions/condition-ref.d.ts +12 -0
  192. package/dist/module/conditions/condition-ref.d.ts.map +1 -0
  193. package/dist/module/conditions/condition-ref.js +33 -0
  194. package/dist/module/conditions/condition-ref.js.map +1 -0
  195. package/dist/module/conditions/condition-value-abstract.d.ts +8 -0
  196. package/dist/module/conditions/condition-value-abstract.d.ts.map +1 -0
  197. package/dist/module/conditions/condition-value-abstract.js +24 -0
  198. package/dist/module/conditions/condition-value-abstract.js.map +1 -0
  199. package/dist/module/conditions/condition-value-registration.d.ts +10 -0
  200. package/dist/module/conditions/condition-value-registration.d.ts.map +1 -0
  201. package/dist/module/conditions/condition-value-registration.js +19 -0
  202. package/dist/module/conditions/condition-value-registration.js.map +1 -0
  203. package/dist/module/conditions/condition-values.d.ts +38 -0
  204. package/dist/module/conditions/condition-values.d.ts.map +1 -0
  205. package/dist/module/conditions/condition-values.js +106 -0
  206. package/dist/module/conditions/condition-values.js.map +1 -0
  207. package/dist/module/conditions/condition.d.ts +15 -0
  208. package/dist/module/conditions/condition.d.ts.map +1 -0
  209. package/dist/module/conditions/condition.js +40 -0
  210. package/dist/module/conditions/condition.js.map +1 -0
  211. package/dist/module/conditions/helpers.d.ts +3 -0
  212. package/dist/module/conditions/helpers.d.ts.map +1 -0
  213. package/dist/module/conditions/helpers.js +12 -0
  214. package/dist/module/conditions/helpers.js.map +1 -0
  215. package/dist/module/conditions/index.d.ts +11 -0
  216. package/dist/module/conditions/index.d.ts.map +1 -0
  217. package/dist/module/conditions/index.js +140 -0
  218. package/dist/module/conditions/index.js.map +1 -0
  219. package/dist/module/conditions/inline-condition-model.d.ts +86 -0
  220. package/dist/module/conditions/inline-condition-model.d.ts.map +1 -0
  221. package/dist/module/conditions/inline-condition-model.js +384 -0
  222. package/dist/module/conditions/inline-condition-model.js.map +1 -0
  223. package/dist/module/conditions/inline-condition-operators.d.ts +175 -0
  224. package/dist/module/conditions/inline-condition-operators.d.ts.map +1 -0
  225. package/dist/module/conditions/inline-condition-operators.js +119 -0
  226. package/dist/module/conditions/inline-condition-operators.js.map +1 -0
  227. package/dist/module/conditions/inline-condition-values.d.ts +93 -0
  228. package/dist/module/conditions/inline-condition-values.d.ts.map +1 -0
  229. package/dist/module/conditions/inline-condition-values.js +134 -0
  230. package/dist/module/conditions/inline-condition-values.js.map +1 -0
  231. package/dist/module/conditions/types.d.ts +38 -0
  232. package/dist/module/conditions/types.d.ts.map +1 -0
  233. package/dist/module/conditions/types.js +10 -0
  234. package/dist/module/conditions/types.js.map +1 -0
  235. package/dist/module/data-model/conditions-wrapper.d.ts +19 -0
  236. package/dist/module/data-model/conditions-wrapper.d.ts.map +1 -0
  237. package/dist/module/data-model/conditions-wrapper.js +30 -0
  238. package/dist/module/data-model/conditions-wrapper.js.map +1 -0
  239. package/dist/module/data-model/index.d.ts +4 -0
  240. package/dist/module/data-model/index.d.ts.map +1 -0
  241. package/dist/module/data-model/index.js +55 -0
  242. package/dist/module/data-model/index.js.map +1 -0
  243. package/dist/module/data-model/input-wrapper.d.ts +16 -0
  244. package/dist/module/data-model/input-wrapper.d.ts.map +1 -0
  245. package/dist/module/data-model/input-wrapper.js +25 -0
  246. package/dist/module/data-model/input-wrapper.js.map +1 -0
  247. package/dist/module/data-model/types.d.ts +153 -0
  248. package/dist/module/data-model/types.d.ts.map +1 -0
  249. package/dist/module/data-model/types.js +20 -0
  250. package/dist/module/data-model/types.js.map +1 -0
  251. package/dist/module/form/form-configuration.d.ts +8 -0
  252. package/dist/module/form/form-configuration.d.ts.map +1 -0
  253. package/dist/module/form/form-configuration.js +17 -0
  254. package/dist/module/form/form-configuration.js.map +1 -0
  255. package/dist/module/form/index.d.ts +2 -0
  256. package/dist/module/form/index.d.ts.map +1 -0
  257. package/dist/module/form/index.js +11 -0
  258. package/dist/module/form/index.js.map +1 -0
  259. package/dist/module/index.d.ts +12 -0
  260. package/dist/module/index.d.ts.map +1 -0
  261. package/dist/module/index.js +135 -0
  262. package/dist/module/index.js.map +1 -0
  263. package/dist/module/migration/index.d.ts +2 -0
  264. package/dist/module/migration/index.d.ts.map +1 -0
  265. package/dist/module/migration/index.js +11 -0
  266. package/dist/module/migration/index.js.map +1 -0
  267. package/dist/module/migration/migration.0-2.d.ts +3 -0
  268. package/dist/module/migration/migration.0-2.d.ts.map +1 -0
  269. package/dist/module/migration/migration.0-2.js +42 -0
  270. package/dist/module/migration/migration.0-2.js.map +1 -0
  271. package/dist/module/migration/migration.1-2.d.ts +3 -0
  272. package/dist/module/migration/migration.1-2.d.ts.map +1 -0
  273. package/dist/module/migration/migration.1-2.js +90 -0
  274. package/dist/module/migration/migration.1-2.js.map +1 -0
  275. package/dist/module/migration/types.d.ts +2 -0
  276. package/dist/module/migration/types.d.ts.map +1 -0
  277. package/dist/module/migration/types.js +1 -0
  278. package/dist/module/migration/types.js.map +1 -0
  279. package/dist/module/migration/whichMigrations.d.ts +7 -0
  280. package/dist/module/migration/whichMigrations.d.ts.map +1 -0
  281. package/dist/module/migration/whichMigrations.js +26 -0
  282. package/dist/module/migration/whichMigrations.js.map +1 -0
  283. package/dist/module/schema/index.d.ts +2 -0
  284. package/dist/module/schema/index.d.ts.map +1 -0
  285. package/dist/module/schema/index.js +17 -0
  286. package/dist/module/schema/index.js.map +1 -0
  287. package/dist/module/schema/schema.d.ts +20 -0
  288. package/dist/module/schema/schema.d.ts.map +1 -0
  289. package/dist/module/schema/schema.js +239 -0
  290. package/dist/module/schema/schema.js.map +1 -0
  291. package/dist/module/utils/helpers.d.ts +9 -0
  292. package/dist/module/utils/helpers.d.ts.map +1 -0
  293. package/dist/module/utils/helpers.js +35 -0
  294. package/dist/module/utils/helpers.js.map +1 -0
  295. package/dist/module/utils/logger.d.ts +11 -0
  296. package/dist/module/utils/logger.d.ts.map +1 -0
  297. package/dist/module/utils/logger.js +27 -0
  298. package/dist/module/utils/logger.js.map +1 -0
  299. package/package.json +35 -0
  300. package/src/components/component-types.ts +229 -0
  301. package/src/components/conditional-component-types.ts +14 -0
  302. package/src/components/index.ts +3 -0
  303. package/src/components/types.ts +362 -0
  304. package/src/conditions/condition-abstract.ts +59 -0
  305. package/src/conditions/condition-field.ts +29 -0
  306. package/src/conditions/condition-group-def.ts +29 -0
  307. package/src/conditions/condition-group.ts +61 -0
  308. package/src/conditions/condition-model.ts +314 -0
  309. package/src/conditions/condition-operators.ts +176 -0
  310. package/src/conditions/condition-ref.ts +47 -0
  311. package/src/conditions/condition-value-abstract.ts +31 -0
  312. package/src/conditions/condition-value-registration.ts +18 -0
  313. package/src/conditions/condition-values.ts +146 -0
  314. package/src/conditions/condition.ts +64 -0
  315. package/src/conditions/helpers.ts +7 -0
  316. package/src/conditions/index.ts +27 -0
  317. package/src/conditions/inline-condition-model.ts +550 -0
  318. package/src/conditions/inline-condition-operators.ts +166 -0
  319. package/src/conditions/inline-condition-values.ts +153 -0
  320. package/src/conditions/types.ts +30 -0
  321. package/src/data-model/conditions-wrapper.ts +42 -0
  322. package/src/data-model/index.ts +3 -0
  323. package/src/data-model/input-wrapper.ts +40 -0
  324. package/src/data-model/types.ts +179 -0
  325. package/src/form/form-configuration.ts +21 -0
  326. package/src/form/index.ts +1 -0
  327. package/src/index.ts +11 -0
  328. package/src/migration/index.ts +1 -0
  329. package/src/migration/migration.0-2.ts +29 -0
  330. package/src/migration/migration.1-2.ts +105 -0
  331. package/src/migration/types.ts +1 -0
  332. package/src/migration/whichMigrations.ts +23 -0
  333. package/src/schema/index.ts +1 -0
  334. package/src/schema/schema.ts +300 -0
  335. package/src/utils/helpers.ts +37 -0
  336. package/src/utils/logger.ts +29 -0
@@ -0,0 +1,550 @@
1
+ import { ComponentTypes } from '../components/component-types'
2
+ import { getExpression } from './inline-condition-operators'
3
+ import { AbstractConditionValue, valueFrom } from './inline-condition-values'
4
+
5
+ export const coordinators = {
6
+ AND: 'and',
7
+ OR: 'or'
8
+ }
9
+
10
+ export class ConditionsModel {
11
+ #groupedConditions
12
+ #userGroupedConditions
13
+ #conditionName
14
+
15
+ constructor() {
16
+ this.#groupedConditions = []
17
+ this.#userGroupedConditions = []
18
+ }
19
+
20
+ clone() {
21
+ const toReturn = new ConditionsModel()
22
+ toReturn.#groupedConditions = this.#groupedConditions.map((it) =>
23
+ it.clone()
24
+ )
25
+ toReturn.#userGroupedConditions = this.#userGroupedConditions.map((it) =>
26
+ it.clone()
27
+ )
28
+ toReturn.#conditionName = this.#conditionName
29
+ return toReturn
30
+ }
31
+
32
+ clear() {
33
+ this.#userGroupedConditions = []
34
+ this.#groupedConditions = []
35
+ this.#conditionName = undefined
36
+ return this
37
+ }
38
+
39
+ set name(name) {
40
+ this.#conditionName = name
41
+ }
42
+
43
+ get name() {
44
+ return this.#conditionName
45
+ }
46
+
47
+ add(condition) {
48
+ const coordinatorExpected = this.#userGroupedConditions.length !== 0
49
+ if (condition.getCoordinator() && !coordinatorExpected) {
50
+ throw Error('No coordinator allowed on the first condition')
51
+ } else if (!condition.getCoordinator() && coordinatorExpected) {
52
+ throw Error('Coordinator must be present on subsequent conditions')
53
+ }
54
+ this.#userGroupedConditions.push(condition)
55
+ this.#groupedConditions = this._applyGroups(this.#userGroupedConditions)
56
+ return this
57
+ }
58
+
59
+ replace(index, condition) {
60
+ const coordinatorExpected = index !== 0
61
+ if (condition.getCoordinator() && !coordinatorExpected) {
62
+ throw Error('No coordinator allowed on the first condition')
63
+ } else if (!condition.getCoordinator() && coordinatorExpected) {
64
+ throw Error('Coordinator must be present on subsequent conditions')
65
+ } else if (index >= this.#userGroupedConditions.length) {
66
+ throw Error(
67
+ `Cannot replace condition ${index} as no such condition exists`
68
+ )
69
+ }
70
+ this.#userGroupedConditions.splice(index, 1, condition)
71
+ this.#groupedConditions = this._applyGroups(this.#userGroupedConditions)
72
+ return this
73
+ }
74
+
75
+ remove(indexes) {
76
+ this.#userGroupedConditions = this.#userGroupedConditions
77
+ .filter((_condition, index) => !indexes.includes(index))
78
+ .map((condition, index) =>
79
+ index === 0 ? condition.asFirstCondition() : condition
80
+ )
81
+
82
+ this.#groupedConditions = this._applyGroups(this.#userGroupedConditions)
83
+ return this
84
+ }
85
+
86
+ addGroups(groupDefs) {
87
+ this.#userGroupedConditions = this._group(
88
+ this.#userGroupedConditions,
89
+ groupDefs
90
+ )
91
+ this.#groupedConditions = this._applyGroups(this.#userGroupedConditions)
92
+ return this
93
+ }
94
+
95
+ splitGroup(index) {
96
+ this.#userGroupedConditions = this._ungroup(
97
+ this.#userGroupedConditions,
98
+ index
99
+ )
100
+ this.#groupedConditions = this._applyGroups(this.#userGroupedConditions)
101
+ return this
102
+ }
103
+
104
+ moveEarlier(index) {
105
+ if (index > 0 && index < this.#userGroupedConditions.length) {
106
+ this.#userGroupedConditions.splice(
107
+ index - 1,
108
+ 0,
109
+ this.#userGroupedConditions.splice(index, 1)[0]
110
+ )
111
+ if (index === 1) {
112
+ this.switchCoordinators()
113
+ }
114
+ this.#groupedConditions = this._applyGroups(this.#userGroupedConditions)
115
+ }
116
+ return this
117
+ }
118
+
119
+ moveLater(index) {
120
+ if (index >= 0 && index < this.#userGroupedConditions.length - 1) {
121
+ this.#userGroupedConditions.splice(
122
+ index + 1,
123
+ 0,
124
+ this.#userGroupedConditions.splice(index, 1)[0]
125
+ )
126
+ if (index === 0) {
127
+ this.switchCoordinators()
128
+ }
129
+ this.#groupedConditions = this._applyGroups(this.#userGroupedConditions)
130
+ }
131
+ return this
132
+ }
133
+
134
+ switchCoordinators() {
135
+ this.#userGroupedConditions[1].setCoordinator(
136
+ this.#userGroupedConditions[0].getCoordinator()
137
+ )
138
+ this.#userGroupedConditions[0].setCoordinator(undefined)
139
+ }
140
+
141
+ get asPerUserGroupings() {
142
+ return [...this.#userGroupedConditions]
143
+ }
144
+
145
+ get hasConditions() {
146
+ return this.#userGroupedConditions.length > 0
147
+ }
148
+
149
+ get lastIndex() {
150
+ return this.#userGroupedConditions.length - 1
151
+ }
152
+
153
+ toPresentationString() {
154
+ return this.#groupedConditions
155
+ .map((condition) => toPresentationString(condition))
156
+ .join(' ')
157
+ }
158
+
159
+ toExpression() {
160
+ return this.#groupedConditions
161
+ .map((condition) => toExpression(condition))
162
+ .join(' ')
163
+ }
164
+
165
+ _applyGroups(userGroupedConditions) {
166
+ const correctedUserGroups = userGroupedConditions.map((condition) =>
167
+ condition instanceof ConditionGroup && condition.conditions.length > 2
168
+ ? new ConditionGroup(
169
+ this._group(
170
+ condition.conditions,
171
+ this._autoGroupDefs(condition.conditions)
172
+ )
173
+ )
174
+ : condition
175
+ )
176
+ return this._group(
177
+ correctedUserGroups,
178
+ this._autoGroupDefs(correctedUserGroups)
179
+ )
180
+ }
181
+
182
+ _group(conditions, groupDefs) {
183
+ return conditions.reduce((groups, condition, index, conditions) => {
184
+ const groupDef = groupDefs.find((groupDef) => groupDef.contains(index))
185
+ if (groupDef) {
186
+ if (groupDef.startsWith(index)) {
187
+ const groupConditions = groupDef.applyTo(conditions)
188
+ groups.push(new ConditionGroup(groupConditions))
189
+ }
190
+ } else {
191
+ groups.push(condition)
192
+ }
193
+ return groups
194
+ }, [])
195
+ }
196
+
197
+ _ungroup(conditions, splitIndex) {
198
+ if (conditions[splitIndex].isGroup()) {
199
+ const copy = [...conditions]
200
+ copy.splice(
201
+ splitIndex,
202
+ 1,
203
+ ...conditions[splitIndex].getGroupedConditions()
204
+ )
205
+ return copy
206
+ }
207
+ return conditions
208
+ }
209
+
210
+ _autoGroupDefs(conditions) {
211
+ const orPositions: number[] = []
212
+ conditions.forEach((condition, index) => {
213
+ if (condition.getCoordinator() === coordinators.OR) {
214
+ orPositions.push(index)
215
+ }
216
+ })
217
+ const hasAnd = !!conditions.find(
218
+ (condition) => condition.getCoordinator() === coordinators.AND
219
+ )
220
+ const hasOr = orPositions.length > 0
221
+ if (hasAnd && hasOr) {
222
+ let start = 0
223
+ const groupDefs: GroupDef[] = []
224
+ orPositions.forEach((position, index) => {
225
+ if (start < position - 1) {
226
+ groupDefs.push(new GroupDef(start, position - 1))
227
+ }
228
+ const thisIsTheLastOr = orPositions.length === index + 1
229
+ const thereAreMoreConditions = conditions.length - 1 > position
230
+ if (thisIsTheLastOr && thereAreMoreConditions) {
231
+ groupDefs.push(new GroupDef(position, conditions.length - 1))
232
+ }
233
+ start = position
234
+ })
235
+ return groupDefs
236
+ }
237
+ return []
238
+ }
239
+
240
+ toJSON() {
241
+ const name = this.#conditionName
242
+ const conditions = this.#userGroupedConditions
243
+ return {
244
+ name,
245
+ conditions: conditions.map((it) => it.clone())
246
+ }
247
+ }
248
+
249
+ static from(obj) {
250
+ if (obj instanceof ConditionsModel) {
251
+ return obj
252
+ }
253
+ const toReturn = new ConditionsModel()
254
+ toReturn.#conditionName = obj.name
255
+ toReturn.#userGroupedConditions = obj.conditions.map((it) =>
256
+ conditionFrom(it)
257
+ )
258
+ toReturn.#groupedConditions = toReturn._applyGroups(
259
+ toReturn.#userGroupedConditions
260
+ )
261
+ return toReturn
262
+ }
263
+ }
264
+
265
+ function conditionFrom(it) {
266
+ if (it.conditions) {
267
+ return new ConditionGroup(
268
+ it.conditions.map((condition) => conditionFrom(condition))
269
+ )
270
+ }
271
+ if (it.conditionName) {
272
+ return new ConditionRef(
273
+ it.conditionName,
274
+ it.conditionDisplayName,
275
+ it.coordinator
276
+ )
277
+ }
278
+ return new Condition(
279
+ Field.from(it.field),
280
+ it.operator,
281
+ valueFrom(it.value),
282
+ it.coordinator
283
+ )
284
+ }
285
+
286
+ export class GroupDef {
287
+ first
288
+ last
289
+
290
+ constructor(first, last) {
291
+ if (typeof first !== 'number' || typeof last !== 'number') {
292
+ throw Error(`Cannot construct a group from ${first} and ${last}`)
293
+ } else if (first >= last) {
294
+ throw Error(`Last (${last}) must be greater than first (${first})`)
295
+ }
296
+ this.first = first
297
+ this.last = last
298
+ }
299
+
300
+ contains(index) {
301
+ return this.first <= index && this.last >= index
302
+ }
303
+
304
+ startsWith(index) {
305
+ return this.first === index
306
+ }
307
+
308
+ applyTo(conditions) {
309
+ return [...conditions].splice(this.first, this.last - this.first + 1)
310
+ }
311
+ }
312
+
313
+ class ConditionGroup {
314
+ conditions
315
+
316
+ constructor(conditions) {
317
+ if (!Array.isArray(conditions) || conditions.length < 2) {
318
+ throw Error('Cannot construct a condition group from a single condition')
319
+ }
320
+ this.conditions = conditions
321
+ }
322
+
323
+ coordinatorString() {
324
+ return this.conditions[0].coordinatorString()
325
+ }
326
+
327
+ conditionString() {
328
+ const copy = [...this.conditions]
329
+ copy.splice(0, 1)
330
+ return `(${this.conditions[0].conditionString()} ${copy
331
+ .map((condition) => toPresentationString(condition))
332
+ .join(' ')})`
333
+ }
334
+
335
+ conditionExpression() {
336
+ const copy = [...this.conditions]
337
+ copy.splice(0, 1)
338
+ return `(${this.conditions[0].conditionExpression()} ${copy
339
+ .map((condition) => toExpression(condition))
340
+ .join(' ')})`
341
+ }
342
+
343
+ asFirstCondition() {
344
+ this.conditions[0].asFirstCondition()
345
+ return this
346
+ }
347
+
348
+ getCoordinator() {
349
+ return this.conditions[0].getCoordinator()
350
+ }
351
+
352
+ setCoordinator(coordinator) {
353
+ this.conditions[0].setCoordinator(coordinator)
354
+ }
355
+
356
+ isGroup() {
357
+ return true
358
+ }
359
+
360
+ getGroupedConditions() {
361
+ return this.conditions.map((condition) => condition.clone())
362
+ }
363
+
364
+ clone() {
365
+ return new ConditionGroup(
366
+ this.conditions.map((condition) => condition.clone())
367
+ )
368
+ }
369
+ }
370
+
371
+ export function toPresentationString(condition) {
372
+ return `${condition.coordinatorString()}${condition.conditionString()}`
373
+ }
374
+
375
+ export function toExpression(condition) {
376
+ return `${condition.coordinatorString()}${condition.conditionExpression()}`
377
+ }
378
+
379
+ export class Field {
380
+ name
381
+ type
382
+ display
383
+
384
+ constructor(name, type, display) {
385
+ if (!name || typeof name !== 'string') {
386
+ throw Error(`name ${name} is not valid`)
387
+ }
388
+ if (!ComponentTypes.find((componentType) => componentType.name === type)) {
389
+ throw Error(`type ${type} is not valid`)
390
+ }
391
+ if (!display || typeof display !== 'string') {
392
+ throw Error(`display ${display} is not valid`)
393
+ }
394
+ this.name = name
395
+ this.type = type
396
+ this.display = display
397
+ }
398
+
399
+ static from(obj) {
400
+ return new Field(obj.name, obj.type, obj.display)
401
+ }
402
+ }
403
+
404
+ class AbstractCondition {
405
+ coordinator
406
+
407
+ constructor(coordinator) {
408
+ if (coordinator && !Object.values(coordinators).includes(coordinator)) {
409
+ throw Error(`coordinator ${coordinator} is not a valid coordinator`)
410
+ }
411
+ this.coordinator = coordinator
412
+ }
413
+
414
+ coordinatorString() {
415
+ return this.coordinator ? `${this.coordinator} ` : ''
416
+ }
417
+
418
+ getCoordinator() {
419
+ return this.coordinator
420
+ }
421
+
422
+ setCoordinator(coordinator) {
423
+ this.coordinator = coordinator
424
+ }
425
+
426
+ isGroup() {
427
+ return false
428
+ }
429
+
430
+ getGroupedConditions() {
431
+ return [this]
432
+ }
433
+
434
+ _asFirstCondition() {
435
+ delete this.coordinator
436
+ }
437
+
438
+ asFirstCondition() {
439
+ throw Error(
440
+ 'Implement on the subclass (Why do we have to have this method here at all?!)'
441
+ )
442
+ }
443
+
444
+ clone() {
445
+ throw Error(
446
+ 'Implement on the subclass (Why do we have to have this method here at all?!)'
447
+ )
448
+ }
449
+
450
+ conditionString() {
451
+ throw Error(
452
+ 'Implement on the subclass (Why do we have to have this method here at all?!)'
453
+ )
454
+ }
455
+
456
+ conditionExpression() {
457
+ throw Error(
458
+ 'Implement on the subclass (Why do we have to have this method here at all?!)'
459
+ )
460
+ }
461
+ }
462
+
463
+ export class Condition extends AbstractCondition {
464
+ field
465
+ operator
466
+ value
467
+
468
+ constructor(field, operator, value, coordinator) {
469
+ super(coordinator)
470
+ if (!(field instanceof Field)) {
471
+ throw Error(`field ${field} is not a valid Field object`)
472
+ }
473
+ if (typeof operator !== 'string') {
474
+ throw Error(`operator ${operator} is not a valid operator`)
475
+ }
476
+ if (!(value instanceof AbstractConditionValue)) {
477
+ throw Error(`value ${value} is not a valid value type`)
478
+ }
479
+ this.field = field
480
+ this.operator = operator
481
+ this.value = value
482
+ }
483
+
484
+ asFirstCondition() {
485
+ this._asFirstCondition()
486
+ return this
487
+ }
488
+
489
+ conditionString() {
490
+ return `'${this.field.display}' ${
491
+ this.operator
492
+ } '${this.value.toPresentationString()}'`
493
+ }
494
+
495
+ conditionExpression() {
496
+ return getExpression(
497
+ this.field.type,
498
+ this.field.name,
499
+ this.operator,
500
+ this.value
501
+ )
502
+ }
503
+
504
+ clone() {
505
+ return new Condition(
506
+ Field.from(this.field),
507
+ this.operator,
508
+ this.value.clone(),
509
+ this.coordinator
510
+ )
511
+ }
512
+ }
513
+
514
+ export class ConditionRef extends AbstractCondition {
515
+ conditionName
516
+ conditionDisplayName
517
+
518
+ constructor(conditionName, conditionDisplayName, coordinator) {
519
+ super(coordinator)
520
+ if (typeof conditionName !== 'string') {
521
+ throw Error(`condition name ${conditionName} is not valid`)
522
+ }
523
+ if (typeof conditionDisplayName !== 'string') {
524
+ throw Error(`condition display name ${conditionDisplayName} is not valid`)
525
+ }
526
+ this.conditionName = conditionName
527
+ this.conditionDisplayName = conditionDisplayName
528
+ }
529
+
530
+ asFirstCondition() {
531
+ this._asFirstCondition()
532
+ return this
533
+ }
534
+
535
+ conditionString() {
536
+ return `'${this.conditionDisplayName}'`
537
+ }
538
+
539
+ conditionExpression() {
540
+ return this.conditionName
541
+ }
542
+
543
+ clone() {
544
+ return new ConditionRef(
545
+ this.conditionName,
546
+ this.conditionDisplayName,
547
+ this.coordinator
548
+ )
549
+ }
550
+ }
@@ -0,0 +1,166 @@
1
+ import {
2
+ ConditionValue,
3
+ dateDirections,
4
+ dateTimeUnits,
5
+ dateUnits,
6
+ RelativeTimeValue,
7
+ timeUnits
8
+ } from './inline-condition-values'
9
+
10
+ const defaultOperators = {
11
+ is: inline('=='),
12
+ 'is not': inline('!=')
13
+ }
14
+
15
+ function withDefaults(param) {
16
+ return Object.assign({}, param, defaultOperators)
17
+ }
18
+
19
+ const textBasedFieldCustomisations = {
20
+ 'is longer than': lengthIs('>'),
21
+ 'is shorter than': lengthIs('<'),
22
+ 'has length': lengthIs('==')
23
+ }
24
+
25
+ const absoluteDateTimeOperators = {
26
+ is: absoluteDateTime('=='),
27
+ 'is not': absoluteDateTime('!='),
28
+ 'is before': absoluteDateTime('<'),
29
+ 'is after': absoluteDateTime('>')
30
+ }
31
+
32
+ const relativeTimeOperators = (units) => ({
33
+ 'is at least': relativeTime('<=', '>=', units),
34
+ 'is at most': relativeTime('>=', '<=', units),
35
+ 'is less than': relativeTime('>', '<', units),
36
+ 'is more than': relativeTime('<', '>', units)
37
+ })
38
+
39
+ export const customOperators = {
40
+ CheckboxesField: {
41
+ contains: reverseInline('in'),
42
+ 'does not contain': not(reverseInline('in'))
43
+ },
44
+ NumberField: withDefaults({
45
+ 'is at least': inline('>='),
46
+ 'is at most': inline('<='),
47
+ 'is less than': inline('<'),
48
+ 'is more than': inline('>')
49
+ }),
50
+ DateField: Object.assign(
51
+ {},
52
+ absoluteDateTimeOperators,
53
+ relativeTimeOperators(dateUnits)
54
+ ),
55
+ TimeField: Object.assign(
56
+ {},
57
+ absoluteDateTimeOperators,
58
+ relativeTimeOperators(timeUnits)
59
+ ),
60
+ DatePartsField: Object.assign(
61
+ {},
62
+ absoluteDateTimeOperators,
63
+ relativeTimeOperators(dateUnits)
64
+ ),
65
+ DateTimeField: Object.assign(
66
+ {},
67
+ absoluteDateTimeOperators,
68
+ relativeTimeOperators(dateTimeUnits)
69
+ ),
70
+ DateTimePartsField: Object.assign(
71
+ {},
72
+ absoluteDateTimeOperators,
73
+ relativeTimeOperators(dateTimeUnits)
74
+ ),
75
+ TextField: withDefaults(textBasedFieldCustomisations),
76
+ MultilineTextField: withDefaults(textBasedFieldCustomisations),
77
+ EmailAddressField: withDefaults(textBasedFieldCustomisations)
78
+ }
79
+
80
+ export function getOperatorNames(fieldType) {
81
+ return Object.keys(getConditionals(fieldType)).sort()
82
+ }
83
+
84
+ export function getExpression(fieldType, fieldName, operator, value) {
85
+ return getConditionals(fieldType)[operator].expression(
86
+ { type: fieldType, name: fieldName },
87
+ value
88
+ )
89
+ }
90
+
91
+ export function getOperatorConfig(fieldType, operator) {
92
+ return getConditionals(fieldType)[operator]
93
+ }
94
+
95
+ function getConditionals(fieldType) {
96
+ return customOperators[fieldType] || defaultOperators
97
+ }
98
+
99
+ function inline(operator) {
100
+ return {
101
+ expression: (field, value) =>
102
+ `${field.name} ${operator} ${formatValue(field.type, value.value)}`
103
+ }
104
+ }
105
+
106
+ function lengthIs(operator) {
107
+ return {
108
+ expression: (field, value) =>
109
+ `length(${field.name}) ${operator} ${value.value}`
110
+ }
111
+ }
112
+
113
+ function reverseInline(operator) {
114
+ return {
115
+ expression: (field, value) =>
116
+ `${formatValue(field.type, value.value)} ${operator} ${field.name}`
117
+ }
118
+ }
119
+
120
+ function not(operatorDefinition) {
121
+ return {
122
+ expression: (field, value) =>
123
+ `not (${operatorDefinition.expression(field, value)})`
124
+ }
125
+ }
126
+
127
+ function formatValue(fieldType, value) {
128
+ if (fieldType === 'NumberField' || fieldType === 'YesNoField') {
129
+ return value
130
+ }
131
+ return `'${value}'`
132
+ }
133
+
134
+ export const absoluteDateOrTimeOperatorNames = Object.keys(
135
+ absoluteDateTimeOperators
136
+ )
137
+ export const relativeDateOrTimeOperatorNames = Object.keys(
138
+ relativeTimeOperators(dateTimeUnits)
139
+ )
140
+
141
+ function absoluteDateTime(operator) {
142
+ return {
143
+ expression: (field, value) => {
144
+ if (value instanceof ConditionValue) {
145
+ return `${field.name} ${operator} '${value.toExpression()}'`
146
+ }
147
+ throw Error('only Value types are supported')
148
+ }
149
+ }
150
+ }
151
+
152
+ function relativeTime(pastOperator, futureOperator, units) {
153
+ return {
154
+ units,
155
+ expression: (field, value) => {
156
+ if (value instanceof RelativeTimeValue) {
157
+ const operator =
158
+ value.direction === dateDirections.PAST
159
+ ? pastOperator
160
+ : futureOperator
161
+ return `${field.name} ${operator} ${value.toExpression()}`
162
+ }
163
+ throw Error('time shift requires a TimeShiftValue')
164
+ }
165
+ }
166
+ }