@fc3/mmcadi 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (460) hide show
  1. package/LICENSE +673 -0
  2. package/README.md +5 -0
  3. package/bin/compile +63 -0
  4. package/bin/copy-static-files +13 -0
  5. package/bin/install +5 -0
  6. package/bin/precompile +55 -0
  7. package/bin/prepublish +7 -0
  8. package/bin/remap-paths +113 -0
  9. package/bin/test +9 -0
  10. package/config/tsconfig.json +37 -0
  11. package/package.json +33 -0
  12. package/src/bootstrap/start.ts +12 -0
  13. package/src/client/bootstrap.ts +5 -0
  14. package/src/client/client.ts +54 -0
  15. package/src/client/enum/key-code.ts +34 -0
  16. package/src/client/enum/page-type.ts +19 -0
  17. package/src/client/factory/page.ts +61 -0
  18. package/src/client/page/confirm-delete-block.ts +30 -0
  19. package/src/client/page/create-block.ts +6 -0
  20. package/src/client/page/day.ts +8 -0
  21. package/src/client/page/edit-block.ts +43 -0
  22. package/src/client/page/edit-custom.ts +16 -0
  23. package/src/client/page/home.ts +8 -0
  24. package/src/client/page/login.ts +8 -0
  25. package/src/client/page/logout.ts +8 -0
  26. package/src/client/page/month.ts +8 -0
  27. package/src/client/page/move-block.ts +8 -0
  28. package/src/client/page/select-block-type.ts +56 -0
  29. package/src/client/page/settings.ts +8 -0
  30. package/src/client/page/view-custom.ts +665 -0
  31. package/src/client/page/week.ts +8 -0
  32. package/src/client/page/year.ts +8 -0
  33. package/src/client/page.ts +128 -0
  34. package/src/client/shim/execute.ts +5 -0
  35. package/src/client/shim/logger.ts +44 -0
  36. package/src/client/utility/get-meta-value.ts +23 -0
  37. package/src/common/builder/block/background.ts +25 -0
  38. package/src/common/builder/block/folder.ts +43 -0
  39. package/src/common/builder/block/header.ts +15 -0
  40. package/src/common/builder/block/link.ts +32 -0
  41. package/src/common/builder/block/multicolumn.ts +16 -0
  42. package/src/common/builder/block/note.ts +13 -0
  43. package/src/common/builder/block/whitespace.ts +13 -0
  44. package/src/common/utility/get-parent-path.ts +29 -0
  45. package/src/constant/month-names.ts +16 -0
  46. package/src/enum/action-type.ts +11 -0
  47. package/src/enum/block-type.ts +18 -0
  48. package/src/enum/calendar-view-mode.ts +9 -0
  49. package/src/enum/color.ts +15 -0
  50. package/src/enum/default-role.ts +6 -0
  51. package/src/enum/directory-item-type.ts +6 -0
  52. package/src/enum/emoji.ts +94 -0
  53. package/src/enum/field-type.ts +8 -0
  54. package/src/enum/header-size.ts +7 -0
  55. package/src/enum/permission-type.ts +8 -0
  56. package/src/enum/time-place-visibility.ts +8 -0
  57. package/src/enum/tool-type.ts +14 -0
  58. package/src/index.ts +8 -0
  59. package/src/interface/hydration-callback.ts +7 -0
  60. package/src/interface/provider.ts +8 -0
  61. package/src/interface/repository.ts +12 -0
  62. package/src/lib/array/add.ts +10 -0
  63. package/src/lib/array/assert-is-empty.ts +23 -0
  64. package/src/lib/array/clone.ts +5 -0
  65. package/src/lib/array/difference.ts +8 -0
  66. package/src/lib/array/empty.ts +6 -0
  67. package/src/lib/array/equal.ts +24 -0
  68. package/src/lib/array/get-first-value.ts +5 -0
  69. package/src/lib/array/get-last-value.ts +5 -0
  70. package/src/lib/array/get-max-value.ts +5 -0
  71. package/src/lib/array/get-value-after.ts +23 -0
  72. package/src/lib/array/get-value-before.ts +23 -0
  73. package/src/lib/array/get-values-between.ts +18 -0
  74. package/src/lib/array/index.ts +5 -0
  75. package/src/lib/array/is-empty.ts +6 -0
  76. package/src/lib/array/remove.ts +19 -0
  77. package/src/lib/array/sum.ts +11 -0
  78. package/src/lib/array/unique.ts +13 -0
  79. package/src/lib/environment/bootstrap.ts +1 -0
  80. package/src/lib/environment/enum/environment-type.ts +8 -0
  81. package/src/lib/environment/enum/service-type.ts +5 -0
  82. package/src/lib/environment/index.ts +7 -0
  83. package/src/lib/environment/utility/get-environment-type.ts +28 -0
  84. package/src/lib/environment/utility/is-browser.ts +5 -0
  85. package/src/lib/environment/utility/is-development.ts +10 -0
  86. package/src/lib/environment/utility/is-production-or-staging.ts +8 -0
  87. package/src/lib/environment/utility/is-production.ts +10 -0
  88. package/src/lib/environment/utility/is-staging.ts +10 -0
  89. package/src/lib/errors/enum/error-type.ts +13 -0
  90. package/src/lib/errors/error/base.ts +40 -0
  91. package/src/lib/errors/error/conflict.ts +16 -0
  92. package/src/lib/errors/error/generic.ts +23 -0
  93. package/src/lib/errors/error/invalid.ts +14 -0
  94. package/src/lib/errors/error/invariant-violation.ts +5 -0
  95. package/src/lib/errors/error/not-allowed.ts +14 -0
  96. package/src/lib/errors/error/not-found.ts +16 -0
  97. package/src/lib/errors/error/not-implemented.ts +20 -0
  98. package/src/lib/errors/error/omitted.ts +14 -0
  99. package/src/lib/errors/error/timeout.ts +14 -0
  100. package/src/lib/errors/error/unauthorized.ts +14 -0
  101. package/src/lib/errors/index.ts +18 -0
  102. package/src/lib/errors/sugar/invariant.ts +7 -0
  103. package/src/lib/errors/type/coded-error.ts +7 -0
  104. package/src/lib/errors/type/error-data.ts +11 -0
  105. package/src/lib/errors/utility/create-error-for-error-type.ts +60 -0
  106. package/src/lib/errors/utility/create-error-from-ambiguous-json-data.ts +26 -0
  107. package/src/lib/errors/utility/error-matches.ts +28 -0
  108. package/src/lib/errors/utility/get-error-type-for-posix-error-code.ts +37 -0
  109. package/src/lib/errors/utility/get-error-type-for-status-code.ts +38 -0
  110. package/src/lib/errors/utility/get-message-for-error-type.ts +29 -0
  111. package/src/lib/errors/utility/matches-posix-error-code.ts +11 -0
  112. package/src/lib/errors/utility/wrap-error.ts +39 -0
  113. package/src/lib/event-emitter/index.ts +63 -0
  114. package/src/lib/execution-context/execution-context.ts +90 -0
  115. package/src/lib/execution-context/index.ts +8 -0
  116. package/src/lib/execution-context/type/session.ts +7 -0
  117. package/src/lib/feature/feature.ts +108 -0
  118. package/src/lib/feature/index.ts +3 -0
  119. package/src/lib/filesystem/bootstrap.ts +1 -0
  120. package/src/lib/filesystem/enum/file-extension.ts +19 -0
  121. package/src/lib/filesystem/index.ts +4 -0
  122. package/src/lib/filesystem/utility/exists.ts +21 -0
  123. package/src/lib/filesystem/utility/get-extension-for-filepath.ts +20 -0
  124. package/src/lib/filesystem/utility/strip-extension.ts +26 -0
  125. package/src/lib/grammar/index.ts +3 -0
  126. package/src/lib/grammar/noun-inflector.ts +104 -0
  127. package/src/lib/grammar/utility/get-words-from-identifier.ts +9 -0
  128. package/src/lib/grammar/verb-inflector.ts +344 -0
  129. package/src/lib/http/buffer-stream.ts +76 -0
  130. package/src/lib/http/enum/content-type.ts +19 -0
  131. package/src/lib/http/enum/cookie-attribute.ts +11 -0
  132. package/src/lib/http/enum/header.ts +29 -0
  133. package/src/lib/http/enum/method.ts +11 -0
  134. package/src/lib/http/enum/same-site-policy.ts +7 -0
  135. package/src/lib/http/enum/status-code.ts +9 -0
  136. package/src/lib/http/factory/body-parser.ts +55 -0
  137. package/src/lib/http/index.ts +24 -0
  138. package/src/lib/http/interface/client-request.ts +15 -0
  139. package/src/lib/http/interface/incoming-message.ts +24 -0
  140. package/src/lib/http/interface/network-library.ts +9 -0
  141. package/src/lib/http/interface/request-callback.ts +7 -0
  142. package/src/lib/http/isomorphic/request.ts +77 -0
  143. package/src/lib/http/isomorphic/response.ts +77 -0
  144. package/src/lib/http/isomorphic.ts +20 -0
  145. package/src/lib/http/parser/accept-header.ts +35 -0
  146. package/src/lib/http/parser/basic-auth-header.ts +48 -0
  147. package/src/lib/http/parser/body/json.ts +14 -0
  148. package/src/lib/http/parser/body/multipart.ts +89 -0
  149. package/src/lib/http/parser/body/url-encoded.ts +16 -0
  150. package/src/lib/http/parser/body.ts +44 -0
  151. package/src/lib/http/parser/cookie.ts +114 -0
  152. package/src/lib/http/parser/querystring.ts +92 -0
  153. package/src/lib/http/parser/url.ts +76 -0
  154. package/src/lib/http/request/incoming.ts +299 -0
  155. package/src/lib/http/request/outgoing.ts +276 -0
  156. package/src/lib/http/request.ts +26 -0
  157. package/src/lib/http/response/incoming.ts +243 -0
  158. package/src/lib/http/response/outgoing.ts +160 -0
  159. package/src/lib/http/response.ts +74 -0
  160. package/src/lib/http/serializer/basic-auth-header.ts +27 -0
  161. package/src/lib/http/serializer/cookie.ts +90 -0
  162. package/src/lib/http/serializer/query-data.ts +54 -0
  163. package/src/lib/http/transaction.ts +320 -0
  164. package/src/lib/http/type/basic-auth-credentials.ts +6 -0
  165. package/src/lib/http/type/header-map.ts +5 -0
  166. package/src/lib/http/type/log-attributes.ts +12 -0
  167. package/src/lib/http/type/path-parameters.ts +5 -0
  168. package/src/lib/http/type/query-data.ts +7 -0
  169. package/src/lib/http/type/query-value.ts +11 -0
  170. package/src/lib/http/type/request-options.ts +16 -0
  171. package/src/lib/http/type/transaction-data.ts +4 -0
  172. package/src/lib/http/utility/get-content-type-for-extension.ts +47 -0
  173. package/src/lib/http/utility/get-library-for-protocol.ts +25 -0
  174. package/src/lib/http/utility/get-status-code-for-error-type.ts +37 -0
  175. package/src/lib/http/utility/get-status-code-for-error.ts +13 -0
  176. package/src/lib/http/utility/is-client-error-status.ts +15 -0
  177. package/src/lib/http/utility/is-error-status.ts +9 -0
  178. package/src/lib/http/utility/is-server-error-status.ts +7 -0
  179. package/src/lib/http/utility/is-success-status.ts +7 -0
  180. package/src/lib/http/utility/proxy-request.ts +58 -0
  181. package/src/lib/http/utility/serialize-request-options.ts +9 -0
  182. package/src/lib/http/utility/slug-generator.ts +20 -0
  183. package/src/lib/key-generator/index.ts +3 -0
  184. package/src/lib/key-generator/key-generator.ts +7 -0
  185. package/src/lib/logger/enum/ansi-escape-code.ts +14 -0
  186. package/src/lib/logger/enum/log-level.ts +8 -0
  187. package/src/lib/logger/formatter.ts +59 -0
  188. package/src/lib/logger/index.ts +7 -0
  189. package/src/lib/logger/interface/error-reporter.ts +7 -0
  190. package/src/lib/logger/interface/logger.ts +13 -0
  191. package/src/lib/logger/logger.ts +239 -0
  192. package/src/lib/logger/type/error-parameters.ts +9 -0
  193. package/src/lib/logger/type/loggable-data.ts +5 -0
  194. package/src/lib/logger/type/loggable-value.ts +1 -0
  195. package/src/lib/metrics/dispatcher.ts +264 -0
  196. package/src/lib/metrics/enum/dispatch-mode.ts +6 -0
  197. package/src/lib/metrics/index.ts +2 -0
  198. package/src/lib/metrics/settings-hydrator.ts +51 -0
  199. package/src/lib/metrics/type/dispatcher-settings.ts +12 -0
  200. package/src/lib/metrics/type/tag-map.ts +5 -0
  201. package/src/lib/network/bootstrap.ts +1 -0
  202. package/src/lib/network/enum/connection-status.ts +14 -0
  203. package/src/lib/network/enum/http-status-code.ts +75 -0
  204. package/src/lib/network/enum/network-protocol.ts +10 -0
  205. package/src/lib/network/event-emitter.ts +63 -0
  206. package/src/lib/network/index.ts +7 -0
  207. package/src/lib/network/interface/socket.ts +42 -0
  208. package/src/lib/network/type/socket-options.ts +6 -0
  209. package/src/lib/network/utility/get-protocol-from-url.ts +15 -0
  210. package/src/lib/operation/index.ts +6 -0
  211. package/src/lib/operation/operation/auto-logging.ts +94 -0
  212. package/src/lib/operation/operation/silent.ts +17 -0
  213. package/src/lib/operation/operation.ts +80 -0
  214. package/src/lib/process/bootstrap.ts +1 -0
  215. package/src/lib/process/enum/posix-error-code.ts +138 -0
  216. package/src/lib/process/enum/process-signal.ts +68 -0
  217. package/src/lib/process/error.ts +6 -0
  218. package/src/lib/process/execute.ts +77 -0
  219. package/src/lib/process/index.ts +4 -0
  220. package/src/lib/process/type/command-options.ts +9 -0
  221. package/src/lib/process/utility/bind-process-lifespan-to.ts +10 -0
  222. package/src/lib/promise-wrapper/index.ts +3 -0
  223. package/src/lib/promise-wrapper/promise-wrapper.ts +51 -0
  224. package/src/lib/random/chance.ts +5 -0
  225. package/src/lib/random/element.ts +7 -0
  226. package/src/lib/random/elements.ts +12 -0
  227. package/src/lib/random/enum.ts +34 -0
  228. package/src/lib/random/enums.ts +11 -0
  229. package/src/lib/random/index.ts +3 -0
  230. package/src/lib/random/number.ts +8 -0
  231. package/src/lib/server/base.ts +194 -0
  232. package/src/lib/server/enum/server-event.ts +5 -0
  233. package/src/lib/server/enum/server-status.ts +10 -0
  234. package/src/lib/server/http/endpoint/ping.ts +21 -0
  235. package/src/lib/server/http/endpoint.ts +345 -0
  236. package/src/lib/server/http/interface/endpoint-constructor.ts +12 -0
  237. package/src/lib/server/http/interface/result-serializer.ts +5 -0
  238. package/src/lib/server/http/middleware.ts +18 -0
  239. package/src/lib/server/http/result-serializer/html.ts +92 -0
  240. package/src/lib/server/http/result-serializer/json.ts +23 -0
  241. package/src/lib/server/http/route.ts +104 -0
  242. package/src/lib/server/http/router.ts +125 -0
  243. package/src/lib/server/http/type/session-resolver.ts +8 -0
  244. package/src/lib/server/http/utility/create-server.ts +34 -0
  245. package/src/lib/server/http/utility/path-parser.ts +49 -0
  246. package/src/lib/server/http/utility/standardize-html-indentation.ts +54 -0
  247. package/src/lib/server/http/websocket-wrapper.ts +83 -0
  248. package/src/lib/server/http.ts +301 -0
  249. package/src/lib/server/index.ts +5 -0
  250. package/src/lib/server/tcp.ts +53 -0
  251. package/src/lib/server/type/server-options.ts +10 -0
  252. package/src/lib/string/calculate-length.ts +17 -0
  253. package/src/lib/string/capitalize.ts +8 -0
  254. package/src/lib/string/create-slug.ts +14 -0
  255. package/src/lib/string/enum/ansi-escape-code.ts +14 -0
  256. package/src/lib/string/enum/string-encoding.ts +9 -0
  257. package/src/lib/string/hyphenate.ts +5 -0
  258. package/src/lib/string/index.ts +3 -0
  259. package/src/lib/string/pad.ts +14 -0
  260. package/src/lib/string/trim-multiline.ts +21 -0
  261. package/src/lib/string/trim.ts +8 -0
  262. package/src/lib/tcp/channel.ts +13 -0
  263. package/src/lib/tcp/connection/incoming.ts +72 -0
  264. package/src/lib/tcp/connection/outgoing.ts +219 -0
  265. package/src/lib/tcp/connection.ts +360 -0
  266. package/src/lib/tcp/enum/connection-event.ts +12 -0
  267. package/src/lib/tcp/enum/message-type.ts +9 -0
  268. package/src/lib/tcp/index.ts +1 -0
  269. package/src/lib/tcp/type/connection-parameters.ts +6 -0
  270. package/src/lib/tcp/type/message/channel-close.ts +9 -0
  271. package/src/lib/tcp/type/message/channel-open.ts +9 -0
  272. package/src/lib/tcp/type/message.ts +10 -0
  273. package/src/lib/test/index.ts +2 -0
  274. package/src/lib/test/utility/build-config.ts +17 -0
  275. package/src/lib/test/utility/build-execution-context.ts +11 -0
  276. package/src/lib/time/bootstrap.ts +1 -0
  277. package/src/lib/time/enum/time-interval.ts +12 -0
  278. package/src/lib/time/index.ts +4 -0
  279. package/src/lib/time/utility/format-duration.ts +139 -0
  280. package/src/lib/time/utility/format-relative-duration.ts +22 -0
  281. package/src/lib/time/utility/sleep.ts +9 -0
  282. package/src/operation.ts +18 -0
  283. package/src/server/endpoint/abstract-page.ts +126 -0
  284. package/src/server/endpoint/action/create.ts +545 -0
  285. package/src/server/endpoint/action/get.ts +231 -0
  286. package/src/server/endpoint/base.ts +51 -0
  287. package/src/server/endpoint/day.ts +13 -0
  288. package/src/server/endpoint/generic-page.ts +14 -0
  289. package/src/server/endpoint/index.ts +11 -0
  290. package/src/server/endpoint/login.ts +45 -0
  291. package/src/server/endpoint/logout.ts +38 -0
  292. package/src/server/endpoint/month.ts +35 -0
  293. package/src/server/endpoint/robots.ts +18 -0
  294. package/src/server/endpoint/session/create.ts +62 -0
  295. package/src/server/endpoint/settings/get.ts +40 -0
  296. package/src/server/endpoint/settings/update.ts +44 -0
  297. package/src/server/endpoint/today.ts +15 -0
  298. package/src/server/endpoint/week.ts +34 -0
  299. package/src/server/endpoint/year.ts +34 -0
  300. package/src/server/enum/custom-page-type.ts +10 -0
  301. package/src/server/factory/block-result-serializer.ts +115 -0
  302. package/src/server/middleware/base.ts +6 -0
  303. package/src/server/middleware/error-handler.ts +177 -0
  304. package/src/server/middleware/static-file.ts +83 -0
  305. package/src/server/operation/add-block.ts +110 -0
  306. package/src/server/operation/create-session.ts +43 -0
  307. package/src/server/operation/delete-block.ts +96 -0
  308. package/src/server/operation/demote-block.ts +108 -0
  309. package/src/server/operation/destroy-session.ts +26 -0
  310. package/src/server/operation/load-account.ts +30 -0
  311. package/src/server/operation/load-block.ts +48 -0
  312. package/src/server/operation/load-directory-items.ts +75 -0
  313. package/src/server/operation/load-page.ts +368 -0
  314. package/src/server/operation/promote-block.ts +104 -0
  315. package/src/server/operation/save-page.ts +60 -0
  316. package/src/server/operation/update-account-settings.ts +52 -0
  317. package/src/server/operation/update-block.ts +124 -0
  318. package/src/server/repository/memory.ts +112 -0
  319. package/src/server/result-serializer/action.ts +939 -0
  320. package/src/server/result-serializer/base.ts +1267 -0
  321. package/src/server/result-serializer/block/audio.ts +33 -0
  322. package/src/server/result-serializer/block/background.ts +20 -0
  323. package/src/server/result-serializer/block/calendar.ts +148 -0
  324. package/src/server/result-serializer/block/directory.ts +57 -0
  325. package/src/server/result-serializer/block/ephemeral.ts +14 -0
  326. package/src/server/result-serializer/block/folder.ts +106 -0
  327. package/src/server/result-serializer/block/header.ts +31 -0
  328. package/src/server/result-serializer/block/image.ts +46 -0
  329. package/src/server/result-serializer/block/link.ts +40 -0
  330. package/src/server/result-serializer/block/list.ts +140 -0
  331. package/src/server/result-serializer/block/multi-column.ts +97 -0
  332. package/src/server/result-serializer/block/note.ts +44 -0
  333. package/src/server/result-serializer/block/todo.ts +78 -0
  334. package/src/server/result-serializer/block/whitespace.ts +15 -0
  335. package/src/server/result-serializer/block.ts +248 -0
  336. package/src/server/result-serializer/common/time-place-options.ts +33 -0
  337. package/src/server/result-serializer/login.ts +58 -0
  338. package/src/server/result-serializer/month.ts +170 -0
  339. package/src/server/result-serializer/page.ts +548 -0
  340. package/src/server/result-serializer/settings.ts +85 -0
  341. package/src/server/result-serializer/week.ts +195 -0
  342. package/src/server/result-serializer/year.ts +160 -0
  343. package/src/server/utility/accepts-content-type.ts +16 -0
  344. package/src/server/utility/accepts-html.ts +9 -0
  345. package/src/server/utility/accepts-json.ts +9 -0
  346. package/src/server/utility/add-days.ts +11 -0
  347. package/src/server/utility/create-date.ts +23 -0
  348. package/src/server/utility/create-index-path.ts +5 -0
  349. package/src/server/utility/create-slug.ts +9 -0
  350. package/src/server/utility/create-toast-path.ts +19 -0
  351. package/src/server/utility/date-less-than.ts +5 -0
  352. package/src/server/utility/date-occurs-before.ts +22 -0
  353. package/src/server/utility/date-to-key.ts +7 -0
  354. package/src/server/utility/date-to-label.ts +5 -0
  355. package/src/server/utility/date-to-path.ts +9 -0
  356. package/src/server/utility/dates-are-equal.ts +22 -0
  357. package/src/server/utility/dates-are-in-order.ts +9 -0
  358. package/src/server/utility/dates-are-on-the-same-day.ts +9 -0
  359. package/src/server/utility/dates-in-same-month.ts +8 -0
  360. package/src/server/utility/day-to-date.ts +40 -0
  361. package/src/server/utility/decrement-date.ts +11 -0
  362. package/src/server/utility/get-block-at-index-path.ts +32 -0
  363. package/src/server/utility/get-block-permissions.ts +15 -0
  364. package/src/server/utility/get-compact-label-for-date.ts +8 -0
  365. package/src/server/utility/get-custom-page-type-for-path.ts +37 -0
  366. package/src/server/utility/get-element-id-for-block.ts +15 -0
  367. package/src/server/utility/get-emoji-for-block-type.ts +39 -0
  368. package/src/server/utility/get-emoji-for-tool-type.ts +20 -0
  369. package/src/server/utility/get-end-of-month.ts +13 -0
  370. package/src/server/utility/get-end-of-week.ts +13 -0
  371. package/src/server/utility/get-filepath-for-folder-block.ts +23 -0
  372. package/src/server/utility/get-hex-for-color.ts +31 -0
  373. package/src/server/utility/get-label-for-time-place-visibility.ts +23 -0
  374. package/src/server/utility/get-month-name.ts +18 -0
  375. package/src/server/utility/get-next-day.ts +7 -0
  376. package/src/server/utility/get-next-month.ts +12 -0
  377. package/src/server/utility/get-next-week.ts +12 -0
  378. package/src/server/utility/get-next-year.ts +13 -0
  379. package/src/server/utility/get-ordinal-label-for-week.ts +11 -0
  380. package/src/server/utility/get-ordinal-of-week-within-month.ts +15 -0
  381. package/src/server/utility/get-padded-date.ts +11 -0
  382. package/src/server/utility/get-parent-index-path.ts +18 -0
  383. package/src/server/utility/get-path-for-folder-block.ts +25 -0
  384. package/src/server/utility/get-path-from-url.ts +13 -0
  385. package/src/server/utility/get-previous-index-path.ts +27 -0
  386. package/src/server/utility/get-previous-month.ts +12 -0
  387. package/src/server/utility/get-previous-week.ts +11 -0
  388. package/src/server/utility/get-previous-year.ts +13 -0
  389. package/src/server/utility/get-random-emoji-for-date.ts +109 -0
  390. package/src/server/utility/get-short-label-for-date.ts +11 -0
  391. package/src/server/utility/get-short-month-name.ts +9 -0
  392. package/src/server/utility/get-short-ordinal.ts +26 -0
  393. package/src/server/utility/get-siblings-and-index-for-index-path.ts +67 -0
  394. package/src/server/utility/get-start-of-month.ts +11 -0
  395. package/src/server/utility/get-start-of-week.ts +12 -0
  396. package/src/server/utility/get-start-of-year.ts +12 -0
  397. package/src/server/utility/get-weekday-name.ts +24 -0
  398. package/src/server/utility/increment-date.ts +15 -0
  399. package/src/server/utility/is-index-path.ts +5 -0
  400. package/src/server/utility/key-to-date.ts +25 -0
  401. package/src/server/utility/month-has-week-containing-date.ts +13 -0
  402. package/src/server/utility/month-to-date.ts +28 -0
  403. package/src/server/utility/month-to-path.ts +10 -0
  404. package/src/server/utility/months-are-equal.ts +8 -0
  405. package/src/server/utility/parse-index-path.ts +23 -0
  406. package/src/server/utility/path-is-date.ts +13 -0
  407. package/src/server/utility/path-to-date.ts +24 -0
  408. package/src/server/utility/subtract-days.ts +7 -0
  409. package/src/server/utility/validate-month.ts +10 -0
  410. package/src/server/utility/validate-page.ts +46 -0
  411. package/src/server/utility/validate-path.ts +9 -0
  412. package/src/server/utility/validate-url.ts +12 -0
  413. package/src/server/utility/week-greater-than.ts +10 -0
  414. package/src/server/utility/week-to-date.ts +8 -0
  415. package/src/server/utility/week-to-path.ts +12 -0
  416. package/src/server/utility/weeks-are-equal.ts +8 -0
  417. package/src/server/utility/year-to-date.ts +26 -0
  418. package/src/server/utility/year-to-path.ts +7 -0
  419. package/src/server/utility/years-are-equal.ts +8 -0
  420. package/src/server.ts +140 -0
  421. package/src/test.ts +195 -0
  422. package/src/type/account-settings.ts +9 -0
  423. package/src/type/account.ts +11 -0
  424. package/src/type/action/add-block.ts +74 -0
  425. package/src/type/action/complete-block.ts +10 -0
  426. package/src/type/action/delete-block.ts +11 -0
  427. package/src/type/action/demote-block.ts +9 -0
  428. package/src/type/action/edit-block.ts +11 -0
  429. package/src/type/action/promote-block.ts +9 -0
  430. package/src/type/action.ts +9 -0
  431. package/src/type/block/audio.ts +8 -0
  432. package/src/type/block/background.ts +10 -0
  433. package/src/type/block/directory.ts +18 -0
  434. package/src/type/block/ephemeral.ts +9 -0
  435. package/src/type/block/folder.ts +14 -0
  436. package/src/type/block/header.ts +11 -0
  437. package/src/type/block/image.ts +8 -0
  438. package/src/type/block/link.ts +12 -0
  439. package/src/type/block/list.ts +24 -0
  440. package/src/type/block/multi-column.ts +10 -0
  441. package/src/type/block/note.ts +9 -0
  442. package/src/type/block/todo.ts +10 -0
  443. package/src/type/block/whitespace.ts +9 -0
  444. package/src/type/block-metadata.ts +14 -0
  445. package/src/type/block.ts +18 -0
  446. package/src/type/day.ts +5 -0
  447. package/src/type/field-definition.ts +8 -0
  448. package/src/type/field-value.ts +5 -0
  449. package/src/type/file.ts +6 -0
  450. package/src/type/month.ts +5 -0
  451. package/src/type/page.ts +8 -0
  452. package/src/type/price.ts +11 -0
  453. package/src/type/resource.ts +5 -0
  454. package/src/type/runtime-config.ts +13 -0
  455. package/src/type/server-settings.ts +17 -0
  456. package/src/type/toast.ts +8 -0
  457. package/src/type/week.ts +5 -0
  458. package/src/type/year.ts +5 -0
  459. package/test/unit/index.ts +11 -0
  460. package/test/unit/server/operation/promote-block.ts +84 -0
@@ -0,0 +1,126 @@
1
+ import {ContentType, HttpMethod} from 'lib/http';
2
+
3
+ import PageResultSerializer, {PageMetadata} from 'server/result-serializer/page';
4
+ import BaseEndpoint from 'server/endpoint/base';
5
+ import BlockType from 'enum/block-type';
6
+ import LoadPageOperation from 'server/operation/load-page';
7
+ import getPathForFolderBlock from 'server/utility/get-path-for-folder-block';
8
+ import FolderBlock from 'type/block/folder';
9
+ import validateUrl from 'server/utility/validate-url';
10
+ import Page from 'type/page';
11
+ import createIndexPath from 'server/utility/create-index-path';
12
+ import getCustomPageTypeForPath from 'server/utility/get-custom-page-type-for-path';
13
+ import Toast from 'type/toast';
14
+ import LoadAccountOperation from 'server/operation/load-account';
15
+ import Color from 'enum/color';
16
+
17
+ type PageInput = {}
18
+ type PageOutput = Page;
19
+
20
+ abstract class AbstractPageEndpoint extends BaseEndpoint<PageInput, PageOutput> {
21
+ public method = HttpMethod.GET;
22
+
23
+ public content_types = [
24
+ ContentType.HTML,
25
+ ContentType.JSON
26
+ ];
27
+
28
+ protected async process(): Promise<PageOutput> {
29
+ const execution_context = this.getExecutionContext();
30
+ const session = this.getSession();
31
+
32
+ execution_context.setSession(session);
33
+
34
+ const path = await this.determinePath();
35
+ const operation = new LoadPageOperation(path, execution_context);
36
+
37
+ return operation.perform();
38
+ }
39
+
40
+ protected async getHtmlResultSerializer(page: Page): Promise<PageResultSerializer> {
41
+ const editing = this.getQueryParameter('editing') === 'true';
42
+
43
+ const target_index_path = (() => {
44
+ const path_parameter = this.getQueryParameter('index_path') as string;
45
+
46
+ if (path_parameter) {
47
+ return path_parameter;
48
+ }
49
+
50
+ const referrer_url = this.getReferrerUrl();
51
+
52
+ if (referrer_url !== null) {
53
+ let index = 0;
54
+
55
+ while (index < page.blocks.length) {
56
+ const block = page.blocks[index];
57
+
58
+ if (block.block_type === BlockType.FOLDER) {
59
+ const folder_block = block as FolderBlock;
60
+
61
+ const block_path = getPathForFolderBlock({
62
+ base_path: page.path,
63
+ block: folder_block
64
+ });
65
+
66
+ validateUrl(referrer_url);
67
+
68
+ const url = new URL(referrer_url);
69
+
70
+ if (url.pathname === block_path) {
71
+ return createIndexPath([index]);
72
+ }
73
+ }
74
+
75
+ index++;
76
+ }
77
+ }
78
+
79
+ return null;
80
+ })();
81
+
82
+ const toast_message = this.getQueryParameter('toast_message') as string;
83
+ const custom_page_type = getCustomPageTypeForPath(page.path);
84
+
85
+ let toast: Toast | null = null;
86
+
87
+ if (toast_message) {
88
+ const raw_color = this.getQueryParameter('toast_color') as string;
89
+ const toast_color = raw_color ? decodeURIComponent(raw_color) as Color : Color.GREY;
90
+
91
+ toast = {
92
+ message: decodeURIComponent(toast_message),
93
+ color: toast_color
94
+ };
95
+ }
96
+
97
+ const execution_context = this.getExecutionContext();
98
+ const account_operation = new LoadAccountOperation(execution_context);
99
+ const account = await account_operation.perform();
100
+ const {roles} = execution_context.getConfig();
101
+
102
+ const metadata: PageMetadata = {
103
+ editing,
104
+ target_index_path,
105
+ toast,
106
+ custom_page_type,
107
+ roles,
108
+ account
109
+ };
110
+
111
+ const session = this.getSession();
112
+ const referrer_url = this.getReferrerUrl();
113
+
114
+ return new PageResultSerializer(
115
+ page,
116
+ metadata,
117
+ page.path,
118
+ referrer_url,
119
+ session
120
+ );
121
+ }
122
+
123
+ protected abstract determinePath(): Promise<string>;
124
+ }
125
+
126
+ export default AbstractPageEndpoint;
@@ -0,0 +1,545 @@
1
+ import {unlink, copyFile, mkdir} from 'fs/promises';
2
+
3
+ import {ContentType, HttpMethod, HttpHeader, StatusCode} from 'lib/http';
4
+ import {InvalidError, UnauthorizedError} from 'lib/errors';
5
+
6
+ import BaseEndpoint from 'server/endpoint/base';
7
+ import AddBlockOperation from 'server/operation/add-block';
8
+ import Emoji from 'enum/emoji';
9
+ import DeleteBlockOperation from 'server/operation/delete-block';
10
+ import Color from 'enum/color';
11
+ import PromoteBlockOperation from 'server/operation/promote-block';
12
+ import PermissionType from 'enum/permission-type';
13
+ import getBlockAtIndexPath from 'server/utility/get-block-at-index-path';
14
+ import MultiColumnBlock from 'type/block/multi-column';
15
+ import LinkBlock from 'type/block/link';
16
+ import DemoteBlockOperation from 'server/operation/demote-block';
17
+ import UpdateBlockOperation from 'server/operation/update-block';
18
+ import createToastPath from 'server/utility/create-toast-path';
19
+ import TimePlaceVisibility from 'enum/time-place-visibility';
20
+ import LoadPageOperation from 'server/operation/load-page';
21
+ import File from 'type/file';
22
+ import HeaderBlock from 'type/block/header';
23
+ import TodoBlock from 'type/block/todo';
24
+ import BlockType from 'enum/block-type';
25
+ import AudioBlock from 'type/block/audio';
26
+ import BackgroundBlock from 'type/block/background';
27
+ import WhitespaceBlock from 'type/block/whitespace';
28
+ import NoteBlock from 'type/block/note';
29
+ import FolderBlock from 'type/block/folder';
30
+ import ImageBlock from 'type/block/image';
31
+ import Block from 'type/block';
32
+ import ActionType from 'enum/action-type';
33
+ import AddBlockAction, {
34
+ AddFolderBlockAction,
35
+ AddLinkBlockAction,
36
+ AddNoteBlockAction,
37
+ AddHeaderBlockAction,
38
+ AddTodoBlockAction,
39
+ AddMultiColumnBlockAction,
40
+ AddWhitespaceBlockAction,
41
+ AddBackgroundBlockAction
42
+ } from 'type/action/add-block';
43
+ import DeleteBlockAction from 'type/action/delete-block';
44
+ import CompleteBlockAction from 'type/action/complete-block';
45
+ import DemoteBlockAction from 'type/action/demote-block';
46
+ import PromoteBlockAction from 'type/action/promote-block';
47
+ import Action from 'type/action';
48
+ import getPreviousIndexPath from 'server/utility/get-previous-index-path';
49
+
50
+ type MultipartFile = {
51
+ readonly filepath: string;
52
+ readonly size: number;
53
+ readonly mimetype: string;
54
+ readonly originalFilename: string;
55
+ }
56
+
57
+ type FilePayload = {
58
+ readonly files: MultipartFile[];
59
+ }
60
+
61
+ type ActionWithFiles = Action & FilePayload;
62
+
63
+ type CreateActionInput = Action;
64
+ type CreateActionOutput = string;
65
+
66
+ class CreateActionEndpoint extends BaseEndpoint<CreateActionInput, CreateActionOutput> {
67
+ public path = '/actions';
68
+ public method = HttpMethod.POST;
69
+ public content_types = [
70
+ ContentType.JSON,
71
+ ContentType.HTML
72
+ ];
73
+
74
+ protected async authorize(): Promise<void> {
75
+ const session = this.getSession();
76
+ const {account_id} = session;
77
+
78
+ if (account_id === null) {
79
+ throw new UnauthorizedError();
80
+ }
81
+ }
82
+
83
+ protected async process(): Promise<CreateActionOutput> {
84
+ const redirect_url = await this.processBlock();
85
+ const response = this.getResponse();
86
+
87
+ response.setHeaderValue(HttpHeader.LOCATION, redirect_url);
88
+ response.setStatusCode(StatusCode.REDIRECT);
89
+
90
+ return '';
91
+ }
92
+
93
+ private async processBlock(): Promise<string> {
94
+ const action_type = this.getActionType();
95
+
96
+ switch (action_type) {
97
+ case ActionType.ADD_BLOCK:
98
+ return this.processAddBlock();
99
+
100
+ case ActionType.DELETE_BLOCK:
101
+ return this.processDeleteBlock();
102
+
103
+ case ActionType.PROMOTE_BLOCK:
104
+ return this.processPromoteBlock();
105
+
106
+ case ActionType.DEMOTE_BLOCK:
107
+ return this.processDemoteBlock();
108
+
109
+ case ActionType.EDIT_BLOCK:
110
+ return this.processEditBlock();
111
+
112
+ case ActionType.COMPLETE_BLOCK:
113
+ return this.processCompleteBlock();
114
+
115
+ default:
116
+ throw new InvalidError(`Unsupported action type: ${action_type}`);
117
+ }
118
+ }
119
+
120
+ private async processAddBlock(): Promise<string> {
121
+ const filenames = await this.storeFiles();
122
+ const body = this.getRequestBody() as AddBlockAction;
123
+ const editing = this.getQueryParameter('editing') === 'true';
124
+
125
+ const action: AddBlockAction = {
126
+ ...body,
127
+ editing
128
+ };
129
+
130
+ const {index_path} = action;
131
+
132
+ const files = filenames.map((filename) => {
133
+ const description = null;
134
+
135
+ return {
136
+ filename,
137
+ description
138
+ }
139
+ });
140
+
141
+ const path = this.getPath();
142
+ const block = this.loadBlockParameters(files);
143
+ const execution_context = this.getExecutionContext();
144
+
145
+ const page_operation = new LoadPageOperation(path, execution_context);
146
+ const page = await page_operation.perform();
147
+
148
+ const block_operation = new AddBlockOperation(
149
+ page,
150
+ block,
151
+ index_path,
152
+ execution_context
153
+ );
154
+
155
+ await block_operation.perform();
156
+
157
+ return `${path}?index_path=${index_path}&editing=${editing}`;
158
+ }
159
+
160
+ private async processCompleteBlock(): Promise<string> {
161
+ const path = this.getPath();
162
+ const body = this.getRequestBody() as CompleteBlockAction;
163
+ const {index_path} = body;
164
+ const execution_context = this.getExecutionContext();
165
+ const page_operation = new LoadPageOperation(path, execution_context);
166
+ const page = await page_operation.perform();
167
+ const original_block = getBlockAtIndexPath(page, index_path);
168
+
169
+ const todo_block = original_block as TodoBlock;
170
+ const {title} = todo_block;
171
+ const completed_at = Date.now();
172
+ const editing = this.getQueryParameter('editing') === 'true';
173
+
174
+ const updated_block = {
175
+ ...todo_block,
176
+ completed_at
177
+ };
178
+
179
+ const block_operation = new UpdateBlockOperation(
180
+ page,
181
+ updated_block,
182
+ index_path,
183
+ execution_context
184
+ );
185
+
186
+ await block_operation.perform();
187
+
188
+ return createToastPath(`${path}?index_path=${index_path}&editing=${editing}`, {
189
+ message: `${Emoji.COMPLETED_CHECKMARK} todo completed: ${title}`,
190
+ color: Color.GREEN
191
+ });
192
+ }
193
+
194
+ private async processEditBlock(): Promise<string> {
195
+ const filenames = await this.storeFiles();
196
+ const body = this.getRequestBody();
197
+ const action = body as AddBlockAction;
198
+ const editing = this.getQueryParameter('editing') === 'true';
199
+ const {index_path} = action;
200
+
201
+ const files = filenames.map((filename) => {
202
+ const description = null;
203
+
204
+ return {
205
+ filename,
206
+ description
207
+ }
208
+ });
209
+
210
+ const path = this.getPath();
211
+ const block = this.loadBlockParameters(files);
212
+ const execution_context = this.getExecutionContext();
213
+
214
+ const page_operation = new LoadPageOperation(path, execution_context);
215
+ const page = await page_operation.perform();
216
+
217
+ const block_operation = new UpdateBlockOperation(
218
+ page,
219
+ block,
220
+ index_path,
221
+ execution_context
222
+ );
223
+
224
+ await block_operation.perform();
225
+
226
+ return `${path}?index_path=${index_path}&editing=${editing}`;
227
+ }
228
+
229
+ private loadBlockParameters(files: File[]): Block {
230
+ const action = this.getRequestBody() as AddBlockAction;
231
+ const {block_type} = action;
232
+ const created_at = Date.now();
233
+ const visibility = action.time_place_visibility;
234
+
235
+ const {create_role, read_role, update_role, delete_role} = action;
236
+ const permissions = {
237
+ [PermissionType.CREATE]: create_role,
238
+ [PermissionType.READ]: read_role,
239
+ [PermissionType.UPDATE]: update_role,
240
+ [PermissionType.DELETE]: delete_role
241
+ };
242
+
243
+ const [show_time, show_place] = (() => {
244
+ switch (visibility) {
245
+ case TimePlaceVisibility.NONE:
246
+ return [false, false];
247
+
248
+ case TimePlaceVisibility.PLACE:
249
+ return [false, true];
250
+
251
+ case TimePlaceVisibility.BOTH:
252
+ return [true, true];
253
+
254
+ case TimePlaceVisibility.TIME:
255
+ default:
256
+ return [true, false];
257
+ }
258
+ })();
259
+
260
+ switch (block_type) {
261
+ case BlockType.NOTE:
262
+ const add_note_action = action as AddNoteBlockAction;
263
+
264
+ const a: NoteBlock = {
265
+ block_type,
266
+ text: add_note_action.text,
267
+ show_time,
268
+ show_place,
269
+ created_at,
270
+ permissions
271
+ };
272
+
273
+ return a;
274
+
275
+ case BlockType.IMAGE:
276
+ const b: ImageBlock = {
277
+ block_type,
278
+ files,
279
+ show_time,
280
+ show_place,
281
+ created_at,
282
+ permissions
283
+ };
284
+
285
+ return b;
286
+
287
+ case BlockType.AUDIO:
288
+ const c: AudioBlock = {
289
+ block_type,
290
+ files,
291
+ show_time,
292
+ show_place,
293
+ created_at,
294
+ permissions
295
+ };
296
+
297
+ return c;
298
+
299
+ case BlockType.HEADER:
300
+ const add_header_action = action as AddHeaderBlockAction;
301
+
302
+ const d: HeaderBlock = {
303
+ block_type,
304
+ title: add_header_action.title,
305
+ created_at,
306
+ show_time: false,
307
+ show_place: false,
308
+ permissions
309
+ };
310
+
311
+ return d;
312
+
313
+ case BlockType.FOLDER:
314
+ const add_folder_action = action as AddFolderBlockAction;
315
+ const default_emoji = Emoji.FOLDER;
316
+ const default_color = Color.GREY;
317
+
318
+ const e: FolderBlock = {
319
+ block_type,
320
+ title: add_folder_action.title,
321
+ subtitle: add_folder_action.subtitle,
322
+ emoji: add_folder_action.emoji || default_emoji,
323
+ color: add_folder_action.color || default_color,
324
+ created_at,
325
+ show_time: false,
326
+ show_place: false,
327
+ permissions
328
+ };
329
+
330
+ return e;
331
+
332
+ case BlockType.MULTI_COLUMN:
333
+ const {max_columns} = action as AddMultiColumnBlockAction;
334
+ const parsed_columns = parseInt(max_columns.toString());
335
+
336
+ const f: MultiColumnBlock = {
337
+ block_type,
338
+ created_at,
339
+ show_time: false,
340
+ show_place: false,
341
+ max_columns: parsed_columns || 3,
342
+ children: [],
343
+ permissions
344
+ };
345
+
346
+ return f;
347
+
348
+ case BlockType.TODO:
349
+ const add_todo_action = action as AddTodoBlockAction;
350
+
351
+ const g: TodoBlock = {
352
+ block_type,
353
+ title: add_todo_action.title,
354
+ completed_at: null,
355
+ created_at,
356
+ show_time: false,
357
+ show_place: false,
358
+ permissions
359
+ };
360
+
361
+ return g;
362
+
363
+ case BlockType.LINK:
364
+ const add_link_action = action as AddLinkBlockAction;
365
+
366
+ const h: LinkBlock = {
367
+ block_type,
368
+ label: add_link_action.label,
369
+ href: add_link_action.href,
370
+ color: add_link_action.color,
371
+ show_time,
372
+ show_place,
373
+ created_at,
374
+ permissions
375
+ };
376
+
377
+ return h;
378
+
379
+ case BlockType.BACKGROUND:
380
+ const add_background_action = action as AddBackgroundBlockAction;
381
+
382
+ const i: BackgroundBlock = {
383
+ block_type,
384
+ color: add_background_action.color,
385
+ show_time,
386
+ show_place,
387
+ created_at,
388
+ permissions
389
+ };
390
+
391
+ return i;
392
+
393
+ case BlockType.WHITESPACE:
394
+ const add_whitespace_action = action as AddWhitespaceBlockAction;
395
+
396
+ const j: WhitespaceBlock = {
397
+ block_type,
398
+ line_count: add_whitespace_action.line_count,
399
+ show_time,
400
+ show_place,
401
+ created_at,
402
+ permissions
403
+ };
404
+
405
+ return j;
406
+
407
+ default:
408
+ throw new InvalidError(`
409
+ Unsupported block type: ${block_type}
410
+ `);
411
+ }
412
+ }
413
+
414
+ private async processDeleteBlock(): Promise<string> {
415
+ const body = this.getRequestBody();
416
+ const action = body as DeleteBlockAction;
417
+ const {index_path} = action;
418
+ const path = this.getPath();
419
+ const execution_context = this.getExecutionContext();
420
+ const editing = this.getQueryParameter('editing') === 'true';
421
+
422
+ const operation = new DeleteBlockOperation(
423
+ path,
424
+ index_path,
425
+ execution_context
426
+ );
427
+
428
+ const previous_path = getPreviousIndexPath(index_path);
429
+
430
+ await operation.perform();
431
+
432
+ return createToastPath(`${path}?editing=${editing}&index_path=${previous_path}`, {
433
+ message: 'block deleted',
434
+ color: Color.FUSCHIA
435
+ });
436
+ }
437
+
438
+ private async processPromoteBlock(): Promise<string> {
439
+ const path = this.getPath();
440
+ const body = this.getRequestBody();
441
+ const action = body as PromoteBlockAction;
442
+ const {index_path} = action;
443
+ const editing = this.getQueryParameter('editing') === 'true';
444
+ const execution_context = this.getExecutionContext();
445
+ const operation = new PromoteBlockOperation(path, index_path, execution_context);
446
+ const updated_path = await operation.perform();
447
+
448
+ return `${path}?index_path=${updated_path}&editing=${editing}`;
449
+ }
450
+
451
+ private async processDemoteBlock(): Promise<string> {
452
+ const path = this.getPath();
453
+ const body = this.getRequestBody();
454
+ const action = body as DemoteBlockAction;
455
+ const {index_path} = action;
456
+ const editing = this.getQueryParameter('editing') === 'true';
457
+ const execution_context = this.getExecutionContext();
458
+ const operation = new DemoteBlockOperation(path, index_path, execution_context);
459
+ const updated_path = await operation.perform();
460
+
461
+ return `${path}?index_path=${updated_path}&editing=${editing}`;
462
+ }
463
+
464
+ private getActionType(): ActionType {
465
+ const request_body = this.getRequestBody()
466
+ const fallback_value = this.getQueryParameter('action_type');
467
+
468
+ const action_type = request_body.action_type || fallback_value;
469
+
470
+ if (typeof action_type !== 'string') {
471
+ throw new InvalidError(`Invalid action_type: ${action_type}`);
472
+ }
473
+
474
+ const action_types = Object.values(ActionType);
475
+
476
+ if (!action_types.includes(action_type)) {
477
+ throw new InvalidError(`Invalid action_type: ${action_type}`);
478
+ }
479
+
480
+ return action_type as ActionType;
481
+ }
482
+
483
+ private getPath(): string {
484
+ const {path} = this.getRequestBody();
485
+
486
+ if (typeof path !== 'string') {
487
+ throw new InvalidError(`
488
+ Invalid path: ${path}
489
+ `);
490
+ }
491
+
492
+ return path;
493
+ }
494
+
495
+ private async storeFiles(): Promise<string[]> {
496
+ const action = this.getRequestBody();
497
+ const path = this.getPath();
498
+ const {files} = action as ActionWithFiles;
499
+
500
+ if (files === undefined) {
501
+ return [];
502
+ }
503
+
504
+ const execution_context = this.getExecutionContext();
505
+ const logger = execution_context.getLogger();
506
+ const {public_directory} = execution_context.getConfig();
507
+ const page_path = `${public_directory}${path}`;
508
+
509
+ await mkdir(page_path, {
510
+ recursive: true
511
+ });
512
+
513
+ const filenames: string[] = [];
514
+
515
+ let index = 0;
516
+
517
+ while (index < files.length) {
518
+ const file = files[index++];
519
+
520
+ if (file.size === 0) {
521
+ continue;
522
+ }
523
+
524
+ const new_filename = file.originalFilename;
525
+ const new_filepath = `${page_path}/${new_filename}`;
526
+
527
+ logger.info(`Moving upload: ${file.filepath} -> ${new_filepath}`);
528
+
529
+ try {
530
+ await copyFile(file.filepath, new_filepath);
531
+ await unlink(file.filepath);
532
+ } catch (error) {
533
+ logger.error(error as Error);
534
+
535
+ throw error;
536
+ }
537
+
538
+ filenames.push(new_filename);
539
+ }
540
+
541
+ return filenames;
542
+ }
543
+ }
544
+
545
+ export default CreateActionEndpoint;