@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,10 @@
1
+ enum CustomPageType {
2
+ BLANK = 'blank',
3
+ FORM = 'form',
4
+ PRODUCT = 'product',
5
+ DATE = 'date',
6
+ INDEX = 'index',
7
+ ERROR = 'error'
8
+ }
9
+
10
+ export default CustomPageType;
@@ -0,0 +1,115 @@
1
+ import {InvalidError, InvariantViolation} from 'lib/errors';
2
+ import {Session} from 'lib/execution-context';
3
+
4
+ import Block from 'type/block';
5
+ import BlockResultSerializer from 'server/result-serializer/block';
6
+ import NoteBlock from 'type/block/note';
7
+ import BlockMetadata from 'type/block-metadata';
8
+ import ImageBlock from 'type/block/image';
9
+ import HeaderBlock from 'type/block/header';
10
+ import BlockType from 'enum/block-type';
11
+ import AudioBlock from 'type/block/audio';
12
+ import LinkBlock from 'type/block/link';
13
+ import ListBlock from 'type/block/list';
14
+ import EphemeralBlock from 'type/block/ephemeral';
15
+ import DirectoryBlock from 'type/block/directory';
16
+ import TodoBlock from 'type/block/todo';
17
+ import BackgroundBlock from 'type/block/background';
18
+ import TodoBlockResultSerializer from 'server/result-serializer/block/todo';
19
+ import FolderBlock from 'type/block/folder';
20
+ import WhitespaceBlock from 'type/block/whitespace';
21
+ import MultiColumnBlock from 'type/block/multi-column';
22
+ import NoteBlockResultSerializer from 'server/result-serializer/block/note';
23
+ import LinkBlockResultSerializer from 'server/result-serializer/block/link';
24
+ import ListBlockResultSerializer from 'server/result-serializer/block/list';
25
+ import HeaderBlockResultSerializer from 'server/result-serializer/block/header';
26
+ import WhitespaceBlockResultSerializer from 'server/result-serializer/block/whitespace';
27
+ import BackgroundBlockResultSerializer from 'server/result-serializer/block/background';
28
+ import ImageBlockResultSerializer from 'server/result-serializer/block/image';
29
+ import AudioBlockResultSerializer from 'server/result-serializer/block/audio';
30
+ import DirectoryBlockResultSerializer from 'server/result-serializer/block/directory';
31
+ import MultiColumnBlockResultSerializer from 'server/result-serializer/block/multi-column';
32
+ import FolderBlockResultSerializer from 'server/result-serializer/block/folder';
33
+ import EphemeralBlockResultSerializer from 'server/result-serializer/block/ephemeral';
34
+
35
+ class BlockResultSerializerFactory {
36
+ private block: Block;
37
+ private metadata: BlockMetadata;
38
+ private session: Session;
39
+
40
+ public constructor(block: Block, metadata: BlockMetadata, session: Session) {
41
+ this.block = block;
42
+ this.metadata = metadata;
43
+ this.session = session;
44
+ }
45
+
46
+ public create(): BlockResultSerializer<Block> {
47
+ const block = this.getBlock();
48
+
49
+ if (!block) {
50
+ throw new InvariantViolation('Tried to read block, but it was not set');
51
+ }
52
+
53
+ const {block_type} = block;
54
+ const metadata = this.getMetadata();
55
+ const session = this.getSession();
56
+
57
+ switch (block_type) {
58
+ case BlockType.NOTE:
59
+ return new NoteBlockResultSerializer(block as NoteBlock, metadata, session);
60
+
61
+ case BlockType.IMAGE:
62
+ return new ImageBlockResultSerializer(block as ImageBlock, metadata, session);
63
+
64
+ case BlockType.AUDIO:
65
+ return new AudioBlockResultSerializer(block as AudioBlock, metadata, session);
66
+
67
+ case BlockType.HEADER:
68
+ return new HeaderBlockResultSerializer(block as HeaderBlock, metadata, session)
69
+
70
+ case BlockType.EPHEMERAL:
71
+ return new EphemeralBlockResultSerializer(block as EphemeralBlock, metadata, session);
72
+
73
+ case BlockType.DIRECTORY:
74
+ return new DirectoryBlockResultSerializer(block as DirectoryBlock, metadata, session);
75
+
76
+ case BlockType.FOLDER:
77
+ return new FolderBlockResultSerializer(block as FolderBlock, metadata, session);
78
+
79
+ case BlockType.MULTI_COLUMN:
80
+ return new MultiColumnBlockResultSerializer(block as MultiColumnBlock, metadata, session);
81
+
82
+ case BlockType.LINK:
83
+ return new LinkBlockResultSerializer(block as LinkBlock, metadata, session);
84
+
85
+ case BlockType.TODO:
86
+ return new TodoBlockResultSerializer(block as TodoBlock, metadata, session);
87
+
88
+ case BlockType.LIST:
89
+ return new ListBlockResultSerializer(block as ListBlock, metadata, session);
90
+
91
+ case BlockType.BACKGROUND:
92
+ return new BackgroundBlockResultSerializer(block as BackgroundBlock, metadata, session);
93
+
94
+ case BlockType.WHITESPACE:
95
+ return new WhitespaceBlockResultSerializer(block as WhitespaceBlock, metadata, session);
96
+
97
+ default:
98
+ throw new InvalidError(`Unsupported block type: ${block_type}`);
99
+ }
100
+ }
101
+
102
+ private getBlock(): Block {
103
+ return this.block;
104
+ }
105
+
106
+ private getMetadata(): BlockMetadata {
107
+ return this.metadata;
108
+ }
109
+
110
+ private getSession(): Session {
111
+ return this.session;
112
+ }
113
+ }
114
+
115
+ export default BlockResultSerializerFactory;
@@ -0,0 +1,6 @@
1
+ import {Middleware} from 'lib/server';
2
+
3
+ abstract class BaseMiddleware extends Middleware {
4
+ }
5
+
6
+ export default BaseMiddleware;
@@ -0,0 +1,177 @@
1
+ import {
2
+ HttpHeader,
3
+ StatusCode,
4
+ ContentType,
5
+ IncomingRequest,
6
+ OutgoingResponse,
7
+ getStatusCodeForError
8
+ } from 'lib/http';
9
+ import {InvalidError, NotFoundError} from 'lib/errors';
10
+
11
+ import BaseMiddleware from 'server/middleware/base';
12
+ import LoadPageOperation from 'server/operation/load-page';
13
+ import PageType from 'client/enum/page-type';
14
+ import TimePlaceVisibility from 'enum/time-place-visibility';
15
+ import getPathFromUrl from 'server/utility/get-path-from-url';
16
+ import PageResultSerializer from 'server/result-serializer/page';
17
+ import DefaultRole from 'enum/default-role';
18
+ import validateUrl from 'server/utility/validate-url';
19
+ import LoginResultSerializer from 'server/result-serializer/login';
20
+ import CustomPageType from 'server/enum/custom-page-type';
21
+ import Page from 'type/page';
22
+ import HeaderBlock from 'type/block/header';
23
+ import NoteBlock from 'type/block/note';
24
+ import BlockType from 'enum/block-type';
25
+ import acceptsHtml from 'server/utility/accepts-html';
26
+ import acceptsJson from 'server/utility/accepts-json';
27
+
28
+ function getReferrerUrl(request: IncomingRequest): string {
29
+ const referrer_header = request.getHeaderValue(HttpHeader.REFERER);
30
+ const host_header = request.getHeaderValue(HttpHeader.HOST);
31
+ const protocol = request.getProtocol();
32
+ const host_url = `${protocol}://${host_header}`;
33
+ const header_value = referrer_header || host_url;
34
+
35
+ if (header_value === undefined) {
36
+ throw new InvalidError('Request must specify a valid Host header');
37
+ }
38
+
39
+ validateUrl(header_value);
40
+
41
+ return header_value;
42
+ }
43
+
44
+ class ErrorHandlerMiddleware extends BaseMiddleware {
45
+ public async handleRequest(
46
+ request: IncomingRequest,
47
+ response: OutgoingResponse
48
+ ): Promise<boolean> {
49
+ const path = request.getPath();
50
+ const error = new NotFoundError(path);
51
+
52
+ return this.handleError(error, request, response);
53
+ }
54
+
55
+ public async handleError(
56
+ error: Error,
57
+ request: IncomingRequest,
58
+ response: OutgoingResponse
59
+ ): Promise<boolean> {
60
+ const status_code = getStatusCodeForError(error);
61
+ const accepts_html = acceptsHtml(request);
62
+ const is_unauthorized = status_code === StatusCode.UNAUTHORIZED;
63
+
64
+ const session = request.getSession() || {
65
+ id: 'xxx',
66
+ account_id: null,
67
+ username: null
68
+ };
69
+
70
+ const referrer_url = getReferrerUrl(request);
71
+ const referrer_path = getPathFromUrl(referrer_url);
72
+
73
+ if (is_unauthorized && accepts_html) {
74
+ const result = {
75
+ source_path: referrer_path
76
+ };
77
+
78
+ const path = '/login';
79
+
80
+ const serializer = new LoginResultSerializer(
81
+ result,
82
+ path,
83
+ referrer_path,
84
+ session
85
+ );
86
+
87
+ const serialized_page = serializer.serialize();
88
+
89
+ response.setHeaderValue(HttpHeader.CONTENT_TYPE, ContentType.HTML);
90
+ response.send(serialized_page);
91
+ return true;
92
+ }
93
+
94
+ const page_key = status_code.toString();
95
+ const page_path = `/${page_key}`;
96
+ const execution_context = request.getExecutionContext();
97
+
98
+ let page: Page;
99
+
100
+ try {
101
+ const operation = new LoadPageOperation(page_path, execution_context);
102
+
103
+ page = await operation.perform();
104
+ } catch (error) {
105
+ const now = Date.now();
106
+
107
+ page = {
108
+ path: page_path,
109
+ blocks: [
110
+ {
111
+ block_type: BlockType.HEADER,
112
+ title: page_key,
113
+ created_at: now,
114
+ show_time: false,
115
+ show_place: false
116
+ } as HeaderBlock,
117
+ {
118
+ block_type: BlockType.NOTE,
119
+ text: (error as Error).message,
120
+ created_at: now,
121
+ show_time: false,
122
+ show_place: false
123
+ } as NoteBlock
124
+ ]
125
+ };
126
+ }
127
+
128
+ const metadata = {
129
+ editing: false,
130
+ referrer_url,
131
+ toast: null,
132
+ page_type: PageType.VIEW_CUSTOM,
133
+ custom_page_type: CustomPageType.ERROR,
134
+ target_index_path: null,
135
+ roles: Object.values(DefaultRole),
136
+ account: {
137
+ id: '',
138
+ username: '',
139
+ password: '',
140
+ role: DefaultRole.PUBLIC,
141
+ settings: {
142
+ default_time_place_visibility: TimePlaceVisibility.NONE,
143
+ tool_types: []
144
+ }
145
+ }
146
+ };
147
+
148
+ response.setStatusCode(status_code);
149
+
150
+ const path = request.getPath();
151
+
152
+ if (accepts_html) {
153
+ const serializer = new PageResultSerializer(
154
+ page,
155
+ metadata,
156
+ path,
157
+ referrer_url,
158
+ session
159
+ );
160
+
161
+ const serialized_page = serializer.serialize();
162
+
163
+ response.setHeaderValue(HttpHeader.CONTENT_TYPE, ContentType.HTML);
164
+ response.send(serialized_page);
165
+ } else if (acceptsJson(request)) {
166
+ response.setHeaderValue(HttpHeader.CONTENT_TYPE, ContentType.JSON);
167
+ response.error(error);
168
+ } else {
169
+ response.setHeaderValue(HttpHeader.CONTENT_TYPE, ContentType.TEXT);
170
+ response.send(error.message);
171
+ }
172
+
173
+ return true;
174
+ }
175
+ }
176
+
177
+ export default ErrorHandlerMiddleware;
@@ -0,0 +1,83 @@
1
+ import FS from 'fs';
2
+
3
+ import {
4
+ HttpHeader,
5
+ IncomingRequest,
6
+ OutgoingResponse,
7
+ getContentTypeForExtension
8
+ } from 'lib/http';
9
+ import {InvalidError} from 'lib/errors';
10
+ import {exists, getExtensionForFilepath} from 'lib/filesystem';
11
+
12
+ import BaseMiddleware from 'server/middleware/base';
13
+
14
+ class StaticFileMiddleware extends BaseMiddleware {
15
+ public async handleRequest(
16
+ request: IncomingRequest,
17
+ response: OutgoingResponse
18
+ ): Promise<boolean> {
19
+ let url = request.getPath();
20
+
21
+ if (url.includes('?')) {
22
+ const parts = url.split('?');
23
+
24
+ url = parts[0];
25
+ }
26
+
27
+ const execution_context = request.getExecutionContext();
28
+ const config = execution_context.getConfig();
29
+ const public_directory = config.public_directory;
30
+ const absolute_filepath = `${public_directory}${url}`;
31
+
32
+ if (absolute_filepath.includes('..') || absolute_filepath.includes('./')) {
33
+ throw new InvalidError('Illegal filepath');
34
+ }
35
+
36
+ // TODO: This was originally only being set for .mp3 file requests.
37
+ // Is it okay to enable it for all types of files?
38
+ response.setHeaderValue(HttpHeader.ACCESS_CONTROL_ALLOW_ORIGIN, '*');
39
+
40
+ // TODO: Determine whether this needs to be reenabled:
41
+ /*
42
+ const {base_url} = execution_context.getConfig();
43
+ const policy = `script-src ${base_url}`;
44
+
45
+ response.setHeaderValue(HttpHeader.CONTENT_SECURITY_POLICY, policy);
46
+ */
47
+
48
+ const extension = getExtensionForFilepath(absolute_filepath);
49
+
50
+ if (extension === undefined) {
51
+ return false;
52
+ }
53
+
54
+ const content_type = getContentTypeForExtension(extension);
55
+
56
+ response.setHeaderValue(HttpHeader.CONTENT_TYPE, content_type);
57
+
58
+ const file_exists = await exists(absolute_filepath);
59
+
60
+ if (!file_exists) {
61
+ return false;
62
+ }
63
+
64
+ const stream = FS.createReadStream(absolute_filepath);
65
+ const native_response = response.getNativeResponse();
66
+
67
+ await new Promise<void>((resolve, reject) => {
68
+ stream.on('end', () => {
69
+ resolve();
70
+ });
71
+
72
+ stream.on('error', (error) => {
73
+ reject(error);
74
+ });
75
+
76
+ stream.pipe(native_response);
77
+ });
78
+
79
+ return true;
80
+ }
81
+ }
82
+
83
+ export default StaticFileMiddleware;
@@ -0,0 +1,110 @@
1
+ import {mkdir} from 'fs/promises';
2
+ import Path from 'path';
3
+
4
+ import ExecutionContext from 'lib/execution-context';
5
+
6
+ import Block from 'type/block';
7
+ import BlockType from 'enum/block-type';
8
+ import FolderBlock from 'type/block/folder';
9
+ import createSlug from 'server/utility/create-slug';
10
+ import getSiblingsAndIndexForIndexPath from 'server/utility/get-siblings-and-index-for-index-path';
11
+ import HeaderBlock from 'type/block/header';
12
+ import EphemeralBlock from 'type/block/ephemeral';
13
+ import BaseOperation from 'operation';
14
+ import Page from 'type/page';
15
+ import SavePageOperation from 'server/operation/save-page';
16
+
17
+ class AddBlockOperation extends BaseOperation<Block> {
18
+ private page: Page;
19
+ private block: Block;
20
+ private index_path: string;
21
+
22
+ public constructor(page: Page, block: Block, index_path: string, execution_context: ExecutionContext) {
23
+ super(execution_context);
24
+
25
+ this.page = page;
26
+ this.block = block;
27
+ this.index_path = index_path;
28
+ }
29
+
30
+ protected async performInternal(): Promise<Block> {
31
+ await this.createBlockArtifacts();
32
+
33
+ return this.saveBlockToPage();
34
+ }
35
+
36
+ private async createBlockArtifacts(): Promise<void> {
37
+ const block = this.getBlock();
38
+ const {block_type} = block;
39
+
40
+ if (block_type !== BlockType.FOLDER) {
41
+ return;
42
+ }
43
+
44
+ const folder_block = block as FolderBlock;
45
+ const {title} = folder_block;
46
+ const slug = createSlug(title);
47
+ const {path} = this.getPage();
48
+ const {public_directory} = this.getConfig();
49
+ const new_path = Path.resolve(path, `./${slug}`);
50
+ const filepath = Path.resolve(public_directory, `.${new_path}`);
51
+
52
+ await mkdir(filepath, {
53
+ recursive: true
54
+ });
55
+
56
+ const created_at = Date.now();
57
+
58
+ const title_block: HeaderBlock = {
59
+ block_type: BlockType.HEADER,
60
+ title,
61
+ created_at
62
+ };
63
+
64
+ const ephemeral_block: EphemeralBlock = {
65
+ block_type: BlockType.EPHEMERAL,
66
+ label: '(nothing here yet)',
67
+ created_at
68
+ };
69
+
70
+ const page = {
71
+ path: new_path,
72
+ blocks: [title_block, ephemeral_block]
73
+ };
74
+
75
+ const execution_context = this.getExecutionContext();
76
+ const operation = new SavePageOperation(page, execution_context);
77
+
78
+ await operation.perform();
79
+ }
80
+
81
+ private async saveBlockToPage(): Promise<Block> {
82
+ const page = this.getPage();
83
+ const execution_context = this.getExecutionContext();
84
+ const block = this.getBlock();
85
+ const index_path = this.getIndexPath();
86
+ const {siblings, index} = getSiblingsAndIndexForIndexPath(page, index_path);
87
+
88
+ siblings.splice(index, 0, block);
89
+
90
+ const save_operation = new SavePageOperation(page, execution_context);
91
+
92
+ await save_operation.perform();
93
+
94
+ return block;
95
+ }
96
+
97
+ private getPage(): Page {
98
+ return this.page;
99
+ }
100
+
101
+ private getBlock(): Block {
102
+ return this.block;
103
+ }
104
+
105
+ private getIndexPath(): string {
106
+ return this.index_path;
107
+ }
108
+ }
109
+
110
+ export default AddBlockOperation;
@@ -0,0 +1,43 @@
1
+ import {UnauthorizedError} from 'lib/errors';
2
+ import ExecutionContext, {Session} from 'lib/execution-context';
3
+
4
+ import BaseOperation from 'operation';
5
+
6
+ class CreateSessionOperation extends BaseOperation<Session> {
7
+ private username: string;
8
+ private password: string;
9
+
10
+ public constructor(username: string, password: string, execution_context: ExecutionContext) {
11
+ super(execution_context);
12
+
13
+ this.username = username;
14
+ this.password = password;
15
+ }
16
+
17
+ protected async performInternal(): Promise<Session> {
18
+ const {repository} = this.getConfig();
19
+ const username = this.getUsername();
20
+ const password = this.getPassword();
21
+ const account = await repository.getAccountForUsername(username);
22
+
23
+ if (account === undefined) {
24
+ throw new UnauthorizedError();
25
+ }
26
+
27
+ if (account.password !== password) {
28
+ throw new UnauthorizedError();
29
+ }
30
+
31
+ return repository.createSessionForAccount(account);
32
+ }
33
+
34
+ private getUsername(): string {
35
+ return this.username;
36
+ }
37
+
38
+ private getPassword(): string {
39
+ return this.password;
40
+ }
41
+ }
42
+
43
+ export default CreateSessionOperation;
@@ -0,0 +1,96 @@
1
+ import {rm} from 'fs/promises';
2
+
3
+ import ExecutionContext from 'lib/execution-context';
4
+ import {InvariantViolation, InvalidError} from 'lib/errors';
5
+
6
+ import BaseOperation from 'operation';
7
+ import FolderBlock from 'type/block/folder';
8
+ import BlockType from 'enum/block-type';
9
+ import Page from 'type/page';
10
+ import Block from 'type/block';
11
+ import LoadPageOperation from 'server/operation/load-page';
12
+ import getFilepathForFolderBlock from 'server/utility/get-filepath-for-folder-block';
13
+ import SavePageOperation from 'server/operation/save-page';
14
+ import getSiblingsAndIndexForIndexPath from 'server/utility/get-siblings-and-index-for-index-path';
15
+
16
+ class DeleteBlockOperation extends BaseOperation<void> {
17
+ private key: string;
18
+ private index_path: string;
19
+ private page: Page | undefined;
20
+
21
+ public constructor(key: string, index_path: string, execution_context: ExecutionContext) {
22
+ super(execution_context);
23
+
24
+ this.key = key;
25
+ this.index_path = index_path;
26
+ }
27
+
28
+ protected async performInternal(): Promise<void> {
29
+ await this.loadPage();
30
+
31
+ const page = this.getPage();
32
+ const index_path = this.getIndexPath();
33
+ const {siblings, index} = getSiblingsAndIndexForIndexPath(page, index_path);
34
+ const [deleted_block] = siblings.splice(index, 1);
35
+
36
+ if (deleted_block === undefined) {
37
+ throw new InvalidError(`Unable to remove block at path ${index_path}`);
38
+ }
39
+
40
+ const execution_context = this.getExecutionContext();
41
+ const save_operation = new SavePageOperation(page, execution_context);
42
+
43
+ await save_operation.perform();
44
+ await this.deleteBlockArtifacts(deleted_block);
45
+ }
46
+
47
+ private async loadPage(): Promise<void> {
48
+ const key = this.getKey();
49
+ const execution_context = this.getExecutionContext();
50
+ const operation = new LoadPageOperation(key, execution_context);
51
+ const page = await operation.perform();
52
+
53
+ this.page = page;
54
+ }
55
+
56
+ private async deleteBlockArtifacts(block: Block): Promise<void> {
57
+ const {block_type} = block;
58
+
59
+ if (block_type !== BlockType.FOLDER) {
60
+ return;
61
+ }
62
+
63
+ const {public_directory} = this.getConfig();
64
+ const {path} = this.getPage();
65
+ const folder_block = block as FolderBlock;
66
+
67
+ const folder_path = getFilepathForFolderBlock({
68
+ base_path: path,
69
+ public_directory,
70
+ block: folder_block
71
+ });
72
+
73
+ await rm(folder_path, {
74
+ recursive: true,
75
+ force: true
76
+ });
77
+ }
78
+
79
+ private getPage(): Page {
80
+ if (this.page === undefined) {
81
+ throw new InvariantViolation('Tried to read page, but it was not set');
82
+ }
83
+
84
+ return this.page;
85
+ }
86
+
87
+ private getKey(): string {
88
+ return this.key;
89
+ }
90
+
91
+ private getIndexPath(): string {
92
+ return this.index_path;
93
+ }
94
+ }
95
+
96
+ export default DeleteBlockOperation;