@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.
- package/LICENSE +673 -0
- package/README.md +5 -0
- package/bin/compile +63 -0
- package/bin/copy-static-files +13 -0
- package/bin/install +5 -0
- package/bin/precompile +55 -0
- package/bin/prepublish +7 -0
- package/bin/remap-paths +113 -0
- package/bin/test +9 -0
- package/config/tsconfig.json +37 -0
- package/package.json +33 -0
- package/src/bootstrap/start.ts +12 -0
- package/src/client/bootstrap.ts +5 -0
- package/src/client/client.ts +54 -0
- package/src/client/enum/key-code.ts +34 -0
- package/src/client/enum/page-type.ts +19 -0
- package/src/client/factory/page.ts +61 -0
- package/src/client/page/confirm-delete-block.ts +30 -0
- package/src/client/page/create-block.ts +6 -0
- package/src/client/page/day.ts +8 -0
- package/src/client/page/edit-block.ts +43 -0
- package/src/client/page/edit-custom.ts +16 -0
- package/src/client/page/home.ts +8 -0
- package/src/client/page/login.ts +8 -0
- package/src/client/page/logout.ts +8 -0
- package/src/client/page/month.ts +8 -0
- package/src/client/page/move-block.ts +8 -0
- package/src/client/page/select-block-type.ts +56 -0
- package/src/client/page/settings.ts +8 -0
- package/src/client/page/view-custom.ts +665 -0
- package/src/client/page/week.ts +8 -0
- package/src/client/page/year.ts +8 -0
- package/src/client/page.ts +128 -0
- package/src/client/shim/execute.ts +5 -0
- package/src/client/shim/logger.ts +44 -0
- package/src/client/utility/get-meta-value.ts +23 -0
- package/src/common/builder/block/background.ts +25 -0
- package/src/common/builder/block/folder.ts +43 -0
- package/src/common/builder/block/header.ts +15 -0
- package/src/common/builder/block/link.ts +32 -0
- package/src/common/builder/block/multicolumn.ts +16 -0
- package/src/common/builder/block/note.ts +13 -0
- package/src/common/builder/block/whitespace.ts +13 -0
- package/src/common/utility/get-parent-path.ts +29 -0
- package/src/constant/month-names.ts +16 -0
- package/src/enum/action-type.ts +11 -0
- package/src/enum/block-type.ts +18 -0
- package/src/enum/calendar-view-mode.ts +9 -0
- package/src/enum/color.ts +15 -0
- package/src/enum/default-role.ts +6 -0
- package/src/enum/directory-item-type.ts +6 -0
- package/src/enum/emoji.ts +94 -0
- package/src/enum/field-type.ts +8 -0
- package/src/enum/header-size.ts +7 -0
- package/src/enum/permission-type.ts +8 -0
- package/src/enum/time-place-visibility.ts +8 -0
- package/src/enum/tool-type.ts +14 -0
- package/src/index.ts +8 -0
- package/src/interface/hydration-callback.ts +7 -0
- package/src/interface/provider.ts +8 -0
- package/src/interface/repository.ts +12 -0
- package/src/lib/array/add.ts +10 -0
- package/src/lib/array/assert-is-empty.ts +23 -0
- package/src/lib/array/clone.ts +5 -0
- package/src/lib/array/difference.ts +8 -0
- package/src/lib/array/empty.ts +6 -0
- package/src/lib/array/equal.ts +24 -0
- package/src/lib/array/get-first-value.ts +5 -0
- package/src/lib/array/get-last-value.ts +5 -0
- package/src/lib/array/get-max-value.ts +5 -0
- package/src/lib/array/get-value-after.ts +23 -0
- package/src/lib/array/get-value-before.ts +23 -0
- package/src/lib/array/get-values-between.ts +18 -0
- package/src/lib/array/index.ts +5 -0
- package/src/lib/array/is-empty.ts +6 -0
- package/src/lib/array/remove.ts +19 -0
- package/src/lib/array/sum.ts +11 -0
- package/src/lib/array/unique.ts +13 -0
- package/src/lib/environment/bootstrap.ts +1 -0
- package/src/lib/environment/enum/environment-type.ts +8 -0
- package/src/lib/environment/enum/service-type.ts +5 -0
- package/src/lib/environment/index.ts +7 -0
- package/src/lib/environment/utility/get-environment-type.ts +28 -0
- package/src/lib/environment/utility/is-browser.ts +5 -0
- package/src/lib/environment/utility/is-development.ts +10 -0
- package/src/lib/environment/utility/is-production-or-staging.ts +8 -0
- package/src/lib/environment/utility/is-production.ts +10 -0
- package/src/lib/environment/utility/is-staging.ts +10 -0
- package/src/lib/errors/enum/error-type.ts +13 -0
- package/src/lib/errors/error/base.ts +40 -0
- package/src/lib/errors/error/conflict.ts +16 -0
- package/src/lib/errors/error/generic.ts +23 -0
- package/src/lib/errors/error/invalid.ts +14 -0
- package/src/lib/errors/error/invariant-violation.ts +5 -0
- package/src/lib/errors/error/not-allowed.ts +14 -0
- package/src/lib/errors/error/not-found.ts +16 -0
- package/src/lib/errors/error/not-implemented.ts +20 -0
- package/src/lib/errors/error/omitted.ts +14 -0
- package/src/lib/errors/error/timeout.ts +14 -0
- package/src/lib/errors/error/unauthorized.ts +14 -0
- package/src/lib/errors/index.ts +18 -0
- package/src/lib/errors/sugar/invariant.ts +7 -0
- package/src/lib/errors/type/coded-error.ts +7 -0
- package/src/lib/errors/type/error-data.ts +11 -0
- package/src/lib/errors/utility/create-error-for-error-type.ts +60 -0
- package/src/lib/errors/utility/create-error-from-ambiguous-json-data.ts +26 -0
- package/src/lib/errors/utility/error-matches.ts +28 -0
- package/src/lib/errors/utility/get-error-type-for-posix-error-code.ts +37 -0
- package/src/lib/errors/utility/get-error-type-for-status-code.ts +38 -0
- package/src/lib/errors/utility/get-message-for-error-type.ts +29 -0
- package/src/lib/errors/utility/matches-posix-error-code.ts +11 -0
- package/src/lib/errors/utility/wrap-error.ts +39 -0
- package/src/lib/event-emitter/index.ts +63 -0
- package/src/lib/execution-context/execution-context.ts +90 -0
- package/src/lib/execution-context/index.ts +8 -0
- package/src/lib/execution-context/type/session.ts +7 -0
- package/src/lib/feature/feature.ts +108 -0
- package/src/lib/feature/index.ts +3 -0
- package/src/lib/filesystem/bootstrap.ts +1 -0
- package/src/lib/filesystem/enum/file-extension.ts +19 -0
- package/src/lib/filesystem/index.ts +4 -0
- package/src/lib/filesystem/utility/exists.ts +21 -0
- package/src/lib/filesystem/utility/get-extension-for-filepath.ts +20 -0
- package/src/lib/filesystem/utility/strip-extension.ts +26 -0
- package/src/lib/grammar/index.ts +3 -0
- package/src/lib/grammar/noun-inflector.ts +104 -0
- package/src/lib/grammar/utility/get-words-from-identifier.ts +9 -0
- package/src/lib/grammar/verb-inflector.ts +344 -0
- package/src/lib/http/buffer-stream.ts +76 -0
- package/src/lib/http/enum/content-type.ts +19 -0
- package/src/lib/http/enum/cookie-attribute.ts +11 -0
- package/src/lib/http/enum/header.ts +29 -0
- package/src/lib/http/enum/method.ts +11 -0
- package/src/lib/http/enum/same-site-policy.ts +7 -0
- package/src/lib/http/enum/status-code.ts +9 -0
- package/src/lib/http/factory/body-parser.ts +55 -0
- package/src/lib/http/index.ts +24 -0
- package/src/lib/http/interface/client-request.ts +15 -0
- package/src/lib/http/interface/incoming-message.ts +24 -0
- package/src/lib/http/interface/network-library.ts +9 -0
- package/src/lib/http/interface/request-callback.ts +7 -0
- package/src/lib/http/isomorphic/request.ts +77 -0
- package/src/lib/http/isomorphic/response.ts +77 -0
- package/src/lib/http/isomorphic.ts +20 -0
- package/src/lib/http/parser/accept-header.ts +35 -0
- package/src/lib/http/parser/basic-auth-header.ts +48 -0
- package/src/lib/http/parser/body/json.ts +14 -0
- package/src/lib/http/parser/body/multipart.ts +89 -0
- package/src/lib/http/parser/body/url-encoded.ts +16 -0
- package/src/lib/http/parser/body.ts +44 -0
- package/src/lib/http/parser/cookie.ts +114 -0
- package/src/lib/http/parser/querystring.ts +92 -0
- package/src/lib/http/parser/url.ts +76 -0
- package/src/lib/http/request/incoming.ts +299 -0
- package/src/lib/http/request/outgoing.ts +276 -0
- package/src/lib/http/request.ts +26 -0
- package/src/lib/http/response/incoming.ts +243 -0
- package/src/lib/http/response/outgoing.ts +160 -0
- package/src/lib/http/response.ts +74 -0
- package/src/lib/http/serializer/basic-auth-header.ts +27 -0
- package/src/lib/http/serializer/cookie.ts +90 -0
- package/src/lib/http/serializer/query-data.ts +54 -0
- package/src/lib/http/transaction.ts +320 -0
- package/src/lib/http/type/basic-auth-credentials.ts +6 -0
- package/src/lib/http/type/header-map.ts +5 -0
- package/src/lib/http/type/log-attributes.ts +12 -0
- package/src/lib/http/type/path-parameters.ts +5 -0
- package/src/lib/http/type/query-data.ts +7 -0
- package/src/lib/http/type/query-value.ts +11 -0
- package/src/lib/http/type/request-options.ts +16 -0
- package/src/lib/http/type/transaction-data.ts +4 -0
- package/src/lib/http/utility/get-content-type-for-extension.ts +47 -0
- package/src/lib/http/utility/get-library-for-protocol.ts +25 -0
- package/src/lib/http/utility/get-status-code-for-error-type.ts +37 -0
- package/src/lib/http/utility/get-status-code-for-error.ts +13 -0
- package/src/lib/http/utility/is-client-error-status.ts +15 -0
- package/src/lib/http/utility/is-error-status.ts +9 -0
- package/src/lib/http/utility/is-server-error-status.ts +7 -0
- package/src/lib/http/utility/is-success-status.ts +7 -0
- package/src/lib/http/utility/proxy-request.ts +58 -0
- package/src/lib/http/utility/serialize-request-options.ts +9 -0
- package/src/lib/http/utility/slug-generator.ts +20 -0
- package/src/lib/key-generator/index.ts +3 -0
- package/src/lib/key-generator/key-generator.ts +7 -0
- package/src/lib/logger/enum/ansi-escape-code.ts +14 -0
- package/src/lib/logger/enum/log-level.ts +8 -0
- package/src/lib/logger/formatter.ts +59 -0
- package/src/lib/logger/index.ts +7 -0
- package/src/lib/logger/interface/error-reporter.ts +7 -0
- package/src/lib/logger/interface/logger.ts +13 -0
- package/src/lib/logger/logger.ts +239 -0
- package/src/lib/logger/type/error-parameters.ts +9 -0
- package/src/lib/logger/type/loggable-data.ts +5 -0
- package/src/lib/logger/type/loggable-value.ts +1 -0
- package/src/lib/metrics/dispatcher.ts +264 -0
- package/src/lib/metrics/enum/dispatch-mode.ts +6 -0
- package/src/lib/metrics/index.ts +2 -0
- package/src/lib/metrics/settings-hydrator.ts +51 -0
- package/src/lib/metrics/type/dispatcher-settings.ts +12 -0
- package/src/lib/metrics/type/tag-map.ts +5 -0
- package/src/lib/network/bootstrap.ts +1 -0
- package/src/lib/network/enum/connection-status.ts +14 -0
- package/src/lib/network/enum/http-status-code.ts +75 -0
- package/src/lib/network/enum/network-protocol.ts +10 -0
- package/src/lib/network/event-emitter.ts +63 -0
- package/src/lib/network/index.ts +7 -0
- package/src/lib/network/interface/socket.ts +42 -0
- package/src/lib/network/type/socket-options.ts +6 -0
- package/src/lib/network/utility/get-protocol-from-url.ts +15 -0
- package/src/lib/operation/index.ts +6 -0
- package/src/lib/operation/operation/auto-logging.ts +94 -0
- package/src/lib/operation/operation/silent.ts +17 -0
- package/src/lib/operation/operation.ts +80 -0
- package/src/lib/process/bootstrap.ts +1 -0
- package/src/lib/process/enum/posix-error-code.ts +138 -0
- package/src/lib/process/enum/process-signal.ts +68 -0
- package/src/lib/process/error.ts +6 -0
- package/src/lib/process/execute.ts +77 -0
- package/src/lib/process/index.ts +4 -0
- package/src/lib/process/type/command-options.ts +9 -0
- package/src/lib/process/utility/bind-process-lifespan-to.ts +10 -0
- package/src/lib/promise-wrapper/index.ts +3 -0
- package/src/lib/promise-wrapper/promise-wrapper.ts +51 -0
- package/src/lib/random/chance.ts +5 -0
- package/src/lib/random/element.ts +7 -0
- package/src/lib/random/elements.ts +12 -0
- package/src/lib/random/enum.ts +34 -0
- package/src/lib/random/enums.ts +11 -0
- package/src/lib/random/index.ts +3 -0
- package/src/lib/random/number.ts +8 -0
- package/src/lib/server/base.ts +194 -0
- package/src/lib/server/enum/server-event.ts +5 -0
- package/src/lib/server/enum/server-status.ts +10 -0
- package/src/lib/server/http/endpoint/ping.ts +21 -0
- package/src/lib/server/http/endpoint.ts +345 -0
- package/src/lib/server/http/interface/endpoint-constructor.ts +12 -0
- package/src/lib/server/http/interface/result-serializer.ts +5 -0
- package/src/lib/server/http/middleware.ts +18 -0
- package/src/lib/server/http/result-serializer/html.ts +92 -0
- package/src/lib/server/http/result-serializer/json.ts +23 -0
- package/src/lib/server/http/route.ts +104 -0
- package/src/lib/server/http/router.ts +125 -0
- package/src/lib/server/http/type/session-resolver.ts +8 -0
- package/src/lib/server/http/utility/create-server.ts +34 -0
- package/src/lib/server/http/utility/path-parser.ts +49 -0
- package/src/lib/server/http/utility/standardize-html-indentation.ts +54 -0
- package/src/lib/server/http/websocket-wrapper.ts +83 -0
- package/src/lib/server/http.ts +301 -0
- package/src/lib/server/index.ts +5 -0
- package/src/lib/server/tcp.ts +53 -0
- package/src/lib/server/type/server-options.ts +10 -0
- package/src/lib/string/calculate-length.ts +17 -0
- package/src/lib/string/capitalize.ts +8 -0
- package/src/lib/string/create-slug.ts +14 -0
- package/src/lib/string/enum/ansi-escape-code.ts +14 -0
- package/src/lib/string/enum/string-encoding.ts +9 -0
- package/src/lib/string/hyphenate.ts +5 -0
- package/src/lib/string/index.ts +3 -0
- package/src/lib/string/pad.ts +14 -0
- package/src/lib/string/trim-multiline.ts +21 -0
- package/src/lib/string/trim.ts +8 -0
- package/src/lib/tcp/channel.ts +13 -0
- package/src/lib/tcp/connection/incoming.ts +72 -0
- package/src/lib/tcp/connection/outgoing.ts +219 -0
- package/src/lib/tcp/connection.ts +360 -0
- package/src/lib/tcp/enum/connection-event.ts +12 -0
- package/src/lib/tcp/enum/message-type.ts +9 -0
- package/src/lib/tcp/index.ts +1 -0
- package/src/lib/tcp/type/connection-parameters.ts +6 -0
- package/src/lib/tcp/type/message/channel-close.ts +9 -0
- package/src/lib/tcp/type/message/channel-open.ts +9 -0
- package/src/lib/tcp/type/message.ts +10 -0
- package/src/lib/test/index.ts +2 -0
- package/src/lib/test/utility/build-config.ts +17 -0
- package/src/lib/test/utility/build-execution-context.ts +11 -0
- package/src/lib/time/bootstrap.ts +1 -0
- package/src/lib/time/enum/time-interval.ts +12 -0
- package/src/lib/time/index.ts +4 -0
- package/src/lib/time/utility/format-duration.ts +139 -0
- package/src/lib/time/utility/format-relative-duration.ts +22 -0
- package/src/lib/time/utility/sleep.ts +9 -0
- package/src/operation.ts +18 -0
- package/src/server/endpoint/abstract-page.ts +126 -0
- package/src/server/endpoint/action/create.ts +545 -0
- package/src/server/endpoint/action/get.ts +231 -0
- package/src/server/endpoint/base.ts +51 -0
- package/src/server/endpoint/day.ts +13 -0
- package/src/server/endpoint/generic-page.ts +14 -0
- package/src/server/endpoint/index.ts +11 -0
- package/src/server/endpoint/login.ts +45 -0
- package/src/server/endpoint/logout.ts +38 -0
- package/src/server/endpoint/month.ts +35 -0
- package/src/server/endpoint/robots.ts +18 -0
- package/src/server/endpoint/session/create.ts +62 -0
- package/src/server/endpoint/settings/get.ts +40 -0
- package/src/server/endpoint/settings/update.ts +44 -0
- package/src/server/endpoint/today.ts +15 -0
- package/src/server/endpoint/week.ts +34 -0
- package/src/server/endpoint/year.ts +34 -0
- package/src/server/enum/custom-page-type.ts +10 -0
- package/src/server/factory/block-result-serializer.ts +115 -0
- package/src/server/middleware/base.ts +6 -0
- package/src/server/middleware/error-handler.ts +177 -0
- package/src/server/middleware/static-file.ts +83 -0
- package/src/server/operation/add-block.ts +110 -0
- package/src/server/operation/create-session.ts +43 -0
- package/src/server/operation/delete-block.ts +96 -0
- package/src/server/operation/demote-block.ts +108 -0
- package/src/server/operation/destroy-session.ts +26 -0
- package/src/server/operation/load-account.ts +30 -0
- package/src/server/operation/load-block.ts +48 -0
- package/src/server/operation/load-directory-items.ts +75 -0
- package/src/server/operation/load-page.ts +368 -0
- package/src/server/operation/promote-block.ts +104 -0
- package/src/server/operation/save-page.ts +60 -0
- package/src/server/operation/update-account-settings.ts +52 -0
- package/src/server/operation/update-block.ts +124 -0
- package/src/server/repository/memory.ts +112 -0
- package/src/server/result-serializer/action.ts +939 -0
- package/src/server/result-serializer/base.ts +1267 -0
- package/src/server/result-serializer/block/audio.ts +33 -0
- package/src/server/result-serializer/block/background.ts +20 -0
- package/src/server/result-serializer/block/calendar.ts +148 -0
- package/src/server/result-serializer/block/directory.ts +57 -0
- package/src/server/result-serializer/block/ephemeral.ts +14 -0
- package/src/server/result-serializer/block/folder.ts +106 -0
- package/src/server/result-serializer/block/header.ts +31 -0
- package/src/server/result-serializer/block/image.ts +46 -0
- package/src/server/result-serializer/block/link.ts +40 -0
- package/src/server/result-serializer/block/list.ts +140 -0
- package/src/server/result-serializer/block/multi-column.ts +97 -0
- package/src/server/result-serializer/block/note.ts +44 -0
- package/src/server/result-serializer/block/todo.ts +78 -0
- package/src/server/result-serializer/block/whitespace.ts +15 -0
- package/src/server/result-serializer/block.ts +248 -0
- package/src/server/result-serializer/common/time-place-options.ts +33 -0
- package/src/server/result-serializer/login.ts +58 -0
- package/src/server/result-serializer/month.ts +170 -0
- package/src/server/result-serializer/page.ts +548 -0
- package/src/server/result-serializer/settings.ts +85 -0
- package/src/server/result-serializer/week.ts +195 -0
- package/src/server/result-serializer/year.ts +160 -0
- package/src/server/utility/accepts-content-type.ts +16 -0
- package/src/server/utility/accepts-html.ts +9 -0
- package/src/server/utility/accepts-json.ts +9 -0
- package/src/server/utility/add-days.ts +11 -0
- package/src/server/utility/create-date.ts +23 -0
- package/src/server/utility/create-index-path.ts +5 -0
- package/src/server/utility/create-slug.ts +9 -0
- package/src/server/utility/create-toast-path.ts +19 -0
- package/src/server/utility/date-less-than.ts +5 -0
- package/src/server/utility/date-occurs-before.ts +22 -0
- package/src/server/utility/date-to-key.ts +7 -0
- package/src/server/utility/date-to-label.ts +5 -0
- package/src/server/utility/date-to-path.ts +9 -0
- package/src/server/utility/dates-are-equal.ts +22 -0
- package/src/server/utility/dates-are-in-order.ts +9 -0
- package/src/server/utility/dates-are-on-the-same-day.ts +9 -0
- package/src/server/utility/dates-in-same-month.ts +8 -0
- package/src/server/utility/day-to-date.ts +40 -0
- package/src/server/utility/decrement-date.ts +11 -0
- package/src/server/utility/get-block-at-index-path.ts +32 -0
- package/src/server/utility/get-block-permissions.ts +15 -0
- package/src/server/utility/get-compact-label-for-date.ts +8 -0
- package/src/server/utility/get-custom-page-type-for-path.ts +37 -0
- package/src/server/utility/get-element-id-for-block.ts +15 -0
- package/src/server/utility/get-emoji-for-block-type.ts +39 -0
- package/src/server/utility/get-emoji-for-tool-type.ts +20 -0
- package/src/server/utility/get-end-of-month.ts +13 -0
- package/src/server/utility/get-end-of-week.ts +13 -0
- package/src/server/utility/get-filepath-for-folder-block.ts +23 -0
- package/src/server/utility/get-hex-for-color.ts +31 -0
- package/src/server/utility/get-label-for-time-place-visibility.ts +23 -0
- package/src/server/utility/get-month-name.ts +18 -0
- package/src/server/utility/get-next-day.ts +7 -0
- package/src/server/utility/get-next-month.ts +12 -0
- package/src/server/utility/get-next-week.ts +12 -0
- package/src/server/utility/get-next-year.ts +13 -0
- package/src/server/utility/get-ordinal-label-for-week.ts +11 -0
- package/src/server/utility/get-ordinal-of-week-within-month.ts +15 -0
- package/src/server/utility/get-padded-date.ts +11 -0
- package/src/server/utility/get-parent-index-path.ts +18 -0
- package/src/server/utility/get-path-for-folder-block.ts +25 -0
- package/src/server/utility/get-path-from-url.ts +13 -0
- package/src/server/utility/get-previous-index-path.ts +27 -0
- package/src/server/utility/get-previous-month.ts +12 -0
- package/src/server/utility/get-previous-week.ts +11 -0
- package/src/server/utility/get-previous-year.ts +13 -0
- package/src/server/utility/get-random-emoji-for-date.ts +109 -0
- package/src/server/utility/get-short-label-for-date.ts +11 -0
- package/src/server/utility/get-short-month-name.ts +9 -0
- package/src/server/utility/get-short-ordinal.ts +26 -0
- package/src/server/utility/get-siblings-and-index-for-index-path.ts +67 -0
- package/src/server/utility/get-start-of-month.ts +11 -0
- package/src/server/utility/get-start-of-week.ts +12 -0
- package/src/server/utility/get-start-of-year.ts +12 -0
- package/src/server/utility/get-weekday-name.ts +24 -0
- package/src/server/utility/increment-date.ts +15 -0
- package/src/server/utility/is-index-path.ts +5 -0
- package/src/server/utility/key-to-date.ts +25 -0
- package/src/server/utility/month-has-week-containing-date.ts +13 -0
- package/src/server/utility/month-to-date.ts +28 -0
- package/src/server/utility/month-to-path.ts +10 -0
- package/src/server/utility/months-are-equal.ts +8 -0
- package/src/server/utility/parse-index-path.ts +23 -0
- package/src/server/utility/path-is-date.ts +13 -0
- package/src/server/utility/path-to-date.ts +24 -0
- package/src/server/utility/subtract-days.ts +7 -0
- package/src/server/utility/validate-month.ts +10 -0
- package/src/server/utility/validate-page.ts +46 -0
- package/src/server/utility/validate-path.ts +9 -0
- package/src/server/utility/validate-url.ts +12 -0
- package/src/server/utility/week-greater-than.ts +10 -0
- package/src/server/utility/week-to-date.ts +8 -0
- package/src/server/utility/week-to-path.ts +12 -0
- package/src/server/utility/weeks-are-equal.ts +8 -0
- package/src/server/utility/year-to-date.ts +26 -0
- package/src/server/utility/year-to-path.ts +7 -0
- package/src/server/utility/years-are-equal.ts +8 -0
- package/src/server.ts +140 -0
- package/src/test.ts +195 -0
- package/src/type/account-settings.ts +9 -0
- package/src/type/account.ts +11 -0
- package/src/type/action/add-block.ts +74 -0
- package/src/type/action/complete-block.ts +10 -0
- package/src/type/action/delete-block.ts +11 -0
- package/src/type/action/demote-block.ts +9 -0
- package/src/type/action/edit-block.ts +11 -0
- package/src/type/action/promote-block.ts +9 -0
- package/src/type/action.ts +9 -0
- package/src/type/block/audio.ts +8 -0
- package/src/type/block/background.ts +10 -0
- package/src/type/block/directory.ts +18 -0
- package/src/type/block/ephemeral.ts +9 -0
- package/src/type/block/folder.ts +14 -0
- package/src/type/block/header.ts +11 -0
- package/src/type/block/image.ts +8 -0
- package/src/type/block/link.ts +12 -0
- package/src/type/block/list.ts +24 -0
- package/src/type/block/multi-column.ts +10 -0
- package/src/type/block/note.ts +9 -0
- package/src/type/block/todo.ts +10 -0
- package/src/type/block/whitespace.ts +9 -0
- package/src/type/block-metadata.ts +14 -0
- package/src/type/block.ts +18 -0
- package/src/type/day.ts +5 -0
- package/src/type/field-definition.ts +8 -0
- package/src/type/field-value.ts +5 -0
- package/src/type/file.ts +6 -0
- package/src/type/month.ts +5 -0
- package/src/type/page.ts +8 -0
- package/src/type/price.ts +11 -0
- package/src/type/resource.ts +5 -0
- package/src/type/runtime-config.ts +13 -0
- package/src/type/server-settings.ts +17 -0
- package/src/type/toast.ts +8 -0
- package/src/type/week.ts +5 -0
- package/src/type/year.ts +5 -0
- package/test/unit/index.ts +11 -0
- package/test/unit/server/operation/promote-block.ts +84 -0
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/ban-types */
|
|
2
|
+
|
|
3
|
+
import HTTP from 'http';
|
|
4
|
+
|
|
5
|
+
import Logger from 'lib/logger';
|
|
6
|
+
import KeyGenerator from 'lib/key-generator';
|
|
7
|
+
import ExecutionContext, {Session} from 'lib/execution-context';
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
HttpMethod,
|
|
11
|
+
HttpHeader,
|
|
12
|
+
StatusCode,
|
|
13
|
+
ContentType,
|
|
14
|
+
IncomingRequest,
|
|
15
|
+
OutgoingResponse,
|
|
16
|
+
CookieSerializer
|
|
17
|
+
} from 'lib/http';
|
|
18
|
+
import {
|
|
19
|
+
InvalidError,
|
|
20
|
+
NotFoundError,
|
|
21
|
+
InvariantViolation,
|
|
22
|
+
NotImplementedError
|
|
23
|
+
} from 'lib/errors';
|
|
24
|
+
|
|
25
|
+
import ResultSerializer from 'lib/server/http/interface/result-serializer';
|
|
26
|
+
import JsonResultSerializer from 'lib/server/http/result-serializer/json';
|
|
27
|
+
import HtmlResultSerializer from 'lib/server/http/result-serializer/html';
|
|
28
|
+
|
|
29
|
+
// TODO: Move this to server/http/type/allowed-outputs (or similar)
|
|
30
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
31
|
+
export type AllowedOutputs = string | Buffer | object;
|
|
32
|
+
|
|
33
|
+
abstract class Endpoint<Input, Output extends AllowedOutputs> {
|
|
34
|
+
private request: IncomingRequest | undefined;
|
|
35
|
+
private response: OutgoingResponse | undefined;
|
|
36
|
+
private content_type: ContentType | undefined;
|
|
37
|
+
|
|
38
|
+
public abstract path: string;
|
|
39
|
+
public abstract method: HttpMethod;
|
|
40
|
+
public abstract content_types: ContentType[];
|
|
41
|
+
|
|
42
|
+
public setRequest(request: IncomingRequest): void {
|
|
43
|
+
this.request = request;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
public setResponse(response: OutgoingResponse): void {
|
|
47
|
+
this.response = response;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
public async serve(): Promise<void> {
|
|
51
|
+
const result = await this.serveInternal()
|
|
52
|
+
|
|
53
|
+
if (result === undefined) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
this.applyNecessaryHeaders();
|
|
58
|
+
|
|
59
|
+
const response = this.getResponse();
|
|
60
|
+
|
|
61
|
+
if (typeof result === 'string' || result instanceof Buffer) {
|
|
62
|
+
response.send(result);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const serialized_result = await this.serializeResult(result as object);
|
|
67
|
+
|
|
68
|
+
response.send(serialized_result);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
protected getRequest(): IncomingRequest {
|
|
72
|
+
if (this.request === undefined) {
|
|
73
|
+
throw new InvariantViolation('Tried to read request, but it was not set');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return this.request;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
protected getNativeRequest(): HTTP.IncomingMessage {
|
|
80
|
+
const request = this.getRequest();
|
|
81
|
+
|
|
82
|
+
return request.getNativeRequest();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
protected getResponse(): OutgoingResponse {
|
|
86
|
+
if (this.response === undefined) {
|
|
87
|
+
throw new InvariantViolation(`
|
|
88
|
+
Tried to read response, but it was not setttt
|
|
89
|
+
`);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return this.response;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
protected getNativeResponse(): HTTP.ServerResponse {
|
|
96
|
+
const response = this.getResponse();
|
|
97
|
+
|
|
98
|
+
return response.getNativeResponse();
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
protected getPathParameter(parameter: string): string {
|
|
102
|
+
const request = this.getRequest();
|
|
103
|
+
const value = request.getPathParameter(parameter);
|
|
104
|
+
|
|
105
|
+
if (value === undefined) {
|
|
106
|
+
throw new InvalidError(`
|
|
107
|
+
No value found for url parameter "${parameter}"
|
|
108
|
+
`);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return value;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
protected getQueryParameter(
|
|
115
|
+
parameter: string
|
|
116
|
+
): string | string[] | undefined {
|
|
117
|
+
const request = this.getRequest();
|
|
118
|
+
|
|
119
|
+
return request.getQueryParameter(parameter);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
protected getNumericParameter(parameter: string, fallback?: number): number {
|
|
123
|
+
const raw_value = this.getQueryParameter(parameter);
|
|
124
|
+
|
|
125
|
+
if (raw_value === undefined) {
|
|
126
|
+
if (fallback === undefined) {
|
|
127
|
+
throw new InvalidError(`Query parameter not found: ${parameter}`);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return fallback;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (typeof raw_value !== 'string') {
|
|
134
|
+
throw new InvalidError(`
|
|
135
|
+
Invalid numeric value for parameter ${parameter}: ${raw_value}
|
|
136
|
+
`);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const parsed_value = parseFloat(raw_value);
|
|
140
|
+
|
|
141
|
+
if (isNaN(parsed_value)) {
|
|
142
|
+
throw new InvalidError(`
|
|
143
|
+
Invalid numeric value for parameter ${parameter}: ${raw_value}
|
|
144
|
+
`);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return parsed_value;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
protected setStatusCode(status_code: StatusCode): void {
|
|
151
|
+
const response = this.getResponse();
|
|
152
|
+
|
|
153
|
+
response.setStatusCode(status_code);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
protected getRequestBody(): Input {
|
|
157
|
+
const request = this.getRequest();
|
|
158
|
+
const data = request.getData();
|
|
159
|
+
|
|
160
|
+
return data as Input;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
protected getLogger(): Logger {
|
|
164
|
+
const execution_context = this.getExecutionContext();
|
|
165
|
+
|
|
166
|
+
return execution_context.getLogger();
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
protected getExecutionContext(): ExecutionContext {
|
|
170
|
+
const request = this.getRequest();
|
|
171
|
+
|
|
172
|
+
return request.getExecutionContext();
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
protected applyCorsHeaders(
|
|
176
|
+
request: IncomingRequest,
|
|
177
|
+
response: OutgoingResponse
|
|
178
|
+
): void {
|
|
179
|
+
const origin = request.getAllowedCorsOrigin();
|
|
180
|
+
|
|
181
|
+
response.setHeaderValue(HttpHeader.ACCESS_CONTROL_ALLOW_ORIGIN, origin);
|
|
182
|
+
|
|
183
|
+
const allowed_headers = request.getAllowedCorsHeaders();
|
|
184
|
+
const header_string = allowed_headers.join(',');
|
|
185
|
+
|
|
186
|
+
response.setHeaderValue(
|
|
187
|
+
HttpHeader.ACCESS_CONTROL_ALLOW_HEADERS,
|
|
188
|
+
header_string
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
response.setHeaderValue(
|
|
192
|
+
HttpHeader.ACCESS_CONTROL_ALLOW_CREDENTIALS,
|
|
193
|
+
'true'
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
protected getSessionId(): string {
|
|
198
|
+
const {id} = this.getSession();
|
|
199
|
+
|
|
200
|
+
return id;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
protected setSession(session: Session): Session {
|
|
204
|
+
const response = this.getResponse();
|
|
205
|
+
const serializer = new CookieSerializer(session.id);
|
|
206
|
+
const cookie_value = serializer.serialize();
|
|
207
|
+
const execution_context = this.getExecutionContext();
|
|
208
|
+
|
|
209
|
+
execution_context.setSession(session);
|
|
210
|
+
response.setHeaderValue(HttpHeader.SET_COOKIE, cookie_value);
|
|
211
|
+
|
|
212
|
+
return session;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
protected getSession(): Session {
|
|
216
|
+
const request = this.getRequest();
|
|
217
|
+
const execution_context = this.getExecutionContext();
|
|
218
|
+
const session = execution_context.getSession();
|
|
219
|
+
const session_id = request.getSessionIdFromCookie();
|
|
220
|
+
|
|
221
|
+
if (session_id === undefined || session === undefined || session_id !== session.id) {
|
|
222
|
+
|
|
223
|
+
return this.setSession({
|
|
224
|
+
id: KeyGenerator.generateToken(),
|
|
225
|
+
account_id: null,
|
|
226
|
+
username: null
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
return session;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
protected getJsonResultSerializer(
|
|
234
|
+
result: object
|
|
235
|
+
): JsonResultSerializer<object> {
|
|
236
|
+
return new JsonResultSerializer(result);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
protected getHtmlResultSerializer(
|
|
240
|
+
_result: object
|
|
241
|
+
): HtmlResultSerializer<object> | Promise<HtmlResultSerializer<object>> {
|
|
242
|
+
throw new NotImplementedError(
|
|
243
|
+
'Must implement getHtmlResultSerializer in child class'
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
protected async authorize(): Promise<void> {
|
|
248
|
+
// Noop by default, override this in child classes.
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
private async serveInternal(): Promise<Output | void> {
|
|
252
|
+
await this.authorize();
|
|
253
|
+
await this.parseBody();
|
|
254
|
+
|
|
255
|
+
return this.process();
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
private async serializeResult(result: object): Promise<string | Buffer> {
|
|
259
|
+
const serializer = await this.getResultSerializer(result);
|
|
260
|
+
|
|
261
|
+
return serializer.serialize();
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
private getResultSerializer(
|
|
265
|
+
result: object
|
|
266
|
+
): ResultSerializer | Promise<ResultSerializer> {
|
|
267
|
+
const content_type = this.getContentType();
|
|
268
|
+
|
|
269
|
+
switch (content_type) {
|
|
270
|
+
case ContentType.JSON:
|
|
271
|
+
return this.getJsonResultSerializer(result);
|
|
272
|
+
|
|
273
|
+
case ContentType.HTML:
|
|
274
|
+
return this.getHtmlResultSerializer(result);
|
|
275
|
+
|
|
276
|
+
default:
|
|
277
|
+
throw new Error(
|
|
278
|
+
`Unable to serialize result for content type: ${content_type}`
|
|
279
|
+
);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
private parseBody(): Promise<void> {
|
|
284
|
+
const request = this.getRequest();
|
|
285
|
+
|
|
286
|
+
return request.parseBody();
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
private applyNecessaryHeaders(): void {
|
|
290
|
+
this.applyContentTypeHeader();
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
private applyContentTypeHeader(): void {
|
|
294
|
+
const content_type = this.getContentType();
|
|
295
|
+
const response = this.getResponse();
|
|
296
|
+
|
|
297
|
+
response.setHeaderValue(HttpHeader.CONTENT_TYPE, content_type);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
private getContentType(): ContentType {
|
|
301
|
+
if (this.content_type === undefined) {
|
|
302
|
+
this.content_type = this.determineContentType();
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
return this.content_type;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
private determineContentType(): ContentType {
|
|
309
|
+
const supported_content_types = this.getContentTypes();
|
|
310
|
+
|
|
311
|
+
if (supported_content_types.length === 1) {
|
|
312
|
+
return supported_content_types[0];
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
const request = this.getRequest();
|
|
316
|
+
const accepted_content_types = request.getAcceptedContentTypes();
|
|
317
|
+
const has_any_type = accepted_content_types.includes(ContentType.ANY);
|
|
318
|
+
|
|
319
|
+
const matching_type = accepted_content_types.find((content_type) => {
|
|
320
|
+
return supported_content_types.includes(content_type);
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
if (matching_type !== undefined) {
|
|
324
|
+
return matching_type;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
if (has_any_type && supported_content_types.includes(ContentType.JSON)) {
|
|
328
|
+
return ContentType.JSON;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
throw new NotFoundError(`
|
|
332
|
+
No matching content types found for this request
|
|
333
|
+
supported content types: ${supported_content_types}
|
|
334
|
+
accepted content types: ${accepted_content_types}
|
|
335
|
+
`);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
private getContentTypes(): ContentType[] {
|
|
339
|
+
return this.content_types;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
protected abstract process(): Promise<Output | void>;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
export default Endpoint;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/ban-types */
|
|
2
|
+
|
|
3
|
+
import Endpoint from 'lib/server/http/endpoint';
|
|
4
|
+
|
|
5
|
+
interface EndpointConstructor {
|
|
6
|
+
new (): Endpoint<
|
|
7
|
+
object | unknown,
|
|
8
|
+
string | object | Buffer
|
|
9
|
+
>;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export default EndpointConstructor;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import {IncomingRequest, OutgoingResponse} from 'lib/http';
|
|
2
|
+
|
|
3
|
+
abstract class Middleware {
|
|
4
|
+
public abstract handleRequest(
|
|
5
|
+
request: IncomingRequest,
|
|
6
|
+
response: OutgoingResponse
|
|
7
|
+
): Promise<boolean>;
|
|
8
|
+
|
|
9
|
+
public async handleError(
|
|
10
|
+
error: Error,
|
|
11
|
+
request: IncomingRequest,
|
|
12
|
+
response: OutgoingResponse
|
|
13
|
+
): Promise<boolean> {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export default Middleware;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import ResultSerializer from 'lib/server/http/interface/result-serializer';
|
|
2
|
+
import standardizeHtmlIndentation from 'lib/server/http/utility/standardize-html-indentation';
|
|
3
|
+
|
|
4
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
5
|
+
abstract class HtmlResultSerializer<ResultType extends object>
|
|
6
|
+
implements ResultSerializer {
|
|
7
|
+
private result: ResultType;
|
|
8
|
+
|
|
9
|
+
public constructor(result: ResultType) {
|
|
10
|
+
this.result = result;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
public serialize(): string {
|
|
14
|
+
const title = this.getTitle();
|
|
15
|
+
const content = this.serializeContent();
|
|
16
|
+
const link_tags = this.serializeLinkTags();
|
|
17
|
+
const meta_tags = this.serializeMetaTags();
|
|
18
|
+
const body_class = this.getBodyClass();
|
|
19
|
+
const css = this.serializeCss();
|
|
20
|
+
|
|
21
|
+
const html = `
|
|
22
|
+
<!doctype html>
|
|
23
|
+
<html>
|
|
24
|
+
<head>
|
|
25
|
+
<meta charset="UTF-8">
|
|
26
|
+
<meta content="text/html;charset=utf-8" http-equiv="Content-Type" />
|
|
27
|
+
<meta content="utf-8" http-equiv="encoding" />
|
|
28
|
+
<meta name="viewport" content="width=640, user-scalable=no">
|
|
29
|
+
<meta name="robots" content="noindex" />
|
|
30
|
+
<link rel="icon" href="/public/favicon.ico" type="image/x-icon">
|
|
31
|
+
<title>${title}</title>
|
|
32
|
+
${meta_tags}
|
|
33
|
+
${link_tags}
|
|
34
|
+
${css}
|
|
35
|
+
</head>
|
|
36
|
+
<body class="${body_class}">
|
|
37
|
+
${content}
|
|
38
|
+
</body>
|
|
39
|
+
</html>
|
|
40
|
+
`;
|
|
41
|
+
|
|
42
|
+
return standardizeHtmlIndentation(html);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
protected getResult(): ResultType {
|
|
46
|
+
return this.result;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Override this as necessary on child classes:
|
|
50
|
+
protected getCssUrls(): string[] {
|
|
51
|
+
return [];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
protected serializeCss(): string {
|
|
55
|
+
return '';
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
protected getBodyClass(): string {
|
|
59
|
+
return '';
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
private serializeLinkTags(): string {
|
|
63
|
+
const css_urls = this.getCssUrls();
|
|
64
|
+
|
|
65
|
+
const serialized_links = css_urls.map((url) => {
|
|
66
|
+
return `<link rel="stylesheet" href="${url}">`;
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
return serialized_links.join('\n');
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
protected serializeMetaTags(): string {
|
|
73
|
+
const meta_mappings = this.getMetaMappings();
|
|
74
|
+
|
|
75
|
+
const serialized_tags = Object.entries(meta_mappings).map((tuple) => {
|
|
76
|
+
const [key, value] = tuple;
|
|
77
|
+
|
|
78
|
+
return `<meta name="${key}" content="${value}" />`;
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
return serialized_tags.join('\n');
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
protected getMetaMappings(): Record<string, string | number | boolean> {
|
|
85
|
+
return {};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
public abstract serializeContent(): string;
|
|
89
|
+
protected abstract getTitle(): string;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export default HtmlResultSerializer;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import ResultSerializer from 'lib/server/http/interface/result-serializer';
|
|
2
|
+
|
|
3
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
4
|
+
class JsonResultSerializer<ResultType extends object>
|
|
5
|
+
implements ResultSerializer {
|
|
6
|
+
private result: ResultType;
|
|
7
|
+
|
|
8
|
+
public constructor(result: ResultType) {
|
|
9
|
+
this.result = result;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
public serialize(): string {
|
|
13
|
+
const result = this.getResult();
|
|
14
|
+
|
|
15
|
+
return JSON.stringify(result);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
protected getResult(): ResultType {
|
|
19
|
+
return this.result;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export default JsonResultSerializer;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import {HttpMethod, ContentType, PathParameters, IncomingRequest, OutgoingResponse} from 'lib/http';
|
|
2
|
+
|
|
3
|
+
import EndpointConstructor from 'lib/server/http/interface/endpoint-constructor';
|
|
4
|
+
import PathParser from 'lib/server/http/utility/path-parser';
|
|
5
|
+
import Endpoint from 'lib/server/http/endpoint';
|
|
6
|
+
|
|
7
|
+
class Route {
|
|
8
|
+
private endpoint_constructor: EndpointConstructor;
|
|
9
|
+
private method: HttpMethod;
|
|
10
|
+
private content_types: ContentType[];
|
|
11
|
+
|
|
12
|
+
private regex: RegExp;
|
|
13
|
+
private parameter_keys: string[];
|
|
14
|
+
|
|
15
|
+
public constructor(endpoint_constructor: EndpointConstructor) {
|
|
16
|
+
this.endpoint_constructor = endpoint_constructor;
|
|
17
|
+
|
|
18
|
+
const throwaway_endpoint = new endpoint_constructor();
|
|
19
|
+
|
|
20
|
+
this.method = throwaway_endpoint.method;
|
|
21
|
+
this.content_types = throwaway_endpoint.content_types;
|
|
22
|
+
|
|
23
|
+
const path = throwaway_endpoint.path;
|
|
24
|
+
const parser = new PathParser(path);
|
|
25
|
+
const parsed_path = parser.parse();
|
|
26
|
+
|
|
27
|
+
this.regex = parsed_path.regex;
|
|
28
|
+
this.parameter_keys = parsed_path.parameter_keys;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
public getMethod(): HttpMethod {
|
|
32
|
+
return this.method;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
public matchesPath(path: string): boolean {
|
|
36
|
+
return this.regex.test(path);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
public matchesContentTypes(content_types: ContentType[]): boolean {
|
|
40
|
+
if (content_types.length === 0) {
|
|
41
|
+
// If the user agent didn't specify any accepted content types,
|
|
42
|
+
// they are going to have to live with whatever they get back.
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const route_content_types = this.getContentTypes();
|
|
47
|
+
|
|
48
|
+
return content_types.some((content_type) => {
|
|
49
|
+
return route_content_types.includes(content_type);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
public async buildEndpoint(
|
|
54
|
+
request: IncomingRequest,
|
|
55
|
+
response: OutgoingResponse
|
|
56
|
+
): Promise<Endpoint<any, any>> {
|
|
57
|
+
const endpoint_constructor = this.getEndpointConstructor();
|
|
58
|
+
const endpoint = new endpoint_constructor();
|
|
59
|
+
|
|
60
|
+
endpoint.setRequest(request);
|
|
61
|
+
endpoint.setResponse(response);
|
|
62
|
+
|
|
63
|
+
return endpoint;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
public getPathParametersForRequest(request: IncomingRequest): PathParameters {
|
|
67
|
+
const path = request.getPath();
|
|
68
|
+
const regex = this.getRegex();
|
|
69
|
+
const match = path.match(regex);
|
|
70
|
+
const result: PathParameters = {};
|
|
71
|
+
|
|
72
|
+
if (match === null) {
|
|
73
|
+
return result;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const parameter_keys = this.getParameterKeys();
|
|
77
|
+
|
|
78
|
+
parameter_keys.forEach((parameter_key, index) => {
|
|
79
|
+
const parameter_value = match[index + 1];
|
|
80
|
+
|
|
81
|
+
result[parameter_key] = parameter_value;
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
return result;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
private getEndpointConstructor(): EndpointConstructor {
|
|
88
|
+
return this.endpoint_constructor;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
private getParameterKeys(): string[] {
|
|
92
|
+
return this.parameter_keys;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
private getRegex(): RegExp {
|
|
96
|
+
return this.regex;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
private getContentTypes(): ContentType[] {
|
|
100
|
+
return [...this.content_types, ContentType.ANY];
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export default Route;
|