@kravc/dos 1.12.5 → 2.0.0-alpha.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/README.md +31 -994
- package/dist/Component/Component.d.ts +43 -0
- package/dist/Component/Component.d.ts.map +1 -0
- package/dist/Component/Component.js +99 -0
- package/dist/Component/Component.js.map +1 -0
- package/dist/Component/index.d.ts +4 -0
- package/dist/Component/index.d.ts.map +1 -0
- package/dist/Component/index.js +10 -0
- package/dist/Component/index.js.map +1 -0
- package/dist/Context/Context.d.ts +86 -0
- package/dist/Context/Context.d.ts.map +1 -0
- package/dist/Context/Context.js +148 -0
- package/dist/Context/Context.js.map +1 -0
- package/dist/Context/Request.d.ts +35 -0
- package/dist/Context/Request.d.ts.map +1 -0
- package/dist/Context/Request.js +3 -0
- package/dist/Context/Request.js.map +1 -0
- package/dist/Context/__tests__/__helpers.d.ts +14 -0
- package/dist/Context/__tests__/__helpers.d.ts.map +1 -0
- package/dist/Context/__tests__/__helpers.js +69 -0
- package/dist/Context/__tests__/__helpers.js.map +1 -0
- package/dist/Context/getHttpMethod.d.ts +6 -0
- package/dist/Context/getHttpMethod.d.ts.map +1 -0
- package/dist/Context/getHttpMethod.js +16 -0
- package/dist/Context/getHttpMethod.js.map +1 -0
- package/dist/Context/getHttpPath.d.ts +6 -0
- package/dist/Context/getHttpPath.d.ts.map +1 -0
- package/dist/Context/getHttpPath.js +25 -0
- package/dist/Context/getHttpPath.js.map +1 -0
- package/dist/Context/getMutationParameters.d.ts +8 -0
- package/dist/Context/getMutationParameters.d.ts.map +1 -0
- package/dist/Context/getMutationParameters.js +25 -0
- package/dist/Context/getMutationParameters.js.map +1 -0
- package/dist/Context/getOperationId.d.ts +6 -0
- package/dist/Context/getOperationId.d.ts.map +1 -0
- package/dist/Context/getOperationId.js +21 -0
- package/dist/Context/getOperationId.js.map +1 -0
- package/dist/Context/getQueryParameters.d.ts +5 -0
- package/dist/Context/getQueryParameters.d.ts.map +1 -0
- package/dist/Context/getQueryParameters.js +33 -0
- package/dist/Context/getQueryParameters.js.map +1 -0
- package/dist/Context/index.d.ts +7 -0
- package/dist/Context/index.d.ts.map +1 -0
- package/dist/Context/index.js +12 -0
- package/dist/Context/index.js.map +1 -0
- package/dist/Context/withSafeAttributes.d.ts +23 -0
- package/dist/Context/withSafeAttributes.d.ts.map +1 -0
- package/dist/Context/withSafeAttributes.js +39 -0
- package/dist/Context/withSafeAttributes.js.map +1 -0
- package/dist/Document/Document.d.ts +114 -0
- package/dist/Document/Document.d.ts.map +1 -0
- package/dist/Document/Document.js +285 -0
- package/dist/Document/Document.js.map +1 -0
- package/dist/Document/MemoryDocument.d.ts +34 -0
- package/dist/Document/MemoryDocument.d.ts.map +1 -0
- package/dist/Document/MemoryDocument.js +103 -0
- package/dist/Document/MemoryDocument.js.map +1 -0
- package/dist/Document/__tests__/__helpers.d.ts +18 -0
- package/dist/Document/__tests__/__helpers.d.ts.map +1 -0
- package/dist/Document/__tests__/__helpers.js +28 -0
- package/dist/Document/__tests__/__helpers.js.map +1 -0
- package/dist/Document/index.d.ts +5 -0
- package/dist/Document/index.d.ts.map +1 -0
- package/dist/Document/index.js +11 -0
- package/dist/Document/index.js.map +1 -0
- package/dist/Operation/Operation.d.ts +95 -0
- package/dist/Operation/Operation.d.ts.map +1 -0
- package/dist/Operation/Operation.js +301 -0
- package/dist/Operation/Operation.js.map +1 -0
- package/dist/Operation/errors/AccessDeniedError.d.ts +22 -0
- package/dist/Operation/errors/AccessDeniedError.d.ts.map +1 -0
- package/dist/Operation/errors/AccessDeniedError.js +29 -0
- package/dist/Operation/errors/AccessDeniedError.js.map +1 -0
- package/dist/Operation/errors/CommonError.d.ts +30 -0
- package/dist/Operation/errors/CommonError.d.ts.map +1 -0
- package/dist/Operation/errors/CommonError.js +39 -0
- package/dist/Operation/errors/CommonError.js.map +1 -0
- package/dist/Operation/errors/DocumentExistsError.d.ts +27 -0
- package/dist/Operation/errors/DocumentExistsError.d.ts.map +1 -0
- package/dist/Operation/errors/DocumentExistsError.js +35 -0
- package/dist/Operation/errors/DocumentExistsError.js.map +1 -0
- package/dist/Operation/errors/DocumentNotFoundError.d.ts +28 -0
- package/dist/Operation/errors/DocumentNotFoundError.d.ts.map +1 -0
- package/dist/Operation/errors/DocumentNotFoundError.js +36 -0
- package/dist/Operation/errors/DocumentNotFoundError.js.map +1 -0
- package/dist/Operation/errors/InvalidParametersError.d.ts +27 -0
- package/dist/Operation/errors/InvalidParametersError.d.ts.map +1 -0
- package/dist/Operation/errors/InvalidParametersError.js +34 -0
- package/dist/Operation/errors/InvalidParametersError.js.map +1 -0
- package/dist/Operation/errors/UnauthorizedError.d.ts +25 -0
- package/dist/Operation/errors/UnauthorizedError.d.ts.map +1 -0
- package/dist/Operation/errors/UnauthorizedError.js +32 -0
- package/dist/Operation/errors/UnauthorizedError.js.map +1 -0
- package/dist/Operation/errors/UnprocessibleConditionError.d.ts +29 -0
- package/dist/Operation/errors/UnprocessibleConditionError.d.ts.map +1 -0
- package/dist/Operation/errors/UnprocessibleConditionError.js +36 -0
- package/dist/Operation/errors/UnprocessibleConditionError.js.map +1 -0
- package/dist/Operation/errors/index.d.ts +9 -0
- package/dist/Operation/errors/index.d.ts.map +1 -0
- package/dist/Operation/errors/index.js +21 -0
- package/dist/Operation/errors/index.js.map +1 -0
- package/dist/Operation/helpers/index.d.ts +4 -0
- package/dist/Operation/helpers/index.d.ts.map +1 -0
- package/dist/Operation/helpers/index.js +9 -0
- package/dist/Operation/helpers/index.js.map +1 -0
- package/dist/Operation/helpers/withActivity.d.ts +16 -0
- package/dist/Operation/helpers/withActivity.d.ts.map +1 -0
- package/dist/Operation/helpers/withActivity.js +23 -0
- package/dist/Operation/helpers/withActivity.js.map +1 -0
- package/dist/Operation/index.d.ts +14 -0
- package/dist/Operation/index.d.ts.map +1 -0
- package/dist/Operation/index.js +40 -0
- package/dist/Operation/index.js.map +1 -0
- package/dist/Operation/operations/Create.d.ts +5 -0
- package/dist/Operation/operations/Create.d.ts.map +1 -0
- package/dist/Operation/operations/Create.js +44 -0
- package/dist/Operation/operations/Create.js.map +1 -0
- package/dist/Operation/operations/Delete.d.ts +5 -0
- package/dist/Operation/operations/Delete.d.ts.map +1 -0
- package/dist/Operation/operations/Delete.js +58 -0
- package/dist/Operation/operations/Delete.js.map +1 -0
- package/dist/Operation/operations/Index.d.ts +11 -0
- package/dist/Operation/operations/Index.d.ts.map +1 -0
- package/dist/Operation/operations/Index.js +128 -0
- package/dist/Operation/operations/Index.js.map +1 -0
- package/dist/Operation/operations/List.d.ts +5 -0
- package/dist/Operation/operations/List.d.ts.map +1 -0
- package/dist/Operation/operations/List.js +48 -0
- package/dist/Operation/operations/List.js.map +1 -0
- package/dist/Operation/operations/Read.d.ts +5 -0
- package/dist/Operation/operations/Read.d.ts.map +1 -0
- package/dist/Operation/operations/Read.js +50 -0
- package/dist/Operation/operations/Read.js.map +1 -0
- package/dist/Operation/operations/Update.d.ts +5 -0
- package/dist/Operation/operations/Update.d.ts.map +1 -0
- package/dist/Operation/operations/Update.js +54 -0
- package/dist/Operation/operations/Update.js.map +1 -0
- package/dist/Operation/security/JwtAuthorization.d.ts +67 -0
- package/dist/Operation/security/JwtAuthorization.d.ts.map +1 -0
- package/dist/Operation/security/JwtAuthorization.js +148 -0
- package/dist/Operation/security/JwtAuthorization.js.map +1 -0
- package/dist/Operation/security/LambdaAuthorization.d.ts +30 -0
- package/dist/Operation/security/LambdaAuthorization.d.ts.map +1 -0
- package/dist/Operation/security/LambdaAuthorization.js +77 -0
- package/dist/Operation/security/LambdaAuthorization.js.map +1 -0
- package/dist/Operation/security/index.d.ts +8 -0
- package/dist/Operation/security/index.d.ts.map +1 -0
- package/dist/Operation/security/index.js +17 -0
- package/dist/Operation/security/index.js.map +1 -0
- package/dist/Operation/security/systemAuthorization.d.ts +5 -0
- package/dist/Operation/security/systemAuthorization.d.ts.map +1 -0
- package/dist/Operation/security/systemAuthorization.js +24 -0
- package/dist/Operation/security/systemAuthorization.js.map +1 -0
- package/dist/Operation/security/userAuthorization.d.ts +11 -0
- package/dist/Operation/security/userAuthorization.d.ts.map +1 -0
- package/dist/Operation/security/userAuthorization.js +36 -0
- package/dist/Operation/security/userAuthorization.js.map +1 -0
- package/dist/Operation/security/verifyToken.d.ts +6 -0
- package/dist/Operation/security/verifyToken.d.ts.map +1 -0
- package/dist/Operation/security/verifyToken.js +15 -0
- package/dist/Operation/security/verifyToken.js.map +1 -0
- package/dist/Service/Service.d.ts +62 -0
- package/dist/Service/Service.d.ts.map +1 -0
- package/dist/Service/Service.js +213 -0
- package/dist/Service/Service.js.map +1 -0
- package/dist/Service/authorize.d.ts +26 -0
- package/dist/Service/authorize.d.ts.map +1 -0
- package/dist/Service/authorize.js +40 -0
- package/dist/Service/authorize.js.map +1 -0
- package/dist/Service/errors/InvalidInputError.d.ts +29 -0
- package/dist/Service/errors/InvalidInputError.d.ts.map +1 -0
- package/dist/Service/errors/InvalidInputError.js +36 -0
- package/dist/Service/errors/InvalidInputError.js.map +1 -0
- package/dist/Service/errors/InvalidOutputError.d.ts +29 -0
- package/dist/Service/errors/InvalidOutputError.d.ts.map +1 -0
- package/dist/Service/errors/InvalidOutputError.js +36 -0
- package/dist/Service/errors/InvalidOutputError.js.map +1 -0
- package/dist/Service/errors/OperationError.d.ts +30 -0
- package/dist/Service/errors/OperationError.d.ts.map +1 -0
- package/dist/Service/errors/OperationError.js +61 -0
- package/dist/Service/errors/OperationError.js.map +1 -0
- package/dist/Service/errors/OperationNotFoundError.d.ts +38 -0
- package/dist/Service/errors/OperationNotFoundError.d.ts.map +1 -0
- package/dist/Service/errors/OperationNotFoundError.js +45 -0
- package/dist/Service/errors/OperationNotFoundError.js.map +1 -0
- package/dist/Service/errors/index.d.ts +8 -0
- package/dist/Service/errors/index.d.ts.map +1 -0
- package/dist/Service/errors/index.js +15 -0
- package/dist/Service/errors/index.js.map +1 -0
- package/dist/Service/errors/logOperationError.d.ts +35 -0
- package/dist/Service/errors/logOperationError.d.ts.map +1 -0
- package/dist/Service/errors/logOperationError.js +47 -0
- package/dist/Service/errors/logOperationError.js.map +1 -0
- package/dist/Service/errors/maskSecrets.d.ts +13 -0
- package/dist/Service/errors/maskSecrets.d.ts.map +1 -0
- package/dist/Service/errors/maskSecrets.js +57 -0
- package/dist/Service/errors/maskSecrets.js.map +1 -0
- package/dist/Service/index.d.ts +5 -0
- package/dist/Service/index.d.ts.map +1 -0
- package/dist/Service/index.js +25 -0
- package/dist/Service/index.js.map +1 -0
- package/dist/Service/logRequest.d.ts +5 -0
- package/dist/Service/logRequest.d.ts.map +1 -0
- package/dist/Service/logRequest.js +26 -0
- package/dist/Service/logRequest.js.map +1 -0
- package/dist/Service/spec/createSpec.d.ts +7 -0
- package/dist/Service/spec/createSpec.d.ts.map +1 -0
- package/dist/Service/spec/createSpec.js +56 -0
- package/dist/Service/spec/createSpec.js.map +1 -0
- package/dist/Service/spec/getErrorResponseDescription.d.ts +8 -0
- package/dist/Service/spec/getErrorResponseDescription.d.ts.map +1 -0
- package/dist/Service/spec/getErrorResponseDescription.js +15 -0
- package/dist/Service/spec/getErrorResponseDescription.js.map +1 -0
- package/dist/Service/spec/getHttpMethod.d.ts +4 -0
- package/dist/Service/spec/getHttpMethod.d.ts.map +1 -0
- package/dist/Service/spec/getHttpMethod.js +21 -0
- package/dist/Service/spec/getHttpMethod.js.map +1 -0
- package/dist/Service/spec/getOperation.d.ts +6 -0
- package/dist/Service/spec/getOperation.d.ts.map +1 -0
- package/dist/Service/spec/getOperation.js +71 -0
- package/dist/Service/spec/getOperation.js.map +1 -0
- package/dist/Service/spec/getOperationParameters.d.ts +6 -0
- package/dist/Service/spec/getOperationParameters.d.ts.map +1 -0
- package/dist/Service/spec/getOperationParameters.js +32 -0
- package/dist/Service/spec/getOperationParameters.js.map +1 -0
- package/dist/Service/spec/getServiceDefinitions.d.ts +6 -0
- package/dist/Service/spec/getServiceDefinitions.d.ts.map +1 -0
- package/dist/Service/spec/getServiceDefinitions.js +18 -0
- package/dist/Service/spec/getServiceDefinitions.js.map +1 -0
- package/dist/Service/spec/getServiceInfo.d.ts +7 -0
- package/dist/Service/spec/getServiceInfo.d.ts.map +1 -0
- package/dist/Service/spec/getServiceInfo.js +15 -0
- package/dist/Service/spec/getServiceInfo.js.map +1 -0
- package/dist/Service/spec/getServiceSecurityDefinitions.d.ts +6 -0
- package/dist/Service/spec/getServiceSecurityDefinitions.d.ts.map +1 -0
- package/dist/Service/spec/getServiceSecurityDefinitions.js +21 -0
- package/dist/Service/spec/getServiceSecurityDefinitions.js.map +1 -0
- package/dist/Service/spec/getServiceTags.d.ts +7 -0
- package/dist/Service/spec/getServiceTags.d.ts.map +1 -0
- package/dist/Service/spec/getServiceTags.js +19 -0
- package/dist/Service/spec/getServiceTags.js.map +1 -0
- package/dist/Service/spec/getSuccessStatusCode.d.ts +4 -0
- package/dist/Service/spec/getSuccessStatusCode.d.ts.map +1 -0
- package/dist/Service/spec/getSuccessStatusCode.js +14 -0
- package/dist/Service/spec/getSuccessStatusCode.js.map +1 -0
- package/dist/Service/spec/index.d.ts +3 -0
- package/dist/Service/spec/index.d.ts.map +1 -0
- package/dist/Service/spec/index.js +9 -0
- package/dist/Service/spec/index.js.map +1 -0
- package/dist/Service/spec/validateSpec.d.ts +5 -0
- package/dist/Service/spec/validateSpec.d.ts.map +1 -0
- package/dist/Service/spec/validateSpec.js +21 -0
- package/dist/Service/spec/validateSpec.js.map +1 -0
- package/dist/Service/test/createAccessToken.d.ts +9 -0
- package/dist/Service/test/createAccessToken.d.ts.map +1 -0
- package/dist/Service/test/createAccessToken.js +16 -0
- package/dist/Service/test/createAccessToken.js.map +1 -0
- package/dist/Service/test/ensureItem.d.ts +5 -0
- package/dist/Service/test/ensureItem.d.ts.map +1 -0
- package/dist/Service/test/ensureItem.js +13 -0
- package/dist/Service/test/ensureItem.js.map +1 -0
- package/dist/Service/test/ensureNoItem.d.ts +5 -0
- package/dist/Service/test/ensureNoItem.d.ts.map +1 -0
- package/dist/Service/test/ensureNoItem.js +13 -0
- package/dist/Service/test/ensureNoItem.js.map +1 -0
- package/dist/Service/test/execute.d.ts +44 -0
- package/dist/Service/test/execute.d.ts.map +1 -0
- package/dist/Service/test/execute.js +65 -0
- package/dist/Service/test/execute.js.map +1 -0
- package/dist/Service/test/findItem.d.ts +7 -0
- package/dist/Service/test/findItem.d.ts.map +1 -0
- package/dist/Service/test/findItem.js +16 -0
- package/dist/Service/test/findItem.js.map +1 -0
- package/dist/Service/test/firstItemGet.d.ts +5 -0
- package/dist/Service/test/firstItemGet.d.ts.map +1 -0
- package/dist/Service/test/firstItemGet.js +15 -0
- package/dist/Service/test/firstItemGet.js.map +1 -0
- package/dist/Service/test/index.d.ts +10 -0
- package/dist/Service/test/index.d.ts.map +1 -0
- package/dist/Service/test/index.js +36 -0
- package/dist/Service/test/index.js.map +1 -0
- package/dist/Service/test/keys.d.ts +5 -0
- package/dist/Service/test/keys.d.ts.map +1 -0
- package/dist/Service/test/keys.js +74 -0
- package/dist/Service/test/keys.js.map +1 -0
- package/dist/Service/test/wait.d.ts +4 -0
- package/dist/Service/test/wait.d.ts.map +1 -0
- package/dist/Service/test/wait.js +6 -0
- package/dist/Service/test/wait.js.map +1 -0
- package/dist/Service/useComposerMiddleware.d.ts +11 -0
- package/dist/Service/useComposerMiddleware.d.ts.map +1 -0
- package/dist/Service/useComposerMiddleware.js +41 -0
- package/dist/Service/useComposerMiddleware.js.map +1 -0
- package/dist/Service/useOasMiddleware.d.ts +16 -0
- package/dist/Service/useOasMiddleware.d.ts.map +1 -0
- package/dist/Service/useOasMiddleware.js +53 -0
- package/dist/Service/useOasMiddleware.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/eslint.config.mjs +32 -52
- package/example/documents/Profile/Profile.ts +8 -0
- package/example/documents/Profile/Profile.yaml +6 -0
- package/example/documents/Profile/ProfileAttributes.d.ts +5 -0
- package/example/documents/Profile/index.ts +3 -0
- package/example/documents/index.ts +5 -0
- package/example/index.ts +38 -0
- package/example/lib/createActivity.ts +28 -0
- package/example/lib/index.ts +24 -0
- package/example/operations/Profile/CreateProfile.ts +9 -0
- package/example/operations/Profile/DeleteProfile.ts +9 -0
- package/example/operations/Profile/IndexProfiles.ts +9 -0
- package/example/operations/Profile/ReadProfile.ts +9 -0
- package/example/operations/Profile/ReadProfileSystem.ts +9 -0
- package/example/operations/Profile/UpdateProfile.ts +9 -0
- package/example/operations/Service/Health.ts +11 -0
- package/example/operations/index.ts +22 -0
- package/example/security/index.ts +25 -0
- package/jest.config.mjs +7 -0
- package/package.json +34 -24
- package/src/Component/Component.ts +120 -0
- package/src/Component/__tests__/Component.test.ts +161 -0
- package/src/Component/index.ts +7 -0
- package/src/Context/Context.ts +217 -0
- package/src/Context/Request.ts +41 -0
- package/src/Context/__tests__/Context.test.ts +271 -0
- package/src/Context/__tests__/__helpers.ts +86 -0
- package/src/Context/getHttpMethod.ts +21 -0
- package/src/Context/getHttpPath.ts +34 -0
- package/src/Context/getMutationParameters.ts +35 -0
- package/src/Context/getOperationId.ts +23 -0
- package/src/Context/getQueryParameters.ts +45 -0
- package/src/Context/index.ts +12 -0
- package/src/Context/withSafeAttributes.ts +39 -0
- package/src/Document/Document.ts +448 -0
- package/src/Document/MemoryDocument.ts +152 -0
- package/src/Document/__tests__/MemoryDocument.test.ts +406 -0
- package/src/Document/__tests__/__helpers.ts +40 -0
- package/src/Document/index.ts +11 -0
- package/src/Operation/Operation.ts +401 -0
- package/src/Operation/__tests__/Operation.test.ts +142 -0
- package/src/Operation/errors/AccessDeniedError.ts +25 -0
- package/src/Operation/errors/CommonError.ts +41 -0
- package/src/Operation/errors/DocumentExistsError.ts +33 -0
- package/src/Operation/errors/DocumentNotFoundError.ts +34 -0
- package/src/Operation/errors/InvalidParametersError.ts +30 -0
- package/src/Operation/errors/UnauthorizedError.ts +28 -0
- package/src/Operation/errors/UnprocessibleConditionError.ts +32 -0
- package/src/Operation/errors/__tests__/InvalidParametersError.test.ts +20 -0
- package/src/Operation/errors/__tests__/UnprocessibleConditionError.test.ts +20 -0
- package/src/Operation/errors/index.ts +17 -0
- package/src/Operation/helpers/index.ts +9 -0
- package/src/Operation/helpers/withActivity.ts +43 -0
- package/src/Operation/index.ts +29 -0
- package/src/Operation/operations/Create.ts +49 -0
- package/src/Operation/operations/Delete.ts +65 -0
- package/src/Operation/operations/Index.ts +164 -0
- package/src/Operation/operations/List.ts +62 -0
- package/src/Operation/operations/Read.ts +55 -0
- package/src/Operation/operations/Update.ts +60 -0
- package/src/Operation/operations/__tests__/Create.test.ts +153 -0
- package/src/Operation/operations/__tests__/Delete.test.ts +163 -0
- package/src/Operation/operations/__tests__/Index.test.ts +209 -0
- package/src/Operation/operations/__tests__/List.test.ts +146 -0
- package/src/Operation/operations/__tests__/Read.test.ts +152 -0
- package/src/Operation/operations/__tests__/Update.test.ts +158 -0
- package/src/Operation/security/JwtAuthorization.ts +247 -0
- package/src/Operation/security/LambdaAuthorization.ts +103 -0
- package/src/Operation/security/__tests__/JwtAuthorization.test.ts +230 -0
- package/src/Operation/security/__tests__/LambdaAuthorization.test.ts +63 -0
- package/src/Operation/security/__tests__/userAuthorization.test.ts +42 -0
- package/src/Operation/security/index.ts +15 -0
- package/src/Operation/security/systemAuthorization.ts +23 -0
- package/src/Operation/security/userAuthorization.ts +47 -0
- package/src/Operation/security/verifyToken.ts +22 -0
- package/src/Service/Service.ts +317 -0
- package/src/Service/__tests__/Service.test.ts +229 -0
- package/src/Service/authorize.ts +80 -0
- package/src/Service/errors/InvalidInputError.ts +40 -0
- package/src/Service/errors/InvalidOutputError.ts +40 -0
- package/src/Service/errors/OperationError.ts +74 -0
- package/src/{errors → Service/errors}/OperationError.yaml +7 -10
- package/src/Service/errors/OperationErrorAttributes.d.ts +12 -0
- package/src/Service/errors/OperationNotFoundError.ts +45 -0
- package/src/Service/errors/__tests__/OperationError.test.ts +17 -0
- package/src/Service/errors/__tests__/maskSecrets.test.ts +92 -0
- package/src/Service/errors/index.ts +18 -0
- package/src/Service/errors/logOperationError.ts +72 -0
- package/src/Service/errors/maskSecrets.ts +65 -0
- package/src/Service/index.ts +9 -0
- package/src/Service/logRequest.ts +50 -0
- package/src/Service/spec/__tests__/validateSpec.test.ts +10 -0
- package/src/Service/spec/createSpec.ts +68 -0
- package/src/Service/spec/getErrorResponseDescription.ts +20 -0
- package/src/Service/spec/getHttpMethod.ts +20 -0
- package/src/Service/spec/getOperation.ts +99 -0
- package/src/Service/spec/getOperationParameters.ts +43 -0
- package/src/Service/spec/getServiceDefinitions.ts +23 -0
- package/src/Service/spec/getServiceInfo.ts +18 -0
- package/src/Service/spec/getServiceSecurityDefinitions.ts +26 -0
- package/src/Service/spec/getServiceTags.ts +23 -0
- package/src/Service/spec/getSuccessStatusCode.ts +15 -0
- package/src/Service/spec/index.ts +5 -0
- package/src/Service/spec/validateSpec.ts +22 -0
- package/src/Service/test/__tests__/createAccessToken.test.ts +104 -0
- package/src/Service/test/__tests__/ensureItem.test.ts +41 -0
- package/src/Service/test/__tests__/ensureNoItem.test.ts +49 -0
- package/src/Service/test/__tests__/execute.test.ts +125 -0
- package/src/Service/test/__tests__/findItem.test.ts +45 -0
- package/src/Service/test/__tests__/firstItemGet.test.ts +50 -0
- package/src/Service/test/__tests__/wait.test.ts +66 -0
- package/src/Service/test/createAccessToken.ts +28 -0
- package/src/Service/test/ensureItem.ts +9 -0
- package/src/Service/test/ensureNoItem.ts +9 -0
- package/src/Service/test/execute.ts +112 -0
- package/src/Service/test/findItem.ts +22 -0
- package/src/Service/test/firstItemGet.ts +18 -0
- package/src/Service/test/index.ts +19 -0
- package/src/Service/test/keys.ts +75 -0
- package/src/Service/test/wait.ts +5 -0
- package/src/Service/useComposerMiddleware.ts +56 -0
- package/src/Service/useOasMiddleware.ts +69 -0
- package/src/index.ts +12 -0
- package/tsconfig.json +26 -0
- package/examples/CreateProfile.js +0 -40
- package/examples/DeleteProfile.js +0 -6
- package/examples/Health.js +0 -8
- package/examples/IndexProfiles.js +0 -6
- package/examples/Profile.js +0 -8
- package/examples/Profile.yaml +0 -4
- package/examples/ReadProfile.js +0 -18
- package/examples/UpdateProfile.js +0 -25
- package/examples/index.js +0 -29
- package/src/Component.js +0 -59
- package/src/Component.spec.js +0 -65
- package/src/Document.js +0 -310
- package/src/Document.spec.js +0 -331
- package/src/Operation.js +0 -258
- package/src/Operation.spec.js +0 -474
- package/src/Service.js +0 -207
- package/src/Service.spec.js +0 -388
- package/src/errors/AccessDeniedError.js +0 -11
- package/src/errors/CommonError.js +0 -19
- package/src/errors/DocumentExistsError.js +0 -15
- package/src/errors/DocumentNotFoundError.js +0 -15
- package/src/errors/InvalidInputError.js +0 -19
- package/src/errors/InvalidOutputError.js +0 -20
- package/src/errors/InvalidParametersError.js +0 -11
- package/src/errors/OperationError.js +0 -44
- package/src/errors/OperationNotFoundError.js +0 -16
- package/src/errors/UnauthorizedError.js +0 -11
- package/src/errors/UnprocessibleConditionError.js +0 -11
- package/src/errors/index.js +0 -11
- package/src/helpers/asSafeClass.js +0 -22
- package/src/helpers/authorize.js +0 -44
- package/src/helpers/createContext.js +0 -96
- package/src/helpers/createSchemasMap.js +0 -37
- package/src/helpers/createSpec.js +0 -196
- package/src/helpers/defaultId.js +0 -30
- package/src/helpers/defaultSummary.js +0 -15
- package/src/helpers/defaultTags.js +0 -16
- package/src/helpers/getComponentTitle.js +0 -22
- package/src/helpers/getDefaultSchemaAttributes.js +0 -32
- package/src/helpers/getHttpMethod.js +0 -19
- package/src/helpers/getIdPrefix.js +0 -7
- package/src/helpers/getOrFail.js +0 -24
- package/src/helpers/getOrFail.spec.js +0 -17
- package/src/helpers/getSuccessStatusCode.js +0 -15
- package/src/helpers/handler.js +0 -21
- package/src/helpers/loadSync.js +0 -14
- package/src/helpers/logError.js +0 -33
- package/src/helpers/logRequest.js +0 -36
- package/src/helpers/maskSecrets.js +0 -42
- package/src/helpers/specMiddleware.js +0 -81
- package/src/index.d.ts +0 -350
- package/src/index.js +0 -35
- package/src/operations/Create.js +0 -39
- package/src/operations/Delete.js +0 -54
- package/src/operations/Index.js +0 -107
- package/src/operations/Read.js +0 -46
- package/src/operations/Update.js +0 -50
- package/src/security/JwtAuthorization.js +0 -125
- package/src/security/SystemAuthorization.js +0 -73
- package/src/security/index.js +0 -9
- package/src/security/verifyToken.js +0 -17
- package/src/test/createAccessToken.js +0 -23
- package/src/test/execute.js +0 -84
- package/src/test/index.js +0 -11
- package/src/test/keys.js +0 -39
- package/src/test/wait.js +0 -5
- /package/{specs → .composer}/Documents.yaml +0 -0
- /package/{specs → .composer}/Enums.yaml +0 -0
- /package/{specs → .composer}/Operations.yaml +0 -0
- /package/{specs → .composer}/Parameters.yaml +0 -0
- /package/{specs → .composer}/Scenarios.yaml +0 -0
- /package/{specs → .composer}/Schemas.yaml +0 -0
|
@@ -0,0 +1,448 @@
|
|
|
1
|
+
import { ulid } from 'ulid';
|
|
2
|
+
import Component from '../Component';
|
|
3
|
+
import { Schema, type PropertiesSchemaSource, got } from '@kravc/schema';
|
|
4
|
+
import Context, { type QueryMap, type MutationMap } from '../Context';
|
|
5
|
+
import { get, set, omit, pick, cloneDeep, capitalize } from 'lodash';
|
|
6
|
+
|
|
7
|
+
const DEFAULT_INDEX_SORT = 'desc';
|
|
8
|
+
const DEFAULT_INDEX_LIMIT = 300;
|
|
9
|
+
const DEFAULT_PARTITION_KEY = 'partition';
|
|
10
|
+
|
|
11
|
+
export type IndexOptions = {
|
|
12
|
+
sort?: 'asc' | 'desc';
|
|
13
|
+
limit?: number;
|
|
14
|
+
index?: string;
|
|
15
|
+
exclusiveStartKey?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export type IndexAllOptions = {
|
|
19
|
+
sort?: 'asc' | 'desc';
|
|
20
|
+
index?: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export type DefaultAttributes = {
|
|
24
|
+
id: string;
|
|
25
|
+
createdAt: string;
|
|
26
|
+
createdBy: string;
|
|
27
|
+
createdByUserName?: string;
|
|
28
|
+
updatedAt?: string;
|
|
29
|
+
updatedBy?: string;
|
|
30
|
+
updatedByUserName?: string;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
type Constructor<T, D extends Document<T> = Document<T>> = {
|
|
34
|
+
new(context: Context, attributes: T): D;
|
|
35
|
+
|
|
36
|
+
_index(query: QueryMap, options: IndexOptions): Promise<{
|
|
37
|
+
count: number;
|
|
38
|
+
items: T[];
|
|
39
|
+
lastEvaluatedKey?: string;
|
|
40
|
+
}>;
|
|
41
|
+
|
|
42
|
+
_indexAll(query: QueryMap, options: IndexAllOptions): Promise<{
|
|
43
|
+
count: number;
|
|
44
|
+
items: T[];
|
|
45
|
+
}>;
|
|
46
|
+
|
|
47
|
+
_read(query: QueryMap, options: unknown): Promise<T>;
|
|
48
|
+
|
|
49
|
+
_create(attributes: T): Promise<void>;
|
|
50
|
+
|
|
51
|
+
_update<T>(query: QueryMap, mutation: MutationMap): Promise<T>;
|
|
52
|
+
|
|
53
|
+
_delete(query: QueryMap): Promise<void>;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/** Abstract document class. */
|
|
57
|
+
class Document<Attributes> extends Component<Attributes> {
|
|
58
|
+
private static _bodySchema: Schema;
|
|
59
|
+
|
|
60
|
+
private _previousAttributes: Attributes | undefined;
|
|
61
|
+
|
|
62
|
+
/** Returns partition key of a document. */
|
|
63
|
+
static get partitionKey(): string {
|
|
64
|
+
return DEFAULT_PARTITION_KEY;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Returns prefix for new IDs. */
|
|
68
|
+
static get idPrefix(): string {
|
|
69
|
+
return this.name;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** Returns attribute name to sort index action results by. */
|
|
73
|
+
static get indexSortBy(): string {
|
|
74
|
+
return this.idKey;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** Defines default sort direction for index action results. */
|
|
78
|
+
static get indexDefaultSort(): 'asc' | 'desc' {
|
|
79
|
+
return DEFAULT_INDEX_SORT;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** Defines default limit for index action. */
|
|
83
|
+
static get indexDefaultLimit(): number {
|
|
84
|
+
return DEFAULT_INDEX_LIMIT;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** Generates ID for new document unless it's defined in parameters. */
|
|
88
|
+
static createId(attributes: Record<string, unknown>): string {
|
|
89
|
+
const id = get(attributes, this.idKey) as string;
|
|
90
|
+
const hasId = !!id;
|
|
91
|
+
|
|
92
|
+
if (hasId) {
|
|
93
|
+
return id;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return `${this.idPrefix}_` + ulid();
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** Returns default attributes schema source. */
|
|
100
|
+
static get defaultAttributesSchemaSource(): PropertiesSchemaSource {
|
|
101
|
+
const documentTitle = this.getTitle(false);
|
|
102
|
+
|
|
103
|
+
return {
|
|
104
|
+
id: {
|
|
105
|
+
description: capitalize(documentTitle) + ' ID',
|
|
106
|
+
required: true
|
|
107
|
+
},
|
|
108
|
+
createdAt: {
|
|
109
|
+
description: `Date and time when ${documentTitle} was created`,
|
|
110
|
+
format: 'date-time',
|
|
111
|
+
required: true
|
|
112
|
+
},
|
|
113
|
+
createdBy: {
|
|
114
|
+
description: `ID of a user who created ${documentTitle}`,
|
|
115
|
+
required: true
|
|
116
|
+
},
|
|
117
|
+
createdByUserName: {
|
|
118
|
+
description: `Name of a user who created ${documentTitle}`
|
|
119
|
+
},
|
|
120
|
+
updatedAt: {
|
|
121
|
+
description: `Date and time when ${documentTitle} was updated`,
|
|
122
|
+
format: 'date-time'
|
|
123
|
+
},
|
|
124
|
+
updatedBy: {
|
|
125
|
+
description: `ID of a user who updated ${documentTitle}`
|
|
126
|
+
},
|
|
127
|
+
updatedByUserName: {
|
|
128
|
+
description: `Name of a user who updated ${documentTitle}`
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/** Extends document schema with default attributes. */
|
|
134
|
+
static set schema(schema: Schema) {
|
|
135
|
+
this._schema = schema.extend(this.defaultAttributesSchemaSource, this.id);
|
|
136
|
+
this._bodySchema = schema.clone(`${this.id}Body`);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/** Returns schema to validate document attributes. */
|
|
140
|
+
static get schema(): Schema {
|
|
141
|
+
if (!this._schema) {
|
|
142
|
+
throw new Error(`Schema is not set for "${this.id}"`);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return this._schema;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/** Returns body schema of a document. */
|
|
149
|
+
static get bodySchema() {
|
|
150
|
+
return this._bodySchema;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/** Returns schema for document create and update mutations. */
|
|
154
|
+
static get mutationSchema(): Schema {
|
|
155
|
+
return this.bodySchema;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/** Returns partition to save document based on context and parameters. */
|
|
159
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
160
|
+
static getPartition(_context: Context, _parameters: Record<string, unknown>): string | undefined {
|
|
161
|
+
return undefined;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/** Extends parameters with partition of a document. */
|
|
165
|
+
static _extendWithPartition(context: Context, parameters: Record<string, unknown>): void {
|
|
166
|
+
const hasPartition = !!get(parameters, this.partitionKey);
|
|
167
|
+
|
|
168
|
+
if (hasPartition) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const partition = this.getPartition(context, parameters);
|
|
173
|
+
|
|
174
|
+
if (!partition) {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
set(parameters, this.partitionKey, partition);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/** Extends mutation with created stamps. */
|
|
182
|
+
static _extendWithCreatedStamps(context: Context, mutation: MutationMap) {
|
|
183
|
+
const timestamp = new Date().toJSON();
|
|
184
|
+
|
|
185
|
+
mutation.createdAt = timestamp;
|
|
186
|
+
mutation.createdBy = context.identityId;
|
|
187
|
+
mutation.createdByUserName = context.identityName;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/** Extends mutation with updated stamps. */
|
|
191
|
+
static _extendWithUpdatedStamps(context: Context, mutation: MutationMap) {
|
|
192
|
+
const timestamp = new Date().toJSON();
|
|
193
|
+
|
|
194
|
+
mutation.updatedAt = timestamp;
|
|
195
|
+
mutation.updatedBy = context.identityId;
|
|
196
|
+
mutation.updatedByUserName = context.identityName;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/** Returns documents in batches. */
|
|
200
|
+
static async index<T, D extends Document<T> = Document<T>>(
|
|
201
|
+
this: Constructor<T, D>,
|
|
202
|
+
context: Context,
|
|
203
|
+
query: QueryMap = {},
|
|
204
|
+
options: IndexOptions = {}
|
|
205
|
+
): Promise<{
|
|
206
|
+
count: number;
|
|
207
|
+
objects: D[];
|
|
208
|
+
lastEvaluatedKey?: string;
|
|
209
|
+
}> {
|
|
210
|
+
const _this = this as unknown as typeof Document;
|
|
211
|
+
_this._extendWithPartition(context, query);
|
|
212
|
+
|
|
213
|
+
if (!options.limit) {
|
|
214
|
+
options.limit = _this.indexDefaultLimit;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if (!options.sort) {
|
|
218
|
+
options.sort = _this.indexDefaultSort;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const { items, count, lastEvaluatedKey, ...otherPagination } = await this._index(query, options);
|
|
222
|
+
const objects = items.map(attributes => new this(context, attributes));
|
|
223
|
+
|
|
224
|
+
return { objects, count, lastEvaluatedKey, ...otherPagination };
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/** Returns all documents. */
|
|
228
|
+
static async indexAll<T, D extends Document<T> = Document<T>>(
|
|
229
|
+
this: Constructor<T, D>,
|
|
230
|
+
context: Context,
|
|
231
|
+
query: QueryMap = {},
|
|
232
|
+
options: IndexAllOptions = {}
|
|
233
|
+
): Promise<{
|
|
234
|
+
count: number;
|
|
235
|
+
objects: D[];
|
|
236
|
+
}> {
|
|
237
|
+
const _this = this as unknown as typeof Document;
|
|
238
|
+
_this._extendWithPartition(context, query);
|
|
239
|
+
|
|
240
|
+
if (!options.sort) {
|
|
241
|
+
options.sort = _this.indexDefaultSort;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
const { items, count } = await this._indexAll(query, options);
|
|
245
|
+
const objects = items.map(attributes => new this(context, attributes));
|
|
246
|
+
|
|
247
|
+
return { objects, count };
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/** Returns a document by ID attribute. */
|
|
251
|
+
static async read<T, D extends Document<T> = Document<T>>(
|
|
252
|
+
this: Constructor<T, D>,
|
|
253
|
+
context: Context,
|
|
254
|
+
query: QueryMap,
|
|
255
|
+
options?: unknown
|
|
256
|
+
): Promise<D> {
|
|
257
|
+
const _this = this as unknown as typeof Document;
|
|
258
|
+
_this._extendWithPartition(context, query);
|
|
259
|
+
|
|
260
|
+
const attributes = await this._read(query, options);
|
|
261
|
+
const object = new this(context, attributes);
|
|
262
|
+
|
|
263
|
+
return object;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/** Creates a document. */
|
|
267
|
+
static async create<T, D extends Document<T> = Document<T>>(
|
|
268
|
+
this: Constructor<T, D>,
|
|
269
|
+
context: Context,
|
|
270
|
+
query: QueryMap | MutationMap,
|
|
271
|
+
mutation?: MutationMap
|
|
272
|
+
): Promise<D> {
|
|
273
|
+
const _this = this as unknown as typeof Document;
|
|
274
|
+
|
|
275
|
+
// NOTE: This allows implementing the create-unless-exists flow, which first
|
|
276
|
+
// checks existence of the document via before hooks. If it does
|
|
277
|
+
// exist, they add it to the context. Then the operation's action
|
|
278
|
+
// method would do nothing and just return the document from the context.
|
|
279
|
+
const createdDocument = context.get('createdDocument') as D;
|
|
280
|
+
const shouldNotCreate = createdDocument?.componentId === this.name;
|
|
281
|
+
|
|
282
|
+
if (shouldNotCreate) {
|
|
283
|
+
return createdDocument;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
if (!mutation) {
|
|
287
|
+
mutation = query;
|
|
288
|
+
query = {};
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
const { validator } = context;
|
|
292
|
+
const attributes = validator.normalize(mutation, _this.id) as MutationMap;
|
|
293
|
+
|
|
294
|
+
const idValue = _this.createId(attributes);
|
|
295
|
+
set(attributes, _this.idKey, idValue);
|
|
296
|
+
|
|
297
|
+
_this._extendWithCreatedStamps(context, attributes);
|
|
298
|
+
_this._extendWithPartition(context, attributes);
|
|
299
|
+
|
|
300
|
+
await _this.beforeCreate(context, query, attributes);
|
|
301
|
+
|
|
302
|
+
await this._create(attributes as T);
|
|
303
|
+
const object = new this(context, attributes as T);
|
|
304
|
+
|
|
305
|
+
await _this.afterCreate(context, query, mutation, object);
|
|
306
|
+
|
|
307
|
+
return object;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/** Before create hook. */
|
|
311
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
312
|
+
static async beforeCreate(_context: Context, _query: QueryMap, _mutation: MutationMap): Promise<void> {
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/** After create hook. */
|
|
317
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
318
|
+
static async afterCreate(_context: Context, _query: QueryMap, _mutation: MutationMap, _createdDocument: unknown): Promise<void> {
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/** Updates a document. */
|
|
323
|
+
static async update<T, D extends Document<T> = Document<T>>(
|
|
324
|
+
this: Constructor<T, D>,
|
|
325
|
+
context: Context,
|
|
326
|
+
query: QueryMap,
|
|
327
|
+
mutation: MutationMap
|
|
328
|
+
): Promise<D> {
|
|
329
|
+
const _this = this as unknown as typeof Document;
|
|
330
|
+
|
|
331
|
+
mutation = omit(mutation, Object.keys(_this.defaultAttributesSchemaSource));
|
|
332
|
+
|
|
333
|
+
_this._extendWithUpdatedStamps(context, mutation);
|
|
334
|
+
_this._extendWithPartition(context, query);
|
|
335
|
+
|
|
336
|
+
await _this.beforeUpdate(context, query, mutation);
|
|
337
|
+
|
|
338
|
+
/* NOTE: In some workflows operation before action helper may be doing
|
|
339
|
+
some verifications with the document to be updated. Here we
|
|
340
|
+
allow to cache it in the context. */
|
|
341
|
+
const idValue = got(query, _this.idKey, 'Query parameter "$PATH" is required') as string;
|
|
342
|
+
|
|
343
|
+
const previousDocument = context.get(idValue) as D;
|
|
344
|
+
let previousAttributes = previousDocument?.attributes;
|
|
345
|
+
|
|
346
|
+
/* NOTE: Ensure that document to be updated exists and save it in the
|
|
347
|
+
context so can be referenced in the after action helper. */
|
|
348
|
+
if (!previousAttributes) {
|
|
349
|
+
previousAttributes = await this._read(query, {});
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
const updatedAttributes = await this._update(query, mutation) as T;
|
|
353
|
+
const object = new this(context, updatedAttributes);
|
|
354
|
+
|
|
355
|
+
object._previousAttributes = previousAttributes;
|
|
356
|
+
|
|
357
|
+
await _this.afterUpdate(context, query, mutation, object);
|
|
358
|
+
|
|
359
|
+
return object;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/** Before update hook. */
|
|
363
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
364
|
+
static async beforeUpdate(_context: Context, _query: QueryMap, _mutation: MutationMap): Promise<void> {
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/** After update hook. */
|
|
369
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
370
|
+
static async afterUpdate(_context: Context, _query: QueryMap, _mutation: MutationMap, _updatedDocument: unknown): Promise<void> {
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/** Deletes a document. */
|
|
375
|
+
static async delete<T, D extends Document<T> = Document<T>>(
|
|
376
|
+
this: Constructor<T, D>,
|
|
377
|
+
context: Context,
|
|
378
|
+
query: QueryMap,
|
|
379
|
+
): Promise<D> {
|
|
380
|
+
const _this = this as unknown as typeof Document;
|
|
381
|
+
|
|
382
|
+
_this._extendWithPartition(context, query);
|
|
383
|
+
|
|
384
|
+
await _this.beforeDelete(context, query);
|
|
385
|
+
|
|
386
|
+
const attributes = await this._read(query, {});
|
|
387
|
+
const object = new this(context, attributes);
|
|
388
|
+
|
|
389
|
+
await this._delete(query);
|
|
390
|
+
|
|
391
|
+
await _this.afterDelete(context, query, object);
|
|
392
|
+
|
|
393
|
+
return object;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/** Before delete hook. */
|
|
397
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
398
|
+
static async beforeDelete(_context: Context, _query: QueryMap): Promise<void> {
|
|
399
|
+
return;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
/** After delete hook. */
|
|
403
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
404
|
+
static async afterDelete(_context: Context, _query: QueryMap, _deletedDocument: unknown): Promise<void> {
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
/** Returns document ID. */
|
|
409
|
+
get id(): string {
|
|
410
|
+
const klass = this.constructor as unknown as typeof Document;
|
|
411
|
+
return got(this.attributes as Record<string, string>, klass.idKey);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
/** Returns previous attributes after update action. */
|
|
415
|
+
get previousAttributes() {
|
|
416
|
+
return this._previousAttributes || null;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/** Flags if document attribute has been changed via update action. */
|
|
420
|
+
hasAttributeChanged(path: string): boolean {
|
|
421
|
+
if (!this.previousAttributes) {
|
|
422
|
+
throw Error(`${this.componentId} ${this.id} has not been updated`);
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
const currentValue = get(this.attributes, path);
|
|
426
|
+
const previousValue = get(this.previousAttributes, path);
|
|
427
|
+
|
|
428
|
+
const hasChanged = previousValue !== currentValue;
|
|
429
|
+
|
|
430
|
+
return hasChanged;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
/** Updates document attributes. */
|
|
434
|
+
async update(mutation: MutationMap): Promise<void> {
|
|
435
|
+
const klass = this.constructor as unknown as Constructor<Attributes, Document<Attributes>> & typeof Document;
|
|
436
|
+
|
|
437
|
+
this.context.set(this.id, this);
|
|
438
|
+
|
|
439
|
+
const query = pick(this.attributes, [ klass.idKey, klass.partitionKey ]);
|
|
440
|
+
const object = await klass.update(this.context, query, mutation);
|
|
441
|
+
|
|
442
|
+
this._previousAttributes = cloneDeep(this.attributes) as Attributes;
|
|
443
|
+
|
|
444
|
+
set(this, '_attributes', object.attributes);
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
export default Document;
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { got } from '@kravc/schema';
|
|
2
|
+
import type { QueryMap, MutationMap } from '../Context';
|
|
3
|
+
import { get, set, last, unset, cloneDeep, sortBy } from 'lodash';
|
|
4
|
+
import { DocumentExistsError, DocumentNotFoundError } from '../Operation';
|
|
5
|
+
import Document, { type IndexOptions, type IndexAllOptions } from './Document';
|
|
6
|
+
|
|
7
|
+
type Item = {
|
|
8
|
+
id: string;
|
|
9
|
+
[index: string]: unknown;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const _MEMORY_STORE = {} as Record<string, Record<string, Item>>;
|
|
13
|
+
|
|
14
|
+
/** Example implementation of a document class stored in memory. */
|
|
15
|
+
class MemoryDocument<T> extends Document<T> {
|
|
16
|
+
/** Returns collection where documents are stored. */
|
|
17
|
+
static get collection() {
|
|
18
|
+
const collectionName = this.name;
|
|
19
|
+
|
|
20
|
+
const hasCollection = !!_MEMORY_STORE[collectionName];
|
|
21
|
+
|
|
22
|
+
if (!hasCollection) {
|
|
23
|
+
_MEMORY_STORE[collectionName] = {};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return _MEMORY_STORE[collectionName];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Resets collection. */
|
|
30
|
+
static async reset() {
|
|
31
|
+
const collectionName = this.name;
|
|
32
|
+
|
|
33
|
+
delete _MEMORY_STORE[collectionName];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** Implements interface to get documents in batches. */
|
|
37
|
+
static async _index<T>(query: QueryMap, options: IndexOptions): Promise<{
|
|
38
|
+
count: number;
|
|
39
|
+
items: T[];
|
|
40
|
+
lastEvaluatedKey?: string;
|
|
41
|
+
}> {
|
|
42
|
+
const {
|
|
43
|
+
sort,
|
|
44
|
+
limit,
|
|
45
|
+
exclusiveStartKey
|
|
46
|
+
} = options;
|
|
47
|
+
|
|
48
|
+
/** Filters result item to match query. */
|
|
49
|
+
const filter = (item: Item) =>
|
|
50
|
+
Object
|
|
51
|
+
.keys(query)
|
|
52
|
+
.every(key => item[key] === query[key]);
|
|
53
|
+
|
|
54
|
+
const sortedItems = sort === 'desc'
|
|
55
|
+
? sortBy(Object.values(this.collection), this.indexSortBy).reverse()
|
|
56
|
+
: sortBy(Object.values(this.collection), this.indexSortBy);
|
|
57
|
+
|
|
58
|
+
const filteredItems = sortedItems
|
|
59
|
+
.filter(filter)
|
|
60
|
+
.map(cloneDeep) as T[];
|
|
61
|
+
|
|
62
|
+
let exclusiveStartKeyIndex = -1;
|
|
63
|
+
|
|
64
|
+
if (exclusiveStartKey) {
|
|
65
|
+
exclusiveStartKeyIndex = filteredItems
|
|
66
|
+
.findIndex(item => got(item, this.idKey) === exclusiveStartKey);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const items = limit
|
|
70
|
+
? filteredItems.slice(exclusiveStartKeyIndex + 1, exclusiveStartKeyIndex + 1 + limit)
|
|
71
|
+
: filteredItems.slice(exclusiveStartKeyIndex + 1, filteredItems.length);
|
|
72
|
+
|
|
73
|
+
const count = items.length;
|
|
74
|
+
|
|
75
|
+
let lastEvaluatedKey = get(last(items), this.idKey);
|
|
76
|
+
|
|
77
|
+
const isLastItemIncluded = get(last(sortedItems), this.idKey) === lastEvaluatedKey;
|
|
78
|
+
|
|
79
|
+
if (isLastItemIncluded) {
|
|
80
|
+
lastEvaluatedKey = undefined;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
items,
|
|
85
|
+
count,
|
|
86
|
+
lastEvaluatedKey,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** Implements interface to get all documents. */
|
|
91
|
+
static async _indexAll<T>(query: QueryMap, options: IndexAllOptions): Promise<{
|
|
92
|
+
count: number;
|
|
93
|
+
items: T[];
|
|
94
|
+
}> {
|
|
95
|
+
const { items, count } = await this._index<T>(query, options);
|
|
96
|
+
|
|
97
|
+
return {
|
|
98
|
+
items,
|
|
99
|
+
count,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** Implements interface to get a document. */
|
|
104
|
+
static async _read<T>(query: QueryMap): Promise<T> {
|
|
105
|
+
const idValue = got(query, this.idKey, 'Query parameter "$PATH" is required') as string;
|
|
106
|
+
|
|
107
|
+
const item = get(this.collection, idValue) as T;
|
|
108
|
+
|
|
109
|
+
if (!item) {
|
|
110
|
+
throw new DocumentNotFoundError(this, query);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return cloneDeep(item);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** Implements interface to save a document, returns false if document is not created. */
|
|
117
|
+
static async _create<T>(attributes: T): Promise<void> {
|
|
118
|
+
const idValue = got(attributes, this.idKey, 'Attribute "$PATH" is required') as string;
|
|
119
|
+
|
|
120
|
+
const item = get(this.collection, idValue) as T;
|
|
121
|
+
|
|
122
|
+
if (item) {
|
|
123
|
+
throw new DocumentExistsError(this, attributes as Record<string, unknown>);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
set(this.collection, idValue, attributes);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/** Implements interface to update a document. */
|
|
130
|
+
static async _update<T>(query: QueryMap, mutation: MutationMap): Promise<T> {
|
|
131
|
+
const idValue = got(query, this.idKey, 'Query parameter "$PATH" is required') as string;
|
|
132
|
+
|
|
133
|
+
const componentTitle = this.getTitle();
|
|
134
|
+
const item = got(this.collection, idValue, `${componentTitle} with ID "$PATH" is not found`) as T;
|
|
135
|
+
|
|
136
|
+
set(this.collection, idValue, { ...item, ...mutation });
|
|
137
|
+
|
|
138
|
+
return cloneDeep({ ...item, ...mutation });
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/** Implements interface to delete a document. */
|
|
142
|
+
static async _delete<T>(query: QueryMap): Promise<void> {
|
|
143
|
+
const idValue = got(query, this.idKey, 'Query parameter "$PATH" is required') as string;
|
|
144
|
+
|
|
145
|
+
const componentTitle = this.getTitle();
|
|
146
|
+
got(this.collection, idValue, `${componentTitle} with ID "$PATH" is not found`) as T;
|
|
147
|
+
|
|
148
|
+
unset(this.collection, idValue);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export default MemoryDocument;
|