@zyno-io/dk-server-foundation 26.216.430
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 +21 -0
- package/README.md +458 -0
- package/dist/devconsole/assets/index-CKF3C3kv.css +1 -0
- package/dist/devconsole/assets/index-CsHdomhM.js +27 -0
- package/dist/devconsole/index.html +13 -0
- package/dist/resources/proto/generated/devconsole/devconsole.d.ts +320 -0
- package/dist/resources/proto/generated/devconsole/devconsole.d.ts.map +1 -0
- package/dist/resources/proto/generated/devconsole/devconsole.js +3751 -0
- package/dist/resources/proto/generated/devconsole/devconsole.js.map +1 -0
- package/dist/src/app/base.d.ts +36 -0
- package/dist/src/app/base.d.ts.map +1 -0
- package/dist/src/app/base.js +240 -0
- package/dist/src/app/base.js.map +1 -0
- package/dist/src/app/config.d.ts +90 -0
- package/dist/src/app/config.d.ts.map +1 -0
- package/dist/src/app/config.js +33 -0
- package/dist/src/app/config.js.map +1 -0
- package/dist/src/app/config.loader.d.ts +14 -0
- package/dist/src/app/config.loader.d.ts.map +1 -0
- package/dist/src/app/config.loader.js +67 -0
- package/dist/src/app/config.loader.js.map +1 -0
- package/dist/src/app/const.d.ts +3 -0
- package/dist/src/app/const.d.ts.map +1 -0
- package/dist/src/app/const.js +6 -0
- package/dist/src/app/const.js.map +1 -0
- package/dist/src/app/dev.d.ts +7 -0
- package/dist/src/app/dev.d.ts.map +1 -0
- package/dist/src/app/dev.js +105 -0
- package/dist/src/app/dev.js.map +1 -0
- package/dist/src/app/index.d.ts +7 -0
- package/dist/src/app/index.d.ts.map +1 -0
- package/dist/src/app/index.js +12 -0
- package/dist/src/app/index.js.map +1 -0
- package/dist/src/app/openapi.d.ts +4 -0
- package/dist/src/app/openapi.d.ts.map +1 -0
- package/dist/src/app/openapi.js +6 -0
- package/dist/src/app/openapi.js.map +1 -0
- package/dist/src/app/resolver.d.ts +11 -0
- package/dist/src/app/resolver.d.ts.map +1 -0
- package/dist/src/app/resolver.js +60 -0
- package/dist/src/app/resolver.js.map +1 -0
- package/dist/src/app/shutdown.d.ts +12 -0
- package/dist/src/app/shutdown.d.ts.map +1 -0
- package/dist/src/app/shutdown.js +63 -0
- package/dist/src/app/shutdown.js.map +1 -0
- package/dist/src/app/state.d.ts +16 -0
- package/dist/src/app/state.d.ts.map +1 -0
- package/dist/src/app/state.js +12 -0
- package/dist/src/app/state.js.map +1 -0
- package/dist/src/auth/index.d.ts +3 -0
- package/dist/src/auth/index.d.ts.map +1 -0
- package/dist/src/auth/index.js +6 -0
- package/dist/src/auth/index.js.map +1 -0
- package/dist/src/auth/jwt.d.ts +76 -0
- package/dist/src/auth/jwt.d.ts.map +1 -0
- package/dist/src/auth/jwt.js +218 -0
- package/dist/src/auth/jwt.js.map +1 -0
- package/dist/src/auth/provider.d.ts +15 -0
- package/dist/src/auth/provider.d.ts.map +1 -0
- package/dist/src/auth/provider.js +50 -0
- package/dist/src/auth/provider.js.map +1 -0
- package/dist/src/cli/dksf-dev.d.ts +3 -0
- package/dist/src/cli/dksf-dev.d.ts.map +1 -0
- package/dist/src/cli/dksf-dev.js +408 -0
- package/dist/src/cli/dksf-dev.js.map +1 -0
- package/dist/src/cli/dksf-gen-proto.d.ts +3 -0
- package/dist/src/cli/dksf-gen-proto.d.ts.map +1 -0
- package/dist/src/cli/dksf-gen-proto.js +164 -0
- package/dist/src/cli/dksf-gen-proto.js.map +1 -0
- package/dist/src/cli/dksf-install.d.ts +3 -0
- package/dist/src/cli/dksf-install.d.ts.map +1 -0
- package/dist/src/cli/dksf-install.js +10 -0
- package/dist/src/cli/dksf-install.js.map +1 -0
- package/dist/src/cli/dksf-test.d.ts +3 -0
- package/dist/src/cli/dksf-test.d.ts.map +1 -0
- package/dist/src/cli/dksf-test.js +78 -0
- package/dist/src/cli/dksf-test.js.map +1 -0
- package/dist/src/cli/dksf-update.d.ts +3 -0
- package/dist/src/cli/dksf-update.d.ts.map +1 -0
- package/dist/src/cli/dksf-update.js +86 -0
- package/dist/src/cli/dksf-update.js.map +1 -0
- package/dist/src/database/common.d.ts +84 -0
- package/dist/src/database/common.d.ts.map +1 -0
- package/dist/src/database/common.js +380 -0
- package/dist/src/database/common.js.map +1 -0
- package/dist/src/database/dialect.d.ts +10 -0
- package/dist/src/database/dialect.d.ts.map +1 -0
- package/dist/src/database/dialect.js +56 -0
- package/dist/src/database/dialect.js.map +1 -0
- package/dist/src/database/entity.d.ts +62 -0
- package/dist/src/database/entity.d.ts.map +1 -0
- package/dist/src/database/entity.js +198 -0
- package/dist/src/database/entity.js.map +1 -0
- package/dist/src/database/index.d.ts +8 -0
- package/dist/src/database/index.d.ts.map +1 -0
- package/dist/src/database/index.js +15 -0
- package/dist/src/database/index.js.map +1 -0
- package/dist/src/database/migration/MigrationResetCommand.d.ts +9 -0
- package/dist/src/database/migration/MigrationResetCommand.d.ts.map +1 -0
- package/dist/src/database/migration/MigrationResetCommand.js +75 -0
- package/dist/src/database/migration/MigrationResetCommand.js.map +1 -0
- package/dist/src/database/migration/MigrationRunCommand.d.ts +11 -0
- package/dist/src/database/migration/MigrationRunCommand.d.ts.map +1 -0
- package/dist/src/database/migration/MigrationRunCommand.js +118 -0
- package/dist/src/database/migration/MigrationRunCommand.js.map +1 -0
- package/dist/src/database/migration/characters.d.ts +14 -0
- package/dist/src/database/migration/characters.d.ts.map +1 -0
- package/dist/src/database/migration/characters.js +56 -0
- package/dist/src/database/migration/characters.js.map +1 -0
- package/dist/src/database/migration/create/MigrationCreateCommand.d.ts +11 -0
- package/dist/src/database/migration/create/MigrationCreateCommand.d.ts.map +1 -0
- package/dist/src/database/migration/create/MigrationCreateCommand.js +106 -0
- package/dist/src/database/migration/create/MigrationCreateCommand.js.map +1 -0
- package/dist/src/database/migration/create/comparator.d.ts +3 -0
- package/dist/src/database/migration/create/comparator.d.ts.map +1 -0
- package/dist/src/database/migration/create/comparator.js +408 -0
- package/dist/src/database/migration/create/comparator.js.map +1 -0
- package/dist/src/database/migration/create/db-reader.d.ts +5 -0
- package/dist/src/database/migration/create/db-reader.d.ts.map +1 -0
- package/dist/src/database/migration/create/db-reader.js +473 -0
- package/dist/src/database/migration/create/db-reader.js.map +1 -0
- package/dist/src/database/migration/create/ddl-generator.d.ts +3 -0
- package/dist/src/database/migration/create/ddl-generator.d.ts.map +1 -0
- package/dist/src/database/migration/create/ddl-generator.js +725 -0
- package/dist/src/database/migration/create/ddl-generator.js.map +1 -0
- package/dist/src/database/migration/create/entity-reader.d.ts +4 -0
- package/dist/src/database/migration/create/entity-reader.d.ts.map +1 -0
- package/dist/src/database/migration/create/entity-reader.js +417 -0
- package/dist/src/database/migration/create/entity-reader.js.map +1 -0
- package/dist/src/database/migration/create/file-generator.d.ts +3 -0
- package/dist/src/database/migration/create/file-generator.d.ts.map +1 -0
- package/dist/src/database/migration/create/file-generator.js +62 -0
- package/dist/src/database/migration/create/file-generator.js.map +1 -0
- package/dist/src/database/migration/create/prompt.d.ts +4 -0
- package/dist/src/database/migration/create/prompt.d.ts.map +1 -0
- package/dist/src/database/migration/create/prompt.js +55 -0
- package/dist/src/database/migration/create/prompt.js.map +1 -0
- package/dist/src/database/migration/create/schema-model.d.ts +109 -0
- package/dist/src/database/migration/create/schema-model.d.ts.map +1 -0
- package/dist/src/database/migration/create/schema-model.js +24 -0
- package/dist/src/database/migration/create/schema-model.js.map +1 -0
- package/dist/src/database/migration/helpers.d.ts +3 -0
- package/dist/src/database/migration/helpers.d.ts.map +1 -0
- package/dist/src/database/migration/helpers.js +13 -0
- package/dist/src/database/migration/helpers.js.map +1 -0
- package/dist/src/database/migration/index.d.ts +9 -0
- package/dist/src/database/migration/index.d.ts.map +1 -0
- package/dist/src/database/migration/index.js +43 -0
- package/dist/src/database/migration/index.js.map +1 -0
- package/dist/src/database/migration/migration.entity.d.ts +8 -0
- package/dist/src/database/migration/migration.entity.d.ts.map +1 -0
- package/dist/src/database/migration/migration.entity.js +16 -0
- package/dist/src/database/migration/migration.entity.js.map +1 -0
- package/dist/src/database/mysql.d.ts +16 -0
- package/dist/src/database/mysql.d.ts.map +1 -0
- package/dist/src/database/mysql.js +140 -0
- package/dist/src/database/mysql.js.map +1 -0
- package/dist/src/database/postgres.d.ts +16 -0
- package/dist/src/database/postgres.d.ts.map +1 -0
- package/dist/src/database/postgres.js +91 -0
- package/dist/src/database/postgres.js.map +1 -0
- package/dist/src/database/types.d.ts +21 -0
- package/dist/src/database/types.d.ts.map +1 -0
- package/dist/src/database/types.js +27 -0
- package/dist/src/database/types.js.map +1 -0
- package/dist/src/devconsole/devconsole.controller.d.ts +7 -0
- package/dist/src/devconsole/devconsole.controller.d.ts.map +1 -0
- package/dist/src/devconsole/devconsole.controller.js +82 -0
- package/dist/src/devconsole/devconsole.controller.js.map +1 -0
- package/dist/src/devconsole/devconsole.middleware.d.ts +12 -0
- package/dist/src/devconsole/devconsole.middleware.d.ts.map +1 -0
- package/dist/src/devconsole/devconsole.middleware.js +28 -0
- package/dist/src/devconsole/devconsole.middleware.js.map +1 -0
- package/dist/src/devconsole/devconsole.srpc.d.ts +14 -0
- package/dist/src/devconsole/devconsole.srpc.d.ts.map +1 -0
- package/dist/src/devconsole/devconsole.srpc.js +94 -0
- package/dist/src/devconsole/devconsole.srpc.js.map +1 -0
- package/dist/src/devconsole/devconsole.store.d.ts +101 -0
- package/dist/src/devconsole/devconsole.store.d.ts.map +1 -0
- package/dist/src/devconsole/devconsole.store.js +125 -0
- package/dist/src/devconsole/devconsole.store.js.map +1 -0
- package/dist/src/devconsole/devconsole.ws.d.ts +18 -0
- package/dist/src/devconsole/devconsole.ws.d.ts.map +1 -0
- package/dist/src/devconsole/devconsole.ws.js +470 -0
- package/dist/src/devconsole/devconsole.ws.js.map +1 -0
- package/dist/src/devconsole/index.d.ts +2 -0
- package/dist/src/devconsole/index.d.ts.map +1 -0
- package/dist/src/devconsole/index.js +6 -0
- package/dist/src/devconsole/index.js.map +1 -0
- package/dist/src/devconsole/patches.d.ts +6 -0
- package/dist/src/devconsole/patches.d.ts.map +1 -0
- package/dist/src/devconsole/patches.js +397 -0
- package/dist/src/devconsole/patches.js.map +1 -0
- package/dist/src/health/health.module.d.ts +6 -0
- package/dist/src/health/health.module.d.ts.map +1 -0
- package/dist/src/health/health.module.js +32 -0
- package/dist/src/health/health.module.js.map +1 -0
- package/dist/src/health/healthcheck.controller.d.ts +10 -0
- package/dist/src/health/healthcheck.controller.d.ts.map +1 -0
- package/dist/src/health/healthcheck.controller.js +30 -0
- package/dist/src/health/healthcheck.controller.js.map +1 -0
- package/dist/src/health/healthcheck.service.d.ts +13 -0
- package/dist/src/health/healthcheck.service.d.ts.map +1 -0
- package/dist/src/health/healthcheck.service.js +33 -0
- package/dist/src/health/healthcheck.service.js.map +1 -0
- package/dist/src/health/index.d.ts +3 -0
- package/dist/src/health/index.d.ts.map +1 -0
- package/dist/src/health/index.js +6 -0
- package/dist/src/health/index.js.map +1 -0
- package/dist/src/helpers/async/context.d.ts +11 -0
- package/dist/src/helpers/async/context.d.ts.map +1 -0
- package/dist/src/helpers/async/context.js +75 -0
- package/dist/src/helpers/async/context.js.map +1 -0
- package/dist/src/helpers/async/process.d.ts +16 -0
- package/dist/src/helpers/async/process.d.ts.map +1 -0
- package/dist/src/helpers/async/process.js +44 -0
- package/dist/src/helpers/async/process.js.map +1 -0
- package/dist/src/helpers/async/promise.d.ts +5 -0
- package/dist/src/helpers/async/promise.d.ts.map +1 -0
- package/dist/src/helpers/async/promise.js +27 -0
- package/dist/src/helpers/async/promise.js.map +1 -0
- package/dist/src/helpers/data/array.d.ts +3 -0
- package/dist/src/helpers/data/array.d.ts.map +1 -0
- package/dist/src/helpers/data/array.js +17 -0
- package/dist/src/helpers/data/array.js.map +1 -0
- package/dist/src/helpers/data/objects.d.ts +12 -0
- package/dist/src/helpers/data/objects.d.ts.map +1 -0
- package/dist/src/helpers/data/objects.js +75 -0
- package/dist/src/helpers/data/objects.js.map +1 -0
- package/dist/src/helpers/data/serialization.d.ts +4 -0
- package/dist/src/helpers/data/serialization.d.ts.map +1 -0
- package/dist/src/helpers/data/serialization.js +15 -0
- package/dist/src/helpers/data/serialization.js.map +1 -0
- package/dist/src/helpers/data/transformer.d.ts +13 -0
- package/dist/src/helpers/data/transformer.d.ts.map +1 -0
- package/dist/src/helpers/data/transformer.js +55 -0
- package/dist/src/helpers/data/transformer.js.map +1 -0
- package/dist/src/helpers/framework/decorators.d.ts +5 -0
- package/dist/src/helpers/framework/decorators.d.ts.map +1 -0
- package/dist/src/helpers/framework/decorators.js +39 -0
- package/dist/src/helpers/framework/decorators.js.map +1 -0
- package/dist/src/helpers/framework/event.d.ts +3 -0
- package/dist/src/helpers/framework/event.d.ts.map +1 -0
- package/dist/src/helpers/framework/event.js +20 -0
- package/dist/src/helpers/framework/event.js.map +1 -0
- package/dist/src/helpers/framework/injection.d.ts +7 -0
- package/dist/src/helpers/framework/injection.d.ts.map +1 -0
- package/dist/src/helpers/framework/injection.js +52 -0
- package/dist/src/helpers/framework/injection.js.map +1 -0
- package/dist/src/helpers/index.d.ts +22 -0
- package/dist/src/helpers/index.d.ts.map +1 -0
- package/dist/src/helpers/index.js +32 -0
- package/dist/src/helpers/index.js.map +1 -0
- package/dist/src/helpers/io/package.d.ts +5 -0
- package/dist/src/helpers/io/package.d.ts.map +1 -0
- package/dist/src/helpers/io/package.js +31 -0
- package/dist/src/helpers/io/package.js.map +1 -0
- package/dist/src/helpers/io/stream.d.ts +18 -0
- package/dist/src/helpers/io/stream.d.ts.map +1 -0
- package/dist/src/helpers/io/stream.js +91 -0
- package/dist/src/helpers/io/stream.js.map +1 -0
- package/dist/src/helpers/redis/broadcast.d.ts +13 -0
- package/dist/src/helpers/redis/broadcast.d.ts.map +1 -0
- package/dist/src/helpers/redis/broadcast.js +100 -0
- package/dist/src/helpers/redis/broadcast.js.map +1 -0
- package/dist/src/helpers/redis/cache.d.ts +7 -0
- package/dist/src/helpers/redis/cache.d.ts.map +1 -0
- package/dist/src/helpers/redis/cache.js +28 -0
- package/dist/src/helpers/redis/cache.js.map +1 -0
- package/dist/src/helpers/redis/mutex.d.ts +24 -0
- package/dist/src/helpers/redis/mutex.d.ts.map +1 -0
- package/dist/src/helpers/redis/mutex.js +240 -0
- package/dist/src/helpers/redis/mutex.js.map +1 -0
- package/dist/src/helpers/redis/redis.d.ts +11 -0
- package/dist/src/helpers/redis/redis.d.ts.map +1 -0
- package/dist/src/helpers/redis/redis.js +59 -0
- package/dist/src/helpers/redis/redis.js.map +1 -0
- package/dist/src/helpers/security/crypto.d.ts +26 -0
- package/dist/src/helpers/security/crypto.d.ts.map +1 -0
- package/dist/src/helpers/security/crypto.js +121 -0
- package/dist/src/helpers/security/crypto.js.map +1 -0
- package/dist/src/helpers/security/validation.d.ts +4 -0
- package/dist/src/helpers/security/validation.d.ts.map +1 -0
- package/dist/src/helpers/security/validation.js +25 -0
- package/dist/src/helpers/security/validation.js.map +1 -0
- package/dist/src/helpers/utils/date.d.ts +4 -0
- package/dist/src/helpers/utils/date.d.ts.map +1 -0
- package/dist/src/helpers/utils/date.js +23 -0
- package/dist/src/helpers/utils/date.js.map +1 -0
- package/dist/src/helpers/utils/error.d.ts +24 -0
- package/dist/src/helpers/utils/error.d.ts.map +1 -0
- package/dist/src/helpers/utils/error.js +168 -0
- package/dist/src/helpers/utils/error.js.map +1 -0
- package/dist/src/helpers/utils/jsx.d.ts +3 -0
- package/dist/src/helpers/utils/jsx.d.ts.map +1 -0
- package/dist/src/helpers/utils/jsx.js +13 -0
- package/dist/src/helpers/utils/jsx.js.map +1 -0
- package/dist/src/helpers/utils/uuid.d.ts +3 -0
- package/dist/src/helpers/utils/uuid.d.ts.map +1 -0
- package/dist/src/helpers/utils/uuid.js +14 -0
- package/dist/src/helpers/utils/uuid.js.map +1 -0
- package/dist/src/http/auth.d.ts +46 -0
- package/dist/src/http/auth.d.ts.map +1 -0
- package/dist/src/http/auth.js +162 -0
- package/dist/src/http/auth.js.map +1 -0
- package/dist/src/http/context.d.ts +5 -0
- package/dist/src/http/context.d.ts.map +1 -0
- package/dist/src/http/context.js +22 -0
- package/dist/src/http/context.js.map +1 -0
- package/dist/src/http/cors.d.ts +36 -0
- package/dist/src/http/cors.d.ts.map +1 -0
- package/dist/src/http/cors.js +171 -0
- package/dist/src/http/cors.js.map +1 -0
- package/dist/src/http/errors.d.ts +3 -0
- package/dist/src/http/errors.d.ts.map +1 -0
- package/dist/src/http/errors.js +10 -0
- package/dist/src/http/errors.js.map +1 -0
- package/dist/src/http/index.d.ts +24 -0
- package/dist/src/http/index.d.ts.map +1 -0
- package/dist/src/http/index.js +25 -0
- package/dist/src/http/index.js.map +1 -0
- package/dist/src/http/kernel.d.ts +17 -0
- package/dist/src/http/kernel.d.ts.map +1 -0
- package/dist/src/http/kernel.js +133 -0
- package/dist/src/http/kernel.js.map +1 -0
- package/dist/src/http/middleware.d.ts +12 -0
- package/dist/src/http/middleware.d.ts.map +1 -0
- package/dist/src/http/middleware.js +61 -0
- package/dist/src/http/middleware.js.map +1 -0
- package/dist/src/http/overrides.d.ts +2 -0
- package/dist/src/http/overrides.d.ts.map +1 -0
- package/dist/src/http/overrides.js +19 -0
- package/dist/src/http/overrides.js.map +1 -0
- package/dist/src/http/store.d.ts +33 -0
- package/dist/src/http/store.d.ts.map +1 -0
- package/dist/src/http/store.js +102 -0
- package/dist/src/http/store.js.map +1 -0
- package/dist/src/http/uploads.d.ts +7 -0
- package/dist/src/http/uploads.d.ts.map +1 -0
- package/dist/src/http/uploads.js +8 -0
- package/dist/src/http/uploads.js.map +1 -0
- package/dist/src/http/workflow.d.ts +18 -0
- package/dist/src/http/workflow.d.ts.map +1 -0
- package/dist/src/http/workflow.js +181 -0
- package/dist/src/http/workflow.js.map +1 -0
- package/dist/src/index.d.ts +13 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +25 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/services/cli/invoke.d.ts +5 -0
- package/dist/src/services/cli/invoke.d.ts.map +1 -0
- package/dist/src/services/cli/invoke.js +45 -0
- package/dist/src/services/cli/invoke.js.map +1 -0
- package/dist/src/services/cli/repl-context.d.ts +13 -0
- package/dist/src/services/cli/repl-context.d.ts.map +1 -0
- package/dist/src/services/cli/repl-context.js +60 -0
- package/dist/src/services/cli/repl-context.js.map +1 -0
- package/dist/src/services/cli/repl.d.ts +5 -0
- package/dist/src/services/cli/repl.d.ts.map +1 -0
- package/dist/src/services/cli/repl.js +32 -0
- package/dist/src/services/cli/repl.js.map +1 -0
- package/dist/src/services/cli.d.ts +12 -0
- package/dist/src/services/cli.d.ts.map +1 -0
- package/dist/src/services/cli.js +76 -0
- package/dist/src/services/cli.js.map +1 -0
- package/dist/src/services/index.d.ts +7 -0
- package/dist/src/services/index.d.ts.map +1 -0
- package/dist/src/services/index.js +10 -0
- package/dist/src/services/index.js.map +1 -0
- package/dist/src/services/leader.d.ts +32 -0
- package/dist/src/services/leader.d.ts.map +1 -0
- package/dist/src/services/leader.js +174 -0
- package/dist/src/services/leader.js.map +1 -0
- package/dist/src/services/logger.d.ts +35 -0
- package/dist/src/services/logger.d.ts.map +1 -0
- package/dist/src/services/logger.js +245 -0
- package/dist/src/services/logger.js.map +1 -0
- package/dist/src/services/mail/index.d.ts +61 -0
- package/dist/src/services/mail/index.d.ts.map +1 -0
- package/dist/src/services/mail/index.js +90 -0
- package/dist/src/services/mail/index.js.map +1 -0
- package/dist/src/services/mail/postmark.d.ts +11 -0
- package/dist/src/services/mail/postmark.d.ts.map +1 -0
- package/dist/src/services/mail/postmark.js +42 -0
- package/dist/src/services/mail/postmark.js.map +1 -0
- package/dist/src/services/mail/smtp.d.ts +11 -0
- package/dist/src/services/mail/smtp.d.ts.map +1 -0
- package/dist/src/services/mail/smtp.js +61 -0
- package/dist/src/services/mail/smtp.js.map +1 -0
- package/dist/src/services/mesh.d.ts +65 -0
- package/dist/src/services/mesh.d.ts.map +1 -0
- package/dist/src/services/mesh.js +422 -0
- package/dist/src/services/mesh.js.map +1 -0
- package/dist/src/services/worker/bootstrap.d.ts +3 -0
- package/dist/src/services/worker/bootstrap.d.ts.map +1 -0
- package/dist/src/services/worker/bootstrap.js +64 -0
- package/dist/src/services/worker/bootstrap.js.map +1 -0
- package/dist/src/services/worker/cli.d.ts +11 -0
- package/dist/src/services/worker/cli.d.ts.map +1 -0
- package/dist/src/services/worker/cli.js +43 -0
- package/dist/src/services/worker/cli.js.map +1 -0
- package/dist/src/services/worker/entity.d.ts +18 -0
- package/dist/src/services/worker/entity.d.ts.map +1 -0
- package/dist/src/services/worker/entity.js +16 -0
- package/dist/src/services/worker/entity.js.map +1 -0
- package/dist/src/services/worker/index.d.ts +9 -0
- package/dist/src/services/worker/index.d.ts.map +1 -0
- package/dist/src/services/worker/index.js +40 -0
- package/dist/src/services/worker/index.js.map +1 -0
- package/dist/src/services/worker/queue.d.ts +8 -0
- package/dist/src/services/worker/queue.d.ts.map +1 -0
- package/dist/src/services/worker/queue.js +32 -0
- package/dist/src/services/worker/queue.js.map +1 -0
- package/dist/src/services/worker/recorder.d.ts +16 -0
- package/dist/src/services/worker/recorder.d.ts.map +1 -0
- package/dist/src/services/worker/recorder.js +168 -0
- package/dist/src/services/worker/recorder.js.map +1 -0
- package/dist/src/services/worker/runner.d.ts +21 -0
- package/dist/src/services/worker/runner.d.ts.map +1 -0
- package/dist/src/services/worker/runner.js +156 -0
- package/dist/src/services/worker/runner.js.map +1 -0
- package/dist/src/services/worker/types.d.ts +26 -0
- package/dist/src/services/worker/types.d.ts.map +1 -0
- package/dist/src/services/worker/types.js +29 -0
- package/dist/src/services/worker/types.js.map +1 -0
- package/dist/src/srpc/SrpcByteStream.d.ts +67 -0
- package/dist/src/srpc/SrpcByteStream.d.ts.map +1 -0
- package/dist/src/srpc/SrpcByteStream.js +319 -0
- package/dist/src/srpc/SrpcByteStream.js.map +1 -0
- package/dist/src/srpc/SrpcClient.d.ts +75 -0
- package/dist/src/srpc/SrpcClient.d.ts.map +1 -0
- package/dist/src/srpc/SrpcClient.js +445 -0
- package/dist/src/srpc/SrpcClient.js.map +1 -0
- package/dist/src/srpc/SrpcServer.d.ts +80 -0
- package/dist/src/srpc/SrpcServer.d.ts.map +1 -0
- package/dist/src/srpc/SrpcServer.js +561 -0
- package/dist/src/srpc/SrpcServer.js.map +1 -0
- package/dist/src/srpc/index.d.ts +7 -0
- package/dist/src/srpc/index.d.ts.map +1 -0
- package/dist/src/srpc/index.js +12 -0
- package/dist/src/srpc/index.js.map +1 -0
- package/dist/src/srpc/types.d.ts +131 -0
- package/dist/src/srpc/types.d.ts.map +1 -0
- package/dist/src/srpc/types.js +65 -0
- package/dist/src/srpc/types.js.map +1 -0
- package/dist/src/telemetry/index.d.ts +2 -0
- package/dist/src/telemetry/index.d.ts.map +1 -0
- package/dist/src/telemetry/index.js +5 -0
- package/dist/src/telemetry/index.js.map +1 -0
- package/dist/src/telemetry/otel/MariaDBInstrumentation.d.ts +22 -0
- package/dist/src/telemetry/otel/MariaDBInstrumentation.d.ts.map +1 -0
- package/dist/src/telemetry/otel/MariaDBInstrumentation.js +248 -0
- package/dist/src/telemetry/otel/MariaDBInstrumentation.js.map +1 -0
- package/dist/src/telemetry/otel/helpers.d.ts +27 -0
- package/dist/src/telemetry/otel/helpers.d.ts.map +1 -0
- package/dist/src/telemetry/otel/helpers.js +126 -0
- package/dist/src/telemetry/otel/helpers.js.map +1 -0
- package/dist/src/telemetry/otel/index.d.ts +14 -0
- package/dist/src/telemetry/otel/index.d.ts.map +1 -0
- package/dist/src/telemetry/otel/index.js +132 -0
- package/dist/src/telemetry/otel/index.js.map +1 -0
- package/dist/src/telemetry/otel/metrics.controller.d.ts +6 -0
- package/dist/src/telemetry/otel/metrics.controller.d.ts.map +1 -0
- package/dist/src/telemetry/otel/metrics.controller.js +63 -0
- package/dist/src/telemetry/otel/metrics.controller.js.map +1 -0
- package/dist/src/telemetry/sentry.d.ts +9 -0
- package/dist/src/telemetry/sentry.d.ts.map +1 -0
- package/dist/src/telemetry/sentry.js +62 -0
- package/dist/src/telemetry/sentry.js.map +1 -0
- package/dist/src/testing/expect.d.ts +25 -0
- package/dist/src/testing/expect.d.ts.map +1 -0
- package/dist/src/testing/expect.js +151 -0
- package/dist/src/testing/expect.js.map +1 -0
- package/dist/src/testing/fixtures.d.ts +19 -0
- package/dist/src/testing/fixtures.d.ts.map +1 -0
- package/dist/src/testing/fixtures.js +69 -0
- package/dist/src/testing/fixtures.js.map +1 -0
- package/dist/src/testing/index.d.ts +260 -0
- package/dist/src/testing/index.d.ts.map +1 -0
- package/dist/src/testing/index.js +345 -0
- package/dist/src/testing/index.js.map +1 -0
- package/dist/src/testing/requests.d.ts +10 -0
- package/dist/src/testing/requests.d.ts.map +1 -0
- package/dist/src/testing/requests.js +56 -0
- package/dist/src/testing/requests.js.map +1 -0
- package/dist/src/testing/sql.d.ts +11 -0
- package/dist/src/testing/sql.d.ts.map +1 -0
- package/dist/src/testing/sql.js +55 -0
- package/dist/src/testing/sql.js.map +1 -0
- package/dist/src/types/index.d.ts +57 -0
- package/dist/src/types/index.d.ts.map +1 -0
- package/dist/src/types/index.js +73 -0
- package/dist/src/types/index.js.map +1 -0
- package/dist/src/types/phone.d.ts +11 -0
- package/dist/src/types/phone.d.ts.map +1 -0
- package/dist/src/types/phone.js +73 -0
- package/dist/src/types/phone.js.map +1 -0
- package/docs/.vitepress/config.mts +79 -0
- package/docs/.yarnrc.yml +1 -0
- package/docs/content/CONTRIBUTING.md +140 -0
- package/docs/content/README-DEV.md +142 -0
- package/docs/content/README.md +39 -0
- package/docs/content/authentication.md +215 -0
- package/docs/content/cli.md +335 -0
- package/docs/content/configuration.md +175 -0
- package/docs/content/database.md +422 -0
- package/docs/content/devconsole.md +123 -0
- package/docs/content/getting-started.md +154 -0
- package/docs/content/guides/test-migration-guide.md +351 -0
- package/docs/content/health.md +54 -0
- package/docs/content/helpers.md +322 -0
- package/docs/content/http.md +253 -0
- package/docs/content/index.md +147 -0
- package/docs/content/leader-service.md +98 -0
- package/docs/content/logging.md +150 -0
- package/docs/content/mail.md +161 -0
- package/docs/content/mesh-service.md +204 -0
- package/docs/content/public/images/devconsole/01-dashboard.png +0 -0
- package/docs/content/public/images/devconsole/02-routes.png +0 -0
- package/docs/content/public/images/devconsole/03-openapi.png +0 -0
- package/docs/content/public/images/devconsole/04-requests.png +0 -0
- package/docs/content/public/images/devconsole/05-srpc.png +0 -0
- package/docs/content/public/images/devconsole/06-database.png +0 -0
- package/docs/content/public/images/devconsole/07-health.png +0 -0
- package/docs/content/public/images/devconsole/08-mutex.png +0 -0
- package/docs/content/public/images/devconsole/09-repl.png +0 -0
- package/docs/content/public/images/devconsole/10-workers.png +0 -0
- package/docs/content/redis.md +168 -0
- package/docs/content/srpc.md +261 -0
- package/docs/content/telemetry.md +166 -0
- package/docs/content/testing.md +222 -0
- package/docs/content/types.md +215 -0
- package/docs/content/worker.md +177 -0
- package/docs/package.json +16 -0
- package/docs/scripts/README-SCREENSHOTS.md +145 -0
- package/docs/scripts/capture-devconsole-screenshots.js +184 -0
- package/docs/yarn.lock +2408 -0
- package/package.json +144 -0
- package/patches/@deepkit+type+1.0.19.patch +38 -0
- package/patches/deepkit-openapi-core+0.0.9.patch +62 -0
- package/src/app/base.ts +253 -0
- package/src/app/config.loader.ts +66 -0
- package/src/app/config.ts +119 -0
- package/src/app/const.ts +4 -0
- package/src/app/dev.ts +92 -0
- package/src/app/index.ts +6 -0
- package/src/app/openapi.ts +3 -0
- package/src/app/resolver.ts +49 -0
- package/src/app/shutdown.ts +55 -0
- package/src/app/state.ts +19 -0
- package/src/auth/index.ts +2 -0
- package/src/auth/jwt.ts +275 -0
- package/src/auth/provider.ts +57 -0
- package/src/cli/dksf-dev.ts +416 -0
- package/src/cli/dksf-gen-proto.ts +176 -0
- package/src/cli/dksf-install.ts +11 -0
- package/src/cli/dksf-test.ts +84 -0
- package/src/cli/dksf-update.ts +101 -0
- package/src/database/common.ts +385 -0
- package/src/database/dialect.ts +43 -0
- package/src/database/entity.ts +285 -0
- package/src/database/index.ts +7 -0
- package/src/database/migration/MigrationResetCommand.ts +72 -0
- package/src/database/migration/MigrationRunCommand.ts +118 -0
- package/src/database/migration/characters.ts +53 -0
- package/src/database/migration/create/MigrationCreateCommand.ts +96 -0
- package/src/database/migration/create/comparator.ts +467 -0
- package/src/database/migration/create/db-reader.ts +510 -0
- package/src/database/migration/create/ddl-generator.ts +755 -0
- package/src/database/migration/create/entity-reader.ts +471 -0
- package/src/database/migration/create/file-generator.ts +57 -0
- package/src/database/migration/create/prompt.ts +49 -0
- package/src/database/migration/create/schema-model.ts +102 -0
- package/src/database/migration/helpers.ts +7 -0
- package/src/database/migration/index.ts +35 -0
- package/src/database/migration/migration.entity.ts +10 -0
- package/src/database/mysql.ts +140 -0
- package/src/database/postgres.ts +97 -0
- package/src/database/types.ts +18 -0
- package/src/devconsole/devconsole.controller.ts +59 -0
- package/src/devconsole/devconsole.middleware.ts +23 -0
- package/src/devconsole/devconsole.srpc.ts +94 -0
- package/src/devconsole/devconsole.store.ts +190 -0
- package/src/devconsole/devconsole.ws.ts +491 -0
- package/src/devconsole/index.ts +1 -0
- package/src/devconsole/patches.ts +428 -0
- package/src/health/health.module.ts +30 -0
- package/src/health/healthcheck.controller.ts +17 -0
- package/src/health/healthcheck.service.ts +28 -0
- package/src/health/index.ts +2 -0
- package/src/helpers/async/context.ts +67 -0
- package/src/helpers/async/process.ts +49 -0
- package/src/helpers/async/promise.ts +16 -0
- package/src/helpers/data/array.ts +11 -0
- package/src/helpers/data/objects.ts +64 -0
- package/src/helpers/data/serialization.ts +11 -0
- package/src/helpers/data/transformer.ts +54 -0
- package/src/helpers/framework/decorators.ts +27 -0
- package/src/helpers/framework/event.ts +11 -0
- package/src/helpers/framework/injection.ts +47 -0
- package/src/helpers/index.ts +34 -0
- package/src/helpers/io/package.ts +26 -0
- package/src/helpers/io/stream.ts +79 -0
- package/src/helpers/redis/broadcast.ts +96 -0
- package/src/helpers/redis/cache.ts +28 -0
- package/src/helpers/redis/mutex.ts +260 -0
- package/src/helpers/redis/redis.ts +60 -0
- package/src/helpers/security/crypto.ts +133 -0
- package/src/helpers/security/validation.ts +16 -0
- package/src/helpers/utils/date.ts +13 -0
- package/src/helpers/utils/error.ts +155 -0
- package/src/helpers/utils/jsx.ts +8 -0
- package/src/helpers/utils/uuid.ts +8 -0
- package/src/http/auth.ts +156 -0
- package/src/http/context.ts +15 -0
- package/src/http/cors.ts +159 -0
- package/src/http/errors.ts +9 -0
- package/src/http/index.ts +19 -0
- package/src/http/kernel.ts +138 -0
- package/src/http/middleware.ts +59 -0
- package/src/http/overrides.ts +20 -0
- package/src/http/store.ts +86 -0
- package/src/http/uploads.ts +6 -0
- package/src/http/workflow.ts +167 -0
- package/src/index.ts +19 -0
- package/src/services/cli/invoke.ts +39 -0
- package/src/services/cli/repl-context.ts +63 -0
- package/src/services/cli/repl.ts +22 -0
- package/src/services/cli.ts +74 -0
- package/src/services/index.ts +6 -0
- package/src/services/leader.ts +201 -0
- package/src/services/logger.ts +258 -0
- package/src/services/mail/index.ts +117 -0
- package/src/services/mail/postmark.ts +37 -0
- package/src/services/mail/smtp.ts +46 -0
- package/src/services/mesh.ts +508 -0
- package/src/services/worker/bootstrap.ts +53 -0
- package/src/services/worker/cli.ts +32 -0
- package/src/services/worker/entity.ts +22 -0
- package/src/services/worker/index.ts +30 -0
- package/src/services/worker/queue.ts +35 -0
- package/src/services/worker/recorder.ts +172 -0
- package/src/services/worker/runner.ts +179 -0
- package/src/services/worker/types.ts +32 -0
- package/src/srpc/SrpcByteStream.ts +382 -0
- package/src/srpc/SrpcClient.ts +512 -0
- package/src/srpc/SrpcServer.ts +681 -0
- package/src/srpc/index.ts +15 -0
- package/src/srpc/types.ts +146 -0
- package/src/telemetry/index.ts +1 -0
- package/src/telemetry/otel/MariaDBInstrumentation.ts +297 -0
- package/src/telemetry/otel/helpers.ts +117 -0
- package/src/telemetry/otel/index.ts +150 -0
- package/src/telemetry/otel/metrics.controller.ts +50 -0
- package/src/telemetry/sentry.ts +58 -0
- package/src/testing/expect.ts +148 -0
- package/src/testing/fixtures.ts +62 -0
- package/src/testing/index.ts +355 -0
- package/src/testing/requests.ts +68 -0
- package/src/testing/sql.ts +50 -0
- package/src/types/index.ts +64 -0
- package/src/types/phone.ts +64 -0
- package/types.d.ts +20 -0
package/src/http/auth.ts
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { timingSafeEqual } from 'crypto';
|
|
2
|
+
import { HttpRequest, HttpUnauthorizedError, RouteParameterResolver, RouteParameterResolverContext } from '@deepkit/http';
|
|
3
|
+
import { ScopedLogger } from '@deepkit/logger';
|
|
4
|
+
import { ActiveRecordClassType } from '@deepkit/orm';
|
|
5
|
+
|
|
6
|
+
// can't import app here or bad things happen!!
|
|
7
|
+
import type { BaseAppConfig } from '../app';
|
|
8
|
+
import { JWT, ParsedJwt } from '../auth';
|
|
9
|
+
import { getEntity, getEntityOrUndefined } from '../database';
|
|
10
|
+
import { HttpMiddleware } from './middleware';
|
|
11
|
+
import { createCachingParameterResolver, getCompositeCacheKey, getOrCacheValue } from './store';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* base request JWT lookup
|
|
15
|
+
*/
|
|
16
|
+
export async function getJwtFromRequest(request: HttpRequest): Promise<ParsedJwt | undefined> {
|
|
17
|
+
return getOrCacheValue(request, ParsedJwt, _getJwtFromRequest);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async function _getJwtFromRequest(request: HttpRequest): Promise<ParsedJwt | undefined> {
|
|
21
|
+
const jwt = await JWT.processWithRequest(request);
|
|
22
|
+
if (!jwt) return undefined;
|
|
23
|
+
if (!jwt.isValid) {
|
|
24
|
+
if (!jwt.isSignatureValid) throw new HttpUnauthorizedError('Invalid JWT signature');
|
|
25
|
+
if (!jwt.isNotExpired) throw new HttpUnauthorizedError('Expired JWT');
|
|
26
|
+
throw new HttpUnauthorizedError('Invalid JWT');
|
|
27
|
+
}
|
|
28
|
+
return jwt;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export class ParsedJwtResolver implements RouteParameterResolver {
|
|
32
|
+
async resolve(context: RouteParameterResolverContext): Promise<ParsedJwt | undefined> {
|
|
33
|
+
const jwt = await getJwtFromRequest(context.request);
|
|
34
|
+
if (!jwt && !context.type.isOptional()) {
|
|
35
|
+
throw new HttpUnauthorizedError('Request does not contain required JWT');
|
|
36
|
+
}
|
|
37
|
+
return jwt;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* base request JWT user ID lookup
|
|
43
|
+
*/
|
|
44
|
+
const EntityIdSymbol = Symbol('EntityId');
|
|
45
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
46
|
+
export async function getEntityIdFromRequestJwt(request: HttpRequest): Promise<any> {
|
|
47
|
+
const jwt = await getJwtFromRequest(request);
|
|
48
|
+
return jwt?.subject;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* request JWT user ID to user object
|
|
53
|
+
*/
|
|
54
|
+
export async function getEntityFromRequestJwt<T extends ActiveRecordClassType>(
|
|
55
|
+
request: HttpRequest,
|
|
56
|
+
EntityClass: T
|
|
57
|
+
): Promise<InstanceType<T> | undefined> {
|
|
58
|
+
const entityId = await getEntityIdFromRequestJwt(request);
|
|
59
|
+
return entityId ? getEntity(EntityClass, entityId) : undefined;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* auth middleware generator
|
|
64
|
+
*/
|
|
65
|
+
interface EntityValidator<T extends ActiveRecordClassType> {
|
|
66
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
67
|
+
getEntityIdFromRequest(request: HttpRequest): Promise<any>;
|
|
68
|
+
validateEntity?(request: HttpRequest, entity: InstanceType<T>): Promise<void>;
|
|
69
|
+
}
|
|
70
|
+
export function createAuthMiddleware<T extends ActiveRecordClassType>(EntityClass: T) {
|
|
71
|
+
return class extends HttpMiddleware implements EntityValidator<T> {
|
|
72
|
+
async handle(request: HttpRequest) {
|
|
73
|
+
const entityId = await getOrCacheValue(
|
|
74
|
+
request,
|
|
75
|
+
getCompositeCacheKey(EntityClass, EntityIdSymbol),
|
|
76
|
+
this.getEntityIdFromRequest.bind(this)
|
|
77
|
+
);
|
|
78
|
+
await this.loadAndValidateEntity(request, entityId);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
async getEntityIdFromRequest(request: HttpRequest) {
|
|
82
|
+
const id = await getEntityIdFromRequestJwt(request);
|
|
83
|
+
if (!id) throw new HttpUnauthorizedError();
|
|
84
|
+
return id;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
88
|
+
async loadAndValidateEntity(request: HttpRequest, id: any) {
|
|
89
|
+
const validateFn = (this as EntityValidator<T>).validateEntity;
|
|
90
|
+
if (validateFn) {
|
|
91
|
+
const entity = await getOrCacheValue(request, EntityClass, () => getEntityOrUndefined(EntityClass, id));
|
|
92
|
+
if (!entity) throw new HttpUnauthorizedError();
|
|
93
|
+
await validateFn(request, entity);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* HTTP basic auth middleware
|
|
101
|
+
*/
|
|
102
|
+
export function createBasicAuthMiddleware(expectedUsername?: string) {
|
|
103
|
+
return class extends HttpMiddleware {
|
|
104
|
+
public config: BaseAppConfig;
|
|
105
|
+
|
|
106
|
+
constructor(public logger: ScopedLogger) {
|
|
107
|
+
super();
|
|
108
|
+
|
|
109
|
+
// todo:figure this out
|
|
110
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
111
|
+
this.config = require('../app').getAppConfig();
|
|
112
|
+
if (!this.config.AUTH_BASIC_SECRET) {
|
|
113
|
+
this.logger.error('No AUTH_BASIC_SECRET provided');
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
async handle(request: HttpRequest) {
|
|
118
|
+
const authHeader = request.headers['authorization'];
|
|
119
|
+
if (!authHeader) {
|
|
120
|
+
throw new HttpUnauthorizedError();
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const [scheme, credentials] = authHeader.split(' ');
|
|
124
|
+
if (scheme.toLowerCase() !== 'basic') {
|
|
125
|
+
throw new HttpUnauthorizedError('Invalid authorization scheme');
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const [username, password] = Buffer.from(credentials, 'base64').toString().split(':');
|
|
129
|
+
const secret = this.config.AUTH_BASIC_SECRET ?? '';
|
|
130
|
+
const usernameInvalid = expectedUsername && expectedUsername !== username;
|
|
131
|
+
const passwordBuf = Buffer.from(password);
|
|
132
|
+
const secretBuf = Buffer.from(secret);
|
|
133
|
+
const passwordInvalid = passwordBuf.length !== secretBuf.length || !timingSafeEqual(passwordBuf, secretBuf);
|
|
134
|
+
if (usernameInvalid || passwordInvalid) {
|
|
135
|
+
throw new HttpUnauthorizedError('Invalid credentials');
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* standard authed entity resolver
|
|
143
|
+
*/
|
|
144
|
+
export async function resolveEntityFromRequestJwt<T extends ActiveRecordClassType>(context: RouteParameterResolverContext, EntityClass: T) {
|
|
145
|
+
const ent = await getEntityFromRequestJwt(context.request, EntityClass);
|
|
146
|
+
if (!ent && !context.type.isOptional()) {
|
|
147
|
+
throw new HttpUnauthorizedError();
|
|
148
|
+
}
|
|
149
|
+
return ent;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export function createEntityFromRequestJwtParameterResolver<T extends ActiveRecordClassType>(EntityClass: T) {
|
|
153
|
+
return createCachingParameterResolver(EntityClass, async (context: RouteParameterResolverContext) => {
|
|
154
|
+
return resolveEntityFromRequestJwt(context, EntityClass);
|
|
155
|
+
});
|
|
156
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { HttpRequest } from '@deepkit/http';
|
|
2
|
+
import { uuid } from '@deepkit/type';
|
|
3
|
+
|
|
4
|
+
export const DefaultHttpContextProvider: (request: HttpRequest) => Record<string, string> = () => ({
|
|
5
|
+
reqId: uuid()
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
let httpContextProvider: (request: HttpRequest) => Record<string, string> = DefaultHttpContextProvider;
|
|
9
|
+
export function setHttpContextResolver(provider: (request: HttpRequest) => Record<string, string>) {
|
|
10
|
+
httpContextProvider = provider;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function getHttpContextResolver() {
|
|
14
|
+
return httpContextProvider;
|
|
15
|
+
}
|
package/src/http/cors.ts
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { eventDispatcher } from '@deepkit/event';
|
|
2
|
+
import { HttpRequest, HttpResponse, HttpRouter, httpWorkflow } from '@deepkit/http';
|
|
3
|
+
|
|
4
|
+
export const CorsHeaders = Symbol('CorsHeaders');
|
|
5
|
+
|
|
6
|
+
export class HttpCorsOptionsMulti {
|
|
7
|
+
constructor(public readonly options: HttpCorsOptions[]) {}
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export class HttpCorsOptions {
|
|
11
|
+
hosts!: (string | RegExp)[];
|
|
12
|
+
paths?: (string | RegExp)[];
|
|
13
|
+
methods?: string[];
|
|
14
|
+
credentials?: boolean;
|
|
15
|
+
allowHeaders?: string[];
|
|
16
|
+
exposeHeaders?: string[];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export class HttpCors {
|
|
20
|
+
static getResponseHeaders(response: HttpResponse): Record<string, string> | undefined {
|
|
21
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
22
|
+
return (response as any)[CorsHeaders];
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export class HttpCorsDescriptor {
|
|
27
|
+
cachedPreflightHeaders: Record<string, string> = {};
|
|
28
|
+
cachedResponseCorsHeaders: Record<string, string> = {};
|
|
29
|
+
|
|
30
|
+
constructor(public readonly options: HttpCorsOptions) {
|
|
31
|
+
this.cachedPreflightHeaders['Access-Control-Allow-Methods'] = options.methods?.join(',') ?? 'GET,HEAD,PUT,PATCH,POST,DELETE';
|
|
32
|
+
|
|
33
|
+
if (options.allowHeaders) {
|
|
34
|
+
this.cachedPreflightHeaders['Access-Control-Allow-Headers'] = options.allowHeaders.join(', ');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (options.credentials) {
|
|
38
|
+
this.cachedPreflightHeaders['Access-Control-Allow-Credentials'] = 'true';
|
|
39
|
+
this.cachedResponseCorsHeaders['Access-Control-Allow-Credentials'] = 'true';
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (options.exposeHeaders) {
|
|
43
|
+
this.cachedResponseCorsHeaders['Access-Control-Expose-Headers'] = options.exposeHeaders.join(', ');
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export class HttpCorsListener {
|
|
49
|
+
descriptors: HttpCorsDescriptor[];
|
|
50
|
+
|
|
51
|
+
constructor(
|
|
52
|
+
protected router: HttpRouter,
|
|
53
|
+
protected corsOptionsMulti: HttpCorsOptionsMulti
|
|
54
|
+
) {
|
|
55
|
+
this.descriptors = corsOptionsMulti.options.map(options => new HttpCorsDescriptor(options));
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// because DK's middleware implemtnation only aborts executing middleware when it encounters a finshed response,
|
|
59
|
+
// we perform writeHead+end in our HttpMiddleware wrapper. this means that the response is already finished
|
|
60
|
+
// by the time it would reach an onResponse handler, and would prevent us from injecting CORS headers into
|
|
61
|
+
// a response such as an HTTP 401. to work around this, we precompute the CORS response headers so they can
|
|
62
|
+
// be used in the normal response flow, or in our HttpMiddleware wrapper
|
|
63
|
+
// note we already have a listener at priority 99, so we use 98 here since it needs to run before that one
|
|
64
|
+
@eventDispatcher.listen(httpWorkflow.onRoute, 98)
|
|
65
|
+
async onRoute(event: typeof httpWorkflow.onRoute.event): Promise<void> {
|
|
66
|
+
if (event.sent) return;
|
|
67
|
+
if (event.hasNext()) return;
|
|
68
|
+
|
|
69
|
+
const descriptor = this.findMatchingDescriptor(event.request);
|
|
70
|
+
if (descriptor) {
|
|
71
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
72
|
+
(event.response as any)[CorsHeaders] = this.getCorsResponseHeaders(event.request, descriptor);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
@eventDispatcher.listen(httpWorkflow.onRouteNotFound, 99)
|
|
77
|
+
async routeNotFound(event: typeof httpWorkflow.onRouteNotFound.event): Promise<void> {
|
|
78
|
+
if (event.sent) return;
|
|
79
|
+
if (event.hasNext()) return;
|
|
80
|
+
|
|
81
|
+
if (event.request.method === 'OPTIONS') {
|
|
82
|
+
const descriptor = this.findMatchingDescriptor(event.request);
|
|
83
|
+
if (descriptor) {
|
|
84
|
+
// DK's response requires a content-type, which doesn't make sense here, so we go around it
|
|
85
|
+
// by using Node's built-in server response
|
|
86
|
+
event.response.writeHead(204, this.getCorsPreflightHeaders(event.request, descriptor));
|
|
87
|
+
event.response.end();
|
|
88
|
+
event.send(event.response);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
@eventDispatcher.listen(httpWorkflow.onResponse, -101)
|
|
94
|
+
async onResponse(event: typeof httpWorkflow.onResponse.event): Promise<void> {
|
|
95
|
+
if (event.response.headersSent) return;
|
|
96
|
+
if (event.hasNext()) return;
|
|
97
|
+
|
|
98
|
+
if (CorsHeaders in event.response) {
|
|
99
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
100
|
+
for (const key in (event.response as any)[CorsHeaders]) {
|
|
101
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
102
|
+
event.response.setHeader(key, (event.response as any)[CorsHeaders][key]);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
private findMatchingDescriptor(request: HttpRequest) {
|
|
108
|
+
const originHeader = request.headers.origin;
|
|
109
|
+
if (!originHeader) return null;
|
|
110
|
+
if (!request.url) return null;
|
|
111
|
+
|
|
112
|
+
return this.descriptors.find(descriptor => {
|
|
113
|
+
const hostMatches = descriptor.options.hosts.some(host => {
|
|
114
|
+
if (host === '*') {
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
if (host instanceof RegExp) {
|
|
118
|
+
return host.test(originHeader);
|
|
119
|
+
}
|
|
120
|
+
return host === request.headers.origin;
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
const patchMatches =
|
|
124
|
+
!descriptor.options.paths ||
|
|
125
|
+
descriptor.options.paths.some(path => {
|
|
126
|
+
if (path instanceof RegExp) {
|
|
127
|
+
return path.test(request.url!);
|
|
128
|
+
}
|
|
129
|
+
return request.url!.startsWith(path);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
return hostMatches && patchMatches;
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
private getCorsPreflightHeaders(request: HttpRequest, descriptor: HttpCorsDescriptor): Record<string, string> {
|
|
137
|
+
const headers: Record<string, string> = {
|
|
138
|
+
...descriptor.cachedPreflightHeaders,
|
|
139
|
+
'Access-Control-Allow-Origin': request.headers.origin ?? '*',
|
|
140
|
+
'Access-Control-Allow-Credentials': 'true',
|
|
141
|
+
'Content-Length': '0'
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
if (!('Access-Control-Allow-Headers' in headers)) {
|
|
145
|
+
if (request.headers['access-control-request-headers']) {
|
|
146
|
+
headers['Access-Control-Allow-Headers'] = request.headers['access-control-request-headers'];
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return headers;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
private getCorsResponseHeaders(request: HttpRequest, descriptor: HttpCorsDescriptor): Record<string, string> {
|
|
154
|
+
return {
|
|
155
|
+
...descriptor.cachedResponseCorsHeaders,
|
|
156
|
+
'Access-Control-Allow-Origin': request.headers.origin ?? '*'
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { createHttpError } from '@deepkit/http';
|
|
2
|
+
|
|
3
|
+
export const HttpUserError = createHttpError(422);
|
|
4
|
+
|
|
5
|
+
// todo: Deepkit has added the original error prop to the event and we can use normal workflow to handle this now
|
|
6
|
+
|
|
7
|
+
// Deepkit's built in HttpAccessDeniedError fires a special workflow event
|
|
8
|
+
// that doesn't contain the original error or the message that was attached to it
|
|
9
|
+
export const HttpDetailedAccessDeniedError = createHttpError(403);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import './overrides';
|
|
2
|
+
|
|
3
|
+
export * from './auth';
|
|
4
|
+
export * from './context';
|
|
5
|
+
export * from './kernel';
|
|
6
|
+
export * from './workflow';
|
|
7
|
+
export { HttpCors } from './cors';
|
|
8
|
+
export * from './errors';
|
|
9
|
+
export * from './middleware';
|
|
10
|
+
export * from './store';
|
|
11
|
+
export * from './uploads';
|
|
12
|
+
|
|
13
|
+
export const OkResponse = { ok: true };
|
|
14
|
+
export type OkResponse = Promise<{ ok: true }>;
|
|
15
|
+
|
|
16
|
+
export type RedirectResponse = Promise<void>;
|
|
17
|
+
export type EmptyResponse = Promise<void>;
|
|
18
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
19
|
+
export type AnyResponse = Promise<any>;
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { HttpKernel, HttpRequest, HttpResponse } from '@deepkit/http';
|
|
2
|
+
import { LoggerInterface } from '@deepkit/logger';
|
|
3
|
+
|
|
4
|
+
import { getAppConfig } from '../app/resolver';
|
|
5
|
+
import { withContextData } from '../helpers';
|
|
6
|
+
import { createLogger } from '../services';
|
|
7
|
+
import { getHttpContextResolver } from './context';
|
|
8
|
+
|
|
9
|
+
interface RequestLogger {
|
|
10
|
+
start?: (logger: LoggerInterface, request: HttpRequest) => void;
|
|
11
|
+
finish?: (logger: LoggerInterface, request: HttpRequest, response: HttpResponse) => void;
|
|
12
|
+
abort?: (logger: LoggerInterface, request: HttpRequest) => void;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export class CustomHttpKernel extends HttpKernel {
|
|
16
|
+
private activeRequestCount = 0;
|
|
17
|
+
private scopedLogger = createLogger('http');
|
|
18
|
+
|
|
19
|
+
private shouldSkipRequestLogging(request: HttpRequest) {
|
|
20
|
+
return request.url === '/healthz' || request.url === '/metrics';
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
private buildRequestLogger(): RequestLogger {
|
|
24
|
+
const logMode = getAppConfig().HTTP_REQUEST_LOGGING_MODE;
|
|
25
|
+
|
|
26
|
+
const abortFn: RequestLogger['abort'] = (logger, request) => {
|
|
27
|
+
logger.warn('Request aborted during processing', {
|
|
28
|
+
method: request.method,
|
|
29
|
+
url: request.url,
|
|
30
|
+
duration: Date.now() - request.store['$RequestTime']
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const finishFn: RequestLogger['finish'] = (logger, request, response) => {
|
|
35
|
+
const msg =
|
|
36
|
+
response.statusCode >= 400 ? 'Request failed' : response.writableEnded ? 'Request completed' : 'Response stream hooked by controller';
|
|
37
|
+
logger.info(msg, {
|
|
38
|
+
method: request.method,
|
|
39
|
+
url: request.url,
|
|
40
|
+
statusCode: response.statusCode,
|
|
41
|
+
duration: Date.now() - request.store['$RequestTime']
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
if (logMode === 'e2e') {
|
|
46
|
+
return {
|
|
47
|
+
start: (logger, request) => {
|
|
48
|
+
request.store['$RequestTime'] = Date.now();
|
|
49
|
+
if (!this.shouldSkipRequestLogging(request)) {
|
|
50
|
+
logger.info('Request started', {
|
|
51
|
+
method: request.method,
|
|
52
|
+
url: request.url,
|
|
53
|
+
remoteAddress: request.getRemoteAddress(),
|
|
54
|
+
contentLength: request.headers['content-length']
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
finish: (logger, request, response) => {
|
|
59
|
+
if (response.statusCode >= 400 || !this.shouldSkipRequestLogging(request)) {
|
|
60
|
+
finishFn(logger, request, response);
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
abort: abortFn
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (logMode === 'finish') {
|
|
68
|
+
return {
|
|
69
|
+
start: (_logger, request) => {
|
|
70
|
+
request.store['$RequestTime'] = Date.now();
|
|
71
|
+
},
|
|
72
|
+
finish: (logger, request, response) => {
|
|
73
|
+
if (response.statusCode >= 400 || !this.shouldSkipRequestLogging(request)) {
|
|
74
|
+
finishFn(logger, request, response);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (logMode === 'errors') {
|
|
81
|
+
return {
|
|
82
|
+
start: (_logger, request) => {
|
|
83
|
+
request.store['$RequestTime'] = Date.now();
|
|
84
|
+
},
|
|
85
|
+
finish: (logger, request, response) => {
|
|
86
|
+
if (response.statusCode >= 400) {
|
|
87
|
+
finishFn(logger, request, response);
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
abort: abortFn
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return {
|
|
95
|
+
start: (_logger, request) => {
|
|
96
|
+
request.store['$RequestTime'] = Date.now();
|
|
97
|
+
},
|
|
98
|
+
abort: abortFn
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
get requestLogger(): RequestLogger {
|
|
103
|
+
const logger = this.buildRequestLogger();
|
|
104
|
+
Object.defineProperty(this, 'requestLogger', { value: logger });
|
|
105
|
+
return logger;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
async handleRequest(req: HttpRequest, res: HttpResponse): Promise<void> {
|
|
109
|
+
try {
|
|
110
|
+
this.activeRequestCount++;
|
|
111
|
+
const httpCtx = getHttpContextResolver()(req);
|
|
112
|
+
await withContextData({ http: httpCtx }, async () => {
|
|
113
|
+
this.requestLogger.start?.(this.scopedLogger, req);
|
|
114
|
+
|
|
115
|
+
await new Promise<void>((resolve, reject) => {
|
|
116
|
+
const onClose = () => {
|
|
117
|
+
if (res.destroyed && !res.writableFinished) {
|
|
118
|
+
this.requestLogger.abort?.(this.scopedLogger, req);
|
|
119
|
+
resolve();
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
res.on('close', onClose);
|
|
123
|
+
|
|
124
|
+
super
|
|
125
|
+
.handleRequest(req, res)
|
|
126
|
+
.then(() => {
|
|
127
|
+
res.removeListener('close', onClose);
|
|
128
|
+
this.requestLogger.finish?.(this.scopedLogger, req, res);
|
|
129
|
+
resolve();
|
|
130
|
+
})
|
|
131
|
+
.catch(reject);
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
} finally {
|
|
135
|
+
this.activeRequestCount--;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { HttpError, HttpMiddleware as BaseHttpMiddleware, HttpRequest, HttpResponse } from '@deepkit/http';
|
|
2
|
+
import { ScopedLogger } from '@deepkit/logger';
|
|
3
|
+
|
|
4
|
+
import { CorsHeaders } from './cors';
|
|
5
|
+
|
|
6
|
+
// Deepkit's middleware code returns a 404 if the middleware throws an error
|
|
7
|
+
// we want to properly handle HTTP errors, so we need to wrap the middleware
|
|
8
|
+
export abstract class HttpMiddleware implements BaseHttpMiddleware {
|
|
9
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
10
|
+
async execute(request: HttpRequest, response: HttpResponse, next: (err?: any) => void) {
|
|
11
|
+
try {
|
|
12
|
+
await this.handle(request, response);
|
|
13
|
+
next();
|
|
14
|
+
} catch (err) {
|
|
15
|
+
if (err instanceof HttpError) {
|
|
16
|
+
response.writeHead(err.httpCode, {
|
|
17
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
18
|
+
...(response as any)[CorsHeaders],
|
|
19
|
+
'content-type': 'application/json'
|
|
20
|
+
});
|
|
21
|
+
response.end(
|
|
22
|
+
JSON.stringify({
|
|
23
|
+
error: err.message
|
|
24
|
+
})
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
// there's some quirk in Deepkit testing where the finish event isn't emitted
|
|
28
|
+
// on ended responses during Jest testing, but works as expected in production
|
|
29
|
+
// will submit a PR for this later. meanwhile, emit the finish event in Jest testing
|
|
30
|
+
if (process.env.NODE_ENV === 'test') {
|
|
31
|
+
response.emit('finish');
|
|
32
|
+
}
|
|
33
|
+
} else {
|
|
34
|
+
response.writeHead(500);
|
|
35
|
+
response.end('Internal Server Error');
|
|
36
|
+
|
|
37
|
+
throw err;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
abstract handle(request: HttpRequest, response: HttpResponse): Promise<void> | void;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export class HttpLogPayloadMiddleware extends HttpMiddleware {
|
|
46
|
+
constructor(private logger: ScopedLogger) {
|
|
47
|
+
super();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async handle(request: HttpRequest, _response: HttpResponse) {
|
|
51
|
+
const body = await request.readBodyText();
|
|
52
|
+
this.logger.info('Logging request', {
|
|
53
|
+
method: request.method,
|
|
54
|
+
url: request.url,
|
|
55
|
+
contentType: request.headers['content-type'] ?? '',
|
|
56
|
+
body: body ?? ''
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { HttpRequest } from '@deepkit/http';
|
|
2
|
+
|
|
3
|
+
import { getAppConfig } from '../app/resolver';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* HttpRequest.getRemoteAddress
|
|
7
|
+
* override to enable x-real-ip header
|
|
8
|
+
*/
|
|
9
|
+
let useRealIpHeader: boolean | null = null;
|
|
10
|
+
HttpRequest.prototype.getRemoteAddress = function () {
|
|
11
|
+
if (useRealIpHeader === null) {
|
|
12
|
+
useRealIpHeader = !!getAppConfig().USE_REAL_IP_HEADER;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (this.headers['x-real-ip'] && useRealIpHeader) {
|
|
16
|
+
return this.headers['x-real-ip'] as string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return this.socket.remoteAddress ?? '';
|
|
20
|
+
};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { ClassType } from '@deepkit/core';
|
|
2
|
+
import { HttpRequest, RouteParameterResolver, RouteParameterResolverContext } from '@deepkit/http';
|
|
3
|
+
|
|
4
|
+
type CacheKey = string | symbol | object;
|
|
5
|
+
const ObjectRefSymbol = Symbol('ObjectRef');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Key generator
|
|
9
|
+
*/
|
|
10
|
+
export function getCompositeCacheKey(target: ClassType, key: symbol) {
|
|
11
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
12
|
+
if ((target as any)[key] === undefined) {
|
|
13
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
14
|
+
(target as any)[key] = Symbol(`${target.name}_${key.description}`);
|
|
15
|
+
}
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
17
|
+
return (target as any)[key];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Cache implementation
|
|
22
|
+
*/
|
|
23
|
+
type ValueResolver<T> = (request: HttpRequest) => Promise<T>;
|
|
24
|
+
export async function getOrCacheValue<T>(request: HttpRequest, key: CacheKey, resolver: ValueResolver<T>): Promise<T> {
|
|
25
|
+
if (typeof key === 'function' || typeof key === 'object') {
|
|
26
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
27
|
+
if (request.store[ObjectRefSymbol as any] === undefined) {
|
|
28
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
29
|
+
request.store[ObjectRefSymbol as any] = new Map<object, T>();
|
|
30
|
+
}
|
|
31
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
32
|
+
const map: Map<object, T> = request.store[ObjectRefSymbol as any];
|
|
33
|
+
if (!map.has(key)) {
|
|
34
|
+
const value = await resolver(request);
|
|
35
|
+
map.set(key, value);
|
|
36
|
+
return value;
|
|
37
|
+
}
|
|
38
|
+
return map.get(key) as T;
|
|
39
|
+
} else {
|
|
40
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
41
|
+
if (request.store[key as any] === undefined) {
|
|
42
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
43
|
+
request.store[key as any] = await resolver(request);
|
|
44
|
+
}
|
|
45
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
46
|
+
return request.store[key as any];
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function getCachedValue<T>(request: HttpRequest, key: CacheKey): T | undefined {
|
|
51
|
+
const isObjectRefKey = typeof key === 'function' || typeof key === 'object';
|
|
52
|
+
const resolvedKey = isObjectRefKey ? ObjectRefSymbol : key;
|
|
53
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
54
|
+
const rawValue = request.store[resolvedKey as any];
|
|
55
|
+
return isObjectRefKey ? rawValue.get(key) : rawValue;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function getCachedValueOrThrow<T>(request: HttpRequest, key: CacheKey): T {
|
|
59
|
+
const value = getCachedValue<T>(request, key);
|
|
60
|
+
if (value === undefined) throw new Error(`Request does not contain cached value [${String(key)}]`);
|
|
61
|
+
return value;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Generic store value resolver
|
|
66
|
+
* Requires a previous listener to have attached data to the store
|
|
67
|
+
*/
|
|
68
|
+
export function createCachedValueResolver<T>(key: string | symbol | object, isRequired = true) {
|
|
69
|
+
const getter = isRequired ? getCachedValueOrThrow : getCachedValue;
|
|
70
|
+
return class implements RouteParameterResolver {
|
|
71
|
+
async resolve(context: RouteParameterResolverContext): Promise<T | undefined> {
|
|
72
|
+
return getter(context.request, key) ?? undefined;
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Generic store value resolver with cache miss lookup
|
|
79
|
+
*/
|
|
80
|
+
export function createCachingParameterResolver<T>(key: string | symbol | object, lookupFn: (context: RouteParameterResolverContext) => Promise<T>) {
|
|
81
|
+
return class implements RouteParameterResolver {
|
|
82
|
+
async resolve(context: RouteParameterResolverContext): Promise<T | undefined> {
|
|
83
|
+
return getOrCacheValue(context.request, key, async () => lookupFn(context));
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
}
|