typo3-typescript-sources 13.4.20

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 (415) hide show
  1. package/.github/workflows/sync-and-publish.yml +265 -0
  2. package/.last-synced-tag +1 -0
  3. package/LICENSE.txt +339 -0
  4. package/README-TYPO3.md +166 -0
  5. package/README.md +28 -0
  6. package/adminpanel/admin-panel.ts +375 -0
  7. package/adminpanel/modules/cache.ts +27 -0
  8. package/adminpanel/modules/preview.ts +75 -0
  9. package/backend/action-button/abstract-action.ts +22 -0
  10. package/backend/action-button/deferred-action.ts +41 -0
  11. package/backend/action-button/immediate-action.ts +31 -0
  12. package/backend/action-dispatcher.ts +104 -0
  13. package/backend/ajax-data-handler/message-interface.ts +18 -0
  14. package/backend/ajax-data-handler/response-interface.ts +20 -0
  15. package/backend/ajax-data-handler.ts +214 -0
  16. package/backend/backend-exception.ts +22 -0
  17. package/backend/broadcast-message.ts +50 -0
  18. package/backend/broadcast-service.ts +52 -0
  19. package/backend/browse-database.ts +38 -0
  20. package/backend/clear-cache.ts +88 -0
  21. package/backend/clipboard-panel.ts +240 -0
  22. package/backend/close-current-window.ts +2 -0
  23. package/backend/code-editor/autocomplete/completion-result.ts +105 -0
  24. package/backend/code-editor/autocomplete/ts-code-completion.ts +142 -0
  25. package/backend/code-editor/autocomplete/ts-parser.ts +485 -0
  26. package/backend/code-editor/autocomplete/ts-ref.ts +164 -0
  27. package/backend/code-editor/element/code-mirror-element.ts +282 -0
  28. package/backend/code-editor/language/typoscript.ts +181 -0
  29. package/backend/code-editor/stream-parser/typoscript.ts +1600 -0
  30. package/backend/color-picker.ts +158 -0
  31. package/backend/color-scheme-switch.ts +179 -0
  32. package/backend/column-selector-button.ts +302 -0
  33. package/backend/context-help.ts +68 -0
  34. package/backend/context-menu-actions.ts +322 -0
  35. package/backend/context-menu.ts +751 -0
  36. package/backend/copy-to-clipboard.ts +79 -0
  37. package/backend/date-time-picker.ts +270 -0
  38. package/backend/document-save-actions.ts +159 -0
  39. package/backend/drag-tooltip.ts +285 -0
  40. package/backend/drag-uploader.ts +914 -0
  41. package/backend/element/alert-element.ts +116 -0
  42. package/backend/element/dispatch-modal-button.ts +50 -0
  43. package/backend/element/draggable-resizable-element.ts +249 -0
  44. package/backend/element/editable-page-title.ts +306 -0
  45. package/backend/element/icon-element.ts +84 -0
  46. package/backend/element/immediate-action-element.ts +89 -0
  47. package/backend/element/pagination.ts +59 -0
  48. package/backend/element/progress-bar-element.ts +172 -0
  49. package/backend/element/progress-tracker-element.ts +119 -0
  50. package/backend/element/pseudo-button.ts +58 -0
  51. package/backend/element/spinner-element.ts +51 -0
  52. package/backend/element/thumbnail-element.ts +80 -0
  53. package/backend/element-browser.ts +182 -0
  54. package/backend/enum/data-transfer-types.ts +21 -0
  55. package/backend/enum/icon-types.ts +31 -0
  56. package/backend/enum/key-types.ts +27 -0
  57. package/backend/enum/severity.ts +20 -0
  58. package/backend/enum/viewport/scaffold-identifier.ts +24 -0
  59. package/backend/event/client-request.ts +25 -0
  60. package/backend/event/consumable.ts +18 -0
  61. package/backend/event/consumer-scope.ts +54 -0
  62. package/backend/event/event-dispatcher.ts +26 -0
  63. package/backend/event/interaction-request-assignment.ts +24 -0
  64. package/backend/event/interaction-request-map.ts +75 -0
  65. package/backend/event/interaction-request.ts +48 -0
  66. package/backend/event/trigger-request.ts +56 -0
  67. package/backend/form/submit-interceptor.ts +66 -0
  68. package/backend/form-engine/container/files-control-container.ts +716 -0
  69. package/backend/form-engine/container/flex-form-container-container.ts +166 -0
  70. package/backend/form-engine/container/flex-form-section-container.ts +210 -0
  71. package/backend/form-engine/container/inline-control-container.ts +1230 -0
  72. package/backend/form-engine/container/site-language-container.ts +616 -0
  73. package/backend/form-engine/element/abstract-sortable-select-items.ts +186 -0
  74. package/backend/form-engine/element/category-element.ts +160 -0
  75. package/backend/form-engine/element/color-element.ts +81 -0
  76. package/backend/form-engine/element/datetime-element.ts +66 -0
  77. package/backend/form-engine/element/extra/char-counter.ts +112 -0
  78. package/backend/form-engine/element/extra/select-box-filter.ts +85 -0
  79. package/backend/form-engine/element/folder-element.ts +66 -0
  80. package/backend/form-engine/element/group-element.ts +47 -0
  81. package/backend/form-engine/element/json-element.ts +52 -0
  82. package/backend/form-engine/element/link-element.ts +121 -0
  83. package/backend/form-engine/element/mfa-info-element.ts +169 -0
  84. package/backend/form-engine/element/modifier/resizable.ts +27 -0
  85. package/backend/form-engine/element/modifier/tabbable.ts +29 -0
  86. package/backend/form-engine/element/online-media-form-element.ts +65 -0
  87. package/backend/form-engine/element/password-element.ts +71 -0
  88. package/backend/form-engine/element/select-multiple-side-by-side-element.ts +83 -0
  89. package/backend/form-engine/element/select-single-element.ts +82 -0
  90. package/backend/form-engine/element/select-tree-element.ts +148 -0
  91. package/backend/form-engine/element/select-tree-toolbar.ts +118 -0
  92. package/backend/form-engine/element/select-tree.ts +210 -0
  93. package/backend/form-engine/element/slug-element.ts +243 -0
  94. package/backend/form-engine/element/suggest/result-container.ts +118 -0
  95. package/backend/form-engine/element/suggest/result-item.ts +90 -0
  96. package/backend/form-engine/element/table-permission-element.ts +101 -0
  97. package/backend/form-engine/element/table-wizard-element.ts +427 -0
  98. package/backend/form-engine/element/text-element.ts +52 -0
  99. package/backend/form-engine/element/text-table-element.ts +31 -0
  100. package/backend/form-engine/field-control/add-record.ts +40 -0
  101. package/backend/form-engine/field-control/edit-popup.ts +64 -0
  102. package/backend/form-engine/field-control/insert-clipboard.ts +50 -0
  103. package/backend/form-engine/field-control/link-popup.ts +53 -0
  104. package/backend/form-engine/field-control/list-module.ts +40 -0
  105. package/backend/form-engine/field-control/password-generator.ts +102 -0
  106. package/backend/form-engine/field-control/reset-selection.ts +48 -0
  107. package/backend/form-engine/field-wizard/localization-state-selector.ts +67 -0
  108. package/backend/form-engine/field-wizard/value-picker.ts +123 -0
  109. package/backend/form-engine/field-wizard/value-slider.ts +86 -0
  110. package/backend/form-engine/inline-relation/ajax-dispatcher.ts +124 -0
  111. package/backend/form-engine/inline-relation/inline-response-interface.ts +41 -0
  112. package/backend/form-engine-link-browser-adapter.ts +129 -0
  113. package/backend/form-engine-review.ts +155 -0
  114. package/backend/form-engine-suggest.ts +133 -0
  115. package/backend/form-engine-validation.ts +686 -0
  116. package/backend/form-engine.ts +1391 -0
  117. package/backend/global-event-handler.ts +252 -0
  118. package/backend/grid-editor.ts +1077 -0
  119. package/backend/hashing/md5.ts +252 -0
  120. package/backend/helper.ts +24 -0
  121. package/backend/hotkeys/hotkey-storage.ts +63 -0
  122. package/backend/hotkeys.ts +216 -0
  123. package/backend/icons.ts +236 -0
  124. package/backend/image-manipulation.ts +885 -0
  125. package/backend/info-window.ts +46 -0
  126. package/backend/input/clearable.ts +128 -0
  127. package/backend/input/index.d.ts +8 -0
  128. package/backend/java-script-module-import-event-handler.ts +19 -0
  129. package/backend/key-bindings.ts +42 -0
  130. package/backend/layout-module/drag-drop.ts +359 -0
  131. package/backend/layout-module/paste.ts +165 -0
  132. package/backend/link-browser.ts +89 -0
  133. package/backend/live-search/element/backend-search.ts +34 -0
  134. package/backend/live-search/element/hint.ts +33 -0
  135. package/backend/live-search/element/provider/default-result-item.ts +52 -0
  136. package/backend/live-search/element/provider/page-provider-result-item.ts +52 -0
  137. package/backend/live-search/element/result/item/action/action-container.ts +135 -0
  138. package/backend/live-search/element/result/item/action/action.ts +56 -0
  139. package/backend/live-search/element/result/item/item-container.ts +224 -0
  140. package/backend/live-search/element/result/item/item.ts +74 -0
  141. package/backend/live-search/element/result/result-container.ts +110 -0
  142. package/backend/live-search/element/result/result-detail-container.ts +50 -0
  143. package/backend/live-search/element/result/result-pagination.ts +122 -0
  144. package/backend/live-search/element/search-option-item.ts +70 -0
  145. package/backend/live-search/live-search-configurator.ts +54 -0
  146. package/backend/live-search/live-search-shortcut.ts +29 -0
  147. package/backend/live-search/result-types/backend-module-result-type.ts +8 -0
  148. package/backend/live-search/result-types/default-result-type.ts +21 -0
  149. package/backend/live-search/result-types/page-result-type.ts +23 -0
  150. package/backend/localization.ts +390 -0
  151. package/backend/login-refresh.ts +525 -0
  152. package/backend/login.ts +179 -0
  153. package/backend/mail-link-handler.ts +45 -0
  154. package/backend/modal-interface.ts +19 -0
  155. package/backend/modal.ts +685 -0
  156. package/backend/module/iframe.ts +125 -0
  157. package/backend/module/router.ts +275 -0
  158. package/backend/module-menu.ts +550 -0
  159. package/backend/module.ts +133 -0
  160. package/backend/multi-record-selection-action.ts +44 -0
  161. package/backend/multi-record-selection-delete-action.ts +108 -0
  162. package/backend/multi-record-selection-edit-action.ts +56 -0
  163. package/backend/multi-record-selection.ts +468 -0
  164. package/backend/multi-step-wizard.ts +568 -0
  165. package/backend/new-content-element-wizard-button.ts +51 -0
  166. package/backend/new-multiple-pages.ts +108 -0
  167. package/backend/new-record-wizard.ts +680 -0
  168. package/backend/notification.ts +366 -0
  169. package/backend/offset.ts +40 -0
  170. package/backend/online-media.ts +110 -0
  171. package/backend/page-actions.ts +91 -0
  172. package/backend/page-link-handler.ts +51 -0
  173. package/backend/pagetsconfig/pagetsconfig-includes.ts +77 -0
  174. package/backend/popover.ts +165 -0
  175. package/backend/record-download-button.ts +104 -0
  176. package/backend/record-link-handler.ts +31 -0
  177. package/backend/record-search.ts +44 -0
  178. package/backend/recordlist.ts +230 -0
  179. package/backend/resource/resource.ts +35 -0
  180. package/backend/security/element/csp-reports.ts +406 -0
  181. package/backend/security/element/sudo-mode.ts +249 -0
  182. package/backend/security/sudo-mode-interceptor.ts +19 -0
  183. package/backend/settings/editor/editable-setting.ts +231 -0
  184. package/backend/settings/editor.ts +451 -0
  185. package/backend/settings/enum/settings-mode.enum.ts +24 -0
  186. package/backend/settings/type/base.ts +200 -0
  187. package/backend/settings/type/bool.ts +56 -0
  188. package/backend/settings/type/color.ts +64 -0
  189. package/backend/settings/type/int.ts +85 -0
  190. package/backend/settings/type/number.ts +61 -0
  191. package/backend/settings/type/page.ts +100 -0
  192. package/backend/settings/type/string.ts +77 -0
  193. package/backend/settings/type/stringlist.ts +87 -0
  194. package/backend/severity.ts +88 -0
  195. package/backend/site-inline-actions.ts +32 -0
  196. package/backend/sortable-table.ts +208 -0
  197. package/backend/storage/abstract-client-storage.ts +76 -0
  198. package/backend/storage/browser-session.ts +28 -0
  199. package/backend/storage/client.ts +28 -0
  200. package/backend/storage/module-state-storage.ts +118 -0
  201. package/backend/storage/persistent.ts +204 -0
  202. package/backend/switch-user.ts +82 -0
  203. package/backend/tabs.ts +72 -0
  204. package/backend/telephone-link-handler.ts +40 -0
  205. package/backend/tests/backend/storage/browser-storage-test.ts +87 -0
  206. package/backend/tests/backend/storage/client-test.ts +87 -0
  207. package/backend/tests/backend/utility/dom-helper-test.ts +51 -0
  208. package/backend/tests/backend-exception-test.ts +28 -0
  209. package/backend/tests/element/immediate-action-element-test.ts +81 -0
  210. package/backend/tests/form-engine-validation-test.ts +304 -0
  211. package/backend/tests/grid-editor-test.ts +29 -0
  212. package/backend/tests/hashing/md5Test.ts +28 -0
  213. package/backend/tests/icons-test.ts +23 -0
  214. package/backend/tests/notification-test.ts +161 -0
  215. package/backend/tests/popover-test.ts +83 -0
  216. package/backend/toolbar/clear-cache-menu.ts +88 -0
  217. package/backend/toolbar/live-search.ts +284 -0
  218. package/backend/toolbar/shortcut-menu.ts +254 -0
  219. package/backend/toolbar/system-information-menu.ts +161 -0
  220. package/backend/toolbar.ts +41 -0
  221. package/backend/tree/file-storage-browser.ts +194 -0
  222. package/backend/tree/file-storage-tree-container.ts +465 -0
  223. package/backend/tree/file-storage-tree.ts +42 -0
  224. package/backend/tree/page-browser.ts +272 -0
  225. package/backend/tree/page-tree-element.ts +602 -0
  226. package/backend/tree/page-tree.ts +152 -0
  227. package/backend/tree/tree-module-state.ts +159 -0
  228. package/backend/tree/tree-node-toggle.ts +31 -0
  229. package/backend/tree/tree-node.ts +97 -0
  230. package/backend/tree/tree-toolbar.ts +117 -0
  231. package/backend/tree/tree.ts +1595 -0
  232. package/backend/url-link-handler.ts +36 -0
  233. package/backend/user-pass-login.ts +255 -0
  234. package/backend/user-settings-manager.ts +189 -0
  235. package/backend/utility/collapse-state-persister.ts +205 -0
  236. package/backend/utility/collapse-state-search.ts +183 -0
  237. package/backend/utility/dom-helper.ts +91 -0
  238. package/backend/utility/drag-drop-utility.ts +47 -0
  239. package/backend/utility/message-utility.ts +45 -0
  240. package/backend/utility/top-level-module-import.ts +32 -0
  241. package/backend/utility.ts +194 -0
  242. package/backend/viewport/abstract-container.ts +22 -0
  243. package/backend/viewport/content-container.ts +98 -0
  244. package/backend/viewport/loader.ts +28 -0
  245. package/backend/viewport/navigation-container.ts +119 -0
  246. package/backend/viewport/resizable-navigation.ts +176 -0
  247. package/backend/viewport/toolbar.ts +27 -0
  248. package/backend/viewport/topbar.ts +39 -0
  249. package/backend/viewport.ts +46 -0
  250. package/backend/window-manager.ts +84 -0
  251. package/backend/wizard/move-content-element.ts +107 -0
  252. package/backend/wizard/move-page.ts +74 -0
  253. package/backend/wizard.ts +331 -0
  254. package/belog/backend-log.ts +88 -0
  255. package/beuser/backend-user-listing.ts +40 -0
  256. package/beuser/permissions.ts +291 -0
  257. package/core/ajax/ajax-request-types.ts +15 -0
  258. package/core/ajax/ajax-request.ts +202 -0
  259. package/core/ajax/ajax-response.ts +57 -0
  260. package/core/ajax/input-transformer.ts +92 -0
  261. package/core/ajax/simple-response-interface.ts +5 -0
  262. package/core/authentication/mfa-provider/totp.ts +54 -0
  263. package/core/cache/dedupe-async-task.ts +95 -0
  264. package/core/directive/markdown.ts +82 -0
  265. package/core/directive/nl2br.ts +16 -0
  266. package/core/document-service.ts +35 -0
  267. package/core/event/debounce-event.ts +40 -0
  268. package/core/event/event-interface.ts +24 -0
  269. package/core/event/regular-event.ts +58 -0
  270. package/core/event/request-animation-frame-event.ts +42 -0
  271. package/core/event/throttle-event.ts +54 -0
  272. package/core/java-script-item-handler.ts +29 -0
  273. package/core/java-script-item-processor.ts +171 -0
  274. package/core/lit-helper.ts +126 -0
  275. package/core/literals.ts +17 -0
  276. package/core/referrer-refresh.ts +2 -0
  277. package/core/security-utility.ts +89 -0
  278. package/core/tests/ajax/ajax-request-test.ts +290 -0
  279. package/core/tests/ajax/input-transformer-test.ts +64 -0
  280. package/core/tests/cache/dedupe-async-task-test.ts +152 -0
  281. package/core/tests/event/throttle-event-test.ts +47 -0
  282. package/core/tests/literals-test.ts +24 -0
  283. package/core/tests/security-utility-test.ts +50 -0
  284. package/core/utility/types.ts +9 -0
  285. package/dashboard/chart-initializer.ts +136 -0
  286. package/dashboard/dashboard.ts +1487 -0
  287. package/extensionmanager/distribution-image.ts +55 -0
  288. package/extensionmanager/main.ts +291 -0
  289. package/extensionmanager/repository.ts +195 -0
  290. package/extensionmanager/update.ts +118 -0
  291. package/extensionmanager/upload-form.ts +42 -0
  292. package/filelist/browse-files.ts +148 -0
  293. package/filelist/browse-folders.ts +94 -0
  294. package/filelist/context-menu-actions.ts +335 -0
  295. package/filelist/create-folder.ts +69 -0
  296. package/filelist/file-delete.ts +69 -0
  297. package/filelist/file-list-actions.ts +132 -0
  298. package/filelist/file-list-dragdrop.ts +139 -0
  299. package/filelist/file-list-rename-handler.ts +128 -0
  300. package/filelist/file-list-transfer-handler.ts +138 -0
  301. package/filelist/file-list.ts +396 -0
  302. package/filelist/file-replace.ts +37 -0
  303. package/filelist/linkbrowser-file-handler.ts +94 -0
  304. package/filelist/linkbrowser-folder-handler.ts +74 -0
  305. package/filelist/rename-file.ts +109 -0
  306. package/form/backend/form-editor/component/property-grid-editor.ts +340 -0
  307. package/form/backend/form-editor/core.ts +2104 -0
  308. package/form/backend/form-editor/helper.ts +226 -0
  309. package/form/backend/form-editor/inspector-component.ts +2323 -0
  310. package/form/backend/form-editor/mediator.ts +941 -0
  311. package/form/backend/form-editor/modals-component.ts +433 -0
  312. package/form/backend/form-editor/stage-component.ts +908 -0
  313. package/form/backend/form-editor/tree-component.ts +548 -0
  314. package/form/backend/form-editor/view-model.ts +1343 -0
  315. package/form/backend/form-editor.ts +846 -0
  316. package/form/backend/form-manager/main.ts +39 -0
  317. package/form/backend/form-manager/view-model.ts +789 -0
  318. package/form/backend/form-manager.ts +180 -0
  319. package/form/backend/helper.ts +60 -0
  320. package/form/frontend/date-picker.ts +38 -0
  321. package/frontend/default_frontend.ts +82 -0
  322. package/impexp/context-menu-actions.ts +50 -0
  323. package/impexp/import-export.ts +62 -0
  324. package/indexed-search/pagination.ts +26 -0
  325. package/indexed-search/statistics.ts +50 -0
  326. package/info/translation-status.ts +48 -0
  327. package/install/ajax/ajax-queue.ts +83 -0
  328. package/install/init-install.ts +2 -0
  329. package/install/init-installer.ts +2 -0
  330. package/install/install.ts +25 -0
  331. package/install/installer.ts +458 -0
  332. package/install/message-interface.ts +18 -0
  333. package/install/module/abstract-inline-module.ts +27 -0
  334. package/install/module/abstract-interactable-module.ts +107 -0
  335. package/install/module/environment/environment-check.ts +92 -0
  336. package/install/module/environment/folder-structure.ts +145 -0
  337. package/install/module/environment/image-processing.ts +141 -0
  338. package/install/module/environment/mail-test.ts +127 -0
  339. package/install/module/environment/php-info.ts +50 -0
  340. package/install/module/environment/system-information.ts +50 -0
  341. package/install/module/maintenance/cache.ts +59 -0
  342. package/install/module/maintenance/clear-tables.ts +134 -0
  343. package/install/module/maintenance/clear-typo3temp-files.ts +137 -0
  344. package/install/module/maintenance/create-admin.ts +126 -0
  345. package/install/module/maintenance/database-analyzer.ts +266 -0
  346. package/install/module/maintenance/dump-autoload.ts +58 -0
  347. package/install/module/maintenance/language-packs.ts +338 -0
  348. package/install/module/maintenance/reset-backend-user-uc.ts +58 -0
  349. package/install/module/password-strength.ts +56 -0
  350. package/install/module/settings/change-install-tool-password.ts +101 -0
  351. package/install/module/settings/extension-configuration.ts +224 -0
  352. package/install/module/settings/features.ts +102 -0
  353. package/install/module/settings/local-configuration.ts +316 -0
  354. package/install/module/settings/presets.ts +147 -0
  355. package/install/module/settings/system-maintainer.ts +111 -0
  356. package/install/module/upgrade/core-update.ts +255 -0
  357. package/install/module/upgrade/extension-compat-tester.ts +195 -0
  358. package/install/module/upgrade/extension-scanner.ts +381 -0
  359. package/install/module/upgrade/tca-ext-tables-check.ts +93 -0
  360. package/install/module/upgrade/tca-migrations-check.ts +101 -0
  361. package/install/module/upgrade/upgrade-docs.ts +310 -0
  362. package/install/module/upgrade/upgrade-wizards.ts +612 -0
  363. package/install/renderable/clearable.ts +113 -0
  364. package/install/renderable/flash-message.ts +64 -0
  365. package/install/renderable/info-box.ts +66 -0
  366. package/install/renderable/language-packs.ts +304 -0
  367. package/install/renderable/offset-group.ts +38 -0
  368. package/install/renderable/severity.ts +49 -0
  369. package/install/renderable/wrap-group.ts +36 -0
  370. package/install/router.ts +468 -0
  371. package/linkvalidator/linkvalidator-modal.ts +45 -0
  372. package/linkvalidator/linkvalidator.ts +101 -0
  373. package/lowlevel/query-generator.ts +132 -0
  374. package/lowlevel/reference-index.ts +44 -0
  375. package/opendocs/toolbar/opendocs-menu.ts +117 -0
  376. package/package.json +34 -0
  377. package/recycler/recycler.ts +539 -0
  378. package/redirects/event-handler.ts +108 -0
  379. package/redirects/form-engine-evaluation.ts +34 -0
  380. package/redirects/redirects-module.ts +58 -0
  381. package/rte-ckeditor/ckeditor5.ts +402 -0
  382. package/rte-ckeditor/css-prefixer.ts +94 -0
  383. package/rte-ckeditor/legacy/ckeditor5-bundle.ts +17 -0
  384. package/rte-ckeditor/legacy/ckeditor5-inspector.ts +2 -0
  385. package/rte-ckeditor/plugin/typo3-link.ts +810 -0
  386. package/rte-ckeditor/plugin/whitespace.ts +114 -0
  387. package/rte-ckeditor/rte-link-browser.ts +112 -0
  388. package/rte-ckeditor/tests/css-prefixer-test.ts +314 -0
  389. package/scheduler/scheduler-add-group.ts +119 -0
  390. package/scheduler/scheduler-editable-group-name.ts +307 -0
  391. package/scheduler/scheduler-sortable-groups.ts +59 -0
  392. package/scheduler/scheduler.ts +466 -0
  393. package/setup/setup-module.ts +122 -0
  394. package/styleguide/checkbox-demo.ts +5 -0
  395. package/styleguide/element/theme-switcher-element.ts +101 -0
  396. package/styleguide/filter.ts +22 -0
  397. package/styleguide/find-icons.ts +78 -0
  398. package/styleguide/processing-indicator.ts +78 -0
  399. package/styleguide/render-notifications.ts +64 -0
  400. package/sys-note/element/delete-button.ts +78 -0
  401. package/tstemplate/constant-editor.ts +64 -0
  402. package/tstemplate/information-module.ts +31 -0
  403. package/tstemplate/template-analyzer.ts +77 -0
  404. package/viewpage/main.ts +253 -0
  405. package/workspaces/backend.ts +979 -0
  406. package/workspaces/preview.ts +232 -0
  407. package/workspaces/renderable/comment-view.ts +79 -0
  408. package/workspaces/renderable/diff-view.ts +58 -0
  409. package/workspaces/renderable/history-view.ts +97 -0
  410. package/workspaces/renderable/record-information.ts +118 -0
  411. package/workspaces/renderable/record-table.ts +355 -0
  412. package/workspaces/renderable/send-to-stage-form.ts +108 -0
  413. package/workspaces/toolbar/workspaces-menu.ts +190 -0
  414. package/workspaces/utility/icon-helper.ts +57 -0
  415. package/workspaces/workspaces.ts +136 -0
@@ -0,0 +1,291 @@
1
+ /*
2
+ * This file is part of the TYPO3 CMS project.
3
+ *
4
+ * It is free software; you can redistribute it and/or modify it under
5
+ * the terms of the GNU General Public License, either version 2
6
+ * of the License, or any later version.
7
+ *
8
+ * For the full copyright and license information, please read the
9
+ * LICENSE.txt file that was distributed with this source code.
10
+ *
11
+ * The TYPO3 project - inspiring people to share!
12
+ */
13
+
14
+ import type { AjaxResponse } from '@typo3/core/ajax/ajax-response';
15
+ import RegularEvent from '@typo3/core/event/regular-event';
16
+ import AjaxRequest from '@typo3/core/ajax/ajax-request';
17
+
18
+ /**
19
+ * Module: @typo3/beuser/permissions
20
+ * Javascript functions regarding the permissions module
21
+ */
22
+ class Permissions {
23
+ private readonly options: any = {
24
+ containerSelector: '#typo3-permissionList',
25
+ editControllerSelector: '#PermissionControllerEdit',
26
+ };
27
+
28
+ private readonly ajaxUrl: string = TYPO3.settings.ajaxUrls.user_access_permissions;
29
+
30
+ constructor() {
31
+ this.initializeCheckboxGroups();
32
+ this.initializeEvents();
33
+ }
34
+
35
+ /**
36
+ * Changes the value of the permissions in the form
37
+ */
38
+ private static setPermissionCheckboxes(checknames: string, permissionValue: number): void {
39
+ const permissionCheckboxes: NodeListOf<HTMLInputElement> = document.querySelectorAll(`input[type="checkbox"][name^="${checknames}"]`);
40
+ for (const permissionCheckbox of permissionCheckboxes) {
41
+ const value = parseInt(permissionCheckbox.value, 10);
42
+ permissionCheckbox.checked = (permissionValue & value) === value;
43
+ }
44
+ }
45
+
46
+ /**
47
+ * checks for a change of the permissions in the form
48
+ */
49
+ private static updatePermissionValue(checknames: string, varname: string): void {
50
+ let permissionValue = 0;
51
+ const checkedPermissionCheckboxes: NodeListOf<HTMLInputElement> = document.querySelectorAll(`input[type="checkbox"][name^="${checknames}"]:checked`);
52
+ for (const permissionCheckbox of checkedPermissionCheckboxes) {
53
+ permissionValue |= parseInt(permissionCheckbox.value, 10);
54
+ }
55
+ document.forms.namedItem('editform')[varname].value = permissionValue | (checknames === 'check[perms_user]' ? 1 : 0);
56
+ }
57
+
58
+ /**
59
+ * Changes permissions by sending an AJAX request to the server
60
+ */
61
+ private setPermissions(element: HTMLElement): void {
62
+ const page = element.dataset.page;
63
+ const who = element.dataset.who;
64
+ const bits = element.dataset.bits;
65
+
66
+ (new AjaxRequest(this.ajaxUrl)).post({
67
+ page: page,
68
+ who: who,
69
+ permissions: element.dataset.permissions,
70
+ mode: element.dataset.mode,
71
+ bits: element.dataset.bits,
72
+ }).then(async (response: AjaxResponse): Promise<void> => {
73
+ const data = await response.resolve();
74
+ const parentElement = element.parentElement;
75
+ parentElement.innerHTML = data;
76
+ const targetElement = parentElement.querySelector('button[data-bits="' + bits + '"]') as HTMLButtonElement;
77
+ targetElement.focus();
78
+ });
79
+ }
80
+
81
+ /**
82
+ * changes the flag to lock the editing on a page by sending an AJAX request
83
+ */
84
+ private toggleEditLock(element: HTMLElement): void {
85
+ const page = element.dataset.page;
86
+ (new AjaxRequest(this.ajaxUrl)).post({
87
+ action: 'toggle_edit_lock',
88
+ page: page,
89
+ editLockState: element.dataset.lockstate,
90
+ }).then(async (response: AjaxResponse): Promise<void> => {
91
+ const data = await response.resolve();
92
+ const parentElement = element.parentElement;
93
+ element.outerHTML = data;
94
+ const targetElement = parentElement.querySelector('button[data-page="' + page + '"]') as HTMLButtonElement;
95
+ targetElement.focus();
96
+ });
97
+ }
98
+
99
+ /**
100
+ * Owner-related: Set the new owner of a page by executing an ajax call
101
+ */
102
+ private changeOwner(element: HTMLElement): void {
103
+ const page = element.dataset.page;
104
+ const container: HTMLElement = document.getElementById('o_' + page);
105
+
106
+ (new AjaxRequest(this.ajaxUrl)).post({
107
+ action: 'change_owner',
108
+ page: page,
109
+ ownerUid: element.dataset.owner,
110
+ newOwnerUid: (container.getElementsByTagName('select')[0] as HTMLSelectElement).value,
111
+ }).then(async (response: AjaxResponse): Promise<void> => {
112
+ // Replace content
113
+ container.outerHTML = await response.resolve();
114
+ });
115
+ }
116
+
117
+ /**
118
+ * Owner-related: load the selector for selecting
119
+ * the owner of a page by executing an ajax call
120
+ */
121
+ private showChangeOwnerSelector(element: HTMLElement): void {
122
+ const page = element.dataset.page;
123
+
124
+ (new AjaxRequest(this.ajaxUrl)).post({
125
+ action: 'show_change_owner_selector',
126
+ page: page,
127
+ ownerUid: element.dataset.owner,
128
+ username: element.dataset.username,
129
+ }).then(async (response: AjaxResponse): Promise<void> => {
130
+ // Replace content
131
+ document.getElementById('o_' + page).outerHTML = await response.resolve();
132
+ });
133
+ }
134
+
135
+ /**
136
+ * Owner-related: Update the HTML view and show the original owner
137
+ */
138
+ private restoreOwner(element: HTMLElement): void {
139
+ const page = element.dataset.page;
140
+ const username = element.dataset.username ?? element.dataset.ifNotSet;
141
+ const span = document.createElement('span');
142
+ span.setAttribute('id', `o_${page}`);
143
+
144
+ const buttonSelector = document.createElement('button');
145
+ buttonSelector.classList.add('ug_selector', 'changeowner', 'btn', 'btn-sm', 'btn-link');
146
+ buttonSelector.setAttribute('type', 'button');
147
+ buttonSelector.setAttribute('data-page', page);
148
+ buttonSelector.setAttribute('data-owner', element.dataset.owner);
149
+ buttonSelector.setAttribute('data-username', username);
150
+ buttonSelector.innerText = username;
151
+ span.appendChild(buttonSelector);
152
+
153
+ // Replace content
154
+ const container = document.getElementById('o_' + page);
155
+ container.parentNode.replaceChild(span, container);
156
+ }
157
+
158
+ /**
159
+ * Group-related: Update the HTML view and show the original group
160
+ */
161
+ private restoreGroup(element: HTMLElement): void {
162
+ const page = element.dataset.page;
163
+ const groupname = element.dataset.groupname ?? element.dataset.ifNotSet;
164
+ const span = document.createElement('span');
165
+ span.setAttribute('id', `g_${page}`);
166
+
167
+ const buttonSelector = document.createElement('button');
168
+ buttonSelector.classList.add('ug_selector', 'changegroup', 'btn', 'btn-sm', 'btn-link');
169
+ buttonSelector.setAttribute('type', 'button');
170
+ buttonSelector.setAttribute('data-page', page);
171
+ buttonSelector.setAttribute('data-group-id', element.dataset.groupId);
172
+ buttonSelector.setAttribute('data-groupname', groupname);
173
+ buttonSelector.innerText = groupname;
174
+ span.appendChild(buttonSelector);
175
+
176
+ // Replace content
177
+ const container = document.getElementById('g_' + page);
178
+ container.parentNode.replaceChild(span, container);
179
+ }
180
+
181
+ /**
182
+ * Group-related: Set the new group by executing an ajax call
183
+ */
184
+ private changeGroup(element: HTMLElement): void {
185
+ const page = element.dataset.page;
186
+ const container: HTMLElement = document.getElementById('g_' + page);
187
+
188
+ (new AjaxRequest(this.ajaxUrl)).post({
189
+ action: 'change_group',
190
+ page: page,
191
+ groupUid: element.dataset.groupId,
192
+ newGroupUid: (container.getElementsByTagName('select')[0] as HTMLSelectElement).value,
193
+ }).then(async (response: AjaxResponse): Promise<void> => {
194
+ // Replace content
195
+ container.outerHTML = await response.resolve();
196
+ });
197
+ }
198
+
199
+ /**
200
+ * Group-related: Load the selector by executing an ajax call
201
+ */
202
+ private showChangeGroupSelector(element: HTMLElement): void {
203
+ const page = element.dataset.page;
204
+ (new AjaxRequest(this.ajaxUrl)).post({
205
+ action: 'show_change_group_selector',
206
+ page: page,
207
+ groupUid: element.dataset.groupId,
208
+ groupname: element.dataset.groupname,
209
+ }).then(async (response: AjaxResponse): Promise<void> => {
210
+ // Replace content
211
+ document.getElementById('g_' + page).outerHTML = await response.resolve();
212
+ });
213
+ }
214
+
215
+ private initializeCheckboxGroups(): void {
216
+ const checkboxGroups: NodeListOf<HTMLInputElement> = document.querySelectorAll('[data-checkbox-group]');
217
+ checkboxGroups.forEach((checkboxGroupCheckbox): void => {
218
+ const permissionGroup = checkboxGroupCheckbox.dataset.checkboxGroup;
219
+ const permissionValue = parseInt(checkboxGroupCheckbox.value, 10);
220
+ Permissions.setPermissionCheckboxes(permissionGroup, permissionValue);
221
+ });
222
+ }
223
+
224
+ /**
225
+ * initializes events using deferred bound to document
226
+ * so AJAX reloads are no problem
227
+ */
228
+ private initializeEvents(): void {
229
+ const containerSelector = document.querySelector(this.options.containerSelector);
230
+ const editControllerSelector = document.querySelector(this.options.editControllerSelector);
231
+
232
+ if (containerSelector !== null) {
233
+ new RegularEvent('click', (e: Event, currentTarget: Element): void => {
234
+ e.preventDefault();
235
+ this.setPermissions(currentTarget as HTMLElement);
236
+ }).delegateTo(containerSelector, '.change-permission');
237
+
238
+ // Click event for lock state
239
+ new RegularEvent('click', (e: Event, currentTarget: Element): void => {
240
+ e.preventDefault();
241
+ this.toggleEditLock(currentTarget as HTMLElement);
242
+ }).delegateTo(containerSelector, '.editlock');
243
+
244
+ // Click event to change owner
245
+ new RegularEvent('click', (e: Event, currentTarget: Element): void => {
246
+ e.preventDefault();
247
+ this.showChangeOwnerSelector(currentTarget as HTMLElement);
248
+ }).delegateTo(containerSelector, '.changeowner');
249
+
250
+ // Click event to change group
251
+ new RegularEvent('click', (e: Event, currentTarget: Element): void => {
252
+ e.preventDefault();
253
+ this.showChangeGroupSelector(currentTarget as HTMLElement);
254
+ }).delegateTo(containerSelector, '.changegroup');
255
+
256
+ // Add click handler for restoring previous owner
257
+ new RegularEvent('click', (e: Event, currentTarget: Element): void => {
258
+ e.preventDefault();
259
+ this.restoreOwner(currentTarget as HTMLElement);
260
+ }).delegateTo(containerSelector, '.restoreowner');
261
+
262
+ // Add click handler for saving owner
263
+ new RegularEvent('click', (e: Event, currentTarget: Element): void => {
264
+ e.preventDefault();
265
+ this.changeOwner(currentTarget as HTMLElement);
266
+ }).delegateTo(containerSelector, '.saveowner');
267
+
268
+ // Add click handler for restoring previous group
269
+ new RegularEvent('click', (e: Event, currentTarget: Element): void => {
270
+ e.preventDefault();
271
+ this.restoreGroup(currentTarget as HTMLElement);
272
+ }).delegateTo(containerSelector, '.restoregroup');
273
+
274
+ // Add click handler for saving group
275
+ new RegularEvent('click', (e: Event, currentTarget: Element): void => {
276
+ e.preventDefault();
277
+ this.changeGroup(currentTarget as HTMLElement);
278
+ }).delegateTo(containerSelector, '.savegroup');
279
+ }
280
+
281
+ if (editControllerSelector !== null) {
282
+ // Click events to change permissions (in template Edit.html)
283
+ new RegularEvent('click', (e: Event, currentTarget: Element): void => {
284
+ const args = (currentTarget as HTMLElement).dataset.checkChangePermissions.split(',').map((item: string) => item.trim());
285
+ Permissions.updatePermissionValue.apply(this, args);
286
+ }).delegateTo(editControllerSelector, '[data-check-change-permissions]');
287
+ }
288
+ }
289
+ }
290
+
291
+ export default new Permissions();
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This file is part of the TYPO3 CMS project.
3
+ *
4
+ * It is free software; you can redistribute it and/or modify it under
5
+ * the terms of the GNU General Public License, either version 2
6
+ * of the License, or any later version.
7
+ *
8
+ * For the full copyright and license information, please read the
9
+ * LICENSE.txt file that was distributed with this source code.
10
+ *
11
+ * The TYPO3 project - inspiring people to share!
12
+ */
13
+
14
+ export type RequestHandler = (request: Request) => Promise<Response>;
15
+ export type RequestMiddleware = (request: Request, next: RequestHandler) => Promise<Response>;
@@ -0,0 +1,202 @@
1
+ /*
2
+ * This file is part of the TYPO3 CMS project.
3
+ *
4
+ * It is free software; you can redistribute it and/or modify it under
5
+ * the terms of the GNU General Public License, either version 2
6
+ * of the License, or any later version.
7
+ *
8
+ * For the full copyright and license information, please read the
9
+ * LICENSE.txt file that was distributed with this source code.
10
+ *
11
+ * The TYPO3 project - inspiring people to share!
12
+ */
13
+
14
+ import { AjaxResponse } from '@typo3/core/ajax/ajax-response';
15
+ import { InputTransformer, type GenericKeyValue } from './input-transformer';
16
+ import type { RequestMiddleware, RequestHandler } from '@typo3/core/ajax/ajax-request-types';
17
+
18
+ /**
19
+ * @example send data as `Content-Type: multipart/form-data` (default)
20
+ * const request = new AjaxRequest('/endpoint');
21
+ * const response = request.post({item: { first: 'value'}});
22
+ * // sends `item[first]=value` in request body (analogous)
23
+ * // can be used like this server-side
24
+ * // `$value = ServerRequest::getParsedBody()['item']['first']`
25
+ *
26
+ * @example send data as `Content-Type: application/json` (must be set explicit)
27
+ * const request = new AjaxRequest('/endpoint');
28
+ * const response = request.post({item: { first: 'value'}});
29
+ * // sends `{"item":{"first":"value"}}` in request body
30
+ * // can be used like this server-side
31
+ * // `$value = json_decode((string)ServerRequest::getBody(), true)['item']['first']`
32
+ */
33
+ class AjaxRequest {
34
+ private static readonly defaultOptions: RequestInit = {
35
+ credentials: 'same-origin'
36
+ };
37
+
38
+ private readonly url: URL;
39
+ private readonly abortController: AbortController;
40
+ private fetch: RequestHandler;
41
+
42
+ constructor(url: URL|string) {
43
+ this.url = url instanceof URL ? url : new URL(url, window.location.origin + window.location.pathname);
44
+ this.abortController = new AbortController();
45
+ this.fetch = (request: Request) => fetch(request);
46
+ }
47
+
48
+ /**
49
+ * Clones the AjaxRequest object, generates the final query string and uses it for the request
50
+ *
51
+ * @param {string|array|GenericKeyValue} data
52
+ * @return {AjaxRequest}
53
+ */
54
+ public withQueryArguments(data: string | Array<string> | GenericKeyValue | URLSearchParams): AjaxRequest {
55
+ const clone = this.clone();
56
+
57
+ if (!(data instanceof URLSearchParams)) {
58
+ data = new URLSearchParams(InputTransformer.toSearchParams(data));
59
+ }
60
+ for (const [key, value] of data.entries()) {
61
+ this.url.searchParams.append(key, value);
62
+ }
63
+ return clone;
64
+ }
65
+
66
+ /**
67
+ * Executes a regular GET request
68
+ *
69
+ * @param {RequestInit} init
70
+ * @return {Promise<Response>}
71
+ */
72
+ public async get(init: RequestInit = {}): Promise<AjaxResponse> {
73
+ const localDefaultOptions: RequestInit = {
74
+ method: 'GET',
75
+ };
76
+
77
+ const response = await this.send({ ...localDefaultOptions, ...init });
78
+ return new AjaxResponse(response);
79
+ }
80
+
81
+ /**
82
+ * Executes a (by default uncached) POST request
83
+ *
84
+ * @param {string | FormData | GenericKeyValue} data
85
+ * @param {RequestInit} init
86
+ * @return {Promise<Response>}
87
+ */
88
+ public async post(data: string | FormData | GenericKeyValue, init: RequestInit = {}): Promise<AjaxResponse> {
89
+ const localDefaultOptions: RequestInit = {
90
+ body: typeof data === 'string' || data instanceof FormData ? data : ( Object.keys(data).length ? InputTransformer.byHeader(data, init?.headers) : ''),
91
+ cache: 'no-cache',
92
+ method: 'POST',
93
+ };
94
+
95
+ const response = await this.send({ ...localDefaultOptions, ...init });
96
+ return new AjaxResponse(response);
97
+ }
98
+
99
+ /**
100
+ * Executes a (by default uncached) PUT request
101
+ *
102
+ * @param {string | FormData | GenericKeyValue} data
103
+ * @param {RequestInit} init
104
+ * @return {Promise<Response>}
105
+ */
106
+ public async put(data: string | FormData | GenericKeyValue, init: RequestInit = {}): Promise<AjaxResponse> {
107
+ const localDefaultOptions: RequestInit = {
108
+ body: typeof data === 'string' || data instanceof FormData ? data : InputTransformer.byHeader(data, init?.headers),
109
+ cache: 'no-cache',
110
+ method: 'PUT',
111
+ };
112
+
113
+ const response = await this.send({ ...localDefaultOptions, ...init });
114
+ return new AjaxResponse(response);
115
+ }
116
+
117
+ /**
118
+ * Executes a regular DELETE request
119
+ *
120
+ * @param {string | FormData | GenericKeyValue} data
121
+ * @param {RequestInit} init
122
+ * @return {Promise<Response>}
123
+ */
124
+ public async delete(data: string | FormData | GenericKeyValue = {}, init: RequestInit = {}): Promise<AjaxResponse> {
125
+ const localDefaultOptions: RequestInit = {
126
+ cache: 'no-cache',
127
+ method: 'DELETE',
128
+ };
129
+
130
+ if ((typeof data === 'string' && data.length > 0) || data instanceof FormData) {
131
+ localDefaultOptions.body = data;
132
+ } else if (typeof data === 'object' && Object.keys(data).length > 0) {
133
+ localDefaultOptions.body = InputTransformer.byHeader(data, init?.headers);
134
+ }
135
+
136
+ const response = await this.send({ ...localDefaultOptions, ...init });
137
+ return new AjaxResponse(response);
138
+ }
139
+
140
+ /**
141
+ * Aborts the current request by using the AbortController
142
+ */
143
+ public abort(): void {
144
+ this.abortController.abort();
145
+ }
146
+
147
+ /**
148
+ * Adds an outer middleware around the fetch invocation.
149
+ * Previous registered middlewares are handled after
150
+ * the one(s) that is/are added here.
151
+ *
152
+ * @param {RequestMiddleware | RequestMiddleware[]} middleware
153
+ * @return {AjaxRequest}
154
+ */
155
+ public addMiddleware(middleware: RequestMiddleware | RequestMiddleware[]): AjaxRequest {
156
+ if (Array.isArray(middleware)) {
157
+ middleware.forEach(middleware => this.addMiddleware(middleware));
158
+ return this;
159
+ }
160
+
161
+ const next = this.fetch;
162
+ this.fetch = (request: Request) => middleware(request, next);
163
+ return this;
164
+ }
165
+
166
+ /**
167
+ * Clones the current AjaxRequest object
168
+ *
169
+ * @return {AjaxRequest}
170
+ */
171
+ private clone(): AjaxRequest {
172
+ return Object.assign(Object.create(this), this);
173
+ }
174
+
175
+ /**
176
+ * Sends the requests by using the fetch API
177
+ *
178
+ * @param {RequestInit} init
179
+ * @return {Promise<Response>}
180
+ */
181
+ private async send(init: RequestInit = {}): Promise<Response> {
182
+ const response = await this.fetch(new Request(this.url, this.getMergedOptions(init)));
183
+ if (!response.ok) {
184
+ throw new AjaxResponse(response);
185
+ }
186
+ return response;
187
+ }
188
+
189
+ /**
190
+ * Merge the incoming RequestInit object with the pre-defined default options
191
+ *
192
+ * @param {RequestInit} init
193
+ * @return {RequestInit}
194
+ */
195
+ private getMergedOptions(init: RequestInit): RequestInit {
196
+ const { signal, ...initOptions } = init;
197
+ signal?.addEventListener('abort', () => this.abortController.abort());
198
+ return { ...AjaxRequest.defaultOptions, ...initOptions, signal: this.abortController.signal };
199
+ }
200
+ }
201
+
202
+ export default AjaxRequest;
@@ -0,0 +1,57 @@
1
+ /*
2
+ * This file is part of the TYPO3 CMS project.
3
+ *
4
+ * It is free software; you can redistribute it and/or modify it under
5
+ * the terms of the GNU General Public License, either version 2
6
+ * of the License, or any later version.
7
+ *
8
+ * For the full copyright and license information, please read the
9
+ * LICENSE.txt file that was distributed with this source code.
10
+ *
11
+ * The TYPO3 project - inspiring people to share!
12
+ */
13
+
14
+ import type SimpleResponseInterface from './simple-response-interface';
15
+
16
+ export class AjaxResponse {
17
+ public readonly response: Response;
18
+ private resolvedBody: string | any;
19
+
20
+ constructor(response: Response) {
21
+ this.response = response;
22
+ }
23
+
24
+ public async resolve(expectedType?: string): Promise<string | any> {
25
+ // streams can only be read once
26
+ // (otherwise response would have to be cloned)
27
+ if (typeof this.resolvedBody !== 'undefined') {
28
+ return this.resolvedBody;
29
+ }
30
+ const contentType: string = this.response.headers.get('Content-Type') ?? '';
31
+ if (expectedType === 'json' || contentType.startsWith('application/json')) {
32
+ this.resolvedBody = await this.response.json();
33
+ } else {
34
+ this.resolvedBody = await this.response.text();
35
+ }
36
+ return this.resolvedBody;
37
+ }
38
+
39
+ public raw(): Response {
40
+ return this.response;
41
+ }
42
+
43
+ /**
44
+ * Dereferences response data from current `window` scope. A dereferenced
45
+ * response (`SimpleResponseInterface`) can be used in events or messages
46
+ * for broadcasting to other windows/frames.
47
+ */
48
+ public async dereference(): Promise<SimpleResponseInterface> {
49
+ const headers = new Map<string, string>();
50
+ this.response.headers.forEach((value: string, name: string) => headers.set(name, value));
51
+ return {
52
+ status: this.response.status,
53
+ headers: headers,
54
+ body: await this.resolve()
55
+ } as SimpleResponseInterface;
56
+ }
57
+ }
@@ -0,0 +1,92 @@
1
+ /*
2
+ * This file is part of the TYPO3 CMS project.
3
+ *
4
+ * It is free software; you can redistribute it and/or modify it under
5
+ * the terms of the GNU General Public License, either version 2
6
+ * of the License, or any later version.
7
+ *
8
+ * For the full copyright and license information, please read the
9
+ * LICENSE.txt file that was distributed with this source code.
10
+ *
11
+ * The TYPO3 project - inspiring people to share!
12
+ */
13
+
14
+ export type GenericKeyValue = { [key: string]: any};
15
+
16
+ export class InputTransformer {
17
+ /**
18
+ * Transforms data by its incoming headers
19
+ *
20
+ * @param data
21
+ * @param headers
22
+ */
23
+ public static byHeader(data: GenericKeyValue, headers: GenericKeyValue = {}): FormData | string {
24
+ if ('Content-Type' in headers && headers['Content-Type'].includes('application/json')) {
25
+ return JSON.stringify(data);
26
+ }
27
+
28
+ return InputTransformer.toFormData(data);
29
+ }
30
+
31
+ /**
32
+ * Transforms the incoming object to a flat FormData object used for POST and PUT
33
+ *
34
+ * @param {GenericKeyValue} data
35
+ * @return {FormData}
36
+ */
37
+ public static toFormData(data: GenericKeyValue): FormData {
38
+ const flattenedData = InputTransformer.filter(InputTransformer.flattenObject(data));
39
+ const formData = new FormData();
40
+ for (const [key, value] of Object.entries(flattenedData)) {
41
+ formData.set(key, value);
42
+ }
43
+
44
+ return formData;
45
+ }
46
+
47
+ /**
48
+ * Transforms the incoming object to a flat URLSearchParams object used for GET
49
+ *
50
+ * @param {string | Array<string> | GenericKeyValue} data
51
+ * @return {string}
52
+ */
53
+ public static toSearchParams(data: string | Array<string> | GenericKeyValue): string {
54
+ if (typeof data === 'string') {
55
+ return data;
56
+ }
57
+
58
+ if (data instanceof Array) {
59
+ return data.join('&');
60
+ }
61
+
62
+ const flattenedData = InputTransformer.filter(InputTransformer.flattenObject(data));
63
+ const searchParams = new URLSearchParams();
64
+ for (const [key, value] of Object.entries(flattenedData)) {
65
+ searchParams.set(key, value);
66
+ }
67
+
68
+ return decodeURI(searchParams.toString());
69
+ }
70
+
71
+ private static flattenObject(obj: GenericKeyValue, prefix: string = ''): GenericKeyValue {
72
+ return Object.keys(obj).reduce((accumulator: GenericKeyValue, currentValue: any) => {
73
+ const objPrefix = prefix.length ? prefix + '[' : '';
74
+ const objSuffix = prefix.length ? ']' : '';
75
+ if (typeof obj[currentValue] === 'object' && obj[currentValue] !== null) {
76
+ Object.assign(accumulator, InputTransformer.flattenObject(obj[currentValue], objPrefix + currentValue + objSuffix));
77
+ } else {
78
+ accumulator[objPrefix + currentValue + objSuffix] = obj[currentValue];
79
+ }
80
+ return accumulator;
81
+ }, {});
82
+ }
83
+
84
+ private static filter(obj: GenericKeyValue): GenericKeyValue {
85
+ Object.keys(obj).forEach((key: string): void => {
86
+ if (typeof obj[key] === 'undefined') {
87
+ delete obj[key];
88
+ }
89
+ });
90
+ return obj;
91
+ }
92
+ }
@@ -0,0 +1,5 @@
1
+ export default interface SimpleResponseInterface {
2
+ status: number;
3
+ headers: Map<string, string>;
4
+ body: string | unknown;
5
+ }