@schukai/monster 3.51.5 → 3.52.1

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 (361) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +15 -12
  3. package/example/components/form/button.mjs +10 -0
  4. package/example/components/form/select.mjs +25 -0
  5. package/example/components/form/tree-select.mjs +27 -0
  6. package/example/components/host/host.mjs +0 -0
  7. package/example/components/notify/message.mjs +4 -0
  8. package/example/components/notify/notify.mjs +4 -0
  9. package/example/components/state/log.mjs +0 -0
  10. package/example/components/state/state.mjs +0 -0
  11. package/example/data/datasource/server/restapi.mjs +7 -1
  12. package/package.json +6 -2
  13. package/source/components/constants.mjs +132 -0
  14. package/source/components/datatable/columnbar.mjs +310 -0
  15. package/source/components/datatable/constants.mjs +121 -0
  16. package/source/components/datatable/dataset.mjs +219 -0
  17. package/source/components/datatable/datasource/dom.mjs +186 -0
  18. package/source/components/datatable/datasource/namespace.mjs +13 -0
  19. package/source/components/datatable/datasource/rest.mjs +400 -0
  20. package/source/components/datatable/datasource.mjs +102 -0
  21. package/source/components/datatable/datatable/header.mjs +268 -0
  22. package/source/components/datatable/datatable/namespace.mjs +13 -0
  23. package/source/components/datatable/datatable.mjs +789 -0
  24. package/source/components/datatable/embedded-pagination.mjs +113 -0
  25. package/source/components/datatable/filter/abstract-base.mjs +31 -0
  26. package/source/components/datatable/filter/date-range.mjs +1041 -0
  27. package/source/components/datatable/filter/input.mjs +175 -0
  28. package/source/components/datatable/filter/namespace.mjs +13 -0
  29. package/source/components/datatable/filter/range.mjs +671 -0
  30. package/source/components/datatable/filter/select.mjs +65 -0
  31. package/source/components/datatable/filter/settings.mjs +116 -0
  32. package/source/components/datatable/filter-button.mjs +98 -0
  33. package/source/components/datatable/filter.mjs +929 -0
  34. package/source/components/datatable/namespace.mjs +11 -0
  35. package/source/components/datatable/pagination.mjs +456 -0
  36. package/source/components/datatable/style/column-bar.pcss +123 -0
  37. package/source/components/datatable/style/dataset.pcss +13 -0
  38. package/source/components/datatable/style/datasource.pcss +16 -0
  39. package/source/components/datatable/style/datatable.pcss +239 -0
  40. package/source/components/datatable/style/embedded-pagination.pcss +101 -0
  41. package/source/components/datatable/style/filter-button.pcss +22 -0
  42. package/source/components/datatable/style/filter-controls-defaults.pcss +46 -0
  43. package/source/components/datatable/style/filter-date-range.pcss +9 -0
  44. package/source/components/datatable/style/filter-range.pcss +5 -0
  45. package/source/components/datatable/style/filter.pcss +156 -0
  46. package/source/components/datatable/style/pagination.pcss +59 -0
  47. package/source/components/datatable/style/select-filter.pcss +27 -0
  48. package/source/components/datatable/stylesheet/column-bar.mjs +27 -0
  49. package/source/components/datatable/stylesheet/dataset.mjs +27 -0
  50. package/source/components/datatable/stylesheet/datasource.mjs +27 -0
  51. package/source/components/datatable/stylesheet/datatable.mjs +27 -0
  52. package/source/components/datatable/stylesheet/embedded-pagination.mjs +27 -0
  53. package/source/components/datatable/stylesheet/filter-button.mjs +27 -0
  54. package/source/components/datatable/stylesheet/filter-controls-defaults.mjs +27 -0
  55. package/source/components/datatable/stylesheet/filter-date-range.mjs +27 -0
  56. package/source/components/datatable/stylesheet/filter-range.mjs +27 -0
  57. package/source/components/datatable/stylesheet/filter.mjs +27 -0
  58. package/source/components/datatable/stylesheet/namespace.mjs +13 -0
  59. package/source/components/datatable/stylesheet/pagination.mjs +27 -0
  60. package/source/components/datatable/stylesheet/select-filter.mjs +27 -0
  61. package/source/components/datatable/util.mjs +60 -0
  62. package/source/components/form/action-button.mjs +262 -0
  63. package/source/components/form/api-button.mjs +515 -0
  64. package/source/components/form/button-bar.mjs +739 -0
  65. package/source/components/form/button.mjs +350 -0
  66. package/source/components/form/confirm-button.mjs +330 -0
  67. package/source/components/form/constants.mjs +111 -0
  68. package/source/components/form/context-help.mjs +123 -0
  69. package/source/components/form/events.mjs +84 -0
  70. package/source/components/form/form.mjs +601 -0
  71. package/source/components/form/message-state-button.mjs +396 -0
  72. package/source/components/form/namespace.mjs +13 -0
  73. package/source/components/form/popper-button.mjs +435 -0
  74. package/source/components/form/popper.mjs +487 -0
  75. package/source/components/form/reload.mjs +360 -0
  76. package/source/components/form/select.mjs +2314 -0
  77. package/source/components/form/shadow-reload.mjs +137 -0
  78. package/source/components/form/state-button.mjs +182 -0
  79. package/source/components/form/style/action-button.pcss +41 -0
  80. package/source/components/form/style/api-button.pcss +0 -0
  81. package/source/components/form/style/button-bar.pcss +51 -0
  82. package/source/components/form/style/button.pcss +8 -0
  83. package/source/components/form/style/confirm-button.pcss +17 -0
  84. package/source/components/form/style/context-help.pcss +16 -0
  85. package/source/components/form/style/form.pcss +10 -0
  86. package/source/components/form/style/message-state-button.pcss +10 -0
  87. package/source/components/form/style/popper-button.pcss +16 -0
  88. package/source/components/form/style/popper.pcss +8 -0
  89. package/source/components/form/style/select.pcss +265 -0
  90. package/source/components/form/style/state-button.pcss +116 -0
  91. package/source/components/form/style/tabs.pcss +173 -0
  92. package/source/components/form/style/tree-select.pcss +81 -0
  93. package/source/components/form/stylesheet/action-button.mjs +27 -0
  94. package/source/components/form/stylesheet/api-button.mjs +27 -0
  95. package/source/components/form/stylesheet/button-bar.mjs +27 -0
  96. package/source/components/form/stylesheet/button.mjs +27 -0
  97. package/source/components/form/stylesheet/confirm-button.mjs +27 -0
  98. package/source/components/form/stylesheet/context-help.mjs +27 -0
  99. package/source/components/form/stylesheet/form.mjs +27 -0
  100. package/source/components/form/stylesheet/message-state-button.mjs +27 -0
  101. package/source/components/form/stylesheet/namespace.mjs +13 -0
  102. package/source/components/form/stylesheet/popper-button.mjs +27 -0
  103. package/source/components/form/stylesheet/popper.mjs +27 -0
  104. package/source/components/form/stylesheet/select.mjs +27 -0
  105. package/source/components/form/stylesheet/state-button.mjs +27 -0
  106. package/source/components/form/stylesheet/tabs.mjs +27 -0
  107. package/source/components/form/stylesheet/tree-select.mjs +27 -0
  108. package/source/components/form/tabs.mjs +1029 -0
  109. package/source/components/form/template.mjs +373 -0
  110. package/source/components/form/tree-select.mjs +527 -0
  111. package/source/components/form/types/namespace.mjs +13 -0
  112. package/source/components/form/types/state.mjs +93 -0
  113. package/source/components/form/util/fetch.mjs +133 -0
  114. package/source/components/form/util/floating-ui.mjs +245 -0
  115. package/source/components/form/util/namespace.mjs +13 -0
  116. package/source/components/form/util/popper.mjs +49 -0
  117. package/source/components/host/call-button.mjs +236 -0
  118. package/source/components/host/collapse.mjs +526 -0
  119. package/source/components/host/config-manager.mjs +304 -0
  120. package/source/components/host/constants.mjs +18 -0
  121. package/source/components/host/details.mjs +268 -0
  122. package/source/components/host/events.mjs +131 -0
  123. package/source/components/host/host.mjs +420 -0
  124. package/source/components/host/namespace.mjs +13 -0
  125. package/source/components/host/overlay.mjs +339 -0
  126. package/source/components/host/style/call-button.pcss +36 -0
  127. package/source/components/host/style/collapse.pcss +67 -0
  128. package/source/components/host/style/config-manager.pcss +5 -0
  129. package/source/components/host/style/details.pcss +68 -0
  130. package/source/components/host/style/host.pcss +43 -0
  131. package/source/components/host/style/overlay.pcss +73 -0
  132. package/source/components/host/style/toggle-button.pcss +36 -0
  133. package/source/components/host/style/viewer.pcss +13 -0
  134. package/source/components/host/stylesheet/call-button.mjs +27 -0
  135. package/source/components/host/stylesheet/collapse.mjs +27 -0
  136. package/source/components/host/stylesheet/config-manager.mjs +27 -0
  137. package/source/components/host/stylesheet/details.mjs +27 -0
  138. package/source/components/host/stylesheet/host.mjs +27 -0
  139. package/source/components/host/stylesheet/namespace.mjs +13 -0
  140. package/source/components/host/stylesheet/overlay.mjs +27 -0
  141. package/source/components/host/stylesheet/toggle-button.mjs +27 -0
  142. package/source/components/host/stylesheet/viewer.mjs +27 -0
  143. package/source/components/host/toggle-button.mjs +88 -0
  144. package/source/components/host/util.mjs +23 -0
  145. package/source/components/host/viewer.mjs +309 -0
  146. package/source/components/namespace.mjs +14 -0
  147. package/source/components/notify/constants.mjs +15 -0
  148. package/source/components/notify/events.mjs +15 -0
  149. package/source/components/notify/message.mjs +374 -0
  150. package/source/components/notify/namespace.mjs +15 -0
  151. package/source/components/notify/notify.mjs +236 -0
  152. package/source/components/notify/style/message.pcss +57 -0
  153. package/source/components/notify/style/notify.pcss +118 -0
  154. package/source/components/notify/stylesheet/message.mjs +27 -0
  155. package/source/components/notify/stylesheet/namespace.mjs +15 -0
  156. package/source/components/notify/stylesheet/notify.mjs +27 -0
  157. package/source/components/state/log/entry.mjs +126 -0
  158. package/source/components/state/log/namespace.mjs +13 -0
  159. package/source/components/state/log.mjs +275 -0
  160. package/source/components/state/namespace.mjs +13 -0
  161. package/source/components/state/state.mjs +131 -0
  162. package/source/components/state/style/log.pcss +111 -0
  163. package/source/components/state/style/state.pcss +113 -0
  164. package/source/components/state/stylesheet/log.mjs +27 -0
  165. package/source/components/state/stylesheet/state.mjs +27 -0
  166. package/source/components/style/badge.pcss +92 -0
  167. package/source/components/style/border.pcss +77 -0
  168. package/source/components/style/button.pcss +105 -0
  169. package/source/components/style/card.pcss +108 -0
  170. package/source/components/style/color.pcss +257 -0
  171. package/source/components/style/common.pcss +105 -0
  172. package/source/components/style/control.pcss +11 -0
  173. package/source/components/style/data-grid.pcss +43 -0
  174. package/source/components/style/display.pcss +42 -0
  175. package/source/components/style/floating-ui.pcss +33 -0
  176. package/source/components/style/form.pcss +5 -0
  177. package/source/components/style/host.pcss +15 -0
  178. package/source/components/style/link.pcss +63 -0
  179. package/source/components/style/mixin/badge.pcss +18 -0
  180. package/source/components/style/mixin/button.pcss +52 -0
  181. package/source/components/style/mixin/form.pcss +247 -0
  182. package/source/components/style/mixin/hover.pcss +8 -0
  183. package/source/components/style/mixin/media.pcss +107 -0
  184. package/source/components/style/mixin/property.pcss +292 -0
  185. package/source/components/style/mixin/skeleton.pcss +26 -0
  186. package/source/components/style/mixin/spinner.pcss +24 -0
  187. package/source/components/style/mixin/typography.pcss +52 -0
  188. package/source/components/style/normalize.pcss +14 -0
  189. package/source/components/style/popper.pcss +78 -0
  190. package/source/components/style/property.pcss +17 -0
  191. package/source/components/style/ripple.pcss +14 -0
  192. package/source/components/style/skeleton.pcss +28 -0
  193. package/source/components/style/space.pcss +47 -0
  194. package/source/components/style/spinner.pcss +6 -0
  195. package/source/components/style/table.pcss +46 -0
  196. package/source/components/style/theme.pcss +119 -0
  197. package/source/components/style/typography.pcss +131 -0
  198. package/source/components/stylesheet/badge.mjs +27 -0
  199. package/source/components/stylesheet/border.mjs +27 -0
  200. package/source/components/stylesheet/button.mjs +27 -0
  201. package/source/components/stylesheet/card.mjs +27 -0
  202. package/source/components/stylesheet/color.mjs +27 -0
  203. package/source/components/stylesheet/common.mjs +27 -0
  204. package/source/components/stylesheet/control.mjs +27 -0
  205. package/source/components/stylesheet/data-grid.mjs +27 -0
  206. package/source/components/stylesheet/display.mjs +27 -0
  207. package/source/components/stylesheet/floating-ui.mjs +27 -0
  208. package/source/components/stylesheet/form.mjs +27 -0
  209. package/source/components/stylesheet/host.mjs +27 -0
  210. package/source/components/stylesheet/link.mjs +27 -0
  211. package/source/components/stylesheet/namespace.mjs +13 -0
  212. package/source/components/stylesheet/normalize.mjs +27 -0
  213. package/source/components/stylesheet/popper.mjs +27 -0
  214. package/source/components/stylesheet/property.mjs +27 -0
  215. package/source/components/stylesheet/ripple.mjs +27 -0
  216. package/source/components/stylesheet/skeleton.mjs +27 -0
  217. package/source/components/stylesheet/space.mjs +27 -0
  218. package/source/components/stylesheet/spinner.mjs +27 -0
  219. package/source/components/stylesheet/table.mjs +27 -0
  220. package/source/components/stylesheet/theme.mjs +27 -0
  221. package/source/components/stylesheet/tree-menu.mjs +33 -0
  222. package/source/components/stylesheet/typography.mjs +27 -0
  223. package/source/components/tree-menu/namespace.mjs +13 -0
  224. package/source/components/tree-menu/style/tree-menu.pcss +107 -0
  225. package/source/components/tree-menu/stylesheet/namespace.mjs +13 -0
  226. package/source/components/tree-menu/stylesheet/tree-menu.mjs +27 -0
  227. package/source/components/tree-menu/tree-menu.mjs +660 -0
  228. package/source/constraints/abstract.mjs +17 -24
  229. package/source/constraints/abstractoperator.mjs +27 -22
  230. package/source/constraints/andoperator.mjs +20 -17
  231. package/source/constraints/invalid.mjs +17 -17
  232. package/source/constraints/isarray.mjs +20 -20
  233. package/source/constraints/isobject.mjs +20 -20
  234. package/source/constraints/oroperator.mjs +45 -45
  235. package/source/constraints/valid.mjs +17 -17
  236. package/source/data/buildmap.mjs +108 -103
  237. package/source/data/buildtree.mjs +59 -57
  238. package/source/data/datasource/dom.mjs +80 -84
  239. package/source/data/datasource/namespace.mjs +1 -1
  240. package/source/data/datasource/server/restapi/data-fetch-error.mjs +27 -25
  241. package/source/data/datasource/server/restapi/writeerror.mjs +35 -32
  242. package/source/data/datasource/server/restapi.mjs +176 -177
  243. package/source/data/datasource/server/webconnect.mjs +150 -156
  244. package/source/data/datasource/server.mjs +62 -63
  245. package/source/data/datasource/storage/localstorage.mjs +25 -24
  246. package/source/data/datasource/storage/sessionstorage.mjs +28 -25
  247. package/source/data/datasource/storage.mjs +74 -73
  248. package/source/data/datasource.mjs +177 -168
  249. package/source/data/diff.mjs +98 -97
  250. package/source/data/extend.mjs +42 -42
  251. package/source/data/pathfinder.mjs +301 -288
  252. package/source/data/pipe.mjs +36 -36
  253. package/source/data/transformer.mjs +742 -726
  254. package/source/dom/assembler.mjs +44 -44
  255. package/source/dom/attributes.mjs +142 -122
  256. package/source/dom/constants.mjs +62 -58
  257. package/source/dom/customcontrol.mjs +299 -299
  258. package/source/dom/customelement.mjs +843 -806
  259. package/source/dom/dimension.mjs +56 -46
  260. package/source/dom/events.mjs +74 -69
  261. package/source/dom/focusmanager.mjs +175 -175
  262. package/source/dom/locale.mjs +28 -28
  263. package/source/dom/ready.mjs +13 -13
  264. package/source/dom/resource/data.mjs +117 -111
  265. package/source/dom/resource/link/stylesheet.mjs +16 -16
  266. package/source/dom/resource/link.mjs +94 -96
  267. package/source/dom/resource/script.mjs +72 -74
  268. package/source/dom/resource.mjs +174 -172
  269. package/source/dom/resourcemanager.mjs +152 -156
  270. package/source/dom/slotted.mjs +78 -80
  271. package/source/dom/template.mjs +126 -112
  272. package/source/dom/theme.mjs +35 -35
  273. package/source/dom/updater.mjs +673 -651
  274. package/source/dom/util/extract-keys.mjs +34 -22
  275. package/source/dom/util/init-options-from-attributes.mjs +46 -38
  276. package/source/dom/util/namespace.mjs +13 -0
  277. package/source/dom/util/set-option-from-attribute.mjs +35 -29
  278. package/source/dom/util.mjs +112 -81
  279. package/source/dom/worker/factory.mjs +83 -83
  280. package/source/i18n/formatter.mjs +75 -73
  281. package/source/i18n/locale.mjs +146 -144
  282. package/source/i18n/provider.mjs +70 -64
  283. package/source/i18n/providers/embed.mjs +136 -127
  284. package/source/i18n/providers/fetch.mjs +84 -76
  285. package/source/i18n/translations.mjs +205 -195
  286. package/source/logging/handler/console.mjs +36 -36
  287. package/source/logging/handler.mjs +140 -140
  288. package/source/logging/logentry.mjs +25 -25
  289. package/source/logging/logger.mjs +177 -175
  290. package/source/math/random.mjs +63 -59
  291. package/source/monster.mjs +223 -103
  292. package/source/net/webconnect/message.mjs +31 -31
  293. package/source/net/webconnect.mjs +278 -271
  294. package/source/text/bracketed-key-value-hash.mjs +182 -179
  295. package/source/text/formatter.mjs +235 -210
  296. package/source/text/generate-range-comparison-expression.mjs +56 -34
  297. package/source/text/namespace.mjs +1 -1
  298. package/source/types/base.mjs +69 -61
  299. package/source/types/basewithoptions.mjs +46 -46
  300. package/source/types/binary.mjs +20 -20
  301. package/source/types/dataurl.mjs +96 -90
  302. package/source/types/global.mjs +45 -39
  303. package/source/types/id.mjs +25 -25
  304. package/source/types/internal.mjs +115 -114
  305. package/source/types/is.mjs +56 -40
  306. package/source/types/mediatype.mjs +119 -119
  307. package/source/types/namespace.mjs +1 -1
  308. package/source/types/node.mjs +160 -150
  309. package/source/types/nodelist.mjs +94 -96
  310. package/source/types/noderecursiveiterator.mjs +50 -50
  311. package/source/types/observablequeue.mjs +73 -73
  312. package/source/types/observer.mjs +114 -106
  313. package/source/types/observerlist.mjs +66 -66
  314. package/source/types/proxyobserver.mjs +210 -210
  315. package/source/types/queue.mjs +63 -63
  316. package/source/types/randomid.mjs +13 -13
  317. package/source/types/regex.mjs +3 -1
  318. package/source/types/stack.mjs +64 -64
  319. package/source/types/tokenlist.mjs +206 -205
  320. package/source/types/typeof.mjs +12 -10
  321. package/source/types/uniquequeue.mjs +48 -48
  322. package/source/types/uuid.mjs +32 -32
  323. package/source/types/validate.mjs +67 -67
  324. package/source/types/version.mjs +115 -105
  325. package/source/util/clone.mjs +103 -91
  326. package/source/util/comparator.mjs +97 -97
  327. package/source/util/deadmansswitch.mjs +40 -44
  328. package/source/util/freeze.mjs +10 -9
  329. package/source/util/namespace.mjs +1 -1
  330. package/source/util/processing.mjs +104 -105
  331. package/source/util/runtime.mjs +56 -44
  332. package/source/util/trimspaces.mjs +24 -24
  333. package/test/cases/components/form/button.mjs +122 -0
  334. package/test/cases/components/form/confirm-button.mjs +127 -0
  335. package/test/cases/components/form/form.mjs +317 -0
  336. package/test/cases/components/form/reload.mjs +188 -0
  337. package/test/cases/components/form/select.mjs +229 -0
  338. package/test/cases/components/form/state-button.mjs +130 -0
  339. package/test/cases/components/form/tabs.mjs +98 -0
  340. package/test/cases/components/form/template.mjs +189 -0
  341. package/test/cases/components/form/tree-select.mjs +216 -0
  342. package/test/cases/components/host/details.mjs +68 -0
  343. package/test/cases/components/host/host.mjs +70 -0
  344. package/test/cases/components/host/overlay.mjs +60 -0
  345. package/test/cases/components/host/util.mjs +79 -0
  346. package/test/cases/components/notify/message.mjs +39 -0
  347. package/test/cases/components/notify/notify.mjs +89 -0
  348. package/test/cases/dom/customcontrol.mjs +5 -4
  349. package/test/cases/math/random.mjs +0 -1
  350. package/test/cases/monster.mjs +1 -1
  351. package/test/cases/net/webconnect/message.mjs +0 -1
  352. package/test/cases/types/node.mjs +1 -1
  353. package/test/util/chai-dom.mjs +2 -2
  354. package/test/util/intersection-mock.mjs +69 -0
  355. package/test/util/jsdom.mjs +41 -25
  356. package/test/util/localstorage.mjs +1 -0
  357. package/test/util/resize-observer.mjs +29 -0
  358. package/test/util/websocket.mjs +4 -1
  359. package/test/web/import.js +16 -1
  360. package/test/web/test.html +28 -5
  361. package/test/web/tests.js +30398 -17879
@@ -10,14 +10,17 @@ import { Base } from "../types/base.mjs";
10
10
  import { getGlobal, getGlobalObject } from "../types/global.mjs";
11
11
  import { ID } from "../types/id.mjs";
12
12
  import { isArray, isObject, isString, isPrimitive } from "../types/is.mjs";
13
- import { getDocumentTranslations, Translations } from "../i18n/translations.mjs";
14
13
  import {
15
- validateFunction,
16
- validateInteger,
17
- validateObject,
18
- validatePrimitive,
19
- validateString,
20
- validateBoolean,
14
+ getDocumentTranslations,
15
+ Translations,
16
+ } from "../i18n/translations.mjs";
17
+ import {
18
+ validateFunction,
19
+ validateInteger,
20
+ validateObject,
21
+ validatePrimitive,
22
+ validateString,
23
+ validateBoolean,
21
24
  } from "../types/validate.mjs";
22
25
  import { clone } from "../util/clone.mjs";
23
26
  import { Pathfinder } from "./pathfinder.mjs";
@@ -42,53 +45,53 @@ export { Transformer };
42
45
  * @memberOf Monster.Data
43
46
  */
44
47
  class Transformer extends Base {
45
- /**
46
- *
47
- * @param {string} definition
48
- */
49
- constructor(definition) {
50
- super();
51
- this.args = disassemble(definition);
52
- this.command = this.args.shift();
53
- this.callbacks = new Map();
54
- }
55
-
56
- /**
57
- *
58
- * @param {string} name
59
- * @param {function} callback
60
- * @param {object} context
61
- * @returns {Transformer}
62
- * @throws {TypeError} value is not a string
63
- * @throws {TypeError} value is not a function
64
- */
65
- setCallback(name, callback, context) {
66
- validateString(name);
67
- validateFunction(callback);
68
-
69
- if (context !== undefined) {
70
- validateObject(context);
71
- }
72
-
73
- this.callbacks.set(name, {
74
- callback: callback,
75
- context: context,
76
- });
77
-
78
- return this;
79
- }
80
-
81
- /**
82
- *
83
- * @param {*} value
84
- * @returns {*}
85
- * @throws {Error} unknown command
86
- * @throws {TypeError} unsupported type
87
- * @throws {Error} type not supported
88
- */
89
- run(value) {
90
- return transform.apply(this, [value]);
91
- }
48
+ /**
49
+ *
50
+ * @param {string} definition
51
+ */
52
+ constructor(definition) {
53
+ super();
54
+ this.args = disassemble(definition);
55
+ this.command = this.args.shift();
56
+ this.callbacks = new Map();
57
+ }
58
+
59
+ /**
60
+ *
61
+ * @param {string} name
62
+ * @param {function} callback
63
+ * @param {object} context
64
+ * @returns {Transformer}
65
+ * @throws {TypeError} value is not a string
66
+ * @throws {TypeError} value is not a function
67
+ */
68
+ setCallback(name, callback, context) {
69
+ validateString(name);
70
+ validateFunction(callback);
71
+
72
+ if (context !== undefined) {
73
+ validateObject(context);
74
+ }
75
+
76
+ this.callbacks.set(name, {
77
+ callback: callback,
78
+ context: context,
79
+ });
80
+
81
+ return this;
82
+ }
83
+
84
+ /**
85
+ *
86
+ * @param {*} value
87
+ * @returns {*}
88
+ * @throws {Error} unknown command
89
+ * @throws {TypeError} unsupported type
90
+ * @throws {Error} type not supported
91
+ */
92
+ run(value) {
93
+ return transform.apply(this, [value]);
94
+ }
92
95
  }
93
96
 
94
97
  /**
@@ -98,41 +101,41 @@ class Transformer extends Base {
98
101
  * @private
99
102
  */
100
103
  function disassemble(command) {
101
- validateString(command);
102
-
103
- let placeholder = new Map();
104
- const regex = /((?<pattern>\\(?<char>.)){1})/gim;
105
-
106
- // The separator for args must be escaped
107
- // undefined string which should not occur normally and is also not a regex
108
- let result = command.matchAll(regex);
109
-
110
- for (let m of result) {
111
- let g = m?.["groups"];
112
- if (!isObject(g)) {
113
- continue;
114
- }
115
-
116
- let p = g?.["pattern"];
117
- let c = g?.["char"];
118
-
119
- if (p && c) {
120
- let r = `__${new ID().toString()}__`;
121
- placeholder.set(r, c);
122
- command = command.replace(p, r);
123
- }
124
- }
125
- let parts = command.split(":");
126
-
127
- parts = parts.map(function (value) {
128
- let v = value.trim();
129
- for (let k of placeholder) {
130
- v = v.replace(k[0], k[1]);
131
- }
132
- return v;
133
- });
134
-
135
- return parts;
104
+ validateString(command);
105
+
106
+ const placeholder = new Map();
107
+ const regex = /((?<pattern>\\(?<char>.)){1})/gim;
108
+
109
+ // The separator for args must be escaped
110
+ // undefined string which should not occur normally and is also not a regex
111
+ const result = command.matchAll(regex);
112
+
113
+ for (const m of result) {
114
+ const g = m?.["groups"];
115
+ if (!isObject(g)) {
116
+ continue;
117
+ }
118
+
119
+ const p = g?.["pattern"];
120
+ const c = g?.["char"];
121
+
122
+ if (p && c) {
123
+ const r = `__${new ID().toString()}__`;
124
+ placeholder.set(r, c);
125
+ command = command.replace(p, r);
126
+ }
127
+ }
128
+ let parts = command.split(":");
129
+
130
+ parts = parts.map(function (value) {
131
+ let v = value.trim();
132
+ for (const k of placeholder) {
133
+ v = v.replace(k[0], k[1]);
134
+ }
135
+ return v;
136
+ });
137
+
138
+ return parts;
136
139
  }
137
140
 
138
141
  /**
@@ -143,12 +146,12 @@ function disassemble(command) {
143
146
  * @private
144
147
  */
145
148
  function convertToString(value) {
146
- if (isObject(value) && value.hasOwnProperty("toString")) {
147
- value = value.toString();
148
- }
149
+ if (isObject(value) && value.hasOwnProperty("toString")) {
150
+ value = value.toString();
151
+ }
149
152
 
150
- validateString(value);
151
- return value;
153
+ validateString(value);
154
+ return value;
152
155
  }
153
156
 
154
157
  /**
@@ -162,636 +165,649 @@ function convertToString(value) {
162
165
  * @throws {Error} missing key parameter
163
166
  */
164
167
  function transform(value) {
165
- const console = getGlobalObject("console");
166
-
167
- let args = clone(this.args);
168
- let key;
169
- let defaultValue;
170
-
171
- let translations;
172
- let date;
173
- let locale;
174
- let timestamp;
175
- let map;
176
- let keyValue;
177
-
178
- switch (this.command) {
179
- case "static":
180
- return this.args.join(":");
181
-
182
- case "tolower":
183
- case "strtolower":
184
- case "tolowercase":
185
- validateString(value);
186
- return value.toLowerCase();
187
-
188
- case "contains":
189
- if (isString(value)) {
190
- return value.includes(args[0]);
191
- }
192
-
193
- if (isArray(value)) {
194
- return value.includes(args[0]);
195
- }
196
-
197
- if (isObject(value)) {
198
- return value.hasOwnProperty(args[0]);
199
- }
200
-
201
- return false;
202
-
203
- case "has-entries":
204
- case "hasentries":
205
- if (isObject(value)) {
206
- return Object.keys(value).length > 0;
207
- }
208
-
209
- if (isArray(value)) {
210
- return value.length > 0;
211
- }
212
-
213
- return false;
214
-
215
- case "isundefined":
216
- case "is-undefined":
217
- return value === undefined;
218
-
219
- case "isnull":
220
- case "is-null":
221
- return value === null;
222
-
223
- case "isset":
224
- case "is-set":
225
- return value !== undefined && value !== null;
226
-
227
- case "isnumber":
228
- case "is-number":
229
- return isPrimitive(value) && !isNaN(value);
230
-
231
- case "isinteger":
232
- case "is-integer":
233
- return isPrimitive(value) && !isNaN(value) && value % 1 === 0;
234
-
235
- case "isfloat":
236
- case "is-float":
237
- return isPrimitive(value) && !isNaN(value) && value % 1 !== 0;
238
-
239
- case "isobject":
240
- case "is-object":
241
- return isObject(value);
242
-
243
- case "isarray":
244
- case "is-array":
245
- return Array.isArray(value);
246
-
247
- case "not":
248
- validateBoolean(value);
249
- return !value;
250
-
251
- case "toupper":
252
- case "strtoupper":
253
- case "touppercase":
254
- validateString(value);
255
- return value.toUpperCase();
256
-
257
- case "tostring":
258
- return `${value}`;
259
-
260
- case "tointeger":
261
- let n = parseInt(value);
262
- validateInteger(n);
263
- return n;
264
-
265
- case "to-json":
266
- case "tojson":
267
- return JSON.stringify(value);
268
-
269
- case "from-json":
270
- case "fromjson":
271
- return JSON.parse(value);
272
-
273
- case "trim":
274
- validateString(value);
275
- return value.trim();
276
-
277
- case "rawurlencode":
278
- validateString(value);
279
- return encodeURIComponent(value)
280
- .replace(/!/g, "%21")
281
- .replace(/'/g, "%27")
282
- .replace(/\(/g, "%28")
283
- .replace(/\)/g, "%29")
284
- .replace(/\*/g, "%2A");
285
-
286
- case "call":
287
- /**
288
- * callback-definition
289
- * function callback(value, ...args) {
290
- * return value;
291
- * }
292
- */
293
-
294
- let callback;
295
- let callbackName = args.shift();
296
- let context = getGlobal();
297
-
298
- if (isObject(value) && value.hasOwnProperty(callbackName)) {
299
- callback = value[callbackName];
300
- } else if (this.callbacks.has(callbackName)) {
301
- let s = this.callbacks.get(callbackName);
302
- callback = s?.["callback"];
303
- context = s?.["context"];
304
- } else if (typeof window === "object" && window.hasOwnProperty(callbackName)) {
305
- callback = window[callbackName];
306
- }
307
- validateFunction(callback);
308
-
309
- args.unshift(value);
310
- return callback.call(context, ...args);
311
-
312
- case "plain":
313
- case "plaintext":
314
- validateString(value);
315
- let doc = new DOMParser().parseFromString(value, "text/html");
316
- return doc.body.textContent || "";
317
-
318
- case "if":
319
- case "?":
320
- validatePrimitive(value);
321
-
322
- let trueStatement = args.shift() || undefined;
323
- let falseStatement = args.shift() || undefined;
324
-
325
- if (trueStatement === "value") {
326
- trueStatement = value;
327
- }
328
- if (trueStatement === "\\value") {
329
- trueStatement = "value";
330
- }
331
-
332
- if (trueStatement === "\\undefined") {
333
- trueStatement = undefined;
334
- }
335
-
336
- if (trueStatement === "\\null") {
337
- trueStatement = null;
338
- }
339
-
340
- if (falseStatement === "value") {
341
- falseStatement = value;
342
- }
343
- if (falseStatement === "\\value") {
344
- falseStatement = "value";
345
- }
346
-
347
- if (falseStatement === "\\undefined") {
348
- falseStatement = undefined;
349
- }
350
-
351
- if (falseStatement === "\\null") {
352
- falseStatement = null;
353
- }
354
-
355
- let condition =
356
- (value !== undefined && value !== "" && value !== "off" && value !== "false" && value !== false) ||
357
- value === "on" ||
358
- value === "true" ||
359
- value === true;
360
- return condition ? trueStatement : falseStatement;
361
-
362
- case "ucfirst":
363
- validateString(value);
364
-
365
- let firstchar = value.charAt(0).toUpperCase();
366
- return firstchar + value.substr(1);
367
- case "ucwords":
368
- validateString(value);
369
-
370
- return value.replace(/^([a-z\u00E0-\u00FC])|\s+([a-z\u00E0-\u00FC])/g, function (v) {
371
- return v.toUpperCase();
372
- });
373
-
374
- case "count":
375
- case "length":
376
- if ((isString(value) || isObject(value) || isArray(value)) && value.hasOwnProperty("length")) {
377
- return value.length;
378
- }
379
-
380
- throw new TypeError(`unsupported type ${typeof value}`);
381
-
382
- case "to-base64":
383
- case "btoa":
384
- case "base64":
385
- return btoa(convertToString(value));
386
-
387
- case "atob":
388
- case "from-base64":
389
- return atob(convertToString(value));
390
-
391
- case "empty":
392
- return "";
393
-
394
- case "undefined":
395
- return undefined;
396
-
397
- case "debug":
398
- if (isObject(console)) {
399
- console.log(value);
400
- }
401
-
402
- return value;
403
-
404
- case "prefix":
405
- validateString(value);
406
- let prefix = args?.[0];
407
- return prefix + value;
408
-
409
- case "suffix":
410
- validateString(value);
411
- let suffix = args?.[0];
412
- return value + suffix;
413
-
414
- case "uniqid":
415
- return new ID().toString();
416
-
417
- case "first-key":
418
- case "last-key":
419
- case "nth-last-key":
420
- case "nth-key":
421
- if (!isObject(value)) {
422
- throw new Error("type not supported");
423
- }
424
-
425
- const keys = Object.keys(value).sort();
426
-
427
- if (this.command === "first-key") {
428
- key = 0;
429
- } else if (this.command === "last-key") {
430
- key = keys.length - 1;
431
- } else {
432
- key = validateInteger(parseInt(args.shift()));
433
-
434
- if (this.command === "nth-last-key") {
435
- key = keys.length - key - 1;
436
- }
437
- }
438
-
439
- defaultValue = args.shift() || "";
440
-
441
- let useKey = keys?.[key];
442
-
443
- if (value?.[useKey]) {
444
- return value?.[useKey];
445
- }
446
-
447
- return defaultValue;
448
-
449
- case "key":
450
- case "property":
451
- case "index":
452
- key = args.shift() || undefined;
453
-
454
- if (key === undefined) {
455
- throw new Error("missing key parameter");
456
- }
457
-
458
- defaultValue = args.shift() || undefined;
459
-
460
- if (value instanceof Map) {
461
- if (!value.has(key)) {
462
- return defaultValue;
463
- }
464
- return value.get(key);
465
- }
466
-
467
- if (isObject(value) || isArray(value)) {
468
- if (value?.[key]) {
469
- return value?.[key];
470
- }
471
-
472
- return defaultValue;
473
- }
474
-
475
- throw new Error("type not supported");
476
-
477
- case "path-exists":
478
- key = args.shift();
479
- if (key === undefined) {
480
- throw new Error("missing key parameter");
481
- }
482
-
483
- return new Pathfinder(value).exists(key);
484
-
485
- case "concat":
486
- let pf2 = new Pathfinder(value);
487
- let concat = "";
488
- while (args.length > 0) {
489
- key = args.shift();
490
- if (key === undefined) {
491
- throw new Error("missing key parameter");
492
- }
493
-
494
- // add empty strings
495
- if (isString(key) && key.trim() === "") {
496
- concat += key;
497
- continue;
498
- }
499
-
500
- if (!pf2.exists(key)) {
501
- concat += key;
502
- continue;
503
- }
504
- let v = pf2.getVia(key);
505
- if (!isPrimitive(v)) {
506
- throw new Error("value is not primitive");
507
- }
508
-
509
- concat += v;
510
- }
511
-
512
- return concat;
513
- case "path":
514
- key = args.shift();
515
- if (key === undefined) {
516
- throw new Error("missing key parameter");
517
- }
518
-
519
- let pf = new Pathfinder(value);
520
-
521
- if (!pf.exists(key)) {
522
- return undefined;
523
- }
524
-
525
- return pf.getVia(key);
526
-
527
- case "substring":
528
- validateString(value);
529
-
530
- let start = parseInt(args[0]) || 0;
531
- let end = (parseInt(args[1]) || 0) + start;
532
-
533
- return value.substring(start, end);
534
-
535
- case "nop":
536
- return value;
537
-
538
- case "??":
539
- case "default":
540
- if (value !== undefined && value !== null) {
541
- return value;
542
- }
543
-
544
- defaultValue = args.shift();
545
- let defaultType = args.shift();
546
- if (defaultType === undefined) {
547
- defaultType = "string";
548
- }
549
-
550
- switch (defaultType) {
551
- case "int":
552
- case "integer":
553
- return parseInt(defaultValue);
554
- case "float":
555
- return parseFloat(defaultValue);
556
- case "undefined":
557
- return undefined;
558
- case "bool":
559
- case "boolean":
560
- defaultValue = defaultValue.toLowerCase();
561
- return (
562
- (defaultValue !== "undefined" &&
563
- defaultValue !== "" &&
564
- defaultValue !== "off" &&
565
- defaultValue !== "false" &&
566
- defaultValue !== "false") ||
567
- defaultValue === "on" ||
568
- defaultValue === "true" ||
569
- defaultValue === "true"
570
- );
571
- case "string":
572
- return `${defaultValue}`;
573
- case "object":
574
- return JSON.parse(atob(defaultValue));
575
- }
576
-
577
- throw new Error("type not supported");
578
-
579
- case "map":
580
- map = new Map();
581
- while (args.length > 0) {
582
- keyValue = args.shift();
583
- if (keyValue === undefined) {
584
- throw new Error("missing key parameter");
585
- }
586
-
587
- keyValue = keyValue.split("=");
588
- map.set(keyValue[0], keyValue[1]);
589
- }
590
-
591
- return map.get(value);
592
-
593
- case "equals":
594
- if (args.length === 0) {
595
- throw new Error("missing value parameter");
596
- }
597
-
598
- validatePrimitive(value);
599
-
600
- const equalsValue = args.shift();
601
-
602
- /**
603
- * The history of “typeof null”
604
- * https://2ality.com/2013/10/typeof-null.html
605
- * In JavaScript, typeof null is 'object', which incorrectly suggests
606
- * that null is an object.
607
- */
608
- if (value === null) {
609
- if (equalsValue === "null") {
610
- return true;
611
- }
612
- return false;
613
- }
614
-
615
- const typeOfValue = typeof value;
616
-
617
- switch (typeOfValue) {
618
- case "string":
619
- return value === equalsValue;
620
- case "number":
621
- return value === parseFloat(equalsValue);
622
- case "boolean":
623
- return value === (equalsValue === "true" || equalsValue === "on");
624
- case "undefined":
625
- return equalsValue === "undefined";
626
- default:
627
- throw new Error("type not supported");
628
- }
629
-
630
- case "money":
631
- case "currency":
632
- try {
633
- locale = getLocaleOfDocument();
634
- } catch (e) {
635
- throw new Error(`unsupported locale or missing format (${e.message})`);
636
- }
637
-
638
- const currency = value.substring(0, 3);
639
- if (!currency) {
640
- throw new Error("missing currency parameter");
641
- }
642
-
643
- const maximumFractionDigits = args?.[0] || 2;
644
- const roundingIncrement = args?.[1] || 5;
645
-
646
- const nf = new Intl.NumberFormat(locale, {
647
- style: "currency",
648
- currency: currency,
649
- maximumFractionDigits: maximumFractionDigits,
650
- roundingIncrement: roundingIncrement,
651
- });
652
-
653
- return nf.format(value.substring(3));
654
-
655
- case "timestamp":
656
- date = new Date(value);
657
- timestamp = date.getTime();
658
- if (isNaN(timestamp)) {
659
- throw new Error("invalid date");
660
- }
661
- return timestamp;
662
-
663
- case "time":
664
- date = new Date(value);
665
- if (isNaN(date.getTime())) {
666
- throw new Error("invalid date");
667
- }
668
-
669
- try {
670
- locale = getLocaleOfDocument();
671
- return date.toLocaleTimeString(locale);
672
- } catch (e) {
673
- throw new Error(`unsupported locale or missing format (${e.message})`);
674
- }
675
-
676
- case "datetimeformat":
677
- date = new Date(value);
678
- if (isNaN(date.getTime())) {
679
- throw new Error("invalid date");
680
- }
681
-
682
- const options = {
683
- dateStyle: args.shift() || "medium",
684
- timeStyle: args.shift() || "medium",
685
- };
686
-
687
- try {
688
- locale = getLocaleOfDocument();
689
- return new Intl.DateTimeFormat(locale, options).format(date);
690
- } catch (e) {
691
- throw new Error(`unsupported locale or missing format (${e.message})`);
692
- }
693
-
694
- case "datetime":
695
- date = new Date(value);
696
- if (isNaN(date.getTime())) {
697
- throw new Error("invalid date");
698
- }
699
-
700
- try {
701
- locale = getLocaleOfDocument();
702
- return date.toLocaleString(locale);
703
- } catch (e) {
704
- throw new Error(`unsupported locale or missing format (${e.message})`);
705
- }
706
-
707
- case "date":
708
- date = new Date(value);
709
- if (isNaN(date.getTime())) {
710
- throw new Error("invalid date");
711
- }
712
-
713
- try {
714
- locale = getLocaleOfDocument();
715
- return date.toLocaleDateString(locale);
716
- } catch (e) {
717
- throw new Error(`unsupported locale or missing format (${e.message})`);
718
- }
719
-
720
- case "year":
721
- date = new Date(value);
722
- if (isNaN(date.getTime())) {
723
- throw new Error("invalid date");
724
- }
725
-
726
- return date.getFullYear();
727
-
728
- case "month":
729
- date = new Date(value);
730
- if (isNaN(date.getTime())) {
731
- throw new Error("invalid date");
732
- }
733
-
734
- return date.getMonth() + 1;
735
-
736
- case "day":
737
- date = new Date(value);
738
- if (isNaN(date.getTime())) {
739
- throw new Error("invalid date");
740
- }
741
-
742
- return date.getDate();
743
-
744
- case "weekday":
745
- date = new Date(value);
746
- if (isNaN(date.getTime())) {
747
- throw new Error("invalid date");
748
- }
749
-
750
- return date.getDay();
751
-
752
- case "hour":
753
- case "hours":
754
- date = new Date(value);
755
- if (isNaN(date.getTime())) {
756
- throw new Error("invalid date");
757
- }
758
-
759
- return date.getHours();
760
-
761
- case "minute":
762
- case "minutes":
763
- date = new Date(value);
764
- if (isNaN(date.getTime())) {
765
- throw new Error("invalid date");
766
- }
767
-
768
- return date.getMinutes();
769
-
770
- case "second":
771
- case "seconds":
772
- date = new Date(value);
773
- if (isNaN(date.getTime())) {
774
- throw new Error("invalid date");
775
- }
776
-
777
- return date.getSeconds();
778
-
779
- case "i18n":
780
- case "translation":
781
- translations = getDocumentTranslations();
782
- if (!(translations instanceof Translations)) {
783
- throw new Error("missing translations");
784
- }
785
-
786
- key = args.shift() || undefined;
787
- if (key === undefined) {
788
- key = value;
789
- }
790
-
791
- defaultValue = args.shift() || undefined;
792
- return translations.getText(key, defaultValue);
793
-
794
- default:
795
- throw new Error(`unknown command ${this.command}`);
796
- }
168
+ const console = getGlobalObject("console");
169
+
170
+ const args = clone(this.args);
171
+ let key;
172
+ let defaultValue;
173
+
174
+ let translations;
175
+ let date;
176
+ let locale;
177
+ let timestamp;
178
+ let map;
179
+ let keyValue;
180
+
181
+ switch (this.command) {
182
+ case "static":
183
+ return this.args.join(":");
184
+
185
+ case "tolower":
186
+ case "strtolower":
187
+ case "tolowercase":
188
+ validateString(value);
189
+ return value.toLowerCase();
190
+
191
+ case "contains":
192
+ if (isString(value)) {
193
+ return value.includes(args[0]);
194
+ }
195
+
196
+ if (isArray(value)) {
197
+ return value.includes(args[0]);
198
+ }
199
+
200
+ if (isObject(value)) {
201
+ return value.hasOwnProperty(args[0]);
202
+ }
203
+
204
+ return false;
205
+
206
+ case "has-entries":
207
+ case "hasentries":
208
+ if (isObject(value)) {
209
+ return Object.keys(value).length > 0;
210
+ }
211
+
212
+ if (isArray(value)) {
213
+ return value.length > 0;
214
+ }
215
+
216
+ return false;
217
+
218
+ case "isundefined":
219
+ case "is-undefined":
220
+ return value === undefined;
221
+
222
+ case "isnull":
223
+ case "is-null":
224
+ return value === null;
225
+
226
+ case "isset":
227
+ case "is-set":
228
+ return value !== undefined && value !== null;
229
+
230
+ case "isnumber":
231
+ case "is-number":
232
+ return isPrimitive(value) && !isNaN(value);
233
+
234
+ case "isinteger":
235
+ case "is-integer":
236
+ return isPrimitive(value) && !isNaN(value) && value % 1 === 0;
237
+
238
+ case "isfloat":
239
+ case "is-float":
240
+ return isPrimitive(value) && !isNaN(value) && value % 1 !== 0;
241
+
242
+ case "isobject":
243
+ case "is-object":
244
+ return isObject(value);
245
+
246
+ case "isarray":
247
+ case "is-array":
248
+ return Array.isArray(value);
249
+
250
+ case "not":
251
+ validateBoolean(value);
252
+ return !value;
253
+
254
+ case "toupper":
255
+ case "strtoupper":
256
+ case "touppercase":
257
+ validateString(value);
258
+ return value.toUpperCase();
259
+
260
+ case "tostring":
261
+ return `${value}`;
262
+
263
+ case "tointeger":
264
+ const n = parseInt(value);
265
+ validateInteger(n);
266
+ return n;
267
+
268
+ case "to-json":
269
+ case "tojson":
270
+ return JSON.stringify(value);
271
+
272
+ case "from-json":
273
+ case "fromjson":
274
+ return JSON.parse(value);
275
+
276
+ case "trim":
277
+ validateString(value);
278
+ return value.trim();
279
+
280
+ case "rawurlencode":
281
+ validateString(value);
282
+ return encodeURIComponent(value)
283
+ .replace(/!/g, "%21")
284
+ .replace(/'/g, "%27")
285
+ .replace(/\(/g, "%28")
286
+ .replace(/\)/g, "%29")
287
+ .replace(/\*/g, "%2A");
288
+
289
+ case "call":
290
+ /**
291
+ * callback-definition
292
+ * function callback(value, ...args) {
293
+ * return value;
294
+ * }
295
+ */
296
+
297
+ let callback;
298
+ const callbackName = args.shift();
299
+ let context = getGlobal();
300
+
301
+ if (isObject(value) && value.hasOwnProperty(callbackName)) {
302
+ callback = value[callbackName];
303
+ } else if (this.callbacks.has(callbackName)) {
304
+ const s = this.callbacks.get(callbackName);
305
+ callback = s?.["callback"];
306
+ context = s?.["context"];
307
+ } else if (
308
+ typeof window === "object" &&
309
+ window.hasOwnProperty(callbackName)
310
+ ) {
311
+ callback = window[callbackName];
312
+ }
313
+ validateFunction(callback);
314
+
315
+ args.unshift(value);
316
+ return callback.call(context, ...args);
317
+
318
+ case "plain":
319
+ case "plaintext":
320
+ validateString(value);
321
+ const doc = new DOMParser().parseFromString(value, "text/html");
322
+ return doc.body.textContent || "";
323
+
324
+ case "if":
325
+ case "?":
326
+ validatePrimitive(value);
327
+
328
+ let trueStatement = args.shift() || undefined;
329
+ let falseStatement = args.shift() || undefined;
330
+
331
+ if (trueStatement === "value") {
332
+ trueStatement = value;
333
+ }
334
+ if (trueStatement === "\\value") {
335
+ trueStatement = "value";
336
+ }
337
+
338
+ if (trueStatement === "\\undefined") {
339
+ trueStatement = undefined;
340
+ }
341
+
342
+ if (trueStatement === "\\null") {
343
+ trueStatement = null;
344
+ }
345
+
346
+ if (falseStatement === "value") {
347
+ falseStatement = value;
348
+ }
349
+ if (falseStatement === "\\value") {
350
+ falseStatement = "value";
351
+ }
352
+
353
+ if (falseStatement === "\\undefined") {
354
+ falseStatement = undefined;
355
+ }
356
+
357
+ if (falseStatement === "\\null") {
358
+ falseStatement = null;
359
+ }
360
+
361
+ const condition =
362
+ (value !== undefined &&
363
+ value !== "" &&
364
+ value !== "off" &&
365
+ value !== "false" &&
366
+ value !== false) ||
367
+ value === "on" ||
368
+ value === "true" ||
369
+ value === true;
370
+ return condition ? trueStatement : falseStatement;
371
+
372
+ case "ucfirst":
373
+ validateString(value);
374
+
375
+ const firstchar = value.charAt(0).toUpperCase();
376
+ return firstchar + value.substr(1);
377
+ case "ucwords":
378
+ validateString(value);
379
+
380
+ return value.replace(
381
+ /^([a-z\u00E0-\u00FC])|\s+([a-z\u00E0-\u00FC])/g,
382
+ function (v) {
383
+ return v.toUpperCase();
384
+ },
385
+ );
386
+
387
+ case "count":
388
+ case "length":
389
+ if (
390
+ (isString(value) || isObject(value) || isArray(value)) &&
391
+ value.hasOwnProperty("length")
392
+ ) {
393
+ return value.length;
394
+ }
395
+
396
+ throw new TypeError(`unsupported type ${typeof value}`);
397
+
398
+ case "to-base64":
399
+ case "btoa":
400
+ case "base64":
401
+ return btoa(convertToString(value));
402
+
403
+ case "atob":
404
+ case "from-base64":
405
+ return atob(convertToString(value));
406
+
407
+ case "empty":
408
+ return "";
409
+
410
+ case "undefined":
411
+ return undefined;
412
+
413
+ case "debug":
414
+ if (isObject(console)) {
415
+ console.log(value);
416
+ }
417
+
418
+ return value;
419
+
420
+ case "prefix":
421
+ validateString(value);
422
+ const prefix = args?.[0];
423
+ return prefix + value;
424
+
425
+ case "suffix":
426
+ validateString(value);
427
+ const suffix = args?.[0];
428
+ return value + suffix;
429
+
430
+ case "uniqid":
431
+ return new ID().toString();
432
+
433
+ case "first-key":
434
+ case "last-key":
435
+ case "nth-last-key":
436
+ case "nth-key":
437
+ if (!isObject(value)) {
438
+ throw new Error("type not supported");
439
+ }
440
+
441
+ const keys = Object.keys(value).sort();
442
+
443
+ if (this.command === "first-key") {
444
+ key = 0;
445
+ } else if (this.command === "last-key") {
446
+ key = keys.length - 1;
447
+ } else {
448
+ key = validateInteger(parseInt(args.shift()));
449
+
450
+ if (this.command === "nth-last-key") {
451
+ key = keys.length - key - 1;
452
+ }
453
+ }
454
+
455
+ defaultValue = args.shift() || "";
456
+
457
+ const useKey = keys?.[key];
458
+
459
+ if (value?.[useKey]) {
460
+ return value?.[useKey];
461
+ }
462
+
463
+ return defaultValue;
464
+
465
+ case "key":
466
+ case "property":
467
+ case "index":
468
+ key = args.shift() || undefined;
469
+
470
+ if (key === undefined) {
471
+ throw new Error("missing key parameter");
472
+ }
473
+
474
+ defaultValue = args.shift() || undefined;
475
+
476
+ if (value instanceof Map) {
477
+ if (!value.has(key)) {
478
+ return defaultValue;
479
+ }
480
+ return value.get(key);
481
+ }
482
+
483
+ if (isObject(value) || isArray(value)) {
484
+ if (value?.[key]) {
485
+ return value?.[key];
486
+ }
487
+
488
+ return defaultValue;
489
+ }
490
+
491
+ throw new Error("type not supported");
492
+
493
+ case "path-exists":
494
+ key = args.shift();
495
+ if (key === undefined) {
496
+ throw new Error("missing key parameter");
497
+ }
498
+
499
+ return new Pathfinder(value).exists(key);
500
+
501
+ case "concat":
502
+ const pf2 = new Pathfinder(value);
503
+ let concat = "";
504
+ while (args.length > 0) {
505
+ key = args.shift();
506
+ if (key === undefined) {
507
+ throw new Error("missing key parameter");
508
+ }
509
+
510
+ // add empty strings
511
+ if (isString(key) && key.trim() === "") {
512
+ concat += key;
513
+ continue;
514
+ }
515
+
516
+ if (!pf2.exists(key)) {
517
+ concat += key;
518
+ continue;
519
+ }
520
+ const v = pf2.getVia(key);
521
+ if (!isPrimitive(v)) {
522
+ throw new Error("value is not primitive");
523
+ }
524
+
525
+ concat += v;
526
+ }
527
+
528
+ return concat;
529
+ case "path":
530
+ key = args.shift();
531
+ if (key === undefined) {
532
+ throw new Error("missing key parameter");
533
+ }
534
+
535
+ const pf = new Pathfinder(value);
536
+
537
+ if (!pf.exists(key)) {
538
+ return undefined;
539
+ }
540
+
541
+ return pf.getVia(key);
542
+
543
+ case "substring":
544
+ validateString(value);
545
+
546
+ const start = parseInt(args[0]) || 0;
547
+ const end = (parseInt(args[1]) || 0) + start;
548
+
549
+ return value.substring(start, end);
550
+
551
+ case "nop":
552
+ return value;
553
+
554
+ case "??":
555
+ case "default":
556
+ if (value !== undefined && value !== null) {
557
+ return value;
558
+ }
559
+
560
+ defaultValue = args.shift();
561
+ let defaultType = args.shift();
562
+ if (defaultType === undefined) {
563
+ defaultType = "string";
564
+ }
565
+
566
+ switch (defaultType) {
567
+ case "int":
568
+ case "integer":
569
+ return parseInt(defaultValue);
570
+ case "float":
571
+ return parseFloat(defaultValue);
572
+ case "undefined":
573
+ return undefined;
574
+ case "bool":
575
+ case "boolean":
576
+ defaultValue = defaultValue.toLowerCase();
577
+ return (
578
+ (defaultValue !== "undefined" &&
579
+ defaultValue !== "" &&
580
+ defaultValue !== "off" &&
581
+ defaultValue !== "false" &&
582
+ defaultValue !== "false") ||
583
+ defaultValue === "on" ||
584
+ defaultValue === "true" ||
585
+ defaultValue === "true"
586
+ );
587
+ case "string":
588
+ return `${defaultValue}`;
589
+ case "object":
590
+ return JSON.parse(atob(defaultValue));
591
+ }
592
+
593
+ throw new Error("type not supported");
594
+
595
+ case "map":
596
+ map = new Map();
597
+ while (args.length > 0) {
598
+ keyValue = args.shift();
599
+ if (keyValue === undefined) {
600
+ throw new Error("missing key parameter");
601
+ }
602
+
603
+ keyValue = keyValue.split("=");
604
+ map.set(keyValue[0], keyValue[1]);
605
+ }
606
+
607
+ return map.get(value);
608
+
609
+ case "equals":
610
+ if (args.length === 0) {
611
+ throw new Error("missing value parameter");
612
+ }
613
+
614
+ validatePrimitive(value);
615
+
616
+ const equalsValue = args.shift();
617
+
618
+ /**
619
+ * The history of “typeof null”
620
+ * https://2ality.com/2013/10/typeof-null.html
621
+ * In JavaScript, typeof null is 'object', which incorrectly suggests
622
+ * that null is an object.
623
+ */
624
+ if (value === null) {
625
+ if (equalsValue === "null") {
626
+ return true;
627
+ }
628
+ return false;
629
+ }
630
+
631
+ const typeOfValue = typeof value;
632
+
633
+ switch (typeOfValue) {
634
+ case "string":
635
+ return value === equalsValue;
636
+ case "number":
637
+ return value === parseFloat(equalsValue);
638
+ case "boolean":
639
+ return value === (equalsValue === "true" || equalsValue === "on");
640
+ case "undefined":
641
+ return equalsValue === "undefined";
642
+ default:
643
+ throw new Error("type not supported");
644
+ }
645
+
646
+ case "money":
647
+ case "currency":
648
+ try {
649
+ locale = getLocaleOfDocument();
650
+ } catch (e) {
651
+ throw new Error(`unsupported locale or missing format (${e.message})`);
652
+ }
653
+
654
+ const currency = value.substring(0, 3);
655
+ if (!currency) {
656
+ throw new Error("missing currency parameter");
657
+ }
658
+
659
+ const maximumFractionDigits = args?.[0] || 2;
660
+ const roundingIncrement = args?.[1] || 5;
661
+
662
+ const nf = new Intl.NumberFormat(locale, {
663
+ style: "currency",
664
+ currency: currency,
665
+ maximumFractionDigits: maximumFractionDigits,
666
+ roundingIncrement: roundingIncrement,
667
+ });
668
+
669
+ return nf.format(value.substring(3));
670
+
671
+ case "timestamp":
672
+ date = new Date(value);
673
+ timestamp = date.getTime();
674
+ if (isNaN(timestamp)) {
675
+ throw new Error("invalid date");
676
+ }
677
+ return timestamp;
678
+
679
+ case "time":
680
+ date = new Date(value);
681
+ if (isNaN(date.getTime())) {
682
+ throw new Error("invalid date");
683
+ }
684
+
685
+ try {
686
+ locale = getLocaleOfDocument();
687
+ return date.toLocaleTimeString(locale);
688
+ } catch (e) {
689
+ throw new Error(`unsupported locale or missing format (${e.message})`);
690
+ }
691
+
692
+ case "datetimeformat":
693
+ date = new Date(value);
694
+ if (isNaN(date.getTime())) {
695
+ throw new Error("invalid date");
696
+ }
697
+
698
+ const options = {
699
+ dateStyle: args.shift() || "medium",
700
+ timeStyle: args.shift() || "medium",
701
+ };
702
+
703
+ try {
704
+ locale = getLocaleOfDocument();
705
+ return new Intl.DateTimeFormat(locale, options).format(date);
706
+ } catch (e) {
707
+ throw new Error(`unsupported locale or missing format (${e.message})`);
708
+ }
709
+
710
+ case "datetime":
711
+ date = new Date(value);
712
+ if (isNaN(date.getTime())) {
713
+ throw new Error("invalid date");
714
+ }
715
+
716
+ try {
717
+ locale = getLocaleOfDocument();
718
+ return date.toLocaleString(locale);
719
+ } catch (e) {
720
+ throw new Error(`unsupported locale or missing format (${e.message})`);
721
+ }
722
+
723
+ case "date":
724
+ date = new Date(value);
725
+ if (isNaN(date.getTime())) {
726
+ throw new Error("invalid date");
727
+ }
728
+
729
+ try {
730
+ locale = getLocaleOfDocument();
731
+ return date.toLocaleDateString(locale);
732
+ } catch (e) {
733
+ throw new Error(`unsupported locale or missing format (${e.message})`);
734
+ }
735
+
736
+ case "year":
737
+ date = new Date(value);
738
+ if (isNaN(date.getTime())) {
739
+ throw new Error("invalid date");
740
+ }
741
+
742
+ return date.getFullYear();
743
+
744
+ case "month":
745
+ date = new Date(value);
746
+ if (isNaN(date.getTime())) {
747
+ throw new Error("invalid date");
748
+ }
749
+
750
+ return date.getMonth() + 1;
751
+
752
+ case "day":
753
+ date = new Date(value);
754
+ if (isNaN(date.getTime())) {
755
+ throw new Error("invalid date");
756
+ }
757
+
758
+ return date.getDate();
759
+
760
+ case "weekday":
761
+ date = new Date(value);
762
+ if (isNaN(date.getTime())) {
763
+ throw new Error("invalid date");
764
+ }
765
+
766
+ return date.getDay();
767
+
768
+ case "hour":
769
+ case "hours":
770
+ date = new Date(value);
771
+ if (isNaN(date.getTime())) {
772
+ throw new Error("invalid date");
773
+ }
774
+
775
+ return date.getHours();
776
+
777
+ case "minute":
778
+ case "minutes":
779
+ date = new Date(value);
780
+ if (isNaN(date.getTime())) {
781
+ throw new Error("invalid date");
782
+ }
783
+
784
+ return date.getMinutes();
785
+
786
+ case "second":
787
+ case "seconds":
788
+ date = new Date(value);
789
+ if (isNaN(date.getTime())) {
790
+ throw new Error("invalid date");
791
+ }
792
+
793
+ return date.getSeconds();
794
+
795
+ case "i18n":
796
+ case "translation":
797
+ translations = getDocumentTranslations();
798
+ if (!(translations instanceof Translations)) {
799
+ throw new Error("missing translations");
800
+ }
801
+
802
+ key = args.shift() || undefined;
803
+ if (key === undefined) {
804
+ key = value;
805
+ }
806
+
807
+ defaultValue = args.shift() || undefined;
808
+ return translations.getText(key, defaultValue);
809
+
810
+ default:
811
+ throw new Error(`unknown command ${this.command}`);
812
+ }
797
813
  }