diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 00000000..3d0a9346 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,2 @@ +resources +openapi diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 00000000..31d47702 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": "@openstapps" +} diff --git a/ROUTES.md b/ROUTES.md index d160ecbe..06b8a6cd 100644 --- a/ROUTES.md +++ b/ROUTES.md @@ -18,12 +18,12 @@ This checks if a book is available in a library.
### Definition -| parameter | value | -| --- | --- | -| request | [SCBookAvailabilityRequest](https://openstapps.gitlab.io/core/modules/_index.d_.html#scbookavailabilityrequest) | -| response | [SCBookAvailabilityResponse](https://openstapps.gitlab.io/core/modules/_index.d_.html#scbookavailabilityresponse) | -| success code | 200 | -| errors | [SCInternalServerErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scinternalservererrorresponse.html)
[SCMethodNotAllowedErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scmethodnotallowederrorresponse.html)
[SCNotFoundErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scnotfounderrorresponse.html)
[SCRequestBodyTooLargeErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.screquestbodytoolargeerrorresponse.html)
[SCSyntaxErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scsyntaxerrorresponse.html)
[SCUnsupportedMediaTypeErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scunsupportedmediatypeerrorresponse.html)
[SCValidationErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scvalidationerrorresponse.html) | +| parameter | value | +|--------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| request | [SCBookAvailabilityRequest](https://openstapps.gitlab.io/core/modules/_index.d_.html#scbookavailabilityrequest) | +| response | [SCBookAvailabilityResponse](https://openstapps.gitlab.io/core/modules/_index.d_.html#scbookavailabilityresponse) | +| success code | 200 | +| errors | [SCInternalServerErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scinternalservererrorresponse.html)
[SCMethodNotAllowedErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scmethodnotallowederrorresponse.html)
[SCNotFoundErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scnotfounderrorresponse.html)
[SCRequestBodyTooLargeErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.screquestbodytoolargeerrorresponse.html)
[SCSyntaxErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scsyntaxerrorresponse.html)
[SCUnsupportedMediaTypeErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scunsupportedmediatypeerrorresponse.html)
[SCValidationErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scvalidationerrorresponse.html) | ## `POST /bulk/:UID` [Bulk add route](https://openstapps.gitlab.io/core/classes/_index.d_.scbulkaddroute.html) @@ -34,13 +34,13 @@ This checks if a book is available in a library.
### Definition -| parameter | value | -| --- | --- | -| request | [SCBulkAddRequest](https://openstapps.gitlab.io/core/modules/_index.d_.html#scbulkaddrequest) | -| response | [SCBulkAddResponse](https://openstapps.gitlab.io/core/interfaces/_index.d_.scbulkaddresponse.html) | -| success code | 201 | -| errors | [SCInternalServerErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scinternalservererrorresponse.html)
[SCMethodNotAllowedErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scmethodnotallowederrorresponse.html)
[SCNotFoundErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scnotfounderrorresponse.html)
[SCRequestBodyTooLargeErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.screquestbodytoolargeerrorresponse.html)
[SCSyntaxErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scsyntaxerrorresponse.html)
[SCUnsupportedMediaTypeErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scunsupportedmediatypeerrorresponse.html)
[SCValidationErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scvalidationerrorresponse.html) | -| obligatory parameters |
parametertype
UID[SCUuid](https://openstapps.gitlab.io/core/modules/_index.d_.html#scuuid)
| +| parameter | value | +|-----------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| request | [SCBulkAddRequest](https://openstapps.gitlab.io/core/modules/_index.d_.html#scbulkaddrequest) | +| response | [SCBulkAddResponse](https://openstapps.gitlab.io/core/interfaces/_index.d_.scbulkaddresponse.html) | +| success code | 201 | +| errors | [SCInternalServerErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scinternalservererrorresponse.html)
[SCMethodNotAllowedErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scmethodnotallowederrorresponse.html)
[SCNotFoundErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scnotfounderrorresponse.html)
[SCRequestBodyTooLargeErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.screquestbodytoolargeerrorresponse.html)
[SCSyntaxErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scsyntaxerrorresponse.html)
[SCUnsupportedMediaTypeErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scunsupportedmediatypeerrorresponse.html)
[SCValidationErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scvalidationerrorresponse.html) | +| obligatory parameters |
parametertype
UID[SCUuid](https://openstapps.gitlab.io/core/modules/_index.d_.html#scuuid)
| ## `POST /bulk/:UID/done` [Bulk done route](https://openstapps.gitlab.io/core/classes/_index.d_.scbulkdoneroute.html) @@ -50,13 +50,13 @@ This checks if a book is available in a library.
### Definition -| parameter | value | -| --- | --- | -| request | [SCBulkDoneRequest](https://openstapps.gitlab.io/core/interfaces/_index.d_.scbulkdonerequest.html) | -| response | [SCBulkDoneResponse](https://openstapps.gitlab.io/core/interfaces/_index.d_.scbulkdoneresponse.html) | -| success code | 204 | -| errors | [SCInternalServerErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scinternalservererrorresponse.html)
[SCMethodNotAllowedErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scmethodnotallowederrorresponse.html)
[SCNotFoundErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scnotfounderrorresponse.html)
[SCRequestBodyTooLargeErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.screquestbodytoolargeerrorresponse.html)
[SCSyntaxErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scsyntaxerrorresponse.html)
[SCUnsupportedMediaTypeErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scunsupportedmediatypeerrorresponse.html)
[SCValidationErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scvalidationerrorresponse.html) | -| obligatory parameters |
parametertype
UID[SCUuid](https://openstapps.gitlab.io/core/modules/_index.d_.html#scuuid)
| +| parameter | value | +|-----------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| request | [SCBulkDoneRequest](https://openstapps.gitlab.io/core/interfaces/_index.d_.scbulkdonerequest.html) | +| response | [SCBulkDoneResponse](https://openstapps.gitlab.io/core/interfaces/_index.d_.scbulkdoneresponse.html) | +| success code | 204 | +| errors | [SCInternalServerErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scinternalservererrorresponse.html)
[SCMethodNotAllowedErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scmethodnotallowederrorresponse.html)
[SCNotFoundErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scnotfounderrorresponse.html)
[SCRequestBodyTooLargeErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.screquestbodytoolargeerrorresponse.html)
[SCSyntaxErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scsyntaxerrorresponse.html)
[SCUnsupportedMediaTypeErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scunsupportedmediatypeerrorresponse.html)
[SCValidationErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scvalidationerrorresponse.html) | +| obligatory parameters |
parametertype
UID[SCUuid](https://openstapps.gitlab.io/core/modules/_index.d_.html#scuuid)
| ## `POST /bulk` [Bulk route](https://openstapps.gitlab.io/core/classes/_index.d_.scbulkroute.html) @@ -66,12 +66,12 @@ This checks if a book is available in a library.
### Definition -| parameter | value | -| --- | --- | -| request | [SCBulkRequest](https://openstapps.gitlab.io/core/interfaces/_index.d_.scbulkrequest.html) | -| response | [SCBulkResponse](https://openstapps.gitlab.io/core/interfaces/_index.d_.scbulkresponse.html) | -| success code | 200 | -| errors | [SCInternalServerErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scinternalservererrorresponse.html)
[SCMethodNotAllowedErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scmethodnotallowederrorresponse.html)
[SCRequestBodyTooLargeErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.screquestbodytoolargeerrorresponse.html)
[SCSyntaxErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scsyntaxerrorresponse.html)
[SCUnsupportedMediaTypeErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scunsupportedmediatypeerrorresponse.html)
[SCValidationErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scvalidationerrorresponse.html) | +| parameter | value | +|--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| request | [SCBulkRequest](https://openstapps.gitlab.io/core/interfaces/_index.d_.scbulkrequest.html) | +| response | [SCBulkResponse](https://openstapps.gitlab.io/core/interfaces/_index.d_.scbulkresponse.html) | +| success code | 200 | +| errors | [SCInternalServerErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scinternalservererrorresponse.html)
[SCMethodNotAllowedErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scmethodnotallowederrorresponse.html)
[SCRequestBodyTooLargeErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.screquestbodytoolargeerrorresponse.html)
[SCSyntaxErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scsyntaxerrorresponse.html)
[SCUnsupportedMediaTypeErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scunsupportedmediatypeerrorresponse.html)
[SCValidationErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scvalidationerrorresponse.html) | ## `POST /feedback` [Feedback route](https://openstapps.gitlab.io/core/classes/_index.d_.scfeedbackroute.html) @@ -82,12 +82,12 @@ This checks if a book is available in a library.
### Definition -| parameter | value | -| --- | --- | -| request | [SCFeedbackRequest](https://openstapps.gitlab.io/core/interfaces/_index.d_.scfeedbackrequest.html) | -| response | [SCFeedbackResponse](https://openstapps.gitlab.io/core/interfaces/_index.d_.scfeedbackresponse.html) | -| success code | 204 | -| errors | [SCInternalServerErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scinternalservererrorresponse.html)
[SCMethodNotAllowedErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scmethodnotallowederrorresponse.html)
[SCRequestBodyTooLargeErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.screquestbodytoolargeerrorresponse.html)
[SCSyntaxErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scsyntaxerrorresponse.html)
[SCUnsupportedMediaTypeErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scunsupportedmediatypeerrorresponse.html)
[SCValidationErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scvalidationerrorresponse.html) | +| parameter | value | +|--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| request | [SCFeedbackRequest](https://openstapps.gitlab.io/core/interfaces/_index.d_.scfeedbackrequest.html) | +| response | [SCFeedbackResponse](https://openstapps.gitlab.io/core/interfaces/_index.d_.scfeedbackresponse.html) | +| success code | 204 | +| errors | [SCInternalServerErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scinternalservererrorresponse.html)
[SCMethodNotAllowedErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scmethodnotallowederrorresponse.html)
[SCRequestBodyTooLargeErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.screquestbodytoolargeerrorresponse.html)
[SCSyntaxErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scsyntaxerrorresponse.html)
[SCUnsupportedMediaTypeErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scunsupportedmediatypeerrorresponse.html)
[SCValidationErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scvalidationerrorresponse.html) | ## `POST /` [Index route](https://openstapps.gitlab.io/core/classes/_index.d_.scindexroute.html) @@ -98,12 +98,12 @@ This checks if a book is available in a library.
### Definition -| parameter | value | -| --- | --- | -| request | [SCIndexRequest](https://openstapps.gitlab.io/core/interfaces/_index.d_.scindexrequest.html) | -| response | [SCIndexResponse](https://openstapps.gitlab.io/core/interfaces/_index.d_.scindexresponse.html) | -| success code | 200 | -| errors | [SCInternalServerErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scinternalservererrorresponse.html)
[SCMethodNotAllowedErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scmethodnotallowederrorresponse.html)
[SCRequestBodyTooLargeErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.screquestbodytoolargeerrorresponse.html)
[SCSyntaxErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scsyntaxerrorresponse.html)
[SCUnsupportedMediaTypeErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scunsupportedmediatypeerrorresponse.html)
[SCValidationErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scvalidationerrorresponse.html) | +| parameter | value | +|--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| request | [SCIndexRequest](https://openstapps.gitlab.io/core/interfaces/_index.d_.scindexrequest.html) | +| response | [SCIndexResponse](https://openstapps.gitlab.io/core/interfaces/_index.d_.scindexresponse.html) | +| success code | 200 | +| errors | [SCInternalServerErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scinternalservererrorresponse.html)
[SCMethodNotAllowedErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scmethodnotallowederrorresponse.html)
[SCRequestBodyTooLargeErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.screquestbodytoolargeerrorresponse.html)
[SCSyntaxErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scsyntaxerrorresponse.html)
[SCUnsupportedMediaTypeErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scunsupportedmediatypeerrorresponse.html)
[SCValidationErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scvalidationerrorresponse.html) | ## `POST /search/multi` [Multi search route](https://openstapps.gitlab.io/core/classes/_index.d_.scmultisearchroute.html) @@ -114,12 +114,12 @@ This checks if a book is available in a library.
### Definition -| parameter | value | -| --- | --- | -| request | [SCMultiSearchRequest](https://openstapps.gitlab.io/core/modules/_index.d_.html#scmultisearchrequest) | -| response | [SCMultiSearchResponse](https://openstapps.gitlab.io/core/modules/_index.d_.html#scmultisearchresponse) | -| success code | 200 | -| errors | [SCInternalServerErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scinternalservererrorresponse.html)
[SCMethodNotAllowedErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scmethodnotallowederrorresponse.html)
[SCRequestBodyTooLargeErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.screquestbodytoolargeerrorresponse.html)
[SCSyntaxErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scsyntaxerrorresponse.html)
[SCTooManyRequestsErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.sctoomanyrequestserrorresponse.html)
[SCUnsupportedMediaTypeErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scunsupportedmediatypeerrorresponse.html)
[SCValidationErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scvalidationerrorresponse.html) | +| parameter | value | +|--------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| request | [SCMultiSearchRequest](https://openstapps.gitlab.io/core/modules/_index.d_.html#scmultisearchrequest) | +| response | [SCMultiSearchResponse](https://openstapps.gitlab.io/core/modules/_index.d_.html#scmultisearchresponse) | +| success code | 200 | +| errors | [SCInternalServerErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scinternalservererrorresponse.html)
[SCMethodNotAllowedErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scmethodnotallowederrorresponse.html)
[SCRequestBodyTooLargeErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.screquestbodytoolargeerrorresponse.html)
[SCSyntaxErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scsyntaxerrorresponse.html)
[SCTooManyRequestsErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.sctoomanyrequestserrorresponse.html)
[SCUnsupportedMediaTypeErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scunsupportedmediatypeerrorresponse.html)
[SCValidationErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scvalidationerrorresponse.html) | ## `POST /plugin/register` [Plugin register route](https://openstapps.gitlab.io/core/classes/_index.d_.scpluginregisterroute.html) @@ -130,12 +130,12 @@ This checks if a book is available in a library.
### Definition -| parameter | value | -| --- | --- | -| request | [SCPluginRegisterRequest](https://openstapps.gitlab.io/core/modules/_index.d_.html#scpluginregisterrequest) | -| response | [SCPluginRegisterResponse](https://openstapps.gitlab.io/core/interfaces/_index.d_.scpluginregisterresponse.html) | -| success code | 200 | -| errors | [SCInternalServerErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scinternalservererrorresponse.html)
[SCMethodNotAllowedErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scmethodnotallowederrorresponse.html)
[SCNotFoundErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scnotfounderrorresponse.html)
[SCParametersNotAcceptable](https://openstapps.gitlab.io/core/classes/_index.d_.scparametersnotacceptable.html)
[SCPluginAlreadyRegisteredErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scpluginalreadyregisterederrorresponse.html)
[SCPluginRegisteringFailedErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scpluginregisteringfailederrorresponse.html)
[SCRequestBodyTooLargeErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.screquestbodytoolargeerrorresponse.html)
[SCSyntaxErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scsyntaxerrorresponse.html) | +| parameter | value | +|--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| request | [SCPluginRegisterRequest](https://openstapps.gitlab.io/core/modules/_index.d_.html#scpluginregisterrequest) | +| response | [SCPluginRegisterResponse](https://openstapps.gitlab.io/core/interfaces/_index.d_.scpluginregisterresponse.html) | +| success code | 200 | +| errors | [SCInternalServerErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scinternalservererrorresponse.html)
[SCMethodNotAllowedErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scmethodnotallowederrorresponse.html)
[SCNotFoundErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scnotfounderrorresponse.html)
[SCParametersNotAcceptable](https://openstapps.gitlab.io/core/classes/_index.d_.scparametersnotacceptable.html)
[SCPluginAlreadyRegisteredErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scpluginalreadyregisterederrorresponse.html)
[SCPluginRegisteringFailedErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scpluginregisteringfailederrorresponse.html)
[SCRequestBodyTooLargeErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.screquestbodytoolargeerrorresponse.html)
[SCSyntaxErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scsyntaxerrorresponse.html) | ## `POST /search` [Search route](https://openstapps.gitlab.io/core/classes/_index.d_.scsearchroute.html) @@ -146,12 +146,12 @@ This checks if a book is available in a library.
### Definition -| parameter | value | -| --- | --- | -| request | [SCSearchRequest](https://openstapps.gitlab.io/core/interfaces/_index.d_.scsearchrequest.html) | -| response | [SCSearchResponse](https://openstapps.gitlab.io/core/interfaces/_index.d_.scsearchresponse.html) | -| success code | 200 | -| errors | [SCInternalServerErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scinternalservererrorresponse.html)
[SCMethodNotAllowedErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scmethodnotallowederrorresponse.html)
[SCRequestBodyTooLargeErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.screquestbodytoolargeerrorresponse.html)
[SCSyntaxErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scsyntaxerrorresponse.html)
[SCUnsupportedMediaTypeErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scunsupportedmediatypeerrorresponse.html)
[SCValidationErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scvalidationerrorresponse.html) | +| parameter | value | +|--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| request | [SCSearchRequest](https://openstapps.gitlab.io/core/interfaces/_index.d_.scsearchrequest.html) | +| response | [SCSearchResponse](https://openstapps.gitlab.io/core/interfaces/_index.d_.scsearchresponse.html) | +| success code | 200 | +| errors | [SCInternalServerErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scinternalservererrorresponse.html)
[SCMethodNotAllowedErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scmethodnotallowederrorresponse.html)
[SCRequestBodyTooLargeErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.screquestbodytoolargeerrorresponse.html)
[SCSyntaxErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scsyntaxerrorresponse.html)
[SCUnsupportedMediaTypeErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scunsupportedmediatypeerrorresponse.html)
[SCValidationErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scvalidationerrorresponse.html) | ## `PUT /:TYPE/:UID` [Thing update route](https://openstapps.gitlab.io/core/classes/_index.d_.scthingupdateroute.html) @@ -162,11 +162,11 @@ This checks if a book is available in a library.
### Definition -| parameter | value | -| --- | --- | -| request | [SCThingUpdateRequest](https://openstapps.gitlab.io/core/modules/_index.d_.html#scthingupdaterequest) | -| response | [SCThingUpdateResponse](https://openstapps.gitlab.io/core/interfaces/_index.d_.scthingupdateresponse.html) | -| success code | 200 | -| errors | [SCInternalServerErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scinternalservererrorresponse.html)
[SCMethodNotAllowedErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scmethodnotallowederrorresponse.html)
[SCNotFoundErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scnotfounderrorresponse.html)
[SCRequestBodyTooLargeErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.screquestbodytoolargeerrorresponse.html)
[SCSyntaxErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scsyntaxerrorresponse.html)
[SCUnsupportedMediaTypeErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scunsupportedmediatypeerrorresponse.html)
[SCValidationErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scvalidationerrorresponse.html) | -| obligatory parameters |
parametertype
TYPESCThingTypes
UID[SCUuid](https://openstapps.gitlab.io/core/modules/_index.d_.html#scuuid)
| +| parameter | value | +|-----------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| request | [SCThingUpdateRequest](https://openstapps.gitlab.io/core/modules/_index.d_.html#scthingupdaterequest) | +| response | [SCThingUpdateResponse](https://openstapps.gitlab.io/core/interfaces/_index.d_.scthingupdateresponse.html) | +| success code | 200 | +| errors | [SCInternalServerErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scinternalservererrorresponse.html)
[SCMethodNotAllowedErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scmethodnotallowederrorresponse.html)
[SCNotFoundErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scnotfounderrorresponse.html)
[SCRequestBodyTooLargeErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.screquestbodytoolargeerrorresponse.html)
[SCSyntaxErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scsyntaxerrorresponse.html)
[SCUnsupportedMediaTypeErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scunsupportedmediatypeerrorresponse.html)
[SCValidationErrorResponse](https://openstapps.gitlab.io/core/classes/_index.d_.scvalidationerrorresponse.html) | +| obligatory parameters |
parametertype
TYPESCThingTypes
UID[SCUuid](https://openstapps.gitlab.io/core/modules/_index.d_.html#scuuid)
| diff --git a/package-lock.json b/package-lock.json index 5e3ddf82..25a5428d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,15 +23,15 @@ } }, "@babel/compat-data": { - "version": "7.17.10", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.10.tgz", - "integrity": "sha512-GZt/TCsG70Ms19gfZO1tM4CVnXsPgEPBCpJu+Qz3L0LUDsY5nZqFZglIoPC1kIYOtNBZlrnFT+klg12vFGZXrw==", + "version": "7.18.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.18.5.tgz", + "integrity": "sha512-BxhE40PVCBxVEJsSBhB6UWyAuqJRxGsAw8BdHMJ3AKGydcwuWW4kOO3HmqBQAdcq/OP+/DlTVxLvsCzRTnZuGg==", "dev": true }, "@babel/core": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.2.tgz", - "integrity": "sha512-A8pri1YJiC5UnkdrWcmfZTJTV85b4UXTAfImGmCfYmax4TR9Cw8sDS0MOk++Gp2mE/BefVJ5nwy5yzqNJbP/DQ==", + "version": "7.18.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.5.tgz", + "integrity": "sha512-MGY8vg3DxMnctw0LdvSEojOsumc70g0t18gNyUdAZqB1Rpd1Bqo/svHGvt+UJ6JcGX+DIekGFDxxIWofBxLCnQ==", "dev": true, "requires": { "@ampproject/remapping": "^2.1.0", @@ -40,10 +40,10 @@ "@babel/helper-compilation-targets": "^7.18.2", "@babel/helper-module-transforms": "^7.18.0", "@babel/helpers": "^7.18.2", - "@babel/parser": "^7.18.0", + "@babel/parser": "^7.18.5", "@babel/template": "^7.16.7", - "@babel/traverse": "^7.18.2", - "@babel/types": "^7.18.2", + "@babel/traverse": "^7.18.5", + "@babel/types": "^7.18.4", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -71,12 +71,12 @@ }, "dependencies": { "@jridgewell/gen-mapping": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.1.tgz", - "integrity": "sha512-GcHwniMlA2z+WFPWuY8lp3fsza0I8xPFMWL5+n8LYyP6PSvPrXf4+n8stDHZY2DM0zy9sVkRDy1jDI4XGzYVqg==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", "dev": true, "requires": { - "@jridgewell/set-array": "^1.0.0", + "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.9" } @@ -237,7 +237,7 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" }, "supports-color": { "version": "5.5.0", @@ -250,9 +250,9 @@ } }, "@babel/parser": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.3.tgz", - "integrity": "sha512-rL50YcEuHbbauAFAysNsJA4/f89fGTOBRNs9P81sniKnKAr4xULe5AecolcsKbi88xu0ByWYDj/S1AJ3FSFuSQ==", + "version": "7.18.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.5.tgz", + "integrity": "sha512-YZWVaglMiplo7v8f1oMQ5ZPQr0vn7HPeZXxXWsxXJRjGVrzUFn9OxFQl1sb5wzfootjA/yChhW84BV+383FSOw==", "dev": true }, "@babel/template": { @@ -267,9 +267,9 @@ } }, "@babel/traverse": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.2.tgz", - "integrity": "sha512-9eNwoeovJ6KH9zcCNnENY7DMFwTU9JdGCFtqNLfUAqtUHRCOsTOqWoffosP8vKmNYeSBUv3yVJXjfd8ucwOjUA==", + "version": "7.18.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.5.tgz", + "integrity": "sha512-aKXj1KT66sBj0vVzk6rEeAO6Z9aiiQ68wfDgge3nHhA/my6xMM/7HGQUNumKZaoa2qUPQ5whJG9aAifsxUKfLA==", "dev": true, "requires": { "@babel/code-frame": "^7.16.7", @@ -278,8 +278,8 @@ "@babel/helper-function-name": "^7.17.9", "@babel/helper-hoist-variables": "^7.16.7", "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/parser": "^7.18.0", - "@babel/types": "^7.18.2", + "@babel/parser": "^7.18.5", + "@babel/types": "^7.18.4", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -293,9 +293,9 @@ } }, "@babel/types": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.2.tgz", - "integrity": "sha512-0On6B8A4/+mFUto5WERt3EEuG1NznDirvwca1O8UwXQHVY8g3R7OzYgxXdOfMwLO08UrpUD/2+3Bclyq+/C94Q==", + "version": "7.18.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.4.tgz", + "integrity": "sha512-ThN1mBcMq5pG/Vm2IcBmPPfyPXbd8S02rS+OBIDENdufvqC7Z/jHPCv9IcP01277aKtDI8g/2XysBN4hA8niiw==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.16.7", @@ -324,6 +324,17 @@ "secure-json-parse": "^2.1.0" } }, + "@es-joy/jsdoccomment": { + "version": "0.31.0", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.31.0.tgz", + "integrity": "sha512-tc1/iuQcnaiSIUVad72PBierDFpsxdUHtEF/OrfqvM1CBAsIoMP51j52jTMb3dXriwhieTo289InzZj72jL3EQ==", + "dev": true, + "requires": { + "comment-parser": "1.3.1", + "esquery": "^1.4.0", + "jsdoc-type-pratt-parser": "~3.1.0" + } + }, "@eslint/eslintrc": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", @@ -446,20 +457,20 @@ } }, "@jridgewell/resolve-uri": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.7.tgz", - "integrity": "sha512-8cXDaBBHOr2pQ7j77Y6Vp5VDT2sIqWyWQ56TjEq4ih/a4iST3dItRe8Q9fp0rrIl9DoKhWQtUQz/YpOxLkXbNA==" + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.8.tgz", + "integrity": "sha512-YK5G9LaddzGbcucK4c8h5tWFmMPBvRZ/uyWmN1/SbBdIvqGUdWGkJ5BAaccgs6XbzVLsqbPJrBSFwKv3kT9i7w==" }, "@jridgewell/set-array": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.1.tgz", - "integrity": "sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", "dev": true }, "@jridgewell/sourcemap-codec": { - "version": "1.4.13", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.13.tgz", - "integrity": "sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w==" + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" }, "@jridgewell/trace-mapping": { "version": "0.3.9", @@ -494,50 +505,56 @@ } }, "@npmcli/fs": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz", - "integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.0.tgz", + "integrity": "sha512-DmfBvNXGaetMxj9LTp8NAN9vEidXURrf5ZTslQzEAi/6GbW+4yjaLFQc6Tue5cpZ9Frlk4OBo/Snf1Bh/S7qTQ==", "requires": { - "@gar/promisify": "^1.0.1", + "@gar/promisify": "^1.1.3", "semver": "^7.3.5" } }, "@npmcli/move-file": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", - "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-2.0.0.tgz", + "integrity": "sha512-UR6D5f4KEGWJV6BGPH3Qb2EtgH+t+1XQ1Tt85c7qicN6cezzuHPdZwwAxqZr4JLtnQu0LZsTza/5gmNmSl8XLg==", "requires": { "mkdirp": "^1.0.4", "rimraf": "^3.0.2" } }, "@openstapps/configuration": { - "version": "0.29.1", - "resolved": "https://registry.npmjs.org/@openstapps/configuration/-/configuration-0.29.1.tgz", - "integrity": "sha512-H6DNB1HrujC5LwOF17rYkXQPFaEWTaA5T3IPsfccSuKHSUhB0ry6V5OkMwmvls2nOSrbpuRpyQoM7ulwZ9X9Bw==", + "version": "0.32.0", + "resolved": "https://registry.npmjs.org/@openstapps/configuration/-/configuration-0.32.0.tgz", + "integrity": "sha512-tvM2xsdBoBNlsz3R6veldI45mrGbBhq9sBA+E5DI7mSHC8kP42PJvZ5t24vM3ze6LIcLXSeB5n3LhxIFHgpuHA==", "dev": true, "requires": { "@types/node": "14.18.18", "@types/semver": "7.3.9", "@types/yaml": "1.9.7", "chalk": "4.1.2", - "commander": "9.2.0", + "commander": "9.3.0", "semver": "7.3.7", - "tslint": "6.1.3", - "tslint-eslint-rules": "5.4.0", "yaml": "1.10.2" + }, + "dependencies": { + "@types/node": { + "version": "14.18.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.18.tgz", + "integrity": "sha512-B9EoJFjhqcQ9OmQrNorItO+OwEOORNn3S31WuiHvZY/dm9ajkB7AKD/8toessEtHHNL+58jofbq7hMMY9v4yig==", + "dev": true + } } }, "@openstapps/core": { - "version": "0.66.1", - "resolved": "https://registry.npmjs.org/@openstapps/core/-/core-0.66.1.tgz", - "integrity": "sha512-+B6ZIP9vsllz89pfBu8j9E94QSGQMthhndVLNYT7VkXszxfICC13gE25WOM6asrgYqmIaYQyR3MxRyWrHA11fg==", + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/@openstapps/core/-/core-0.68.0.tgz", + "integrity": "sha512-y6Bg4HO4rNWZHzoLEUhpuNLWtaBomm5RPshHoCh2sKakTqYdYaptgNYOCdpllTGm8Nsvft/P7Ag3phiStqVssw==", "requires": { - "@openstapps/core-tools": "0.30.1", + "@openstapps/core-tools": "0.31.0", "@types/geojson": "1.0.6", "@types/json-patch": "0.0.30", "@types/json-schema": "7.0.11", - "@types/node": "14.18.18", + "@types/node": "14.18.21", "fast-deep-equal": "3.1.3", "http-status-codes": "2.2.0", "json-patch": "0.7.0", @@ -547,46 +564,46 @@ } }, "@openstapps/core-tools": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@openstapps/core-tools/-/core-tools-0.30.1.tgz", - "integrity": "sha512-dNJCqlYE6ihMWQm5lBkts5Xr83EBWE7jG9ErK2rwxIorlyFT7lAn7qTRp7vzbT/vBqKueqYQVswvDYfznBru4Q==", + "version": "0.31.0", + "resolved": "https://registry.npmjs.org/@openstapps/core-tools/-/core-tools-0.31.0.tgz", + "integrity": "sha512-XQF1ORI1h4XsYGvrD4WtpEaNjdtv0ClLtqpDbginhhtHdyjfjAX3qkxFpZkI6fbZyw64fRFLV2JRGGGjwhevag==", "requires": { "@openstapps/logger": "0.8.1", - "ajv": "8.8.2", - "better-ajv-errors": "1.1.2", + "ajv": "8.11.0", + "better-ajv-errors": "1.2.0", "chai": "4.3.6", - "commander": "9.2.0", + "commander": "9.3.0", "deepmerge": "4.2.2", "del": "6.1.1", - "eslint": "8.16.0", + "eslint": "8.18.0", "flatted": "3.2.5", "fs-extra": "10.1.0", "glob": "8.0.3", - "got": "11.8.3", + "got": "11.8.5", "humanize-string": "3.0.0", "json-schema": "0.4.0", "lodash": "4.17.21", "mustache": "4.2.0", - "openapi-types": "11.0.1", + "openapi-types": "11.1.0", "plantuml-encoder": "1.4.0", - "re2": "1.17.4", + "re2": "1.17.7", "toposort": "2.0.2", "ts-json-schema-generator": "1.0.0", - "ts-node": "10.8.0", + "ts-node": "10.8.1", "typescript": "4.4.4" } }, "@openstapps/es-mapping-generator": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@openstapps/es-mapping-generator/-/es-mapping-generator-0.1.0.tgz", - "integrity": "sha512-gPUo8twVEOdx3nWghzsROD+1fIVL8uPM7yAzbBP4MWE/pu45kpJqL6KaJj0XPXu6exC+yjuwT5GPMmNaJApA8w==", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@openstapps/es-mapping-generator/-/es-mapping-generator-0.2.0.tgz", + "integrity": "sha512-tnwl8iR+YJWfK8ZJkif831DItyG+Y8rQn/ySrIGnTDJmqN2ZM0YoF1a0BiwP72oC8Rf5+H4J0JiFZAmo/sFVSA==", "dev": true, "requires": { "@openstapps/logger": "0.8.1", - "commander": "9.2.0", + "commander": "9.3.0", "deepmerge": "4.2.2", "flatted": "3.2.5", - "got": "11.8.3", + "got": "11.8.5", "typedoc": "0.18.0", "typescript": "3.8.3" }, @@ -629,6 +646,12 @@ } } }, + "@openstapps/eslint-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@openstapps/eslint-config/-/eslint-config-1.1.0.tgz", + "integrity": "sha512-yhSWgzKB5cU3kTtWdAOEO6y4PjLDBnyJc+Dpmz9Rxg97WSViOiz3Bv9BWTSl0TR56GAnFi0NI8K56RfCqjpk5w==", + "dev": true + }, "@openstapps/logger": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@openstapps/logger/-/logger-0.8.1.tgz", @@ -640,6 +663,13 @@ "flatted": "3.2.5", "moment": "2.29.3", "nodemailer": "6.7.5" + }, + "dependencies": { + "@types/node": { + "version": "14.18.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.18.tgz", + "integrity": "sha512-B9EoJFjhqcQ9OmQrNorItO+OwEOORNn3S31WuiHvZY/dm9ajkB7AKD/8toessEtHHNL+58jofbq7hMMY9v4yig==" + } } }, "@sindresorhus/is": { @@ -706,29 +736,29 @@ } }, "@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==" }, "@tsconfig/node10": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", - "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==" + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==" }, "@tsconfig/node12": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", - "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==" + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" }, "@tsconfig/node14": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", - "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" }, "@tsconfig/node16": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", - "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==" }, "@types/body-parser": { "version": "1.19.2", @@ -817,9 +847,9 @@ } }, "@types/express-serve-static-core": { - "version": "4.17.28", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz", - "integrity": "sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==", + "version": "4.17.29", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.29.tgz", + "integrity": "sha512-uMd++6dMKS32EOuw1Uli3e3BPgdLIXmezcfHv7N4c1s3gkhikBplORPpMq3fuWkxncZN1reb16d5n8yhQ80x7Q==", "requires": { "@types/node": "*", "@types/qs": "*", @@ -886,9 +916,9 @@ } }, "@types/node": { - "version": "14.18.18", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.18.tgz", - "integrity": "sha512-B9EoJFjhqcQ9OmQrNorItO+OwEOORNn3S31WuiHvZY/dm9ajkB7AKD/8toessEtHHNL+58jofbq7hMMY9v4yig==" + "version": "14.18.21", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.21.tgz", + "integrity": "sha512-x5W9s+8P4XteaxT/jKF0PSb7XEvo5VmqEWgsMlyeY4ZlLK8I6aH6g5TPPyDlLAep+GYf4kefb7HFyc7PAO3m+Q==" }, "@types/node-cron": { "version": "3.0.1", @@ -1008,6 +1038,119 @@ "yaml": "*" } }, + "@typescript-eslint/eslint-plugin": { + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.29.0.tgz", + "integrity": "sha512-kgTsISt9pM53yRFQmLZ4npj99yGl3x3Pl7z4eA66OuTzAGC4bQB5H5fuLwPnqTKU3yyrrg4MIhjF17UYnL4c0w==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "5.29.0", + "@typescript-eslint/type-utils": "5.29.0", + "@typescript-eslint/utils": "5.29.0", + "debug": "^4.3.4", + "functional-red-black-tree": "^1.0.1", + "ignore": "^5.2.0", + "regexpp": "^3.2.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/parser": { + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.29.0.tgz", + "integrity": "sha512-ruKWTv+x0OOxbzIw9nW5oWlUopvP/IQDjB5ZqmTglLIoDTctLlAJpAQFpNPJP/ZI7hTT9sARBosEfaKbcFuECw==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "5.29.0", + "@typescript-eslint/types": "5.29.0", + "@typescript-eslint/typescript-estree": "5.29.0", + "debug": "^4.3.4" + } + }, + "@typescript-eslint/scope-manager": { + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.29.0.tgz", + "integrity": "sha512-etbXUT0FygFi2ihcxDZjz21LtC+Eps9V2xVx09zFoN44RRHPrkMflidGMI+2dUs821zR1tDS6Oc9IXxIjOUZwA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.29.0", + "@typescript-eslint/visitor-keys": "5.29.0" + } + }, + "@typescript-eslint/type-utils": { + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.29.0.tgz", + "integrity": "sha512-JK6bAaaiJozbox3K220VRfCzLa9n0ib/J+FHIwnaV3Enw/TO267qe0pM1b1QrrEuy6xun374XEAsRlA86JJnyg==", + "dev": true, + "requires": { + "@typescript-eslint/utils": "5.29.0", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/types": { + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.29.0.tgz", + "integrity": "sha512-X99VbqvAXOMdVyfFmksMy3u8p8yoRGITgU1joBJPzeYa0rhdf5ok9S56/itRoUSh99fiDoMtarSIJXo7H/SnOg==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.29.0.tgz", + "integrity": "sha512-mQvSUJ/JjGBdvo+1LwC+GY2XmSYjK1nAaVw2emp/E61wEVYEyibRHCqm1I1vEKbXCpUKuW4G7u9ZCaZhJbLoNQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.29.0", + "@typescript-eslint/visitor-keys": "5.29.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/utils": { + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.29.0.tgz", + "integrity": "sha512-3Eos6uP1nyLOBayc/VUdKZikV90HahXE5Dx9L5YlSd/7ylQPXhLk1BYb29SDgnBnTp+jmSZUU0QxUiyHgW4p7A==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.29.0", + "@typescript-eslint/types": "5.29.0", + "@typescript-eslint/typescript-estree": "5.29.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "dependencies": { + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + } + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.29.0.tgz", + "integrity": "sha512-Hpb/mCWsjILvikMQoZIE3voc9wtQcS0A9FUw3h8bhr9UxBdtI/tw1ZDZUOXHXLOVMedKCH5NxyzATwnU78bWCQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.29.0", + "eslint-visitor-keys": "^3.3.0" + } + }, "@ungap/promise-all-settled": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", @@ -1087,9 +1230,9 @@ } }, "ajv": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.2.tgz", - "integrity": "sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", "requires": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -1236,9 +1379,9 @@ } }, "better-ajv-errors": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/better-ajv-errors/-/better-ajv-errors-1.1.2.tgz", - "integrity": "sha512-xpFTC7JqkSGkvchJlH4IFtmwZ5SXomh0FqbEVEHRcXl/aiHh9nM/dnNnGTlxjrFCjWOVLLWpcNW1Hcrzs55/lg==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/better-ajv-errors/-/better-ajv-errors-1.2.0.tgz", + "integrity": "sha512-UW+IsFycygIo7bclP9h5ugkNH8EjCSgqyFB/yQ4Hqqa1OEYDtb0uFIkYE0b6+CjkgJYVM5UKI/pJPxjYe9EZlA==", "requires": { "@babel/code-frame": "^7.16.0", "@humanwhocodes/momoa": "^2.0.2", @@ -1254,9 +1397,9 @@ "dev": true }, "bintrees": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.1.tgz", - "integrity": "sha512-tbaUB1QpTIj4cKY8c1rvNAvEQXA+ekzHmbe4jzNfW3QWsF9GnnP/BRWyl6/qqS53heoYJ93naaFcm/jooONH8g==" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.2.tgz", + "integrity": "sha512-VOMgTMwjAaUG580SXn3LacVgjurrbMme7ZZNYGSSV7mmtY6QQRh0Eg3pwIcntQ77DErK1L0NxkbetjcoXzVwKw==" }, "body-parser": { "version": "1.20.0", @@ -1301,7 +1444,7 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" } } }, @@ -1329,22 +1472,21 @@ "dev": true }, "browserslist": { - "version": "4.20.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.3.tgz", - "integrity": "sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg==", + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.0.tgz", + "integrity": "sha512-UQxE0DIhRB5z/zDz9iA03BOfxaN2+GQdBYH/2WrSIWEUrnpzTPJbhqt+umq6r3acaPRTW1FNTkrcp0PXgtFkvA==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001332", - "electron-to-chromium": "^1.4.118", - "escalade": "^3.1.1", - "node-releases": "^2.0.3", - "picocolors": "^1.0.0" + "caniuse-lite": "^1.0.30001358", + "electron-to-chromium": "^1.4.164", + "node-releases": "^2.0.5", + "update-browserslist-db": "^1.0.0" } }, "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha512-wxXCdllwGhI2kCC0MnvTGYTMvnVZTvqgypkiTI8Pa5tcz2i6VqsqwYGgqwXji+4RgCzms6EajE4IxiUH6HH8nQ==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", "dev": true }, "bytes": { @@ -1353,43 +1495,28 @@ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" }, "cacache": { - "version": "15.3.0", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz", - "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==", + "version": "16.1.1", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.1.1.tgz", + "integrity": "sha512-VDKN+LHyCQXaaYZ7rA/qtkURU+/yYhviUdvqEv2LT6QPZU8jpyzEkEVAcKlKLt5dJ5BRp11ym8lo3NKLluEPLg==", "requires": { - "@npmcli/fs": "^1.0.0", - "@npmcli/move-file": "^1.0.1", + "@npmcli/fs": "^2.1.0", + "@npmcli/move-file": "^2.0.0", "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "glob": "^7.1.4", + "fs-minipass": "^2.1.0", + "glob": "^8.0.1", "infer-owner": "^1.0.4", - "lru-cache": "^6.0.0", - "minipass": "^3.1.1", + "lru-cache": "^7.7.1", + "minipass": "^3.1.6", "minipass-collect": "^1.0.2", "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.2", - "mkdirp": "^1.0.3", + "minipass-pipeline": "^1.2.4", + "mkdirp": "^1.0.4", "p-map": "^4.0.0", "promise-inflight": "^1.0.1", "rimraf": "^3.0.2", - "ssri": "^8.0.1", - "tar": "^6.0.2", + "ssri": "^9.0.0", + "tar": "^6.1.11", "unique-filename": "^1.1.1" - }, - "dependencies": { - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } } }, "cacheable-lookup": { @@ -1463,9 +1590,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001344", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001344.tgz", - "integrity": "sha512-0ZFjnlCaXNOAYcV7i+TtdKBp0L/3XEU2MF/x6Du1lrh+SRX4IfzIVL4HNJg5pB2PmFb8rszIGyOvsZnqqRoc2g==", + "version": "1.0.30001359", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001359.tgz", + "integrity": "sha512-Xln/BAsPzEuiVLgJ2/45IaqD9jShtk3Y33anKb4+yLwQzws3+v6odKfpgES/cDEaZMLzSChpIGdbOYtH9MyuHw==", "dev": true }, "chai": { @@ -1532,6 +1659,21 @@ "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" }, + "ci-info": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.2.tgz", + "integrity": "sha512-xmDt/QIAdeZ9+nfdPsaBCpMvHNLFiLdjj59qjqn+6iPe6YmHGQ35sBnQ8uslRBXFmXkiZQOJRjvQeoGppoTjjg==", + "dev": true + }, + "clean-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", + "integrity": "sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, "clean-stack": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", @@ -1596,9 +1738,15 @@ } }, "commander": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.2.0.tgz", - "integrity": "sha512-e2i4wANQiSXgnrBlIatyHtP1odfUp0BbV5Y5nEGbxtIrStkEOAAzCUirvLBNXHLr7kwLvJl6V+4V3XV9x7Wd9w==" + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.3.0.tgz", + "integrity": "sha512-hv95iU5uXPbK83mjrJKuZyFM/LBAoCV/XhVGkS5Je6tl7sxr6A0ITMw5WoRV46/UaJ46Nllm3Xt7IaJhXTIkzw==" + }, + "comment-parser": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.3.1.tgz", + "integrity": "sha512-B52sN2VNghyq5ofvUsqZjmk6YkihBX5vMSChmSK9v4ShjKf3Vk5Xcmgpw4o+iIgtrnM/u5FiMpz9VKb8lpBveA==", + "dev": true }, "commondir": { "version": "1.0.1", @@ -1952,7 +2100,7 @@ "decamelize-keys": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", - "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", + "integrity": "sha512-ocLWuYzRPoS9bfiSdDd3cxvrzovVMZnRDVEzAs+hWIVXGDbHxWMECij2OBuyB/An0FFW/nLuq6Kv1i/YC5Qfzg==", "dev": true, "requires": { "decamelize": "^1.1.0", @@ -1962,13 +2110,13 @@ "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", "dev": true }, "map-obj": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", "dev": true } } @@ -2039,18 +2187,18 @@ "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "dev": true }, "delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" }, "depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==" }, "destroy": { "version": "1.2.0", @@ -2060,7 +2208,7 @@ "dezalgo": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.3.tgz", - "integrity": "sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY=", + "integrity": "sha512-K7i4zNfT2kgQz3GylDw40ot9GAE47sFZ9EXHFSPP6zONLgH6kWXE0KWJchkbQJLBkRazq4APwZ4OwiFFlT95OQ==", "dev": true, "requires": { "asap": "^2.0.0", @@ -2100,12 +2248,12 @@ "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "electron-to-chromium": { - "version": "1.4.140", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.140.tgz", - "integrity": "sha512-NLz5va823QfJBYOO/hLV4AfU4Crmkl/6Hl2pH3qdJcmi0ySZ3YTWHxOlDm3uJOFBEPy3pIhu8gKQo6prQTWKKA==", + "version": "1.4.170", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.170.tgz", + "integrity": "sha512-rZ8PZLhK4ORPjFqLp9aqC4/S1j4qWFsPPz13xmWdrbBkU/LlxMcok+f+6f8YnQ57MiZwKtOaW15biZZsY5Igvw==", "dev": true }, "emoji-regex": { @@ -2116,7 +2264,7 @@ "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" }, "encoding": { "version": "0.1.13", @@ -2169,17 +2317,17 @@ "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" }, "eslint": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.16.0.tgz", - "integrity": "sha512-MBndsoXY/PeVTDJeWsYj7kLZ5hQpJOfMYLsF6LicLHQWbRDG19lK5jOix4DPl8yY4SUFcE3txy86OzFLWT+yoA==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.18.0.tgz", + "integrity": "sha512-As1EfFMVk7Xc6/CvhssHUjsAQSkpfXvUGMFC3ce8JDe6WvqCgRrLOBQbVpsBFr1X1V+RACOadnzVvcUS5ni2bA==", "requires": { "@eslint/eslintrc": "^1.3.0", "@humanwhocodes/config-array": "^0.9.2", @@ -2249,6 +2397,131 @@ } } }, + "eslint-config-prettier": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz", + "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==", + "dev": true + }, + "eslint-plugin-jsdoc": { + "version": "39.3.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-39.3.3.tgz", + "integrity": "sha512-K/DAjKRUNaUTf0KQhI9PvsF+Y3mGDx/j0pofXsJCQe/tmRsRweBIXR353c8nAro0lytZYEf7l0PluBpzKDiHxw==", + "dev": true, + "requires": { + "@es-joy/jsdoccomment": "~0.31.0", + "comment-parser": "1.3.1", + "debug": "^4.3.4", + "escape-string-regexp": "^4.0.0", + "esquery": "^1.4.0", + "semver": "^7.3.7", + "spdx-expression-parse": "^3.0.1" + }, + "dependencies": { + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + } + } + }, + "eslint-plugin-prettier": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.1.0.tgz", + "integrity": "sha512-A3AXIEfTnq3D5qDFjWJdQ9c4BLhw/TqhSR+6+SVaoPJBAWciFEuJiNQh275OnjRrAi7yssZzuWBRw66VG2g6UA==", + "dev": true, + "requires": { + "prettier-linter-helpers": "^1.0.0" + } + }, + "eslint-plugin-unicorn": { + "version": "42.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-42.0.0.tgz", + "integrity": "sha512-ixBsbhgWuxVaNlPTT8AyfJMlhyC5flCJFjyK3oKE8TRrwBnaHvUbuIkCM1lqg8ryYrFStL/T557zfKzX4GKSlg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.15.7", + "ci-info": "^3.3.0", + "clean-regexp": "^1.0.0", + "eslint-utils": "^3.0.0", + "esquery": "^1.4.0", + "indent-string": "^4.0.0", + "is-builtin-module": "^3.1.0", + "lodash": "^4.17.21", + "pluralize": "^8.0.0", + "read-pkg-up": "^7.0.1", + "regexp-tree": "^0.1.24", + "safe-regex": "^2.1.1", + "semver": "^7.3.5", + "strip-indent": "^3.0.0" + }, + "dependencies": { + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } + } + }, "eslint-scope": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", @@ -2323,7 +2596,7 @@ "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" }, "express": { "version": "4.18.1", @@ -2379,7 +2652,7 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "safe-buffer": { "version": "5.2.1", @@ -2413,6 +2686,12 @@ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, "fast-glob": { "version": "3.2.11", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", @@ -2433,7 +2712,7 @@ "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" }, "fast-safe-stringify": { "version": "2.1.1", @@ -2490,7 +2769,7 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" } } }, @@ -2584,12 +2863,12 @@ "fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" }, "from2": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==", "requires": { "inherits": "^2.0.1", "readable-stream": "^2.0.0" @@ -2622,7 +2901,7 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "fsevents": { "version": "2.3.2", @@ -2639,7 +2918,7 @@ "functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==" }, "gauge": { "version": "4.0.4", @@ -3152,16 +3431,16 @@ "get-func-name": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=" + "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==" }, "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", + "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", "requires": { "function-bind": "^1.1.1", "has": "^1.0.3", - "has-symbols": "^1.0.1" + "has-symbols": "^1.0.3" } }, "get-package-type": { @@ -3224,7 +3503,7 @@ "git-remote-origin-url": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz", - "integrity": "sha1-UoJlna4hBxRaERJhEq0yFuxfpl8=", + "integrity": "sha512-eU+GGrZgccNJcsDH5LkXR3PB9M958hxc7sbA8DFJjrv9j4L2P/eZfKhM+QD6wyzpiv+b1BpK0XrYCxkovtjSLw==", "dev": true, "requires": { "gitconfiglocal": "^1.0.0", @@ -3252,7 +3531,7 @@ "gitconfiglocal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz", - "integrity": "sha1-QdBF84UaXqiPA/JMocYXgRRGS5s=", + "integrity": "sha512-spLUXeTAVHxDtKsJc8FkFVgFtMdEN9qPGpL23VfSHx4fP4+Ds097IXLvymbnDH8FnmxX5Nr9bPw3A+AQ6mWEaQ==", "dev": true, "requires": { "ini": "^1.3.2" @@ -3318,9 +3597,9 @@ } }, "got": { - "version": "11.8.3", - "resolved": "https://registry.npmjs.org/got/-/got-11.8.3.tgz", - "integrity": "sha512-7gtQ5KiPh1RtGS9/Jbv1ofDpBFuq42gyfEib+ejaRBJuj/3tQFeR5+gw57e4ipaU8c/rCjvX6fkQz2lyDlGAOg==", + "version": "11.8.5", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.5.tgz", + "integrity": "sha512-o0Je4NvQObAuZPHLFoRSkdG2lTgtcynqymzg2Vupdx6PorhaT5MCbIyXG6d4D94kk8ZG57QeosgdiqfJWhEhlQ==", "requires": { "@sindresorhus/is": "^4.0.0", "@szmarczak/http-timer": "^4.0.5", @@ -3395,7 +3674,7 @@ "has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" }, "hasha": { "version": "5.2.2", @@ -3440,6 +3719,17 @@ "dev": true, "requires": { "lru-cache": "^6.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + } } }, "html-escaper": { @@ -3473,11 +3763,11 @@ } }, "http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", "requires": { - "@tootallnate/once": "1", + "@tootallnate/once": "2", "agent-base": "6", "debug": "4" } @@ -3508,7 +3798,7 @@ "humanize-ms": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", - "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", "requires": { "ms": "^2.0.0" } @@ -3547,7 +3837,7 @@ "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==" }, "indent-string": { "version": "4.0.0", @@ -3562,7 +3852,7 @@ "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "requires": { "once": "^1.3.0", "wrappy": "1" @@ -3580,9 +3870,9 @@ "dev": true }, "install-artifact-from-github": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/install-artifact-from-github/-/install-artifact-from-github-1.3.0.tgz", - "integrity": "sha512-iT8v1GwOAX0pPXifF/5ihnMhHOCo3OeK7z3TQa4CtSNCIg8k0UxqBEk9jRwz8OP68hHXvJ2gxRa89KYHtBkqGA==" + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/install-artifact-from-github/-/install-artifact-from-github-1.3.1.tgz", + "integrity": "sha512-3l3Bymg2eKDsN5wQuMfgGEj2x6l5MCAv0zPL6rxHESufFVlEAKW/6oY9F1aGgvY/EgWm5+eWGRjINveL4X7Hgg==" }, "interpret": { "version": "1.4.0", @@ -3612,7 +3902,7 @@ "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true }, "is-binary-path": { @@ -3624,6 +3914,15 @@ "binary-extensions": "^2.0.0" } }, + "is-builtin-module": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.1.0.tgz", + "integrity": "sha512-OV7JjAgOTfAFJmHZLvpSTb4qi0nIILDV1gWPYDnDJUTNFM5aGlRAhk4QcT8i7TuAleeEV5Fdkqn3t4mS+Q11fg==", + "dev": true, + "requires": { + "builtin-modules": "^3.0.0" + } + }, "is-core-module": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", @@ -3636,7 +3935,7 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" }, "is-fullwidth-code-point": { "version": "3.0.0", @@ -3654,7 +3953,7 @@ "is-lambda": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", - "integrity": "sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU=" + "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==" }, "is-number": { "version": "7.0.0", @@ -3680,7 +3979,7 @@ "is-plain-obj": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", "dev": true }, "is-promise": { @@ -3697,7 +3996,7 @@ "is-text-path": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", - "integrity": "sha1-Thqg+1G/vLPpJogAE5cgLBd1tm4=", + "integrity": "sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==", "dev": true, "requires": { "text-extensions": "^1.0.0" @@ -3706,7 +4005,7 @@ "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", "dev": true }, "is-unicode-supported": { @@ -3724,12 +4023,12 @@ "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "istanbul-lib-coverage": { "version": "3.2.0", @@ -3767,18 +4066,17 @@ } }, "istanbul-lib-processinfo": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz", - "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.3.tgz", + "integrity": "sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==", "dev": true, "requires": { "archy": "^1.0.0", - "cross-spawn": "^7.0.0", - "istanbul-lib-coverage": "^3.0.0-alpha.1", - "make-dir": "^3.0.0", + "cross-spawn": "^7.0.3", + "istanbul-lib-coverage": "^3.2.0", "p-map": "^3.0.0", "rimraf": "^3.0.0", - "uuid": "^3.3.3" + "uuid": "^8.3.2" }, "dependencies": { "p-map": { @@ -3789,12 +4087,6 @@ "requires": { "aggregate-error": "^3.0.0" } - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true } } }, @@ -3843,6 +4135,12 @@ "argparse": "^2.0.1" } }, + "jsdoc-type-pratt-parser": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-3.1.0.tgz", + "integrity": "sha512-MgtD0ZiCDk9B+eI73BextfRrVQl0oyzRG8B2BjORts6jbunj4ScKPcyXGTbB6eXL4y9TzxCm6hyeLq/2ASzNdw==", + "dev": true + }, "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -3884,12 +4182,12 @@ "json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=" + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" }, "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" }, "json5": { "version": "2.2.1", @@ -3914,7 +4212,7 @@ "jsonparse": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", "dev": true }, "jsonpointer": { @@ -3929,9 +4227,9 @@ "dev": true }, "keyv": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.3.0.tgz", - "integrity": "sha512-C30Un9+63J0CsR7Wka5quXKqYZsT6dcRQ2aOwGcSc3RiQ4HGWpTAHlCA+puNfw2jA/s11EsxA1nCXgZRuRKMQQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.3.2.tgz", + "integrity": "sha512-kn8WmodVBe12lmHpA6W8OY7SNh6wVR+Z+wZESF4iF5FCazaVXGWOtnbnvX0tMQ1bO+/TmOD9LziuYMvrIIs0xw==", "requires": { "compress-brotli": "^1.3.8", "json-buffer": "3.0.1" @@ -3946,7 +4244,7 @@ "lazy-ass": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", - "integrity": "sha1-eZllXoZGwX8In90YfRUNMyTVRRM=", + "integrity": "sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==", "dev": true }, "leven": { @@ -3972,7 +4270,7 @@ "load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", "dev": true, "requires": { "graceful-fs": "^4.1.2", @@ -3984,7 +4282,7 @@ "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", "dev": true, "requires": { "error-ex": "^1.3.1", @@ -3994,7 +4292,7 @@ "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", "dev": true } } @@ -4016,18 +4314,18 @@ "lodash.flattendeep": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=" + "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==" }, "lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", "dev": true }, "lodash.ismatch": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", - "integrity": "sha1-dWy1FQyjum8RCFp4hJZF8Yj4Xzc=", + "integrity": "sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==", "dev": true }, "lodash.merge": { @@ -4035,11 +4333,6 @@ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" }, - "lodash.set": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", - "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=" - }, "log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -4064,12 +4357,9 @@ "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" }, "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "requires": { - "yallist": "^4.0.0" - } + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.10.2.tgz", + "integrity": "sha512-9zDbhgmXAUvUMPV81A705K3tVzcPiZL3Bf5/5JC/FjYJlLZ5AJCeqIRFHJqyBppiLosqF+uKB7p8/RDXylqBIw==" }, "lunr": { "version": "2.3.9", @@ -4100,26 +4390,26 @@ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" }, "make-fetch-happen": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz", - "integrity": "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==", + "version": "10.1.8", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.1.8.tgz", + "integrity": "sha512-0ASJbG12Au6+N5I84W+8FhGS6iM8MyzvZady+zaQAu+6IOaESFzCLLD0AR1sAFF3Jufi8bxm586ABN6hWd3k7g==", "requires": { - "agentkeepalive": "^4.1.3", - "cacache": "^15.2.0", + "agentkeepalive": "^4.2.1", + "cacache": "^16.1.0", "http-cache-semantics": "^4.1.0", - "http-proxy-agent": "^4.0.1", + "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.0", "is-lambda": "^1.0.1", - "lru-cache": "^6.0.0", - "minipass": "^3.1.3", + "lru-cache": "^7.7.1", + "minipass": "^3.1.6", "minipass-collect": "^1.0.2", - "minipass-fetch": "^1.3.2", + "minipass-fetch": "^2.0.3", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.2", + "negotiator": "^0.6.3", "promise-retry": "^2.0.1", - "socks-proxy-agent": "^6.0.0", - "ssri": "^8.0.0" + "socks-proxy-agent": "^7.0.0", + "ssri": "^9.0.0" } }, "map-obj": { @@ -4137,7 +4427,7 @@ "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" }, "meow": { "version": "8.1.2", @@ -4232,7 +4522,7 @@ "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" }, "merge2": { "version": "1.4.1", @@ -4242,7 +4532,7 @@ "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" }, "micromatch": { "version": "4.0.5", @@ -4308,9 +4598,9 @@ } }, "minipass": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", - "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.3.tgz", + "integrity": "sha512-N0BOsdFAlNRfmwMhjAsLVWOk7Ljmeb39iqFlsV1At+jqRhSUP9yeof8FyJu4imaJiSUp8vQebWD/guZwGQC8iA==", "requires": { "yallist": "^4.0.0" } @@ -4324,14 +4614,14 @@ } }, "minipass-fetch": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz", - "integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.0.tgz", + "integrity": "sha512-H9U4UVBGXEyyWJnqYDCLp1PwD8XIkJ4akNHp1aGVI+2Ym7wQMlxDKi4IB4JbmyU+pl9pEs/cVrK6cOuvmbK4Sg==", "requires": { - "encoding": "^0.1.12", - "minipass": "^3.1.0", + "encoding": "^0.1.13", + "minipass": "^3.1.6", "minipass-sized": "^1.0.3", - "minizlib": "^2.0.0" + "minizlib": "^2.1.2" } }, "minipass-flush": { @@ -4553,14 +4843,6 @@ "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.3.tgz", "integrity": "sha512-c6YRvhEo//6T2Jz/vVtYzqBzwvPT95JBQ+smCytzf7c50oMZRsR/a4w88aD34I+/QVSfnoAnSBFPJHItlOMJVw==" }, - "moment-timezone": { - "version": "0.5.34", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.34.tgz", - "integrity": "sha512-3zAEHh2hKUs3EXLESx/wsgw6IQdusOT8Bxm3D9UrHPQR7zlMmzwybC8zHEM1tQ4LJwP7fcxrWr8tuBg05fFCbg==", - "requires": { - "moment": ">= 2.9.0" - } - }, "morgan": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", @@ -4589,12 +4871,12 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "on-finished": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", "requires": { "ee-first": "1.1.1" } @@ -4625,7 +4907,7 @@ "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" }, "negotiator": { "version": "0.6.3", @@ -4654,7 +4936,7 @@ "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", "dev": true }, "path-to-regexp": { @@ -4669,13 +4951,13 @@ } }, "nock": { - "version": "13.2.4", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.2.4.tgz", - "integrity": "sha512-8GPznwxcPNCH/h8B+XZcKjYPXnUV5clOKCjAqyjsiqA++MpNx9E9+t8YPp0MbThO+KauRo7aZJ1WuIZmOrT2Ug==", + "version": "13.2.7", + "resolved": "https://registry.npmjs.org/nock/-/nock-13.2.7.tgz", + "integrity": "sha512-R6NUw7RIPtKwgK7jskuKoEi4VFMqIHtV2Uu9K/Uegc4TA5cqe+oNMYslZcUmnVNQCTG6wcSqUBaGTDd7sq5srg==", "requires": { "debug": "^4.1.0", "json-stringify-safe": "^5.0.1", - "lodash.set": "^4.3.2", + "lodash": "^4.17.21", "propagate": "^2.0.0" } }, @@ -4688,22 +4970,19 @@ } }, "node-cron": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/node-cron/-/node-cron-3.0.0.tgz", - "integrity": "sha512-DDwIvvuCwrNiaU7HEivFDULcaQualDv7KoNlB/UU1wPW0n1tDEmBJKhEIE6DlF2FuoOHcNbLJ8ITL2Iv/3AWmA==", - "requires": { - "moment-timezone": "^0.5.31" - } + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/node-cron/-/node-cron-3.0.1.tgz", + "integrity": "sha512-RAWZTNn2M5KDIUV/389UX0EXsqvdFAwc9QwHQceh0Ga56dygqSRthqIjwpgZsoDspHGt2rkHdk9Z4RgfPMdALw==" }, "node-gyp": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-8.4.1.tgz", - "integrity": "sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.0.0.tgz", + "integrity": "sha512-Ma6p4s+XCTPxCuAMrOA/IJRmVy16R8Sdhtwl4PrCr7IBlj4cPawF0vg/l7nOT1jPbuNS7lIRJpBSvVsXwEZuzw==", "requires": { "env-paths": "^2.2.0", "glob": "^7.1.4", "graceful-fs": "^4.2.6", - "make-fetch-happen": "^9.1.0", + "make-fetch-happen": "^10.0.3", "nopt": "^5.0.0", "npmlog": "^6.0.0", "rimraf": "^3.0.2", @@ -4838,7 +5117,7 @@ "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", "dev": true }, "glob": { @@ -4921,7 +5200,7 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" }, "object-inspect": { "version": "1.12.2", @@ -4944,15 +5223,15 @@ "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "requires": { "wrappy": "1" } }, "openapi-types": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-11.0.1.tgz", - "integrity": "sha512-P2pGRlHFXgP8z6vrp5P/MtftOXYtlIY1A+V0VmioOoo85NN6RSPgGbEprRAUNMIsbfRjnCPdx/r8mi8QRR7grQ==" + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-11.1.0.tgz", + "integrity": "sha512-ZW+Jf12flFF6DXSij8DGL3svDA4RtSyHXjC/xB/JAh18gg3uVfVIFLvCfScUMowrpvlkxsMMbErakbth2g3/iQ==" }, "optional": { "version": "0.1.4", @@ -4976,7 +5255,7 @@ "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", "dev": true }, "p-cancelable": { @@ -5067,7 +5346,7 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" }, "path-key": { "version": "3.1.1", @@ -5083,7 +5362,7 @@ "path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, "path-type": { "version": "4.0.0", @@ -5109,7 +5388,7 @@ "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", "dev": true }, "pkg-dir": { @@ -5126,6 +5405,12 @@ "resolved": "https://registry.npmjs.org/plantuml-encoder/-/plantuml-encoder-1.4.0.tgz", "integrity": "sha512-sxMwpDw/ySY1WB2CE3+IdMuEcWibJ72DDOsXLkSmEaSzwEUaYBT6DWgOfBiHGCux4q433X6+OEFWjlVqp7gL6g==" }, + "pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true + }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -5134,7 +5419,7 @@ "prepend-file": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/prepend-file/-/prepend-file-1.3.1.tgz", - "integrity": "sha1-g7FuC0rBkB/OiNvZRaIvTMgd9Xk=", + "integrity": "sha512-NFKEPDka08hvbVUZOu5JtFKJuWkZhWOJ/Odz6tsMlHWDtg6aUncrbu/BV3uTPRNa5T69SzbWIucg11e2kr4vBA==", "dev": true, "requires": { "tmp": "0.0.31" @@ -5143,13 +5428,28 @@ "prepend-file-cli": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/prepend-file-cli/-/prepend-file-cli-1.0.6.tgz", - "integrity": "sha1-/34RbJMU24XCLEOioH8/k4epp08=", + "integrity": "sha512-znOwErOOemRkN945G6enA0voH5t2g8ow8JMw2XUJDezbsA2TxATIDTaOeh5J1QM7caV6O2xtgQ7il98MmHCgSw==", "dev": true, "requires": { "minimist": "^1.2.0", "prepend-file": "1.3.1" } }, + "prettier": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", + "dev": true + }, + "prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "requires": { + "fast-diff": "^1.1.2" + } + }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -5191,12 +5491,12 @@ "promise-inflight": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=" + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==" }, "promise-queue": { "version": "2.2.5", "resolved": "https://registry.npmjs.org/promise-queue/-/promise-queue-2.2.5.tgz", - "integrity": "sha1-L29ffA9tCBCelnZZx5uIqe1ek7Q=" + "integrity": "sha512-p/iXrPSVfnqPft24ZdNNLECw/UrtLTpT3jpAAMzl/o5/rDsGCPo3/CQS2611flL6LkoEJ3oQZw7C8Q80ZISXRQ==" }, "promise-retry": { "version": "2.0.1", @@ -5238,7 +5538,7 @@ "q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", "dev": true }, "qs": { @@ -5301,19 +5601,19 @@ } }, "re2": { - "version": "1.17.4", - "resolved": "https://registry.npmjs.org/re2/-/re2-1.17.4.tgz", - "integrity": "sha512-xyZ4h5PqE8I9tAxTh3G0UttcK5ufrcUxReFjGzfX61vtanNbS1XZHjnwRSyPcLgChI4KLxVgOT/ioZXnUAdoTA==", + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/re2/-/re2-1.17.7.tgz", + "integrity": "sha512-X8GSuiBoVWwcjuppqSjsIkRxNUKDdjhkO9SBekQbZ2ksqWUReCy7DQPWOVpoTnpdtdz5PIpTTxTFzvJv5UMfjA==", "requires": { - "install-artifact-from-github": "^1.3.0", - "nan": "^2.15.0", - "node-gyp": "^8.4.1" + "install-artifact-from-github": "^1.3.1", + "nan": "^2.16.0", + "node-gyp": "^9.0.0" } }, "read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", "dev": true, "requires": { "load-json-file": "^4.0.0", @@ -5351,7 +5651,7 @@ "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", "dev": true }, "semver": { @@ -5365,7 +5665,7 @@ "read-pkg-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", - "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "integrity": "sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw==", "dev": true, "requires": { "find-up": "^2.0.0", @@ -5375,7 +5675,7 @@ "find-up": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", "dev": true, "requires": { "locate-path": "^2.0.0" @@ -5384,7 +5684,7 @@ "locate-path": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", "dev": true, "requires": { "p-locate": "^2.0.0", @@ -5403,7 +5703,7 @@ "p-locate": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", "dev": true, "requires": { "p-limit": "^1.1.0" @@ -5412,13 +5712,13 @@ "p-try": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", "dev": true }, "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", "dev": true } } @@ -5449,7 +5749,7 @@ "rechoir": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", "dev": true, "requires": { "resolve": "^1.1.6" @@ -5466,9 +5766,9 @@ } }, "redoc-cli": { - "version": "0.13.14", - "resolved": "https://registry.npmjs.org/redoc-cli/-/redoc-cli-0.13.14.tgz", - "integrity": "sha512-QPiVRdz0+CvLmjPzaIAz1RttpYUOSeUbep/WxLXaalu1Z9jeSjsI0yI2+HC3sh/tEuLzaHQ2bvE7mvGq0aTbWA==", + "version": "0.13.16", + "resolved": "https://registry.npmjs.org/redoc-cli/-/redoc-cli-0.13.16.tgz", + "integrity": "sha512-/rqkqJV1r5xgnEFh6cSmv+sZuo/TGCXKRBKZwoC0rLny5N6WGx9YykJhe1jSM4XRbK3VDfrQtOJmPCaI1ut6gg==", "dev": true, "requires": { "chokidar": "^3.5.1", @@ -5479,7 +5779,7 @@ "node-libs-browser": "^2.2.1", "react": "^17.0.1", "react-dom": "^17.0.1", - "redoc": "2.0.0-rc.70", + "redoc": "2.0.0-rc.72", "styled-components": "^5.3.0", "yargs": "^17.3.1" }, @@ -7152,9 +7452,9 @@ "dev": true }, "openapi-sampler": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/openapi-sampler/-/openapi-sampler-1.2.3.tgz", - "integrity": "sha512-dH2QYXqakorV5dxkP/f1BV3Ku4yNn21YmBsqJunnyrHLw7mnCNZZldftgrEpv/66b1m5oaUAmiJoJN+FqBEkJg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/openapi-sampler/-/openapi-sampler-1.3.0.tgz", + "integrity": "sha512-2QfjK1oM9Sv0q82Ae1RrUe3yfFmAyjF548+6eAeb+h/cL1Uj51TW4UezraBEvwEdzoBgfo4AaTLVFGTKj+yYDw==", "dev": true, "requires": { "@types/json-schema": "^7.0.7", @@ -7420,9 +7720,9 @@ } }, "redoc": { - "version": "2.0.0-rc.70", - "resolved": "https://registry.npmjs.org/redoc/-/redoc-2.0.0-rc.70.tgz", - "integrity": "sha512-sdmZ8FX4JjF50hTSjHJ64Ccu9Ewa2O8+Fo8pCLg8GHFrbaFJ2E+KBDK9pGuAqNi61fm3Z5c91Ur7zqpITkUpNg==", + "version": "2.0.0-rc.72", + "resolved": "https://registry.npmjs.org/redoc/-/redoc-2.0.0-rc.72.tgz", + "integrity": "sha512-IX/WvVh4N3zwo4sAjnQFz6ffIUd6G47hcflxPtrpxblJaeOy0MBSzzY8f179WjssWPYcSmmndP5v0hgEXFiimg==", "dev": true, "requires": { "@redocly/openapi-core": "^1.0.0-beta.97", @@ -7435,7 +7735,7 @@ "mark.js": "^8.11.1", "marked": "^4.0.15", "mobx-react": "^7.2.0", - "openapi-sampler": "^1.2.3", + "openapi-sampler": "^1.3.0", "path-browserify": "^1.0.1", "perfect-scrollbar": "^1.5.1", "polished": "^4.1.3", @@ -8035,6 +8335,12 @@ } } }, + "regexp-tree": { + "version": "0.1.24", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.24.tgz", + "integrity": "sha512-s2aEVuLhvnVJW6s/iPgEGK6R+/xngd2jNQ+xy4bXNDKxZKJH6jpPHY6kVeVv1IeLCHgswRj+Kl3ELaDjG6V1iw==", + "dev": true + }, "regexpp": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", @@ -8043,7 +8349,7 @@ "release-zalgo": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", - "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", + "integrity": "sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==", "dev": true, "requires": { "es6-error": "^4.0.1" @@ -8052,7 +8358,7 @@ "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true }, "require-from-string": { @@ -8067,12 +8373,12 @@ "dev": true }, "resolve": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", - "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", "dev": true, "requires": { - "is-core-module": "^2.8.1", + "is-core-module": "^2.9.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" } @@ -8090,7 +8396,7 @@ "response-time": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/response-time/-/response-time-2.3.2.tgz", - "integrity": "sha1-/6cbq5UtYvfB1Jt0NDVfvGjf/Fo=", + "integrity": "sha512-MUIDaDQf+CVqflfTdQ5yam+aYCkXj1PY8fjlPDQ6ppxJlmgZb864pHtA750mayywNg8tx4rS7qH9JXd/OF+3gw==", "requires": { "depd": "~1.1.0", "on-headers": "~1.0.1" @@ -8107,7 +8413,7 @@ "retry": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=" + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==" }, "reusify": { "version": "1.0.4", @@ -8155,6 +8461,15 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, + "safe-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz", + "integrity": "sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==", + "dev": true, + "requires": { + "regexp-tree": "~0.1.1" + } + }, "safe-stable-stringify": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.3.1.tgz", @@ -8176,6 +8491,16 @@ "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", "requires": { "lru-cache": "^6.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + } } }, "send": { @@ -8209,7 +8534,7 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" } } }, @@ -8243,7 +8568,7 @@ "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" }, "setprototypeof": { "version": "1.2.0", @@ -8364,9 +8689,9 @@ } }, "socks-proxy-agent": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.0.tgz", - "integrity": "sha512-wWqJhjb32Q6GsrUqzuFkukxb/zzide5quXYcMVpIjxalDBBYy2nqKCFQ/9+Ie4dvOYSQdOk3hUlZSdzZOd3zMQ==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", + "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", "requires": { "agent-base": "^6.0.2", "debug": "^4.3.3", @@ -8459,13 +8784,13 @@ "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, "ssri": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", - "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-9.0.1.tgz", + "integrity": "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==", "requires": { "minipass": "^3.1.1" } @@ -8504,7 +8829,7 @@ "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true }, "strip-indent": { @@ -8522,9 +8847,9 @@ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" }, "superagent": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/superagent/-/superagent-7.1.3.tgz", - "integrity": "sha512-WA6et4nAvgBCS73lJvv1D0ssI5uk5Gh+TGN/kNe+B608EtcVs/yzfl+OLXTzDs7tOBDIpvgh/WUs1K2OK1zTeQ==", + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-7.1.5.tgz", + "integrity": "sha512-HQYyGuDRFGmZ6GNC4hq2f37KnsY9Lr0/R1marNZTgMweVDQLTLJJ6DGQ9Tj/xVVs5HEnop9EMmTbywb5P30aqw==", "dev": true, "requires": { "component-emitter": "^1.3.0", @@ -8597,11 +8922,11 @@ } }, "tdigest": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.1.tgz", - "integrity": "sha1-Ljyyw56kSeVdHmzZEReszKRYgCE=", + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.2.tgz", + "integrity": "sha512-+G0LLgjjo9BZX2MfdvPfH+MKLCrxlXSYec5DaPYP1fe6Iyhf0/fSmJ0bFiZ1F8BT6cGXl2LpltQptzjXKWEkKA==", "requires": { - "bintrees": "1.0.1" + "bintrees": "1.0.2" } }, "temp-dir": { @@ -8664,12 +8989,12 @@ "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "dev": true }, "through2": { @@ -8697,7 +9022,7 @@ "tmp": { "version": "0.0.31", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz", - "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=", + "integrity": "sha512-lfyEfOppKvWNeId5CArFLwgwef+iCnbEIy0JWYf1httIEXnx4ndL4Dr1adw7hPgeQfSlTbc/gqn6iaKcROpw5Q==", "dev": true, "requires": { "os-tmpdir": "~1.0.1" @@ -8706,7 +9031,7 @@ "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", "dev": true }, "to-regex-range": { @@ -8725,7 +9050,7 @@ "toposort": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz", - "integrity": "sha1-riF2gXXRVZ1IvvNUILL0li8JwzA=" + "integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==" }, "trim-newlines": { "version": "3.0.1", @@ -8767,9 +9092,9 @@ } }, "ts-node": { - "version": "10.8.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.8.0.tgz", - "integrity": "sha512-/fNd5Qh+zTt8Vt1KbYZjRHCE9sI5i7nqfD/dzBBRDeVXZXS6kToW6R7tTU6Nd4XavFs0mAVCg29Q//ML7WsZYA==", + "version": "10.8.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.8.1.tgz", + "integrity": "sha512-Wwsnao4DQoJsN034wePSg5nZiw4YKXf56mPIAeD6wVmiv+RytNSWqc2f3fKvcUoV+Yn2+yocD71VOfQHbmVX4g==", "requires": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -8797,187 +9122,10 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, - "tslint": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz", - "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.3.0", - "commander": "^2.12.1", - "diff": "^4.0.1", - "glob": "^7.1.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.3", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.13.0", - "tsutils": "^2.29.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "requires": { - "minimist": "^1.2.6" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "tslint-eslint-rules": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/tslint-eslint-rules/-/tslint-eslint-rules-5.4.0.tgz", - "integrity": "sha512-WlSXE+J2vY/VPgIcqQuijMQiel+UtmXS+4nvK4ZzlDiqBfXse8FAvkNnTcYhnQyOTW5KFM+uRRGXxYhFpuBc6w==", - "dev": true, - "requires": { - "doctrine": "0.7.2", - "tslib": "1.9.0", - "tsutils": "^3.0.0" - }, - "dependencies": { - "doctrine": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-0.7.2.tgz", - "integrity": "sha1-fLhgNZujvpDgQLJrcpzkv6ZUxSM=", - "dev": true, - "requires": { - "esutils": "^1.1.6", - "isarray": "0.0.1" - } - }, - "esutils": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-1.1.6.tgz", - "integrity": "sha1-wBzKqa5LiXxtDD4hCuUvPHqEQ3U=", - "dev": true - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "tslib": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.0.tgz", - "integrity": "sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ==", - "dev": true - }, - "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - } - } - }, "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", "dev": true, "requires": { "tslib": "^1.8.1" @@ -9020,47 +9168,31 @@ } }, "typedoc": { - "version": "0.22.15", - "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.22.15.tgz", - "integrity": "sha512-CMd1lrqQbFvbx6S9G6fL4HKp3GoIuhujJReWqlIvSb2T26vGai+8Os3Mde7Pn832pXYemd9BMuuYWhFpL5st0Q==", + "version": "0.22.17", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.22.17.tgz", + "integrity": "sha512-h6+uXHVVCPDaANzjwzdsj9aePBjZiBTpiMpBBeyh1zcN2odVsDCNajz8zyKnixF93HJeGpl34j/70yoEE5BfNg==", "dev": true, "requires": { - "glob": "^7.2.0", + "glob": "^8.0.3", "lunr": "^2.3.9", - "marked": "^4.0.12", - "minimatch": "^5.0.1", + "marked": "^4.0.16", + "minimatch": "^5.1.0", "shiki": "^0.10.1" }, "dependencies": { - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "dependencies": { - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } + "balanced-match": "^1.0.0" } }, "marked": { - "version": "4.0.16", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.16.tgz", - "integrity": "sha512-wahonIQ5Jnyatt2fn8KqF/nIqZM8mh3oRu2+l5EANGMhu6RFjiSG52QNE2eWzFMI94HqYSgN184NurgNG6CztA==", + "version": "4.0.17", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.17.tgz", + "integrity": "sha512-Wfk0ATOK5iPxM4ptrORkFemqroz0ZDxp5MWfYA7H/F+wO17NRWV5Ypxi6p3g2Xmw2bKeiYOl6oVnLHKxBA0VhA==", "dev": true }, "minimatch": { @@ -9070,17 +9202,6 @@ "dev": true, "requires": { "brace-expansion": "^2.0.1" - }, - "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - } } } } @@ -9100,9 +9221,9 @@ "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==" }, "uglify-js": { - "version": "3.15.5", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.15.5.tgz", - "integrity": "sha512-hNM5q5GbBRB5xB+PMqVRcgYe4c8jbyZ1pzZhS6jbq54/4F2gFK869ZheiE5A8/t+W5jtTNpWef/5Q9zk639FNQ==", + "version": "3.16.1", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.16.1.tgz", + "integrity": "sha512-X5BGTIDH8U6IQ1TIRP62YC36k+ULAa1d59BxlWvPUJ1NkW5L3FwcGfEzuVvGmhJFBu0YJ5Ge25tmRISqCmLiRQ==", "dev": true, "optional": true }, @@ -9130,7 +9251,17 @@ "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" + }, + "update-browserslist-db": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.4.tgz", + "integrity": "sha512-jnmO2BEGUjsMOe/Fg9u0oczOe/ppIDZPebzccl1yDWGLFP16Pa1/RM5wEoKYPG2zstNcDuAStejyxsOuKINdGA==", + "dev": true, + "requires": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + } }, "uri-js": { "version": "4.4.1", @@ -9148,12 +9279,12 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" }, "uuid": { "version": "8.3.2", @@ -9183,7 +9314,7 @@ "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" }, "vscode-oniguruma": { "version": "1.6.2", @@ -9208,7 +9339,7 @@ "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", "dev": true }, "wide-align": { @@ -9227,7 +9358,7 @@ "wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", "dev": true }, "workerpool": { @@ -9250,7 +9381,7 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "write-file-atomic": { "version": "3.0.3", diff --git a/package.json b/package.json index 6da70eef..71a0de77 100644 --- a/package.json +++ b/package.json @@ -12,10 +12,10 @@ "Michel Jonathan Schmitz", "Rainer Killinger ", "Sebastian Lange", - "Wieland Schöbl" + "Thea Schöbl " ], "scripts": { - "build": "npm run tslint && npm run compile", + "build": "npm run lint && npm run compile", "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0 && git add CHANGELOG.md && git commit -m 'docs: update changelog'", "check-configuration": "openstapps-configuration", "compile": "rimraf lib && tsc && prepend lib/cli.js '#!/usr/bin/env node\n'", @@ -29,35 +29,37 @@ "test": "npm run test-unit && npm run test-integration", "test-unit": "env NODE_CONFIG_ENV=elasticsearch ALLOW_NO_TRANSPORT=true STAPPS_LOG_LEVEL=0 nyc mocha --require ts-node/register --exit 'test/**/*.spec.ts'", "test-integration": "sudo docker-compose -f integration-test.yml pull && sudo docker-compose -f integration-test.yml up --build --abort-on-container-exit --exit-code-from apicli", - "tslint": "tslint -p tsconfig.json -c tslint.json 'src/**/*.ts'" + "lint": "eslint -c .eslintrc.json --ignore-path .eslintignore --ext .ts src/ test/", + "lint:fix": "eslint --fix -c .eslintrc.json --ignore-path .eslintignore --ext .ts src/ test/" }, "dependencies": { "@elastic/elasticsearch": "5.6.22", - "@openstapps/core": "0.66.1", - "@openstapps/core-tools": "0.30.1", + "@openstapps/core": "0.68.0", + "@openstapps/core-tools": "0.31.0", "@openstapps/logger": "0.8.1", "@types/express-prometheus-middleware": "1.2.1", - "@types/node": "14.18.18", + "@types/node": "14.18.21", "config": "3.3.7", "cors": "2.8.5", "express": "4.18.1", "express-prometheus-middleware": "1.2.0", "express-promise-router": "4.1.1", - "got": "11.8.3", + "got": "11.8.5", "moment": "2.29.3", "morgan": "1.10.0", - "nock": "13.2.4", + "nock": "13.2.7", "node-cache": "5.1.2", - "node-cron": "3.0.0", + "node-cron": "3.0.1", "nodemailer": "6.7.5", "prom-client": "14.0.1", "promise-queue": "2.2.5", - "ts-node": "10.8.0", + "ts-node": "10.8.1", "uuid": "8.3.2" }, "devDependencies": { - "@openstapps/configuration": "0.29.1", - "@openstapps/es-mapping-generator": "0.1.0", + "@openstapps/configuration": "0.32.0", + "@openstapps/es-mapping-generator": "0.2.0", + "@openstapps/eslint-config": "1.1.0", "@testdeck/mocha": "0.2.0", "@types/chai": "4.3.1", "@types/chai-as-promised": "7.1.5", @@ -74,21 +76,28 @@ "@types/sinon-express-mock": "1.3.9", "@types/supertest": "2.0.12", "@types/uuid": "8.3.4", + "@typescript-eslint/eslint-plugin": "5.29.0", + "@typescript-eslint/parser": "5.29.0", "chai": "4.3.6", "chai-as-promised": "7.1.1", "conventional-changelog-cli": "2.2.2", + "eslint": "8.18.0", + "eslint-config-prettier": "8.5.0", + "eslint-plugin-jsdoc": "39.3.3", + "eslint-plugin-prettier": "4.1.0", + "eslint-plugin-unicorn": "42.0.0", "get-port": "5.1.1", "mocha": "10.0.0", "mocked-env": "1.3.5", "nyc": "15.1.0", "prepend-file-cli": "1.0.6", - "redoc-cli": "0.13.14", + "prettier": "2.7.1", + "redoc-cli": "0.13.16", "rimraf": "3.0.2", "sinon": "14.0.0", "sinon-express-mock": "2.2.1", "supertest": "6.2.3", - "tslint": "6.1.3", - "typedoc": "0.22.15", + "typedoc": "0.22.17", "typescript": "4.4.4" }, "nyc": { diff --git a/src/app.ts b/src/app.ts index 2dd11573..6c98497e 100644 --- a/src/app.ts +++ b/src/app.ts @@ -24,7 +24,7 @@ import config from 'config'; import cors from 'cors'; import {Express} from 'express'; import morgan from 'morgan'; -import {join} from 'path'; +import path from 'path'; import {configFile, DEFAULT_TIMEOUT, isTestEnvironment, mailer, plugins, validator} from './common'; import {getPrometheusMiddleware} from './middleware/prometheus'; import {MailQueue} from './notification/mail-queue'; @@ -43,26 +43,26 @@ import {DatabaseConstructor} from './storage/database'; /** * Configure the backend */ -export async function configureApp(app: Express, databases: {[name: string]: DatabaseConstructor; }) { +export async function configureApp(app: Express, databases: {[name: string]: DatabaseConstructor}) { let integrationTestTimeout: NodeJS.Timeout; // request loggers have to be the first middleware to be set in express - app.use(morgan('dev', { - skip: (_req, res) => { - if (process.env.NODE_ENV === 'integration-test') { - clearTimeout(integrationTestTimeout); - integrationTestTimeout = setTimeout(() => { - process.exit(1); - }, - DEFAULT_TIMEOUT); + app.use( + morgan('dev', { + skip: (_request, response) => { + if (process.env.NODE_ENV === 'integration-test') { + clearTimeout(integrationTestTimeout); + integrationTestTimeout = setTimeout(() => { + process.exit(1); + }, DEFAULT_TIMEOUT); - return false; - } + return false; + } - // tslint:disable-next-line: no-magic-numbers - return res.statusCode < 400; - - }, stream: process.stdout, - })); + return response.statusCode < 400; + }, + stream: process.stdout, + }), + ); if (process.env.PROMETHEUS_MIDDLEWARE === 'true') { app.use(getPrometheusMiddleware()); @@ -80,7 +80,7 @@ export async function configureApp(app: Express, databases: {[name: string]: Dat 'X-StApps-Version', ], credentials: true, - maxAge: 1728000, + maxAge: 1_728_000, methods: ['GET', 'POST', 'PUT', 'OPTIONS'], optionsSuccessStatus: 204, }; @@ -93,13 +93,13 @@ export async function configureApp(app: Express, databases: {[name: string]: Dat app.options('*', [cors(corsOptions)]); // only accept json as content type for all requests - app.use((req, res, next) => { + app.use((request, response, next) => { // Only accept json as content type - if (req.is('application/json') !== 'application/json') { + if (request.is('application/json') !== 'application/json') { // return an error in the response - const err = new SCUnsupportedMediaTypeErrorResponse(isTestEnvironment); - res.status(err.statusCode); - res.json(err); + const error = new SCUnsupportedMediaTypeErrorResponse(isTestEnvironment); + response.status(error.statusCode); + response.json(error); return; } @@ -111,12 +111,12 @@ export async function configureApp(app: Express, databases: {[name: string]: Dat bodySize += chunk.byteLength; // when adding each chunk size to the total size, check how large it now is. if (bodySize > configFile.backend.maxRequestBodySize) { - req.off('data', chunkGatherer); - req.off('end', endCallback); + request.off('data', chunkGatherer); + request.off('end', endCallback); // return an error in the response - const err = new SCRequestBodyTooLargeErrorResponse(isTestEnvironment); - res.status(err.statusCode); - res.json(err); + const error = new SCRequestBodyTooLargeErrorResponse(isTestEnvironment); + response.status(error.statusCode); + response.json(error); return; } @@ -125,26 +125,24 @@ export async function configureApp(app: Express, databases: {[name: string]: Dat }; const endCallback = () => { - req.body = Buffer.concat(bodyBuffer) - .toString(); + request.body = Buffer.concat(bodyBuffer).toString(); try { - req.body = JSON.parse(req.body); + request.body = JSON.parse(request.body); next(); - } catch (catchErr) { - const err = new SCSyntaxErrorResponse(catchErr.message, isTestEnvironment); - res.status(err.statusCode); - res.json(err); + } catch (error) { + const error_ = new SCSyntaxErrorResponse(error.message, isTestEnvironment); + response.status(error_.statusCode); + response.json(error_); return; } }; - req.on('data', chunkGatherer) - .on('end', endCallback); + request.on('data', chunkGatherer).on('end', endCallback); }); // validate config file - await validator.addSchemas(join('node_modules', '@openstapps', 'core', 'lib', 'schema')); + await validator.addSchemas(path.join('node_modules', '@openstapps', 'core', 'lib', 'schema')); // validate the config file const configValidation = validator.validate(configFile, 'SCConfigFile'); @@ -161,17 +159,16 @@ export async function configureApp(app: Express, databases: {[name: string]: Dat throw new Error('You have to configure a database'); } - const database = - new databases[config.get('internal.database.name')]( - configFile, - // mailQueue - typeof mailer !== 'undefined' && config.has('internal.monitoring') ? new MailQueue(mailer) : undefined, - ); + const database = new databases[config.get('internal.database.name')]( + configFile, + // mailQueue + typeof mailer !== 'undefined' && config.has('internal.monitoring') ? new MailQueue(mailer) : undefined, + ); await database.init(); if (typeof database === 'undefined') { - throw new Error('No implementation for configured database found. Please check your configuration.'); + throw new TypeError('No implementation for configured database found. Please check your configuration.'); } Logger.ok('Validated config file successfully'); @@ -181,10 +178,7 @@ export async function configureApp(app: Express, databases: {[name: string]: Dat app.enable('strict routing'); // make the bulk storage available to all http middlewares/routes - app.set( - 'bulk', - new BulkStorage(database), - ); + app.set('bulk', new BulkStorage(database)); app.set('env', process.env.NODE_ENV); @@ -202,15 +196,15 @@ export async function configureApp(app: Express, databases: {[name: string]: Dat ); // for plugins, as Express doesn't really want you to unregister routes (and doesn't offer any method to do so at all) - app.all('*', async (req, res, next) => { + app.all('*', async (request, response, next) => { // if the route exists then call virtual route on the plugin that registered that route - if (plugins.has(req.originalUrl)) { + if (plugins.has(request.originalUrl)) { try { - res.json(await virtualPluginRoute(req, plugins.get(req.originalUrl)!)); - } catch (e) { + response.json(await virtualPluginRoute(request, plugins.get(request.originalUrl)!)); + } catch (error) { // in case of error send an error response - res.status(e.statusCode); - res.json(e); + response.status(error.statusCode); + response.json(error); } } else { // pass to the next matching route (which is 404) @@ -219,9 +213,9 @@ export async function configureApp(app: Express, databases: {[name: string]: Dat }); // add a route for a missing resource (404) - app.use((_req, res) => { + app.use((_request, response) => { const errorResponse = new SCNotFoundErrorResponse(isTestEnvironment); - res.status(errorResponse.statusCode); - res.json(errorResponse); + response.status(errorResponse.statusCode); + response.json(errorResponse); }); } diff --git a/src/cli.ts b/src/cli.ts index 65631cdf..0ccb0cb4 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -24,7 +24,6 @@ const app = express(); /** * Get port from environment and store in Express. */ -// tslint:disable-next-line: strict-boolean-expressions const port = normalizePort(process.env.PORT || '3000'); /** @@ -42,9 +41,9 @@ server.on('listening', onListening); * Normalize a port into a number, string, or false. */ function normalizePort(value: string) { - const portNumber = parseInt(value, 10); + const portNumber = Number.parseInt(value, 10); - if (isNaN(portNumber)) { + if (Number.isNaN(portNumber)) { // named pipe return value; } @@ -60,15 +59,12 @@ function normalizePort(value: string) { /** * Event listener for HTTP server "error" event. */ -// tslint:disable-next-line: completed-docs -async function onError(error: { code: string; syscall: string; }) { +async function onError(error: {code: string; syscall: string}) { if (error.syscall !== 'listen') { throw error; } - const bind = typeof port === 'string' - ? `Pipe ${port}` - : `Port ${port}`; + const bind = typeof port === 'string' ? `Pipe ${port}` : `Port ${port}`; // handle specific listen errors with friendly messages switch (error.code) { @@ -92,13 +88,10 @@ function onListening() { const addr = server.address(); if (addr !== null) { - const bind = typeof addr === 'string' - ? `pipe ${addr}` - : `port ${addr.port}`; + const bind = typeof addr === 'string' ? `pipe ${addr}` : `port ${addr.port}`; Logger.ok(`Listening on ${bind}`); } else { - // tslint:disable-next-line: no-floating-promises - Logger.error(`Failed to start binding`); + void Logger.error(`Failed to start binding`); } } @@ -108,6 +101,6 @@ configureApp(app, {elasticsearch: Elasticsearch}) // After app setup listen on provided port, on all network interfaces server.listen(port); }) - .catch((err) => { - throw err; + .catch(error => { + throw error; }); diff --git a/src/common.ts b/src/common.ts index 5777a1cd..47723fad 100644 --- a/src/common.ts +++ b/src/common.ts @@ -51,4 +51,4 @@ export const coreVersion: string = configFile.backend.SCVersion; /** * The default timeout in milliseconds */ -export const DEFAULT_TIMEOUT = 20000; +export const DEFAULT_TIMEOUT = 20_000; diff --git a/src/middleware/prometheus.ts b/src/middleware/prometheus.ts index 887e4c99..024d5659 100644 --- a/src/middleware/prometheus.ts +++ b/src/middleware/prometheus.ts @@ -24,9 +24,9 @@ type UserOptions = Parameters[0]; * Create and configure a new Express Prometheus Middleware instance * * This function tries to configure the new instance with JSON read from - * `./conf/prometheus.json`. When this fails an instance configured with + * `./conf/prometheus.json`. When this fails an instance configured with * default options is returned. - * + * * @returns express.Express */ export function getPrometheusMiddleware(): express.Express { @@ -34,9 +34,9 @@ export function getPrometheusMiddleware(): express.Express { let options: UserOptions = {}; try { - options = JSON.parse(fs.readFileSync(configFileName, 'utf-8')); - } catch(err) { - Logger.warn('Could not get options for Prometheus Middleware.', err); + options = JSON.parse(fs.readFileSync(configFileName, 'utf8')); + } catch (error) { + Logger.warn('Could not get options for Prometheus Middleware.', error); } return expressPrometheusMiddleware(options); diff --git a/src/notification/backend-transport.ts b/src/notification/backend-transport.ts index 2abc854e..5a1d7543 100644 --- a/src/notification/backend-transport.ts +++ b/src/notification/backend-transport.ts @@ -103,8 +103,8 @@ export class BackendTransport { if (successful) { Logger.log('SMTP verification successful.'); } - } catch (err) { - throw err; + } catch (error) { + throw error; } finally { this.waitingForVerification = false; } diff --git a/src/notification/mail-queue.ts b/src/notification/mail-queue.ts index b54f39a4..a8912082 100644 --- a/src/notification/mail-queue.ts +++ b/src/notification/mail-queue.ts @@ -22,7 +22,6 @@ import Queue from 'promise-queue'; * A queue that can send mails in serial */ export class MailQueue { - /** * Number of allowed verification attempts after which the initialization of transport fails */ @@ -52,10 +51,10 @@ export class MailQueue { /** * Creates a mail queue + * * @param transport Transport which is used for sending mails */ constructor(private readonly transport: SMTP) { - this.queue = new Queue(1); // this queue saves all request when the transport is not ready yet @@ -80,7 +79,6 @@ export class MailQueue { * Verify the given transport */ private checkForVerification() { - if (this.verificationCounter >= MailQueue.MAX_VERIFICATION_ATTEMPTS) { throw new Error('Failed to initialize the SMTP transport for the mail queue'); } @@ -94,9 +92,9 @@ export class MailQueue { } else { Logger.ok('Transport for mail queue was verified. We can send mails now'); // if the transport finally was verified send all our mails from the dry queue - this.dryQueue.forEach(async (mail) => { - await this.addToQueue(mail); - }); + for (const mail of this.dryQueue) { + void this.addToQueue(mail); + } } } @@ -106,7 +104,8 @@ export class MailQueue { * @param mail Information required for sending a mail */ public async push(mail: MailOptions) { - if (!this.transport.isVerified()) { // the transport has verification, but is not verified yet + if (!this.transport.isVerified()) { + // the transport has verification, but is not verified yet // push to a dry queue which gets pushed to the real queue when the transport is verified this.dryQueue.push(mail); } else { diff --git a/src/routes/bulk-add-route.ts b/src/routes/bulk-add-route.ts index cfba7d5d..f74c8dca 100644 --- a/src/routes/bulk-add-route.ts +++ b/src/routes/bulk-add-route.ts @@ -29,13 +29,12 @@ const bulkRouteModel = new SCBulkAddRoute(); */ export const bulkAddRouter = createRoute( bulkRouteModel, - async (request, app, params) => { - + async (request, app, parameters) => { const bulkMemory: BulkStorage = app.get('bulk'); - const bulk = bulkMemory.read(params.UID); + const bulk = bulkMemory.read(parameters.UID); if (typeof bulk === 'undefined') { - Logger.warn(`Bulk with ${params.UID} not found.`); + Logger.warn(`Bulk with ${parameters.UID} not found.`); throw new SCNotFoundErrorResponse(isTestEnvironment); } diff --git a/src/routes/bulk-done-route.ts b/src/routes/bulk-done-route.ts index 62b13cd9..944fa4fb 100644 --- a/src/routes/bulk-done-route.ts +++ b/src/routes/bulk-done-route.ts @@ -13,7 +13,12 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -import {SCBulkDoneRequest, SCBulkDoneResponse, SCBulkDoneRoute, SCNotFoundErrorResponse} from '@openstapps/core'; +import { + SCBulkDoneRequest, + SCBulkDoneResponse, + SCBulkDoneRoute, + SCNotFoundErrorResponse, +} from '@openstapps/core'; import {Logger} from '@openstapps/logger'; import {isTestEnvironment} from '../common'; import {BulkStorage} from '../storage/bulk-storage'; @@ -29,13 +34,12 @@ const bulkDoneRouteModel = new SCBulkDoneRoute(); */ export const bulkDoneRouter = createRoute( bulkDoneRouteModel, - async (_request, app, params) => { - + async (_request, app, parameters) => { const bulkMemory: BulkStorage = app.get('bulk'); - const bulk = bulkMemory.read(params.UID); + const bulk = bulkMemory.read(parameters.UID); if (typeof bulk === 'undefined') { - Logger.warn(`Bulk with ${params.UID} not found.`); + Logger.warn(`Bulk with ${parameters.UID} not found.`); throw new SCNotFoundErrorResponse(isTestEnvironment); } diff --git a/src/routes/bulk-route.ts b/src/routes/bulk-route.ts index abc56ed7..931f4744 100644 --- a/src/routes/bulk-route.ts +++ b/src/routes/bulk-route.ts @@ -25,11 +25,8 @@ const bulkRouteModel = new SCBulkRoute(); /** * Implementation of the bulk request route (SCBulkRoute) */ -export const bulkRouter = createRoute( - bulkRouteModel, - async (request, app) => { - const bulkMemory: BulkStorage = app.get('bulk'); +export const bulkRouter = createRoute(bulkRouteModel, async (request, app) => { + const bulkMemory: BulkStorage = app.get('bulk'); - return bulkMemory.create(request); - }, -); + return bulkMemory.create(request); +}); diff --git a/src/routes/http-types.ts b/src/routes/http-types.ts index c6b053ad..dc6f8771 100644 --- a/src/routes/http-types.ts +++ b/src/routes/http-types.ts @@ -14,10 +14,31 @@ * along with this program. If not, see . */ // the list provides option to easily implement "isHttpMethod" guard -const httpVerbs = ['get', 'post', 'put', 'delete', 'patch', 'options', - 'head', 'checkout', 'copy', 'lock', 'merge', 'mkactivity', 'mkcol', - 'move', 'm-search', 'notify', 'purge', 'report', 'search', 'subscribe', - 'trace', 'unlock','unsubscribe'] as const; +const httpVerbs = [ + 'get', + 'post', + 'put', + 'delete', + 'patch', + 'options', + 'head', + 'checkout', + 'copy', + 'lock', + 'merge', + 'mkactivity', + 'mkcol', + 'move', + 'm-search', + 'notify', + 'purge', + 'report', + 'search', + 'subscribe', + 'trace', + 'unlock', + 'unsubscribe', +] as const; /** * Strings that can be used as HTTP verbs (e.g. in requests): 'get' | 'post' | 'put' | 'delete' etc. */ @@ -29,5 +50,5 @@ export type HTTPVerb = typeof httpVerbs[number]; * @param method A text (representing a method) to check */ export function isHttpMethod(method: string): method is HTTPVerb { - return (httpVerbs as unknown as string[]).indexOf(method) > -1; + return (httpVerbs as unknown as string[]).includes(method); } diff --git a/src/routes/multi-search-route.ts b/src/routes/multi-search-route.ts index a83d4a90..7deba6c4 100644 --- a/src/routes/multi-search-route.ts +++ b/src/routes/multi-search-route.ts @@ -31,30 +31,28 @@ const multiSearchRouteModel = new SCMultiSearchRoute(); /** * Implementation of the multi search route (SCMultiSearchRoute) */ -export const multiSearchRouter = createRoute - ( - multiSearchRouteModel, - async (request, app) => { +export const multiSearchRouter = createRoute< + SCMultiSearchRequest, + SCMultiSearchResponse | SCTooManyRequestsErrorResponse +>(multiSearchRouteModel, async (request, app) => { + const bulkMemory: BulkStorage = app.get('bulk'); + const queryNames = Object.keys(request); - const bulkMemory: BulkStorage = app.get('bulk'); - const queryNames = Object.keys(request); + if (queryNames.length > configFile.backend.maxMultiSearchRouteQueries) { + throw new SCTooManyRequestsErrorResponse(isTestEnvironment); + } - if (queryNames.length > configFile.backend.maxMultiSearchRouteQueries) { - throw new SCTooManyRequestsErrorResponse(isTestEnvironment); - } + // get a map of promises for each query + const searchRequests = queryNames.map(async queryName => { + return bulkMemory.database.search(request[queryName]); + }); - // get a map of promises for each query - const searchRequests = queryNames.map(async (queryName) => { - return bulkMemory.database.search(request[queryName]); - }); + const listOfSearchResponses = await Promise.all(searchRequests); - const listOfSearchResponses = await Promise.all(searchRequests); + const response: {[queryName: string]: SCSearchResponse} = {}; + for (const [index, queryName] of queryNames.entries()) { + response[queryName] = listOfSearchResponses[index]; + } - const response: { [queryName: string]: SCSearchResponse; } = {}; - queryNames.forEach((queryName, index) => { - response[queryName] = listOfSearchResponses[index]; - }); - - return response; - }, -); + return response; +}); diff --git a/src/routes/plugin-register-route.ts b/src/routes/plugin-register-route.ts index bb9991a4..6415c3e1 100644 --- a/src/routes/plugin-register-route.ts +++ b/src/routes/plugin-register-route.ts @@ -34,8 +34,7 @@ const pluginRegisterRouteModel = new SCPluginRegisterRoute(); /** * Implementation of the plugin registration route (SCPluginRegisterRoute) */ -export const pluginRegisterRouter = createRoute( - pluginRegisterRouteModel, pluginRegisterHandler); +export const pluginRegisterRouter = createRoute(pluginRegisterRouteModel, pluginRegisterHandler); /** * Handles requests on route for registering plugins @@ -43,8 +42,10 @@ export const pluginRegisterRouter = createRoute( * @param request Request received for registering or unregistering a plugin * @param _app Express application */ -export async function pluginRegisterHandler(request: SCPluginRegisterRequest, _app: Express.Application): - Promise { +export async function pluginRegisterHandler( + request: SCPluginRegisterRequest, + _app: Express.Application, +): Promise { switch (request.action) { case 'add': return addPlugin(request.plugin); @@ -66,7 +67,7 @@ function addPlugin(plugin: SCPluginMetaData): SCPluginRegisterResponse { deepStrictEqual(previouslyRegistered, plugin); return {success: true}; - } catch (error) { + } catch { throw new SCPluginAlreadyRegisteredErrorResponse( 'Plugin already registered', plugins.get(plugin.route)!, @@ -80,8 +81,10 @@ function addPlugin(plugin: SCPluginMetaData): SCPluginRegisterResponse { if (typeof configFile.app.features.plugins === 'undefined') { configFile.app.features.plugins = {}; } - configFile.app.features.plugins[plugin.name] = {urlPath : plugin.route}; - Logger.log(`Registered plugin (name: ${plugin.name}, address: ${plugin.address}) on the route "${plugin.route}".`); + configFile.app.features.plugins[plugin.name] = {urlPath: plugin.route}; + Logger.log( + `Registered plugin (name: ${plugin.name}, address: ${plugin.address}) on the route "${plugin.route}".`, + ); return {success: true}; } @@ -93,9 +96,7 @@ function addPlugin(plugin: SCPluginMetaData): SCPluginRegisterResponse { */ function removePlugin(route: string): SCPluginRegisterResponse { if (!plugins.has(route)) { - throw new SCNotFoundErrorResponse( - isTestEnvironment, - ); + throw new SCNotFoundErrorResponse(isTestEnvironment); } if (plugins.has(route)) { const plugin = plugins.get(route)!; diff --git a/src/routes/route.ts b/src/routes/route.ts index fc1e97b9..dcee9fa9 100644 --- a/src/routes/route.ts +++ b/src/routes/route.ts @@ -39,7 +39,8 @@ export function createRoute( routeClass: SCRoute, handler: ( validatedBody: REQUESTTYPE, - app: Application, params: { [parameterName: string]: string; }, + app: Application, + parameters: {[parameterName: string]: string}, ) => Promise, ): Router { // create router @@ -54,81 +55,73 @@ export function createRoute( // check if route has a valid http verb if (isHttpMethod(verb)) { // create a route handler for the given HTTP method - route[verb](async (req, res) => { - + route[verb](async (request, response) => { try { // validate request - const requestValidation = validator.validate(req.body, routeClass.requestBodyName); + const requestValidation = validator.validate(request.body, routeClass.requestBodyName); if (requestValidation.errors.length > 0) { - const error = new SCValidationErrorResponse( - requestValidation.errors, - isTestEnvironment, - ); - res.status(error.statusCode); - res.json(error); + const error = new SCValidationErrorResponse(requestValidation.errors, isTestEnvironment); + response.status(error.statusCode); + response.json(error); await Logger.error(error); return; } // hand over request to handler with path parameters - const response = await handler(req.body, req.app, req.params); + const handlerResponse = await handler(request.body, request.app, request.params); // validate response generated by handler - const responseErrors: ValidationError[] = validator.validate(response, routeClass.responseBodyName).errors; + const responseErrors: ValidationError[] = validator.validate( + handlerResponse, + routeClass.responseBodyName, + ).errors; if (responseErrors.length > 0) { - const validationError = new SCValidationErrorResponse( - responseErrors, - isTestEnvironment, - ); + const validationError = new SCValidationErrorResponse(responseErrors, isTestEnvironment); // The validation error is not caused by faulty user input, but through an error that originates somewhere in // the backend, therefore we use this "stacked" error. - const internalServerError = new SCInternalServerErrorResponse( - validationError, - isTestEnvironment, - ); - res.status(internalServerError.statusCode); - res.json(internalServerError); + const internalServerError = new SCInternalServerErrorResponse(validationError, isTestEnvironment); + response.status(internalServerError.statusCode); + response.json(internalServerError); await Logger.error(internalServerError); return; } // set status code - res.status(routeClass.statusCodeSuccess); + response.status(routeClass.statusCodeSuccess); // respond - res.json(response); + response.json(handlerResponse); } catch (error) { // if the error response is allowed on the route - if (routeClass.errorNames.some((constructorType) => error instanceof constructorType)) { + if (routeClass.errorNames.some(constructorType => error instanceof constructorType)) { // respond with the error from the handler - res.status(error.statusCode); - res.json(error); + response.status(error.statusCode); + response.json(error); await Logger.error(error); } else { // the error is not allowed so something went wrong - const internalServerError = new SCInternalServerErrorResponse( - error, - isTestEnvironment, - ); - res.status(internalServerError.statusCode); - res.json(internalServerError); + const internalServerError = new SCInternalServerErrorResponse(error, isTestEnvironment); + response.status(internalServerError.statusCode); + response.json(internalServerError); await Logger.error(error); } } }); } else { - throw new Error('Invalid HTTP verb in route definition. Please check route definitions in `@openstapps/core`'); + throw new Error( + 'Invalid HTTP verb in route definition. Please check route definitions in `@openstapps/core`', + ); } // return a SCMethodNotAllowedErrorResponse on all other HTTP methods - route.all((_req, res) => { + route.all((_request, response) => { const error = new SCMethodNotAllowedErrorResponse(isTestEnvironment); - res.status(error.statusCode); - res.json(error); + response.status(error.statusCode); + response.json(error); Logger.warn(error); }); diff --git a/src/routes/virtual-plugin-route.ts b/src/routes/virtual-plugin-route.ts index 41721825..dc56c07f 100644 --- a/src/routes/virtual-plugin-route.ts +++ b/src/routes/virtual-plugin-route.ts @@ -14,11 +14,7 @@ * along with this program. If not, see . */ -import { - SCInternalServerErrorResponse, - SCPluginMetaData, - SCValidationErrorResponse, -} from '@openstapps/core'; +import {SCInternalServerErrorResponse, SCPluginMetaData, SCValidationErrorResponse} from '@openstapps/core'; import {Request} from 'express'; import got from 'got'; import {configFile, isTestEnvironment, validator} from '../common'; @@ -26,35 +22,34 @@ import {configFile, isTestEnvironment, validator} from '../common'; /** * Generic route function used to proxy actual requests to plugins * - * @param req The request for a plugin resource + * @param request The request for a plugin resource * @param plugin Meta data of the plugin * @throws {SCInternalServerErrorResponse} On request/response validation or response from the plugin errors */ -export async function virtualPluginRoute(req: Request, plugin: SCPluginMetaData): Promise { +export async function virtualPluginRoute(request: Request, plugin: SCPluginMetaData): Promise { let responseBody: object; try { - const requestValidation = validator.validate(req.body, plugin.requestSchema); + const requestValidation = validator.validate(request.body, plugin.requestSchema); if (requestValidation.errors.length > 0) { + // noinspection ExceptionCaughtLocallyJS throw new SCValidationErrorResponse(requestValidation.errors, isTestEnvironment); } // send the request to the plugin (forward the body) and save the response - const pluginResponse = await got.post( - plugin.route.replace(/^\//gi, ''), - { - prefixUrl: plugin.address, - json: req.body, - timeout: configFile.backend.externalRequestTimeout, - responseType: 'json', - }, - ); + const pluginResponse = await got.post(plugin.route.replace(/^\//gi, ''), { + prefixUrl: plugin.address, + json: request.body, + timeout: configFile.backend.externalRequestTimeout, + responseType: 'json', + }); responseBody = pluginResponse.body as object; const responseValidation = validator.validate(responseBody, plugin.responseSchema); if (responseValidation.errors.length > 0) { + // noinspection ExceptionCaughtLocallyJS throw new SCValidationErrorResponse(responseValidation.errors, isTestEnvironment); } - } catch (e) { + } catch (error) { // wrap exact error inside of the internal server error response - throw new SCInternalServerErrorResponse(e, isTestEnvironment); + throw new SCInternalServerErrorResponse(error, isTestEnvironment); } return responseBody; diff --git a/src/storage/bulk-storage.ts b/src/storage/bulk-storage.ts index c85ee5b8..454e84c3 100644 --- a/src/storage/bulk-storage.ts +++ b/src/storage/bulk-storage.ts @@ -29,7 +29,6 @@ export type BulkOperation = 'create' | 'expired' | 'update'; * Describes an indexing process */ export class Bulk implements SCBulkRequest { - /** * Expiration of the bulk * @@ -70,19 +69,15 @@ export class Bulk implements SCBulkRequest { /** * Creates a new bulk process + * * @param request Data needed for requesting a bulk */ constructor(request: SCBulkRequest) { this.uid = v4(); this.state = 'in progress'; - if (typeof request.expiration === 'string') { - this.expiration = request.expiration; - } else { - this.expiration = moment() - .add(1, 'hour') - .toISOString(); - } + this.expiration = + typeof request.expiration === 'string' ? request.expiration : moment().add(1, 'hour').toISOString(); // when should this process be finished // where does the process come from this.source = request.source; @@ -102,10 +97,10 @@ export class BulkStorage { /** * Creates a new BulkStorage + * * @param database the database that is controlled by this bulk storage */ constructor(public database: Database) { - // a bulk lives 60 minutes if no expiration is given // the cache is checked every 60 seconds this.cache = new NodeCache({stdTTL: 3600, checkperiod: 60}); @@ -121,13 +116,12 @@ export class BulkStorage { /** * Saves a bulk process and assigns to it a user-defined ttl (time-to-live) + * * @param bulk the bulk process to save * @returns the bulk process that was saved */ private save(bulk: Bulk): Bulk { - const expirationInSeconds = moment(bulk.expiration) - // tslint:disable-next-line: no-magic-numbers - .diff(moment.now()) / 1000; + const expirationInSeconds = moment(bulk.expiration).diff(moment.now()) / 1000; Logger.info('Bulk expires in ', expirationInSeconds, 'seconds'); // save the item in the cache with it's expected expiration @@ -138,6 +132,7 @@ export class BulkStorage { /** * Create and save a new bulk process + * * @param bulkRequest a request for a new bulk process * @returns a promise that contains the new bulk process */ @@ -156,6 +151,7 @@ export class BulkStorage { /** * Delete a bulk process + * * @param uid uid of the bulk process * @returns a promise that contains the deleted bulk process */ @@ -163,7 +159,7 @@ export class BulkStorage { const bulk = this.read(uid); if (typeof bulk === 'undefined') { - throw new Error(`Bulk that should be deleted was not found. UID was "${uid}"`); + throw new TypeError(`Bulk that should be deleted was not found. UID was "${uid}"`); } // delete the bulk process from the cache @@ -177,6 +173,7 @@ export class BulkStorage { /** * Update an old bulk process (replace it with the new one) + * * @param bulk new bulk process * @returns an empty promise */ @@ -192,11 +189,11 @@ export class BulkStorage { /** * Read an existing bulk process + * * @param uid uid of the bulk process * @returns a promise that contains a bulk */ public read(uid: string): Bulk | undefined { return this.cache.get(uid); } - } diff --git a/src/storage/database.ts b/src/storage/database.ts index 85075ad3..8b144267 100644 --- a/src/storage/database.ts +++ b/src/storage/database.ts @@ -26,11 +26,11 @@ export type DatabaseConstructor = new (config: SCConfigFile, mailQueue?: MailQue * Defines what one database class needs to have defined */ export interface Database { - /** * Gets called if a bulk was created * * The database should + * * @param bulk A bulk to be created */ bulkCreated(bulk: Bulk): Promise; @@ -39,6 +39,7 @@ export interface Database { * Gets called if a bulk expires * * The database should delete all data that is associtated with this bulk + * * @param bulk A bulk which data needs to be removed */ bulkExpired(bulk: Bulk): Promise; @@ -55,6 +56,7 @@ export interface Database { /** * Get a single document + * * @param uid Unique identifier of the document */ get(uid: SCUuid): Promise; @@ -66,6 +68,7 @@ export interface Database { /** * Add a thing to an existing bulk + * * @param thing A StAppsCore thing to be added * @param bulk A bulk to which the thing should be added */ @@ -82,7 +85,8 @@ export interface Database { /** * Search for things + * * @param params Parameters which form a search query to search the backend data */ - search(params: SCSearchQuery): Promise; + search(parameters: SCSearchQuery): Promise; } diff --git a/src/storage/elasticsearch/aggregations.ts b/src/storage/elasticsearch/aggregations.ts index fe847178..5b01da46 100644 --- a/src/storage/elasticsearch/aggregations.ts +++ b/src/storage/elasticsearch/aggregations.ts @@ -26,10 +26,10 @@ import { /** * Parses elasticsearch aggregations (response from es) to facets for the app + * * @param aggregationResponse - aggregations response from elasticsearch */ export function parseAggregations(aggregationResponse: AggregationResponse): SCFacet[] { - const facets: SCFacet[] = []; // get all names of the types an aggregation is on @@ -52,7 +52,7 @@ export function parseAggregations(aggregationResponse: AggregationResponse): SCF // this should always be true in theory... if (isESTermsFilter(field) && isBucketAggregation(realField) && realField.buckets.length > 0) { const facet: SCFacet = { - buckets: realField.buckets.map((bucket) => { + buckets: realField.buckets.map(bucket => { return { count: bucket.doc_count, key: bucket.key, @@ -71,7 +71,7 @@ export function parseAggregations(aggregationResponse: AggregationResponse): SCF // the last part here means that it is a bucket aggregation } else if (isESTermsFilter(type) && !isNestedAggregation(realType) && realType.buckets.length > 0) { facets.push({ - buckets: realType.buckets.map((bucket) => { + buckets: realType.buckets.map(bucket => { return { count: bucket.doc_count, key: bucket.key, diff --git a/src/storage/elasticsearch/elasticsearch.ts b/src/storage/elasticsearch/elasticsearch.ts index 7bb773ef..b9e76958 100644 --- a/src/storage/elasticsearch/elasticsearch.ts +++ b/src/storage/elasticsearch/elasticsearch.ts @@ -27,7 +27,6 @@ import { import {Logger} from '@openstapps/logger'; // we only have the @types package because some things type definitions are still missing from the official // @elastic/elasticsearch package -// tslint:disable-next-line:no-implicit-dependencies import {IndicesUpdateAliasesParamsAction, SearchResponse} from 'elasticsearch'; import moment from 'moment'; import {MailQueue} from '../../notification/mail-queue'; @@ -39,7 +38,8 @@ import {buildQuery, buildSort} from './query'; import {aggregations, putTemplate} from './templating'; import { AggregationResponse, - ElasticsearchConfig, ElasticsearchObject, + ElasticsearchConfig, + ElasticsearchObject, ElasticsearchQueryDisMaxConfig, ElasticsearchQueryQueryStringConfig, } from './types/elasticsearch'; @@ -53,7 +53,6 @@ const indexRegex = /^stapps_([A-z0-9_]+)_([a-z0-9-_]+)_([-a-z0-9^_]+)$/; * A database interface for elasticsearch */ export class Elasticsearch implements Database { - /** * Length of the index UID used for generation of its name */ @@ -90,7 +89,7 @@ export class Elasticsearch implements Database { */ static getElasticsearchUrl(): string { // check if we have a docker link - if (process.env.ES_ADDR !== undefined ) { + if (process.env.ES_ADDR !== undefined) { return process.env.ES_ADDR; } @@ -100,6 +99,7 @@ export class Elasticsearch implements Database { /** * Gets the index name in elasticsearch for one SCThingType + * * @param type SCThingType of data in the index * @param source source of data in the index * @param bulk bulk process which created this index @@ -115,10 +115,11 @@ export class Elasticsearch implements Database { /** * Provides the index UID (for its name) from the bulk UID + * * @param uid Bulk UID */ static getIndexUID(uid: SCUuid) { - return uid.substring(0, Elasticsearch.INDEX_UID_LENGTH); + return uid.slice(0, Math.max(0, Elasticsearch.INDEX_UID_LENGTH)); } /** @@ -131,6 +132,7 @@ export class Elasticsearch implements Database { /** * Checks for invalid character in alias names and removes them + * * @param alias The alias name * @param uid The UID of the current bulk (for debugging purposes) */ @@ -140,26 +142,25 @@ export class Elasticsearch implements Database { // spaces are included in some types, replace them with underscores if (formattedAlias.includes(' ')) { formattedAlias = formattedAlias.trim(); - formattedAlias = formattedAlias.split(' ') - .join('_'); + formattedAlias = formattedAlias.split(' ').join('_'); } // List of invalid characters: https://www.elastic.co/guide/en/elasticsearch/reference/6.6/indices-create-index.html - ['\\', '/', '*', '?', '"', '<', '>', '|', ',', '#'].forEach((value) => { + for (const value of ['\\', '/', '*', '?', '"', '<', '>', '|', ',', '#']) { if (formattedAlias.includes(value)) { formattedAlias = formattedAlias.replace(value, ''); Logger.warn(`Type of the bulk ${uid} contains an invalid character '${value}'. This can lead to two bulks having the same alias despite having different types, as invalid characters are removed automatically. New alias name is "${formattedAlias}."`); } - }); - ['-', '_', '+'].forEach((value) => { + } + for (const value of ['-', '_', '+']) { if (formattedAlias.charAt(0) === value) { - formattedAlias = formattedAlias.substring(1); + formattedAlias = formattedAlias.slice(1); Logger.warn(`Type of the bulk ${uid} begins with '${value}'. This can lead to two bulks having the same alias despite having different types, as invalid characters are removed automatically. New alias name is "${formattedAlias}."`); } - }); + } if (formattedAlias === '.' || formattedAlias === '..') { Logger.warn(`Type of the bulk ${uid} is ${formattedAlias}. This is an invalid name, please consider using another one, as it will be replaced with 'alias_placeholder', which can lead to strange errors.`); @@ -176,22 +177,24 @@ export class Elasticsearch implements Database { /** * Create a new interface for elasticsearch + * * @param config an assembled config file * @param mailQueue a mailqueue for monitoring */ constructor(private readonly config: SCConfigFile, mailQueue?: MailQueue) { - - if (typeof config.internal.database === 'undefined' - || typeof config.internal.database.version !== 'string') { - throw new Error('Database version is undefined. Check your config file'); + if ( + typeof config.internal.database === 'undefined' || + typeof config.internal.database.version !== 'string' + ) { + throw new TypeError('Database version is undefined. Check your config file'); } this.client = new Client({ node: Elasticsearch.getElasticsearchUrl(), }); - this.client.on(events.REQUEST, async (err: Error | null, result: ApiResponse) => { - if (err !== null) { - await Logger.error(err); + this.client.on(events.REQUEST, async (error: Error | null, result: ApiResponse) => { + if (error !== null) { + await Logger.error(error); } if (process.env.ES_DEBUG === 'true') { Logger.log(result); @@ -215,18 +218,20 @@ export class Elasticsearch implements Database { // create a list of old indices that are not in use const oldIndicesToDelete: string[] = []; - let aliases: { - [index: string]: { - /** - * Aliases of an index - */ - aliases: { - [K in SCThingType]: unknown - }; - }; - } | undefined; + let aliases: + | { + [index: string]: { + /** + * Aliases of an index + */ + aliases: { + [K in SCThingType]: unknown; + }; + }; + } + | undefined; - for(const retry of [...Array(RETRY_COUNT)].map((_, i) => i+1)) { + for (const retry of [...Array.from({length: RETRY_COUNT})].map((_, i) => i + 1)) { if (typeof aliases !== 'undefined') { break; } @@ -241,16 +246,14 @@ export class Elasticsearch implements Database { } if (typeof aliases === 'undefined') { - throw Error(`Failed to retrieve alias map after ${RETRY_COUNT} attempts!`); + throw new TypeError(`Failed to retrieve alias map after ${RETRY_COUNT} attempts!`); } for (const index in aliases) { if (aliases.hasOwnProperty(index)) { - const matches = indexRegex.exec(index); if (matches !== null) { const type = matches[1]; - // tslint:disable-next-line: no-magic-numbers const source = matches[2]; // check if there is an alias for the current index @@ -278,12 +281,13 @@ export class Elasticsearch implements Database { Logger.warn(`Deleted old indices: oldIndicesToDelete`); } - // tslint:disable-next-line: no-magic-numbers + // eslint-disable-next-line unicorn/no-null Logger.ok(`Read alias map from elasticsearch: ${JSON.stringify(this.aliasMap, null, 2)}`); } /** * Provides an elasticsearch object using containing thing's UID + * * @param uid an UID to use for the search * @returns an elasticsearch object containing the thing */ @@ -309,6 +313,7 @@ export class Elasticsearch implements Database { /** * Should be called, when a new bulk was created. Creates a new index and applies a the mapping to the index + * * @param bulk the bulk process that was created */ public async bulkCreated(bulk: Bulk): Promise { @@ -346,6 +351,7 @@ export class Elasticsearch implements Database { /** * Should be called when a bulk process is expired. The index that was created with this bulk gets deleted + * * @param bulk the bulk process that is expired */ public async bulkExpired(bulk: Bulk): Promise { @@ -365,6 +371,7 @@ export class Elasticsearch implements Database { /** * Should be called when a bulk process is updated (replaced by a newer bulk). This will replace the old * index and publish all data, that was index in the new instead + * * @param bulk the new bulk process that should replace the old one with same type and source */ public async bulkUpdated(bulk: Bulk): Promise { @@ -391,6 +398,7 @@ export class Elasticsearch implements Database { } // create the new index if it does not exists + // eslint-disable-next-line unicorn/no-await-expression-member if (!(await this.client.indices.exists({index})).body) { // re-apply the index template before each new bulk operation await putTemplate(this.client, bulk.type); @@ -411,6 +419,7 @@ export class Elasticsearch implements Database { ]; // remove our old index if it exists + // noinspection SuspiciousTypeOfGuard if (typeof oldIndex === 'string') { actions.push({ remove: {index: oldIndex, alias: alias}, @@ -431,6 +440,7 @@ export class Elasticsearch implements Database { // swap the index in our aliasMap this.aliasMap[alias][bulk.source] = index; + // noinspection SuspiciousTypeOfGuard if (typeof oldIndex === 'string') { // delete the old index await this.client.indices.delete({index: oldIndex}); @@ -441,13 +451,14 @@ export class Elasticsearch implements Database { /** * Gets an SCThing from all indexed data + * * @param uid uid of an SCThing */ public async get(uid: SCUuid): Promise { const object = await this.getObject(uid); if (typeof object === 'undefined') { - throw new Error('Item not found.'); + throw new TypeError('Item not found.'); } return object._source; @@ -461,7 +472,9 @@ export class Elasticsearch implements Database { if (typeof monitoringConfiguration !== 'undefined') { if (typeof this.mailQueue === 'undefined') { - throw new Error('Monitoring is defined, but MailQueue is undefined. A MailQueue is obligatory for monitoring.'); + throw new TypeError( + 'Monitoring is defined, but MailQueue is undefined. A MailQueue is obligatory for monitoring.', + ); } // read all watches and schedule searches on the client await Monitoring.setUp(monitoringConfiguration, this.client, this.mailQueue); @@ -472,56 +485,55 @@ export class Elasticsearch implements Database { /** * Add an item to an index + * * @param object the SCThing to add to the index * @param bulk the bulk process which item belongs to */ public async post(object: SCThings, bulk: Bulk): Promise { - - // tslint:disable-next-line: completed-docs - const obj: SCThings & { creation_date: string; } = { + const object_: SCThings & {creation_date: string} = { ...object, - creation_date: moment() - .format(), + creation_date: moment().format(), }; const item = await this.getObject(object.uid); // check that the item will get replaced if the index is rolled over (index with the same name excluding ending uid) if (typeof item !== 'undefined') { - const indexOfNew = Elasticsearch.getIndex(obj.type, bulk.source, bulk); + const indexOfNew = Elasticsearch.getIndex(object_.type, bulk.source, bulk); const oldIndex = item._index; // new item doesn't replace the old one - // tslint:disable-next-line:no-magic-numbers - if (oldIndex.substring(0, oldIndex.lastIndexOf('_')) - !== indexOfNew.substring(0, indexOfNew.lastIndexOf('_'))) { + if ( + oldIndex.slice(0, Math.max(0, oldIndex.lastIndexOf('_'))) !== + indexOfNew.slice(0, Math.max(0, indexOfNew.lastIndexOf('_'))) + ) { throw new Error( - // tslint:disable-next-line: no-magic-numbers - `Object "${obj.uid}" already exists. Object was: ${JSON.stringify(obj, null, 2)}`, + // eslint-disable-next-line unicorn/no-null + `Object "${object_.uid}" already exists. Object was: ${JSON.stringify(object_, null, 2)}`, ); } } // regular bulk update (item gets replaced when bulk is updated) const searchResponse = await this.client.create({ - body: obj, - id: obj.uid, - index: Elasticsearch.getIndex(obj.type, bulk.source, bulk), + body: object_, + id: object_.uid, + index: Elasticsearch.getIndex(object_.type, bulk.source, bulk), timeout: '90s', - type: obj.type, + type: object_.type, }); if (!searchResponse.body.created) { - throw new Error(`Object creation Error: Instance was: ${JSON.stringify(obj)}`); + throw new Error(`Object creation Error: Instance was: ${JSON.stringify(object_)}`); } } /** * Put (update) an existing item + * * @param object SCThing to put */ public async put(object: SCThings): Promise { - const item = await this.getObject(object.uid); if (typeof item !== 'undefined') { @@ -542,12 +554,12 @@ export class Elasticsearch implements Database { /** * Search all indexed data - * @param params search query + * + * @param parameters search query */ - public async search(params: SCSearchQuery): Promise { - + public async search(parameters: SCSearchQuery): Promise { if (typeof this.config.internal.database === 'undefined') { - throw new Error('Database is undefined. You have to configure the query build'); + throw new TypeError('Database is undefined. You have to configure the query build'); } // create elasticsearch configuration out of data from database configuration @@ -557,23 +569,23 @@ export class Elasticsearch implements Database { }; if (typeof this.config.internal.database.query !== 'undefined') { - esConfig.query = - this.config.internal.database - .query as ElasticsearchQueryDisMaxConfig | ElasticsearchQueryQueryStringConfig; + esConfig.query = this.config.internal.database.query as + | ElasticsearchQueryDisMaxConfig + | ElasticsearchQueryQueryStringConfig; } const searchRequest: RequestParams.Search = { body: { aggs: aggregations, - query: buildQuery(params, this.config, esConfig), + query: buildQuery(parameters, this.config, esConfig), }, - from: params.from, + from: parameters.from, index: Elasticsearch.getListOfAllIndices(), - size: params.size, + size: parameters.size, }; - if (typeof params.sort !== 'undefined') { - searchRequest.body.sort = buildSort(params.sort); + if (typeof parameters.sort !== 'undefined') { + searchRequest.body.sort = buildSort(parameters.sort); } // perform the search against elasticsearch @@ -582,7 +594,7 @@ export class Elasticsearch implements Database { // gather pagination information const pagination = { count: response.body.hits.hits.length, - offset: (typeof params.from === 'number') ? params.from : 0, + offset: typeof parameters.from === 'number' ? parameters.from : 0, total: response.body.hits.total, }; @@ -593,7 +605,7 @@ export class Elasticsearch implements Database { // we only directly return the _source documents // elasticsearch provides much more information, the user shouldn't see - const data = response.body.hits.hits.map((hit) => { + const data = response.body.hits.hits.map(hit => { return hit._source; // SCThing }); diff --git a/src/storage/elasticsearch/monitoring.ts b/src/storage/elasticsearch/monitoring.ts index 7fe32401..2af1b283 100644 --- a/src/storage/elasticsearch/monitoring.ts +++ b/src/storage/elasticsearch/monitoring.ts @@ -25,13 +25,13 @@ import { import {Logger} from '@openstapps/logger'; // we only have the @types package because some things type definitions are still missing from the official // @elastic/elasticsearch package -// tslint:disable-next-line:no-implicit-dependencies import {SearchResponse} from 'elasticsearch'; import cron from 'node-cron'; import {MailQueue} from '../../notification/mail-queue'; /** * Check if the given condition fails on the given number of results and the condition + * * @param condition condition * @param total number of results */ @@ -48,6 +48,7 @@ function conditionFails( /** * Check if the min condition fails + * * @param minimumLength Minimal length allowed * @param total Number of results */ @@ -57,6 +58,7 @@ function minConditionFails(minimumLength: number, total: number) { /** * Check if the max condition fails + * * @param maximumLength Maximal length allowed * @param total Number of results */ @@ -66,6 +68,7 @@ function maxConditionFails(maximumLength: number, total: number) { /** * Run all the given actions + * * @param actions actions to perform * @param watcherName name of watcher that wants to perform them * @param triggerName name of trigger that triggered the watcher @@ -79,38 +82,39 @@ function runActions( total: number, mailQueue: MailQueue, ) { - - actions.forEach(async (action) => { - if (action.type === 'log') { - await Logger.error( - action.prefix, - `Watcher '${watcherName}' failed. Watcher was triggered by '${triggerName}'`, `Found ${total} hits instead`, - action.message, - ); - } else { - await mailQueue.push({ - subject: action.subject, - text: `Watcher '${watcherName}' failed. Watcher was triggered by '${triggerName}' + for (const action of actions) { + void (action.type === 'log' + ? Logger.error( + action.prefix, + `Watcher '${watcherName}' failed. Watcher was triggered by '${triggerName}'`, + `Found ${total} hits instead`, + action.message, + ) + : mailQueue.push({ + subject: action.subject, + text: `Watcher '${watcherName}' failed. Watcher was triggered by '${triggerName}' ${action.message} Found ${total} hits instead`, - to: action.recipients, - }); - } - }); + to: action.recipients, + })); + } } /** * Set up the triggers for the configured watchers + * * @param monitoringConfig configuration of the monitoring * @param esClient elasticsearch client * @param mailQueue mailQueue for mail actions */ -export async function setUp(monitoringConfig: SCMonitoringConfiguration, esClient: Client, mailQueue: MailQueue) { - +export async function setUp( + monitoringConfig: SCMonitoringConfiguration, + esClient: Client, + mailQueue: MailQueue, +) { // set up Watches - monitoringConfig.watchers.forEach((watcher) => { - + for (const watcher of monitoringConfig.watchers) { // make a schedule for each trigger - watcher.triggers.forEach((trigger) => { + for (const trigger of watcher.triggers) { switch (trigger.executionTime) { case 'hourly': trigger.executionTime = '5 * * * *'; @@ -127,21 +131,21 @@ export async function setUp(monitoringConfig: SCMonitoringConfiguration, esClien cron.schedule(trigger.executionTime, async () => { // execute watch (search->condition->action) - const result: ApiResponse> = - await esClient.search(watcher.query as RequestParams.Search); + const result: ApiResponse> = await esClient.search( + watcher.query as RequestParams.Search, + ); // check conditions const total = result.body.hits.total; - watcher.conditions.forEach((condition) => { + for (const condition of watcher.conditions) { if (conditionFails(condition, total)) { runActions(watcher.actions, watcher.name, trigger.name, total, mailQueue); } - }); + } }); - }); - - }); + } + } Logger.log(`Scheduled ${monitoringConfig.watchers.length} watches`); } diff --git a/src/storage/elasticsearch/query.ts b/src/storage/elasticsearch/query.ts index 64927aed..ef174e64 100644 --- a/src/storage/elasticsearch/query.ts +++ b/src/storage/elasticsearch/query.ts @@ -34,7 +34,8 @@ import { ESFunctionScoreQuery, ESFunctionScoreQueryFunction, ESGenericRange, - ESGenericSort, ESGeoBoundingBoxFilter, + ESGenericSort, + ESGeoBoundingBoxFilter, ESGeoDistanceFilter, ESGeoDistanceFilterArguments, ESGeoDistanceSort, @@ -55,19 +56,19 @@ import { * It is possible to use all, with the exception of < and >, of them by escaping them with a \ * https://www.elastic.co/guide/en/elasticsearch/reference/5.6/query-dsl-query-string-query.html * - * @param str the string to escape the characters from + * @param string_ the string to escape the characters from */ -function escapeESReservedCharacters(str: string): string { - return str.replace(/[+\-=!(){}\[\]^"~*?:\\/]|(&&)|(\|\|)/g, '\\$&'); +function escapeESReservedCharacters(string_: string): string { + return string_.replace(/[+\-=!(){}\[\]^"~*?:\\/]|(&&)|(\|\|)/g, '\\$&'); } /** * Builds a boolean filter. Returns an elasticsearch boolean filter + * * @param booleanFilter a search boolean filter for the retrieval of the data * @returns elasticsearch boolean arguments object */ export function buildBooleanFilter(booleanFilter: SCSearchBooleanFilter): ESBooleanFilterArguments { - const result: ESBooleanFilterArguments = { minimum_should_match: 0, must: [], @@ -76,16 +77,16 @@ export function buildBooleanFilter(booleanFilter: SCSearchBooleanFilter): ESBool }; if (booleanFilter.arguments.operation === 'and') { - result.must = booleanFilter.arguments.filters.map((filter) => buildFilter(filter)); + result.must = booleanFilter.arguments.filters.map(filter => buildFilter(filter)); } if (booleanFilter.arguments.operation === 'or') { - result.should = booleanFilter.arguments.filters.map((filter) => buildFilter(filter)); + result.should = booleanFilter.arguments.filters.map(filter => buildFilter(filter)); result.minimum_should_match = 1; } if (booleanFilter.arguments.operation === 'not') { - result.must_not = booleanFilter.arguments.filters.map((filter) => buildFilter(filter)); + result.must_not = booleanFilter.arguments.filters.map(filter => buildFilter(filter)); } return result; @@ -93,22 +94,31 @@ export function buildBooleanFilter(booleanFilter: SCSearchBooleanFilter): ESBool /** * Converts Array of Filters to elasticsearch query-syntax + * * @param filter A search filter for the retrieval of the data */ -export function buildFilter(filter: SCSearchFilter): - ESTermFilter | ESGeoDistanceFilter | ESBooleanFilter | ESGeoShapeFilter | ESBooleanFilter | ESRangeFilter { - +export function buildFilter( + filter: SCSearchFilter, +): + | ESTermFilter + | ESGeoDistanceFilter + | ESBooleanFilter + | ESGeoShapeFilter + | ESBooleanFilter + | ESRangeFilter { switch (filter.type) { case 'value': - return Array.isArray(filter.arguments.value) ? { - terms: { - [`${filter.arguments.field}.raw`]: filter.arguments.value, - }, - } : { - term: { - [`${filter.arguments.field}.raw`]: filter.arguments.value, - }, - }; + return Array.isArray(filter.arguments.value) + ? { + terms: { + [`${filter.arguments.field}.raw`]: filter.arguments.value, + }, + } + : { + term: { + [`${filter.arguments.field}.raw`]: filter.arguments.value, + }, + }; case 'availability': const scope = filter.arguments.scope?.charAt(0) ?? 's'; const time = typeof filter.arguments.time === 'undefined' ? 'now' : `${filter.arguments.time}||`; @@ -185,8 +195,7 @@ export function buildFilter(filter: SCSearchFilter): /** * https://www.elastic.co/guide/en/elasticsearch/reference/5.6/query-dsl-geo-shape-query.html#_ignore_unmapped_3 */ - // tslint:disable-next-line:ban-ts-ignore - // @ts-ignore unfortunately, typescript is stupid and won't allow me to map this to an actual type. + // @ts-expect-error unfortunately, typescript is stupid and won't allow me to map this to an actual type. ignore_unmapped: true, [`${filter.arguments.field}.polygon`]: { shape: filter.arguments.shape, @@ -195,8 +204,10 @@ export function buildFilter(filter: SCSearchFilter): }, }; - if ((typeof filter.arguments.spatialRelation === 'undefined' || filter.arguments.spatialRelation === 'intersects') - && filter.arguments.shape.type === 'envelope' + if ( + (typeof filter.arguments.spatialRelation === 'undefined' || + filter.arguments.spatialRelation === 'intersects') && + filter.arguments.shape.type === 'envelope' ) { return { bool: { @@ -208,8 +219,6 @@ export function buildFilter(filter: SCSearchFilter): /** * https://www.elastic.co/guide/en/elasticsearch/reference/5.6/query-dsl-geo-shape-query.html#_ignore_unmapped_3 */ - // tslint:disable-next-line:ban-ts-ignore - // @ts-ignore unfortunately, typescript is stupid and won't allow me to map this to an actual type. ignore_unmapped: true, [`${filter.arguments.field}.point.coordinates`]: { top_left: filter.arguments.shape.coordinates[0], @@ -228,6 +237,7 @@ export function buildFilter(filter: SCSearchFilter): /** * Builds scoring functions from boosting config + * * @param boostings Backend boosting configuration for contexts and types * @param context The context of the app from where the search was initiated */ @@ -235,14 +245,14 @@ function buildFunctions( boostings: SCBackendConfigurationSearchBoostingContext, context: SCSearchContext | undefined, ): ESFunctionScoreQueryFunction[] { - // default context - let functions: ESFunctionScoreQueryFunction[] = - buildFunctionsForBoostingTypes(boostings['default' as SCSearchContext]); + let functions: ESFunctionScoreQueryFunction[] = buildFunctionsForBoostingTypes( + boostings['default' as SCSearchContext], + ); if (typeof context !== 'undefined' && context !== 'default') { // specific context provided, extend default context with additional boosts - functions = functions.concat(buildFunctionsForBoostingTypes(boostings[context])); + functions = [...functions, ...buildFunctionsForBoostingTypes(boostings[context])]; } return functions; @@ -258,7 +268,7 @@ function buildFunctionsForBoostingTypes( ): ESFunctionScoreQueryFunction[] { const functions: ESFunctionScoreQueryFunction[] = []; - boostingTypes.forEach((boostingForOneSCType) => { + for (const boostingForOneSCType of boostingTypes) { const typeFilter: ESTypeFilter = { type: { value: boostingForOneSCType.type, @@ -271,7 +281,6 @@ function buildFunctionsForBoostingTypes( }); if (typeof boostingForOneSCType.fields !== 'undefined') { - const fields = boostingForOneSCType.fields; for (const fieldName in boostingForOneSCType.fields) { @@ -291,10 +300,7 @@ function buildFunctionsForBoostingTypes( functions.push({ filter: { bool: { - must: [ - typeFilter, - termFilter, - ], + must: [typeFilter, termFilter], should: [], }, }, @@ -305,24 +311,24 @@ function buildFunctionsForBoostingTypes( } } } - }); + } return functions; } /** * Builds body for Elasticsearch requests - * @param params Parameters for querying the backend + * + * @param parameters Parameters for querying the backend * @param defaultConfig Default configuration of the backend * @param elasticsearchConfig Elasticsearch configuration * @returns ElasticsearchQuery (body of a search-request) */ export function buildQuery( - params: SCSearchQuery, + parameters: SCSearchQuery, defaultConfig: SCConfigFile, elasticsearchConfig: ElasticsearchConfig, ): ESFunctionScoreQuery { - // if config provides an minMatch parameter we use query_string instead of match query let query; if (typeof elasticsearchConfig.query === 'undefined') { @@ -331,7 +337,7 @@ export function buildQuery( analyzer: 'search_german', default_field: 'name', minimum_should_match: '90%', - query: (typeof params.query !== 'string') ? '*' : escapeESReservedCharacters(params.query), + query: typeof parameters.query !== 'string' ? '*' : escapeESReservedCharacters(parameters.query), }, }; } else if (elasticsearchConfig.query.queryType === 'query_string') { @@ -340,11 +346,11 @@ export function buildQuery( analyzer: 'search_german', default_field: 'name', minimum_should_match: elasticsearchConfig.query.minMatch, - query: (typeof params.query !== 'string') ? '*' : escapeESReservedCharacters(params.query), + query: typeof parameters.query !== 'string' ? '*' : escapeESReservedCharacters(parameters.query), }, }; } else if (elasticsearchConfig.query.queryType === 'dis_max') { - if (params.query !== '*') { + if (parameters.query !== '*') { query = { dis_max: { boost: 1.2, @@ -355,7 +361,7 @@ export function buildQuery( boost: elasticsearchConfig.query.matchBoosting, cutoff_frequency: elasticsearchConfig.query.cutoffFrequency, fuzziness: elasticsearchConfig.query.fuzziness, - query: (typeof params.query !== 'string') ? '*' : params.query, + query: typeof parameters.query !== 'string' ? '*' : parameters.query, }, }, }, @@ -364,22 +370,24 @@ export function buildQuery( analyzer: 'search_german', default_field: 'name', minimum_should_match: elasticsearchConfig.query.minMatch, - query: (typeof params.query !== 'string') ? '*' : escapeESReservedCharacters(params.query), + query: + typeof parameters.query !== 'string' ? '*' : escapeESReservedCharacters(parameters.query), }, }, ], tie_breaker: elasticsearchConfig.query.tieBreaker, }, - }; } } else { - throw new Error('Unsupported query type. Check your config file and reconfigure your elasticsearch query'); + throw new Error( + 'Unsupported query type. Check your config file and reconfigure your elasticsearch query', + ); } const functionScoreQuery: ESFunctionScoreQuery = { function_score: { - functions: buildFunctions(defaultConfig.internal.boostings, params.context), + functions: buildFunctions(defaultConfig.internal.boostings, parameters.context), query: { bool: { minimum_should_match: 0, // if we have no should, nothing can match @@ -398,8 +406,8 @@ export function buildQuery( mustMatch.push(query); } - if (typeof params.filter !== 'undefined') { - mustMatch.push(buildFilter(params.filter)); + if (typeof parameters.filter !== 'undefined') { + mustMatch.push(buildFilter(parameters.filter)); } } @@ -408,13 +416,12 @@ export function buildQuery( /** * converts query to + * * @param sorts Sorting rules to apply to the data that is being queried * @returns an array of sort queries */ -export function buildSort( - sorts: SCSearchSort[], -): Array { - return sorts.map((sort) => { +export function buildSort(sorts: SCSearchSort[]): Array { + return sorts.map(sort => { switch (sort.type) { case 'generic': const esGenericSort: ESGenericSort = {}; @@ -427,26 +434,26 @@ export function buildSort( return esDucetSort; case 'distance': - const args: ESGeoDistanceSortArguments = { + const arguments_: ESGeoDistanceSortArguments = { mode: 'avg', order: sort.order, unit: 'm', }; - args[`${sort.arguments.field}.point.coordinates`] = { + arguments_[`${sort.arguments.field}.point.coordinates`] = { lat: sort.arguments.position[1], lon: sort.arguments.position[0], }; return { - _geo_distance: args, + _geo_distance: arguments_, }; case 'price': return { _script: { order: sort.order, script: buildPriceSortScript(sort.arguments.universityRole, sort.arguments.field), - type: 'number' as 'number', + type: 'number' as const, }, }; } @@ -459,7 +466,10 @@ export function buildSort( * @param universityRole User group which consumes university services * @param field Field in which wanted offers with prices are located */ -export function buildPriceSortScript(universityRole: keyof SCSportCoursePriceGroup, field: SCThingsField): string { +export function buildPriceSortScript( + universityRole: keyof SCSportCoursePriceGroup, + field: SCThingsField, +): string { return ` // initialize the sort value with the maximum double price = Double.MAX_VALUE; diff --git a/src/storage/elasticsearch/templating.ts b/src/storage/elasticsearch/templating.ts index f9509088..4301f6ff 100644 --- a/src/storage/elasticsearch/templating.ts +++ b/src/storage/elasticsearch/templating.ts @@ -15,18 +15,19 @@ */ import {Client} from '@elastic/elasticsearch'; import {SCThingType} from '@openstapps/core'; -// tslint:disable-next-line:no-implicit-dependencies import {AggregationSchema} from '@openstapps/es-mapping-generator/src/types/aggregation'; -// tslint:disable-next-line:no-implicit-dependencies import {ElasticsearchTemplateCollection} from '@openstapps/es-mapping-generator/src/types/mapping'; import {readFileSync} from 'fs'; -import {resolve} from 'path'; +import path from 'path'; -const mappingsPath = resolve('node_modules', '@openstapps', 'core', 'lib','mappings'); - -export const mappings = JSON.parse(readFileSync(resolve(mappingsPath, 'mappings.json'), 'utf-8')) as ElasticsearchTemplateCollection; -export const aggregations = JSON.parse(readFileSync(resolve(mappingsPath, 'aggregations.json'), 'utf-8')) as AggregationSchema; +const mappingsPath = path.resolve('node_modules', '@openstapps', 'core', 'lib', 'mappings'); +export const mappings = JSON.parse( + readFileSync(path.resolve(mappingsPath, 'mappings.json'), 'utf8'), +) as ElasticsearchTemplateCollection; +export const aggregations = JSON.parse( + readFileSync(path.resolve(mappingsPath, 'aggregations.json'), 'utf8'), +) as AggregationSchema; /** * Re-applies all interfaces for every type @@ -44,8 +45,8 @@ export async function refreshAllTemplates(client: Client) { * * This includes applying the mapping, settings * - * @param type the SCThingType of which the template should be set * @param client An elasticsearch client to use + * @param type the SCThingType of which the template should be set */ export async function putTemplate(client: Client, type: SCThingType) { const sanitizedType = `template_${type.replace(/\s/g, '_')}`; diff --git a/src/storage/elasticsearch/types/elasticsearch.ts b/src/storage/elasticsearch/types/elasticsearch.ts index 0277de0d..6804a4f9 100644 --- a/src/storage/elasticsearch/types/elasticsearch.ts +++ b/src/storage/elasticsearch/types/elasticsearch.ts @@ -15,9 +15,7 @@ */ import {SCThing, SCThingType} from '@openstapps/core'; // we only have the @types package because some things type definitions are still missing from the official -// tslint:disable-next-line:no-implicit-dependencies import {NameList} from 'elasticsearch'; -// tslint:disable-next-line:no-implicit-dependencies import {Polygon, Position} from 'geojson'; /** @@ -75,7 +73,6 @@ export interface NestedAggregation { [name: string]: BucketAggregation | number; } - /** * A configuration for using the Dis Max Query * @@ -90,30 +87,35 @@ export interface ElasticsearchQueryDisMaxConfig { /** * The maximum allowed Levenshtein Edit Distance (or number of edits) + * * @see https://www.elastic.co/guide/en/elasticsearch/reference/5.6/common-options.html#fuzziness */ fuzziness: number | string; /** * Increase the importance (relevance score) of a field + * * @see https://www.elastic.co/guide/en/elasticsearch/reference/5.6/mapping-boost.html */ matchBoosting: number; /** * Minimal number (or percentage) of words that should match in a query + * * @see https://www.elastic.co/guide/en/elasticsearch/reference/5.6/query-dsl-minimum-should-match.html */ minMatch: string; /** * Type of the query - in this case 'dis_max' which is a union of its subqueries + * * @see https://www.elastic.co/guide/en/elasticsearch/reference/5.6/query-dsl-dis-max-query.html */ queryType: 'dis_max'; /** * Changes behavior of default calculation of the score when multiple results match + * * @see https://www.elastic.co/guide/en/elasticsearch/reference/5.6/query-dsl-multi-match-query.html#tie-breaker */ tieBreaker: number; @@ -128,12 +130,14 @@ export interface ElasticsearchQueryDisMaxConfig { export interface ElasticsearchQueryQueryStringConfig { /** * Minimal number (or percentage) of words that should match in a query + * * @see https://www.elastic.co/guide/en/elasticsearch/reference/5.6/query-dsl-minimum-should-match.html */ minMatch: string; /** * Type of the query - in this case 'query_string' which uses a query parser in order to parse content + * * @see https://www.elastic.co/guide/en/elasticsearch/reference/5.6/query-dsl-query-string-query.html */ queryType: 'query_string'; @@ -141,6 +145,7 @@ export interface ElasticsearchQueryQueryStringConfig { /** * A hit in an elasticsearch search result + * * @see https://www.elastic.co/guide/en/elasticsearch/reference/5.6/mapping-fields.html */ export interface ElasticsearchObject { @@ -166,6 +171,7 @@ export interface ElasticsearchObject { /** * The document's mapping type + * * @see https://www.elastic.co/guide/en/elasticsearch/reference/5.6/mapping-type-field.html */ _type: string; @@ -177,22 +183,25 @@ export interface ElasticsearchObject { /** * Used to index the same field in different ways for different purposes + * * @see https://www.elastic.co/guide/en/elasticsearch/reference/5.6/multi-fields.html */ fields?: NameList; /** * Used to highlight search results on one or more fields + * * @see https://www.elastic.co/guide/en/elasticsearch/reference/5.6/search-request-highlighting.html */ - // tslint:disable-next-line: no-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any highlight?: any; /** * Used in when nested/children documents match the query + * * @see https://www.elastic.co/guide/en/elasticsearch/reference/5.6/search-request-inner-hits.html */ - // tslint:disable-next-line: no-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any inner_hits?: any; /** @@ -246,21 +255,23 @@ export interface ElasticsearchConfig { /** * An elasticsearch term filter */ -export type ESTermFilter = { - /** - * Definition of a term to match - */ - term: { - [fieldName: string]: string; - }; -} | { - /** - * Definition of terms to match (or) - */ - terms: { - [fieldName: string]: string[]; - }; -}; +export type ESTermFilter = + | { + /** + * Definition of a term to match + */ + term: { + [fieldName: string]: string; + }; + } + | { + /** + * Definition of terms to match (or) + */ + terms: { + [fieldName: string]: string[]; + }; + }; export interface ESGenericRange { /** @@ -318,7 +329,6 @@ export type ESNumericRangeFilter = ESGenericRangeFilter; export type ESRangeFilter = ESNumericRangeFilter | ESDateRangeFilter; - /** * An elasticsearch type filter */ @@ -343,17 +353,19 @@ export interface ESGeoDistanceFilterArguments { */ distance: string; - [fieldName: string]: { - /** - * Latitude - */ - lat: number; + [fieldName: string]: + | { + /** + * Latitude + */ + lat: number; - /** - * Longitude - */ - lon: number; - } | string; + /** + * Longitude + */ + lon: number; + } + | string; } /** @@ -386,11 +398,13 @@ export interface ESEnvelope { /** * An Elasticsearch geo bounding box filter + * * @see https://www.elastic.co/guide/en/elasticsearch/reference/5.6/query-dsl-geo-bounding-box-query.html */ export interface ESGeoBoundingBoxFilter { /** * An Elasticsearch geo bounding box filter + * * @see https://www.elastic.co/guide/en/elasticsearch/reference/5.6/query-dsl-geo-bounding-box-query.html */ geo_bounding_box: { @@ -410,6 +424,7 @@ export interface ESGeoBoundingBoxFilter { /** * An Elasticsearch geo shape filter + * * @see https://www.elastic.co/guide/en/elasticsearch/reference/5.6/query-dsl-geo-shape-query.html */ export interface ESGeoShapeFilter { @@ -432,11 +447,13 @@ export interface ESGeoShapeFilter { /** * Filter arguments for an elasticsearch boolean filter + * * @see https://www.elastic.co/guide/en/elasticsearch/reference/5.6/query-dsl-bool-query.html */ export interface ESBooleanFilterArguments { /** * Minimal number (or percentage) of words that should match in a query + * * @see https://www.elastic.co/guide/en/elasticsearch/reference/5.6/query-dsl-minimum-should-match.html */ minimum_should_match?: number; @@ -469,6 +486,7 @@ export interface ESBooleanFilter { /** * An elasticsearch function score query + * * @see https://www.elastic.co/guide/en/elasticsearch/reference/5.6/query-dsl-function-score-query.html */ export interface ESFunctionScoreQuery { @@ -478,6 +496,7 @@ export interface ESFunctionScoreQuery { function_score: { /** * Functions that compute score for query results (documents) + * * @see ESFunctionScoreQueryFunction */ functions: ESFunctionScoreQueryFunction[]; @@ -535,17 +554,19 @@ export interface ESGeoDistanceSortArguments { */ unit: 'm'; - [field: string]: { - /** - * Latitude - */ - lat: number; + [field: string]: + | { + /** + * Latitude + */ + lat: number; - /** - * Longitude - */ - lon: number; - } | string; + /** + * Longitude + */ + lon: number; + } + | string; } /** diff --git a/src/storage/elasticsearch/types/guards.ts b/src/storage/elasticsearch/types/guards.ts index 637b21be..c5bf60bc 100644 --- a/src/storage/elasticsearch/types/guards.ts +++ b/src/storage/elasticsearch/types/guards.ts @@ -18,12 +18,12 @@ import { ESAggTypeFilter, ESNestedAggregation, ESTermsFilter, -// tslint:disable-next-line:no-implicit-dependencies we're just using the types here } from '@openstapps/es-mapping-generator/src/types/aggregation'; import {BucketAggregation, NestedAggregation} from './elasticsearch'; /** * Checks if the type is a BucketAggregation + * * @param agg the type to check */ export function isBucketAggregation(agg: BucketAggregation | number): agg is BucketAggregation { @@ -32,6 +32,7 @@ export function isBucketAggregation(agg: BucketAggregation | number): agg is Buc /** * Checks if the type is a NestedAggregation + * * @param agg the type to check */ export function isNestedAggregation(agg: BucketAggregation | NestedAggregation): agg is NestedAggregation { @@ -40,6 +41,7 @@ export function isNestedAggregation(agg: BucketAggregation | NestedAggregation): /** * Checks if the parameter is of type ESTermsFilter + * * @param agg the value to check */ export function isESTermsFilter(agg: ESTermsFilter | ESNestedAggregation): agg is ESTermsFilter { @@ -48,6 +50,7 @@ export function isESTermsFilter(agg: ESTermsFilter | ESNestedAggregation): agg i /** * Checks if the parameter is of type ESTermsFilter + * * @param agg the value to check */ export function isESNestedAggregation(agg: ESTermsFilter | ESNestedAggregation): agg is ESNestedAggregation { @@ -59,6 +62,8 @@ export function isESNestedAggregation(agg: ESTermsFilter | ESNestedAggregation): * * @param filter the filter to narrow the type of */ -export function isESAggMatchAllFilter(filter: ESAggTypeFilter | ESAggMatchAllFilter): filter is ESAggMatchAllFilter { +export function isESAggMatchAllFilter( + filter: ESAggTypeFilter | ESAggMatchAllFilter, +): filter is ESAggMatchAllFilter { return filter.hasOwnProperty('match_all'); } diff --git a/test/app.spec.ts b/test/app.spec.ts index b2d9fc86..5ad2ae0a 100644 --- a/test/app.spec.ts +++ b/test/app.spec.ts @@ -35,15 +35,14 @@ describe('App', async function () { sandbox.restore(); }); - it('should exit process if there is 20 seconds of pause after a request during the integration test', async function() { + it('should exit process if there is 20 seconds of pause after a request during the integration test', async function () { const clock = sandbox.useFakeTimers(); - let processExitStub = sandbox.stub(process, 'exit'); + const processExitStub = sandbox.stub(process, 'exit'); // fake NODE_ENV as integration test const restore = mockedEnv({ NODE_ENV: 'integration-test', }); - await testApp - .post('/'); + await testApp.post('/'); // fake timeout of default timeout clock.tick(DEFAULT_TIMEOUT); @@ -67,21 +66,18 @@ describe('App', async function () { }); it('should implement CORS', async function () { - // @ts-ignore - const {headers} = await testApp - .options('/'); + // @ts-expect error + const {headers} = await testApp.options('/'); expect(headers['access-control-allow-origin']).to.be.equal('*'); }); it('should provide unsupported media type error in case of a non-json body', async function () { - const responseNoType = await testApp - .post('/non-existing-route') - .send(); + const responseNoType = await testApp.post('/non-existing-route').send(); const responseOtherType = await testApp .post('/non-existing-route') - .set('Content-Type','application/foo') + .set('Content-Type', 'application/foo') .send(); expect(responseNoType.status).to.equal(new SCUnsupportedMediaTypeErrorResponse().statusCode); diff --git a/test/common.spec.ts b/test/common.spec.ts index 513f0f3a..df3272c5 100644 --- a/test/common.spec.ts +++ b/test/common.spec.ts @@ -19,14 +19,14 @@ import {expect} from 'chai'; describe('Common', function () { describe('inRangeInclusive', function () { it('should provide true if the given number is in the range', function () { - expect(inRangeInclusive(1, [1,3])).to.be.true; - expect(inRangeInclusive(2, [1,3])).to.be.true; - expect(inRangeInclusive(1.1, [1,3])).to.be.true; + expect(inRangeInclusive(1, [1, 3])).to.be.true; + expect(inRangeInclusive(2, [1, 3])).to.be.true; + expect(inRangeInclusive(1.1, [1, 3])).to.be.true; expect(inRangeInclusive(3, [1, 3])).to.be.true; }); it('should provide false if the given number is not in the range', function () { - expect(inRangeInclusive(3.1, [1,3])).to.be.false; + expect(inRangeInclusive(3.1, [1, 3])).to.be.false; expect(inRangeInclusive(0, [1, 3])).to.be.false; }); }); diff --git a/test/common.ts b/test/common.ts index 3e353c6d..7b652905 100644 --- a/test/common.ts +++ b/test/common.ts @@ -42,25 +42,25 @@ export async function startApp(): Promise { const port = await getPort(); server.listen(port); - server.on('error', err => { - throw err; + server.on('error', error => { + throw error; }); - return new Promise(resolve => server.on('listening', () => { - app.set( - 'bulk', - bulkStorageMock, - ); - resolve(app); - })); + return new Promise(resolve => + server.on('listening', () => { + app.set('bulk', bulkStorageMock); + resolve(app); + }), + ); } /** * An elasticsearch mock */ export class ElasticsearchMock implements Database { - // @ts-ignore + // @ts-expect-error never read private bulk: Bulk | undefined; + private storageMock = new Map(); constructor(_configFile: SCConfigFile, _mailQueue?: MailQueue) { @@ -81,7 +81,7 @@ export class ElasticsearchMock implements Database { } get(uid: SCUuid): Promise { - // @ts-ignore + // @ts-expect-error incompatible types return Promise.resolve(this.storageMock.get(uid)); } @@ -98,49 +98,54 @@ export class ElasticsearchMock implements Database { return Promise.resolve(); } - search(_params: SCSearchQuery): Promise { - return Promise.resolve({data: [], facets: [], pagination: {count: 0, offset: 0, total: 0}, stats: {time: 0}}); + search(_parameters: SCSearchQuery): Promise { + return Promise.resolve({ + data: [], + facets: [], + pagination: {count: 0, offset: 0, total: 0}, + stats: {time: 0}, + }); } } export const bulkStorageMock = new BulkStorage(new ElasticsearchMock(configFile)); export const bulk: Bulk = { - expiration: moment().add(3600, 'seconds') - .format(), - source: 'some_source', - state: 'in progress', - type: SCThingType.Book, - uid: '' - }; + expiration: moment().add(3600, 'seconds').format(), + source: 'some_source', + state: 'in progress', + type: SCThingType.Book, + uid: '', +}; -export class FooError extends Error { -} +export class FooError extends Error {} -export const DEFAULT_TEST_TIMEOUT = 10000; +export const DEFAULT_TEST_TIMEOUT = 10_000; export const TRANSPORT_SEND_RESPONSE = 'Send Response'; export const getTransport = (verified: boolean) => { - return { - cc: undefined, - from: undefined, - recipients: undefined, - transportAgent: undefined, - verified: undefined, - isVerified(): boolean { - return verified; - }, - send(_subject: string, _message: string): Promise { - return Promise.resolve(''); - }, - sendMail(_mail: any): Promise { - return Promise.resolve(TRANSPORT_SEND_RESPONSE); - }, - verify(): Promise { - return Promise.resolve(false); - } - } - } + return { + cc: undefined, + from: undefined, + recipients: undefined, + transportAgent: undefined, + verified: undefined, + isVerified(): boolean { + return verified; + }, + send(_subject: string, _message: string): Promise { + return Promise.resolve(''); + }, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + sendMail(_mail: any): Promise { + return Promise.resolve(TRANSPORT_SEND_RESPONSE); + }, + verify(): Promise { + return Promise.resolve(false); + }, + }; +}; -export const getIndex = (uid?: string) => `stapps_footype_foosource_${uid ? uid : Elasticsearch.getIndexUID(v4())}`; +export const getIndex = (uid?: string) => + `stapps_footype_foosource_${uid ? uid : Elasticsearch.getIndexUID(v4())}`; diff --git a/test/notification/backend-transport.spec.ts b/test/notification/backend-transport.spec.ts index 43155715..b7b2d77d 100644 --- a/test/notification/backend-transport.spec.ts +++ b/test/notification/backend-transport.spec.ts @@ -22,7 +22,6 @@ import sinon from 'sinon'; describe('Backend transport', function () { describe('isTransportWithVerification', function () { - it('should return false if transport is not verifiable', function () { expect(isTransportWithVerification({} as Transport)).to.be.false; expect(isTransportWithVerification({verify: 'foo'} as unknown as Transport)).to.be.false; @@ -30,6 +29,7 @@ describe('Backend transport', function () { it('should return true if transport is verifiable', function () { // a transport which has verify function should be verifiable + // eslint-disable-next-line @typescript-eslint/no-empty-function expect(isTransportWithVerification({verify: () => {}} as unknown as Transport)).to.be.true; }); }); @@ -43,7 +43,7 @@ describe('Backend transport', function () { }); it('should provide only one instance of the transport', function () { - // @ts-ignore + // @ts-expect-error not assignable sandbox.stub(SMTP, 'getInstance').callsFake(() => { return {}; }); @@ -77,8 +77,10 @@ describe('Backend transport', function () { }); it('should provide information that the transport if waiting for its verification', function () { - // @ts-ignore - sandbox.stub(SMTP, 'getInstance').callsFake(() => {return {verify: () => Promise.resolve(true)}}); + // @ts-expect-error not assignable + sandbox.stub(SMTP, 'getInstance').callsFake(() => { + return {verify: () => Promise.resolve(true)}; + }); expect(BackendTransport.getInstance().isWaitingForVerification()).to.be.true; }); diff --git a/test/notification/mail-queue.spec.ts b/test/notification/mail-queue.spec.ts index f6a47460..922a8374 100644 --- a/test/notification/mail-queue.spec.ts +++ b/test/notification/mail-queue.spec.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ /* * Copyright (C) 2020 StApps * This program is free software: you can redistribute it and/or modify @@ -37,7 +38,7 @@ describe('MailQueue', async function () { it('should fail after maximal number of verification checks', function () { const loggerStub = sandbox.spy(Logger, 'warn'); const test = () => { - // @ts-ignore + // @ts-expect-error not assignable new MailQueue(getTransport(false)); // fake that VERIFICATION_TIMEOUT was reached more times (one more) than MAX_VERIFICATION_ATTEMPTS clock.tick(MailQueue.VERIFICATION_TIMEOUT * (MailQueue.MAX_VERIFICATION_ATTEMPTS + 1)); @@ -50,8 +51,8 @@ describe('MailQueue', async function () { it('should add queued mails to the queue for sending when transport is verified', async function () { const queueAddStub = sandbox.stub(Queue.prototype, 'add'); const numberOfMails = 3; - let transport = getTransport(false); - // @ts-ignore + const transport = getTransport(false); + // @ts-expect-error not assignable const mailQueue = new MailQueue(transport); const mail: MailOptions = {from: 'Foo', subject: 'Foo Subject'}; for (let i = 0; i < numberOfMails; i++) { @@ -67,7 +68,7 @@ describe('MailQueue', async function () { it('should not add SMTP sending tasks to queue when transport is not verified', function () { const queueAddStub = sandbox.stub(Queue.prototype, 'add'); - // @ts-ignore + // @ts-expect-error not assignable const mailQueue = new MailQueue(getTransport(false)); const mail: MailOptions = {}; mailQueue.push(mail); @@ -77,8 +78,8 @@ describe('MailQueue', async function () { it('should add SMTP sending tasks to queue when transport is verified', function () { const queueAddStub = sandbox.stub(Queue.prototype, 'add'); - let transport = getTransport(false); - // @ts-ignore + const transport = getTransport(false); + // @ts-expect-error not assignable const mailQueue = new MailQueue(transport); const mail: MailOptions = {from: 'Foo', subject: 'Foo Subject'}; // fake that transport is verified @@ -90,11 +91,11 @@ describe('MailQueue', async function () { it('should send SMTP mails when transport is verified', async function () { let caught: any; - sandbox.stub(Queue.prototype, 'add').callsFake(async (promiseGenerator) => { + sandbox.stub(Queue.prototype, 'add').callsFake(async promiseGenerator => { caught = await promiseGenerator(); }); - let transport = getTransport(false); - // @ts-ignore + const transport = getTransport(false); + // @ts-expect-error not assignable const mailQueue = new MailQueue(transport); const mail: MailOptions = {from: 'Foo', subject: 'Foo Subject'}; // fake that transport is verified diff --git a/test/routes/bulk-route.spec.ts b/test/routes/bulk-route.spec.ts index 27d3441a..62f73b91 100644 --- a/test/routes/bulk-route.spec.ts +++ b/test/routes/bulk-route.spec.ts @@ -55,14 +55,11 @@ describe('Bulk routes', async function () { }); it('should return (throw) error if a bulk with the provided UID cannot be found when adding to a bulk', async function () { - await testApp - .post(bulkRoute.urlPath) - .set('Content-Type', 'application/json') - .send(request); - const bulkAddRouteurlPath = bulkAddRoute.urlPath.toLocaleLowerCase().replace(':uid', 'a-wrong-uid'); + await testApp.post(bulkRoute.urlPath).set('Content-Type', 'application/json').send(request); + const bulkAddRouteUrlPath = bulkAddRoute.urlPath.toLocaleLowerCase().replace(':uid', 'a-wrong-uid'); const {status} = await testApp - .post(bulkAddRouteurlPath) + .post(bulkAddRouteUrlPath) .set('Content-Type', 'application/json') .send(book); @@ -86,10 +83,7 @@ describe('Bulk routes', async function () { }); it('should return (throw) error if a bulk with the provided UID cannot be found when closing a bulk (done)', async function () { - await testApp - .post(bulkRoute.urlPath) - .set('Content-Type', 'application/json') - .send(request); + await testApp.post(bulkRoute.urlPath).set('Content-Type', 'application/json').send(request); const bulkDoneRouteurlPath = bulkDoneRoute.urlPath.toLocaleLowerCase().replace(':uid', 'a-wrong-uid'); const {status} = await testApp @@ -100,7 +94,7 @@ describe('Bulk routes', async function () { expect(status).to.be.equal(new SCNotFoundErrorResponse().statusCode); }); - it ('should close the bulk (done)', async function () { + it('should close the bulk (done)', async function () { const response = await testApp .post(bulkRoute.urlPath) .set('Content-Type', 'application/json') diff --git a/test/routes/plugin-register-route.spec.ts b/test/routes/plugin-register-route.spec.ts index 4c531287..1f561cfe 100644 --- a/test/routes/plugin-register-route.spec.ts +++ b/test/routes/plugin-register-route.spec.ts @@ -16,8 +16,11 @@ import { SCNotFoundErrorResponse, SCPluginAdd, - SCPluginAlreadyRegisteredErrorResponse, SCPluginRegisterResponse, SCPluginRegisterRoute, - SCPluginRemove, SCValidationErrorResponse, + SCPluginAlreadyRegisteredErrorResponse, + SCPluginRegisterResponse, + SCPluginRegisterRoute, + SCPluginRemove, + SCValidationErrorResponse, } from '@openstapps/core'; import nock from 'nock'; import {configFile, plugins} from '../../src/common'; @@ -36,7 +39,7 @@ export const registerAddRequest: SCPluginAdd = registerRequest as SCPluginAdd; export const registerRemoveRequest: SCPluginRemove = { action: 'remove', - route: registerAddRequest.plugin.route + route: registerAddRequest.plugin.route, }; describe('Plugin registration', async function () { @@ -52,9 +55,9 @@ describe('Plugin registration', async function () { // register one plugin const response = await pluginRegisterHandler(registerAddRequest, {}); - expect(response).to.deep.equal(bodySuccess) - && expect(plugins.size).to.equal(1) - && expect(configFile.app.features.plugins!['Foo Plugin']).to.not.be.empty; + expect(response).to.deep.equal(bodySuccess) && + expect(plugins.size).to.equal(1) && + expect(configFile.app.features.plugins!['Foo Plugin']).to.not.be.empty; }); it('should allow re-registering the same plugin', async function () { @@ -64,9 +67,11 @@ describe('Plugin registration', async function () { // register the same plugin again const response = await pluginRegisterHandler(registerAddRequest, {}); - return expect(response).to.deep.equal(bodySuccess) - && expect(plugins.size).to.equal(1) - && expect(configFile.app.features.plugins!['Foo Plugin']).to.not.be.empty; + return ( + expect(response).to.deep.equal(bodySuccess) && + expect(plugins.size).to.equal(1) && + expect(configFile.app.features.plugins!['Foo Plugin']).to.not.be.empty + ); }); it('should show an error if a plugin has already been registered', async function () { @@ -74,9 +79,9 @@ describe('Plugin registration', async function () { await pluginRegisterHandler(registerAddRequest, {}); // create new request for adding a plugin with only name that changed - let registerAddRequestAltered: SCPluginAdd = { + const registerAddRequestAltered: SCPluginAdd = { ...registerAddRequest, - plugin: {...registerAddRequest.plugin, name: registerAddRequest.plugin.name + 'foo'} + plugin: {...registerAddRequest.plugin, name: registerAddRequest.plugin.name + 'foo'}, }; // register the same plugin again @@ -95,9 +100,9 @@ describe('Plugin registration', async function () { const response = await pluginRegisterHandler(registerRemoveRequest, {}); - expect(response).to.deep.equal(bodySuccess) - && expect(plugins.size).to.equal(0) - && expect(configFile.app.features.plugins).to.be.empty; + expect(response).to.deep.equal(bodySuccess) && + expect(plugins.size).to.equal(0) && + expect(configFile.app.features.plugins).to.be.empty; }); it('should throw a "not found" error when removing a plugin whose registered route does not exist', async function () { @@ -116,10 +121,10 @@ describe('Plugin registration', async function () { const pluginRegisterRoute = new SCPluginRegisterRoute(); const validationError = new SCValidationErrorResponse([]); const notFoundError = new SCNotFoundErrorResponse(); - //@ts-ignore + // @ts-expect-error not assignable const alreadyRegisteredError = new SCPluginAlreadyRegisteredErrorResponse('Foo Message', {}); - afterEach(async function() { + afterEach(async function () { // remove routes plugins.clear(); // clean up request mocks (fixes issue with receiving response from mock from previous test case) @@ -157,7 +162,10 @@ describe('Plugin registration', async function () { // lets simulate that a plugin is already registered plugins.set(registerAddRequest.plugin.route, registerAddRequest.plugin); // registering a different plugin for the same route causes the expected error - const registerAddRequestAltered = {...registerAddRequest, plugin: {...registerAddRequest.plugin, name: 'FooBar Plugin'}}; + const registerAddRequestAltered = { + ...registerAddRequest, + plugin: {...registerAddRequest.plugin, name: 'FooBar Plugin'}, + }; const {status, body} = await testApp .post(pluginRegisterRoute.urlPath) @@ -169,7 +177,7 @@ describe('Plugin registration', async function () { expect(body).to.haveOwnProperty('name', 'SCPluginAlreadyRegisteredError'); }); - it('should respond with success when de-registering already registered plugin', async function() { + it('should respond with success when de-registering already registered plugin', async function () { // lets simulate that a plugin is already registered plugins.set(registerAddRequest.plugin.route, registerAddRequest.plugin); @@ -183,7 +191,7 @@ describe('Plugin registration', async function () { expect(body).to.be.deep.equal(bodySuccess); }); - it('should response with 404 when deleting a plugin which was not registered', async function() { + it('should response with 404 when deleting a plugin which was not registered', async function () { // lets simulate that the plugin is already registered plugins.set(registerAddRequest.plugin.route, registerAddRequest.plugin); diff --git a/test/routes/route.spec.ts b/test/routes/route.spec.ts index b66360f3..c104e25a 100644 --- a/test/routes/route.spec.ts +++ b/test/routes/route.spec.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ /* * Copyright (C) 2020 StApps * This program is free software: you can redistribute it and/or modify @@ -17,7 +18,8 @@ import { SCInternalServerErrorResponse, SCMethodNotAllowedErrorResponse, SCRoute, - SCRouteHttpVerbs, SCValidationErrorResponse, + SCRouteHttpVerbs, + SCValidationErrorResponse, } from '@openstapps/core'; import * as bodyParser from 'body-parser'; import sinon from 'sinon'; @@ -31,15 +33,16 @@ import {Logger} from '@openstapps/logger'; import {DEFAULT_TEST_TIMEOUT} from '../common'; interface ReturnType { - foo: boolean; + foo: boolean; } describe('Create route', async function () { let routeClass: SCRoute; let handler: ( - validatedBody: any, - app: Application, params?: { [parameterName: string]: string; }, - ) => Promise; + validatedBody: any, + app: Application, + parameters?: {[parameterName: string]: string}, + ) => Promise; let app: Express; const statusCodeSuccess = 222; const bodySuccess = {foo: true}; @@ -75,10 +78,12 @@ describe('Create route', async function () { it('should complain (throw an error) if used method is other than defined in the route creation', async function () { const methodNotAllowedError = new SCMethodNotAllowedErrorResponse(); - // @ts-ignore - sandbox.stub(validator, 'validate').returns({errors: []}) + // @ts-expect-error not assignable + sandbox.stub(validator, 'validate').returns({errors: []}); let error: any = {}; - sandbox.stub(Logger, 'warn').callsFake((err) => { error = err }); + sandbox.stub(Logger, 'warn').callsFake(error_ => { + error = error_; + }); const router = createRoute(routeClass, handler); await app.use(router); @@ -92,14 +97,12 @@ describe('Create route', async function () { }); it('should provide a route which returns handler response and success code', async function () { - // @ts-ignore + // @ts-expect-error not assignable sandbox.stub(validator, 'validate').returns({errors: []}); const router = createRoute(routeClass, handler); app.use(router); - const response = await supertest(app) - .post(routeClass.urlPath) - .send(); + const response = await supertest(app).post(routeClass.urlPath).send(); expect(response.status).to.be.equal(statusCodeSuccess); expect(response.body).to.be.deep.equal(bodySuccess); @@ -112,7 +115,7 @@ describe('Create route', async function () { app.use(router); const startApp = supertest(app); const validatorStub = sandbox.stub(validator, 'validate'); - // @ts-ignore + // @ts-expect-error not assignable validatorStub.withArgs(body, routeClass.requestBodyName).returns({errors: [new Error('Foo Error')]}); const response = await startApp @@ -128,14 +131,14 @@ describe('Create route', async function () { const router = createRoute(routeClass, handler); await app.use(router); const startApp = supertest(app); - // @ts-ignore - const validatorStub = sandbox.stub(validator, 'validate').returns({errors:[]}); - // @ts-ignore - validatorStub.withArgs(bodySuccess, routeClass.responseBodyName).returns({errors: [new Error('Foo Error')]}); + // @ts-expect-error not assignable + const validatorStub = sandbox.stub(validator, 'validate').returns({errors: []}); + validatorStub + .withArgs(bodySuccess, routeClass.responseBodyName) + // @ts-expect-error not assignable + .returns({errors: [new Error('Foo Error')]}); - const response = await startApp - .post(routeClass.urlPath) - .send(); + const response = await startApp.post(routeClass.urlPath).send(); expect(response.status).to.be.equal(internalServerError.statusCode); }); @@ -143,8 +146,11 @@ describe('Create route', async function () { it('should return internal server error if error response not allowed', async function () { class FooErrorResponse { statusCode: number; + name: string; + message: string; + constructor(statusCode: number, name: string, message: string) { this.statusCode = statusCode; this.name = name; @@ -153,6 +159,7 @@ describe('Create route', async function () { } class BarErrorResponse { statusCode: number; + constructor(statusCode: number) { this.statusCode = statusCode; } @@ -170,12 +177,10 @@ describe('Create route', async function () { await app.use(router); const startApp = supertest(app); - // @ts-ignore - sandbox.stub(validator, 'validate').returns({errors:[]}); + // @ts-expect-error not assignable + sandbox.stub(validator, 'validate').returns({errors: []}); - const response = await startApp - .post(routeClass.urlPath) - .send(); + const response = await startApp.post(routeClass.urlPath).send(); expect(response.status).to.be.equal(internalServerError.statusCode); }); @@ -183,8 +188,11 @@ describe('Create route', async function () { it('should return the exact error if error response is allowed', async function () { class FooErrorResponse { statusCode: number; + name: string; + message: string; + constructor(statusCode: number, name: string, message: string) { this.statusCode = statusCode; this.name = name; @@ -205,12 +213,10 @@ describe('Create route', async function () { await app.use(router); const startApp = supertest(app); - // @ts-ignore - sandbox.stub(validator, 'validate').returns({errors:[]}); + // @ts-expect-error not assignable + sandbox.stub(validator, 'validate').returns({errors: []}); - const response = await startApp - .post(routeClass.urlPath) - .send(); + const response = await startApp.post(routeClass.urlPath).send(); expect(response.status).to.be.equal(fooErrorResponse.statusCode); }); diff --git a/test/routes/search-route.spec.ts b/test/routes/search-route.spec.ts index ca9ca531..f5e7d398 100644 --- a/test/routes/search-route.spec.ts +++ b/test/routes/search-route.spec.ts @@ -18,7 +18,7 @@ import { SCMultiSearchRoute, SCSearchRoute, SCSyntaxErrorResponse, - SCTooManyRequestsErrorResponse + SCTooManyRequestsErrorResponse, } from '@openstapps/core'; import {expect} from 'chai'; import {configFile} from '../../src/common'; @@ -37,33 +37,24 @@ describe('Search route', async function () { it('should reject GET, PUT with a valid search query', async function () { // const expectedParams = JSON.parse(JSON.stringify(defaultParams)); - const {status} = await testApp - .get('/search') - .set('Accept', 'application/json') - .send({ - query: 'Some search terms' - }); + const {status} = await testApp.get('/search').set('Accept', 'application/json').send({ + query: 'Some search terms', + }); expect(status).to.equal(methodNotAllowedError.statusCode); }); - describe('Basic POST /search', async function() { + describe('Basic POST /search', async function () { it('should accept empty JSON object', async function () { - const {status} = await testApp - .post(searchRoute.urlPath) - .set('Accept', 'application/json') - .send({}); + const {status} = await testApp.post(searchRoute.urlPath).set('Accept', 'application/json').send({}); expect(status).to.equal(searchRoute.statusCodeSuccess); }); it('should accept valid search request', async function () { - const {status} = await testApp - .post(searchRoute.urlPath) - .set('Accept', 'application/json') - .send({ - query: 'Some search terms' - }); + const {status} = await testApp.post(searchRoute.urlPath).set('Accept', 'application/json').send({ + query: 'Some search terms', + }); expect(status).to.equal(searchRoute.statusCodeSuccess); }); @@ -74,14 +65,14 @@ describe('Search route', async function () { .set('Content-Type', 'application/json') .set('Accept', 'application/json') .send({ - some: {invalid: 'search'} + some: {invalid: 'search'}, }); expect(status).to.equal(syntaxError.statusCode); }); }); - describe('Basic POST /multi/search', async function() { + describe('Basic POST /multi/search', async function () { it('should respond with bad request on invalid search request (empty JSON object as body)', async function () { const {status} = await testApp .post(multiSearchRoute.urlPath) @@ -96,8 +87,8 @@ describe('Search route', async function () { .post(multiSearchRoute.urlPath) .set('Accept', 'application/json') .send({ - one: { query: 'Some search terms for one search'}, - two: { query: 'Some search terms for another search'} + one: {query: 'Some search terms for one search'}, + two: {query: 'Some search terms for another search'}, }); expect(status).to.equal(multiSearchRoute.statusCodeSuccess); diff --git a/test/routes/thing-update-route.spec.ts b/test/routes/thing-update-route.spec.ts index abfd986c..58985d4a 100644 --- a/test/routes/thing-update-route.spec.ts +++ b/test/routes/thing-update-route.spec.ts @@ -28,7 +28,8 @@ describe('Thing update route', async function () { const thingUpdateRoute = new SCThingUpdateRoute(); it('should update a thing', async function () { - const thingUpdateRouteurlPath = thingUpdateRoute.urlPath.toLocaleLowerCase() + const thingUpdateRouteurlPath = thingUpdateRoute.urlPath + .toLocaleLowerCase() .replace(':type', book.type) .replace(':uid', book.uid); diff --git a/test/routes/virtual-plugin-route.spec.ts b/test/routes/virtual-plugin-route.spec.ts index 9274ae76..abebd343 100644 --- a/test/routes/virtual-plugin-route.spec.ts +++ b/test/routes/virtual-plugin-route.spec.ts @@ -1,3 +1,4 @@ +/* eslint-disable unicorn/consistent-function-scoping,@typescript-eslint/no-explicit-any */ /* * Copyright (C) 2019 StApps * This program is free software: you can redistribute it and/or modify @@ -13,11 +14,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -import { - SCInternalServerErrorResponse, - SCPluginMetaData, - SCValidationErrorResponse -} from '@openstapps/core'; +import {SCInternalServerErrorResponse, SCPluginMetaData, SCValidationErrorResponse} from '@openstapps/core'; import {expect, use} from 'chai'; import chaiAsPromised from 'chai-as-promised'; import {Request} from 'express'; @@ -41,16 +38,17 @@ describe('Virtual plugin routes', async function () { /** * Internal method which provides information about the specific error inside of an internal server error * - * @param req Express request + * @param request Express request * @param plugin Plugin information (metadata) * @param specificError Class of a specific error */ - async function testRejection(req: Request, plugin: SCPluginMetaData, specificError: object) { + async function testRejection(request: Request, plugin: SCPluginMetaData, specificError: object) { + // eslint-disable-next-line unicorn/error-message let thrownError: Error = new Error(); try { - await virtualPluginRoute(req, plugin); - } catch (e) { - thrownError = e; + await virtualPluginRoute(request, plugin); + } catch (error) { + thrownError = error; } // return virtualPluginRoute(req, plugin).should.be.rejectedWith(SCInternalServerErrorResponse); was not working for some reason expect(thrownError).to.be.instanceOf(SCInternalServerErrorResponse); @@ -71,17 +69,17 @@ describe('Virtual plugin routes', async function () { }, }; // spy the post method of got - // @ts-ignore + // @ts-expect-error not assignable const gotStub = sandbox.stub(got, 'post').returns({body: {}}); - // @ts-ignore + // @ts-expect-error not assignable sandbox.stub(validator, 'validate').returns({errors: []}); - const req = mockReq(request); + const request_ = mockReq(request); - await virtualPluginRoute(req, plugin); + await virtualPluginRoute(request_, plugin); - expect(gotStub.args[0][0]).to.equal(plugin.route.substr(1)); + expect(gotStub.args[0][0]).to.equal(plugin.route.slice(1)); expect(((gotStub.args[0] as any)[1] as Options).prefixUrl).to.equal(plugin.address); - expect(((gotStub.args[0] as any)[1] as Options).json).to.equal(req.body); + expect(((gotStub.args[0] as any)[1] as Options).json).to.equal(request_.body); }); it('should provide data from the plugin when its route is called', async function () { @@ -91,18 +89,13 @@ describe('Virtual plugin routes', async function () { }, }; const response = { - result: [ - {foo: 'bar'}, - {bar: 'foo'}, - ] - } + result: [{foo: 'bar'}, {bar: 'foo'}], + }; // mock response of the plugin's address - nock('http://foo.com:1234') - .post('/foo') - .reply(200, response); - const req = mockReq(request); + nock('http://foo.com:1234').post('/foo').reply(200, response); + const request_ = mockReq(request); - expect(await virtualPluginRoute(req, plugin)).to.eql(response); + expect(await virtualPluginRoute(request_, plugin)).to.eql(response); }); it('should throw the validation error if request is not valid', async function () { @@ -111,9 +104,9 @@ describe('Virtual plugin routes', async function () { invalid_query_field: 'foo', }, }; - const req = mockReq(request); + const request_ = mockReq(request); - await testRejection(req, plugin, SCValidationErrorResponse); + await testRejection(request_, plugin, SCValidationErrorResponse); }); it('should throw the validation error if response is not valid', async function () { @@ -126,9 +119,9 @@ describe('Virtual plugin routes', async function () { nock('http://foo.com:1234') .post('/foo') .reply(200, {invalid_result: ['foo bar']}); - const req = mockReq(request); + const request_ = mockReq(request); - await testRejection(req, plugin, SCValidationErrorResponse); + await testRejection(request_, plugin, SCValidationErrorResponse); }); it('should throw error if there is a problem with reaching the address of a plugin', async function () { @@ -139,13 +132,12 @@ describe('Virtual plugin routes', async function () { }; // fake that post method of got throws an error - sandbox.stub(got, 'post') - .callsFake(() => { - throw new FooError(); - }); - const req = mockReq(request); + sandbox.stub(got, 'post').callsFake(() => { + throw new FooError(); + }); + const request_ = mockReq(request); - await testRejection(req, plugin, FooError); + await testRejection(request_, plugin, FooError); }); }); @@ -157,7 +149,7 @@ describe('Virtual plugin routes', async function () { const OK = 200; const internalServerError = new SCInternalServerErrorResponse(); - afterEach(async function() { + afterEach(async function () { // remove routes plugins.clear(); // // restore everything to default methods (remove stubs) @@ -194,16 +186,15 @@ describe('Virtual plugin routes', async function () { expect(barResponse.body).to.be.deep.equal({result: [{foo: 'bar'}, {bar: 'bar'}]}); }); - it('should return error response if plugin address is not responding', async function() { + it('should return error response if plugin address is not responding', async function () { // lets simulate that the plugin is already registered plugins.set(registerAddRequest.plugin.route, registerAddRequest.plugin); class FooError extends Error {} // fake that got's post method throws an error - sandbox.stub(got, 'post') - .callsFake(() => { - throw new FooError(); - }); + sandbox.stub(got, 'post').callsFake(() => { + throw new FooError(); + }); const {status} = await testApp .post('/foo') @@ -214,7 +205,7 @@ describe('Virtual plugin routes', async function () { expect(status).to.be.equal(internalServerError.statusCode); }); - it('should return the validation error response if plugin request is not valid', async function() { + it('should return the validation error response if plugin request is not valid', async function () { // lets simulate that the plugin is already registered plugins.set(registerAddRequest.plugin.route, registerAddRequest.plugin); @@ -223,13 +214,13 @@ describe('Virtual plugin routes', async function () { .set('Content-Type', 'application/json') .set('Accept', 'application/json') // using number for query instead of (in request schema) required text - .send({query: 123}) + .send({query: 123}); expect(status).to.be.equal(502); - expect(body.additionalData).to.haveOwnProperty('name','ValidationError'); + expect(body.additionalData).to.haveOwnProperty('name', 'ValidationError'); }); - it('should return the validation error response if plugin response is not valid', async function() { + it('should return the validation error response if plugin response is not valid', async function () { // lets simulate that the plugin is already registered plugins.set(registerAddRequest.plugin.route, registerAddRequest.plugin); // mock response of the plugin address @@ -244,7 +235,7 @@ describe('Virtual plugin routes', async function () { .send({query: 'foo'}); expect(status).to.be.equal(internalServerError.statusCode); - expect(body.additionalData).to.haveOwnProperty('name','ValidationError'); + expect(body.additionalData).to.haveOwnProperty('name', 'ValidationError'); }); }); }); diff --git a/test/storage/bulk-storage.spec.ts b/test/storage/bulk-storage.spec.ts index 0d6501bd..0ad729cf 100644 --- a/test/storage/bulk-storage.spec.ts +++ b/test/storage/bulk-storage.spec.ts @@ -15,6 +15,7 @@ */ import {SCBulkRequest, SCThingType} from '@openstapps/core'; import moment from 'moment'; +// eslint-disable-next-line unicorn/import-style import util from 'util'; import {configFile} from '../../src/common'; import {Bulk, BulkStorage} from '../../src/storage/bulk-storage'; @@ -72,7 +73,7 @@ describe('Bulk Storage', function () { expect(esMock.calledWith(bulk)).to.be.true; }); - it('should not call appropriate database clean-up method on expire if bulk\'s state is done', async function () { + it("should not call appropriate database clean-up method on expire if bulk's state is done", async function () { bulk.state = 'done'; sandbox.stub(NodeCache.prototype, 'on').withArgs('expired', sinon.match.any).yields(123, bulk); new BulkStorage(database); @@ -88,11 +89,17 @@ describe('Bulk Storage', function () { }); it('should delete a bulk', async function () { - const readStub = sandbox.stub(BulkStorage.prototype, 'read').callsFake(() => bulk); + const readStub = sandbox.stub(BulkStorage.prototype, 'read').callsFake(() => bulk); + // eslint-disable-next-line @typescript-eslint/no-explicit-any let caught: any; - sandbox.stub(NodeCache.prototype, 'del').callsFake(() => caught = 123); + sandbox.stub(NodeCache.prototype, 'del').callsFake(() => (caught = 123)); // force call - sandbox.stub(util, 'promisify').callsFake(() => () => {}).yields(null); + sandbox + .stub(util, 'promisify') + // eslint-disable-next-line @typescript-eslint/no-empty-function,unicorn/consistent-function-scoping + .callsFake(() => () => {}) + // eslint-disable-next-line unicorn/no-null + .yields(null); const bulkStorage = new BulkStorage(database); await bulkStorage.delete(bulk.uid); @@ -103,15 +110,22 @@ describe('Bulk Storage', function () { }); it('should read an existing bulk', async function () { + // eslint-disable-next-line @typescript-eslint/no-explicit-any let caught: any; - sandbox.stub(NodeCache.prototype, 'get').callsFake(() => caught = 123); + sandbox.stub(NodeCache.prototype, 'get').callsFake(() => (caught = 123)); // force call - sandbox.stub(util, 'promisify').callsFake(() => () => {}).yields(null); + sandbox + .stub(util, 'promisify') + // eslint-disable-next-line unicorn/consistent-function-scoping,@typescript-eslint/no-empty-function + .callsFake(() => () => {}) + // eslint-disable-next-line unicorn/no-null + .yields(null); const bulkStorage = new BulkStorage(database); await bulkStorage.read(bulk.uid); expect(caught).to.be.equal(123); - });`` + }); + ``; }); }); diff --git a/test/storage/elasticsearch/aggregations.spec.ts b/test/storage/elasticsearch/aggregations.spec.ts index 8f6d928b..48584cd6 100644 --- a/test/storage/elasticsearch/aggregations.spec.ts +++ b/test/storage/elasticsearch/aggregations.spec.ts @@ -20,23 +20,23 @@ import {AggregationResponse} from '../../../src/storage/elasticsearch/types/elas describe('Aggregations', function () { const aggregations: AggregationResponse = { - catalog: { - doc_count: 4, + 'catalog': { + 'doc_count': 4, 'superCatalogs.categories': { - buckets: [] + buckets: [], }, 'academicTerm.acronym': { buckets: [ { key: 'SoSe 2020', - doc_count: 2 - } - ] + doc_count: 2, + }, + ], }, 'superCatalog.categories': { - buckets: [] + buckets: [], }, - categories: { + 'categories': { buckets: [ { key: 'foo', @@ -46,21 +46,21 @@ describe('Aggregations', function () { key: 'bar', doc_count: 3, }, - ] - } + ], + }, }, - person: { - doc_count: 13, + 'person': { + 'doc_count': 13, 'homeLocations.categories': { - buckets: [] - } + buckets: [], + }, }, 'academic event': { - doc_count: 0, + 'doc_count': 0, 'academicTerms.acronym': { - buckets: [] + buckets: [], }, - categories: { + 'categories': { buckets: [ { key: 'foobar', @@ -70,18 +70,18 @@ describe('Aggregations', function () { key: 'bar', doc_count: 2, }, - ] + ], }, 'creativeWorks.keywords': { - buckets: [] - } + buckets: [], + }, }, - fooType: { + 'fooType': { buckets: [ { doc_count: 321, - key: 'foo' - } + key: 'foo', + }, ], }, '@all': { @@ -90,71 +90,71 @@ describe('Aggregations', function () { buckets: [ { key: 'person', - doc_count: 13 + doc_count: 13, }, { key: 'catalog', - doc_count: 4 - } - ] - } - } + doc_count: 4, + }, + ], + }, + }, }; const expectedFacets: SCFacet[] = [ - { - buckets: [ - { - count: 13, - 'key': 'person' - }, - { - count: 4, - key: 'catalog' - } - ], - field: 'type', - }, - { - buckets: [ - { - count: 8, - key: 'foobar' - }, - { - count: 2, - key: 'bar' - } - ], - field: 'categories', - onlyOnType: SCThingType.AcademicEvent, - }, - { - buckets: [ - { - count: 2, - key: 'SoSe 2020' - } - ], - field: 'academicTerm.acronym', - onlyOnType: SCThingType.Catalog - }, - { - buckets: [ - { - count: 1, - key: 'foo' - }, - { - count: 3, - key: 'bar' - } - ], - field: 'categories', - onlyOnType: SCThingType.Catalog, - }, - // no fooType as it doesn't appear in the aggregation schema - ]; + { + buckets: [ + { + count: 13, + key: 'person', + }, + { + count: 4, + key: 'catalog', + }, + ], + field: 'type', + }, + { + buckets: [ + { + count: 8, + key: 'foobar', + }, + { + count: 2, + key: 'bar', + }, + ], + field: 'categories', + onlyOnType: SCThingType.AcademicEvent, + }, + { + buckets: [ + { + count: 2, + key: 'SoSe 2020', + }, + ], + field: 'academicTerm.acronym', + onlyOnType: SCThingType.Catalog, + }, + { + buckets: [ + { + count: 1, + key: 'foo', + }, + { + count: 3, + key: 'bar', + }, + ], + field: 'categories', + onlyOnType: SCThingType.Catalog, + }, + // no fooType as it doesn't appear in the aggregation schema + ]; it('should parse the aggregations providing the appropriate facets', function () { const facets = parseAggregations(aggregations); diff --git a/test/storage/elasticsearch/common.spec.ts b/test/storage/elasticsearch/common.spec.ts index 3e102970..45629424 100644 --- a/test/storage/elasticsearch/common.spec.ts +++ b/test/storage/elasticsearch/common.spec.ts @@ -17,15 +17,15 @@ import { ESAggMatchAllFilter, ESAggTypeFilter, ESNestedAggregation, - ESTermsFilter + ESTermsFilter, } from '@openstapps/es-mapping-generator/src/types/aggregation'; -import {expect} from "chai"; +import {expect} from 'chai'; import { isNestedAggregation, isBucketAggregation, isESTermsFilter, isESAggMatchAllFilter, - isESNestedAggregation + isESNestedAggregation, } from '../../../lib/storage/elasticsearch/types/guards'; import {BucketAggregation, NestedAggregation} from '../../../src/storage/elasticsearch/types/elasticsearch'; diff --git a/test/storage/elasticsearch/elasticsearch.spec.ts b/test/storage/elasticsearch/elasticsearch.spec.ts index 25463b85..6df70637 100644 --- a/test/storage/elasticsearch/elasticsearch.spec.ts +++ b/test/storage/elasticsearch/elasticsearch.spec.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any,unicorn/no-null */ /* * Copyright (C) 2020 StApps * This program is free software: you can redistribute it and/or modify @@ -14,7 +15,15 @@ * along with this program. If not, see . */ import {ApiResponse, Client} from '@elastic/elasticsearch'; -import {SCBook, SCBulkResponse, SCConfigFile, SCMessage, SCSearchQuery, SCThings, SCThingType} from '@openstapps/core'; +import { + SCBook, + SCBulkResponse, + SCConfigFile, + SCMessage, + SCSearchQuery, + SCThings, + SCThingType, +} from '@openstapps/core'; import {instance as book} from '@openstapps/core/test/resources/indexable/Book.1.json'; import {instance as message} from '@openstapps/core/test/resources/indexable/Message.1.json'; import {Logger} from '@openstapps/logger'; @@ -43,6 +52,7 @@ describe('Elasticsearch', function () { const sandbox = sinon.createSandbox(); before(function () { + // eslint-disable-next-line no-console console.log('before'); sandbox.stub(fs, 'readFileSync').returns('{}'); }); @@ -54,7 +64,7 @@ describe('Elasticsearch', function () { it('should provide custom elasticsearch URL if defined', function () { const customAddress = 'http://foo-address:9200'; const restore = mockedEnv({ - ES_ADDR: customAddress + ES_ADDR: customAddress, }); expect(Elasticsearch.getElasticsearchUrl()).to.be.equal(customAddress); @@ -64,7 +74,7 @@ describe('Elasticsearch', function () { it('should provide local URL as fallback', function () { const restore = mockedEnv({ - ES_ADDR: undefined + ES_ADDR: undefined, }); expect(Elasticsearch.getElasticsearchUrl()).to.match(/(https?:\/\/)?localhost(:\d+)?/); @@ -81,7 +91,7 @@ describe('Elasticsearch', function () { source: '', state: 'in progress', type: SCThingType.Semester, - uid: 'bulk-uid-123-123-123' + uid: 'bulk-uid-123-123-123', }; it('should provide index UID from the provided UID', function () { @@ -94,8 +104,9 @@ describe('Elasticsearch', function () { }); it('should provide index name from the provided data', function () { - expect(Elasticsearch.getIndex(type as SCThingType, source, bulk)) - .to.be.equal(`stapps_${type.split(' ').join('_')}_${source}_${Elasticsearch.getIndexUID(bulk.uid)}`); + expect(Elasticsearch.getIndex(type as SCThingType, source, bulk)).to.be.equal( + `stapps_${type.split(' ').join('_')}_${source}_${Elasticsearch.getIndexUID(bulk.uid)}`, + ); }); }); @@ -109,7 +120,7 @@ describe('Elasticsearch', function () { }); it('should remove invalid characters', function () { - expect(Elasticsearch.removeAliasChars('f,o#o\\b|ar/* ', 'bulk-uid')).to.be.equal('foobaralias'); + expect(Elasticsearch.removeAliasChars('f,o#o\\b|ar/* ', 'bulk-uid')).to.be.equal('foobaralias'); }); it('should remove invalid starting characters', function () { @@ -124,10 +135,12 @@ describe('Elasticsearch', function () { }); it('should work with common cases', function () { - expect(Elasticsearch.removeAliasChars('the-quick-brown-fox-jumps-over-the-lazy-dog-1234567890', 'bulk-uid')) - .to.be.equal('the-quick-brown-fox-jumps-over-the-lazy-dog-1234567890'); - expect(Elasticsearch.removeAliasChars('THE_QUICK_BROWN_FOX_JUMPS_OVER_THE_LAZY_DOG', 'bulk-uid')) - .to.be.equal('THE_QUICK_BROWN_FOX_JUMPS_OVER_THE_LAZY_DOG'); + expect( + Elasticsearch.removeAliasChars('the-quick-brown-fox-jumps-over-the-lazy-dog-1234567890', 'bulk-uid'), + ).to.be.equal('the-quick-brown-fox-jumps-over-the-lazy-dog-1234567890'); + expect( + Elasticsearch.removeAliasChars('THE_QUICK_BROWN_FOX_JUMPS_OVER_THE_LAZY_DOG', 'bulk-uid'), + ).to.be.equal('THE_QUICK_BROWN_FOX_JUMPS_OVER_THE_LAZY_DOG'); }); it('should warn in case of characters that are invalid in future elasticsearch versions', function () { @@ -158,16 +171,16 @@ describe('Elasticsearch', function () { ...configFile.internal, database: { name: 'foo', - version: 123 - } - } + version: 123, + }, + }, }; expect(() => new Elasticsearch(config)).to.throw(Error); }); it('should log an error in case of there is one when getting response from the elasticsearch client', async function () { - const error = Error('Foo Error'); + const error = new Error('Foo Error'); const loggerErrorStub = sandbox.stub(Logger, 'error').resolves('foo'); sandbox.stub(Client.prototype, 'on').yields(error); @@ -185,7 +198,7 @@ describe('Elasticsearch', function () { expect(loggerLogStub.calledWith(fakeResponse)).to.be.false; const restore = mockedEnv({ - 'ES_DEBUG': 'true', + ES_DEBUG: 'true', }); new Elasticsearch(configFile); @@ -208,8 +221,8 @@ describe('Elasticsearch', function () { monitoring: { actions: [], watchers: [], - } - } + }, + }, }; const es = new Elasticsearch(config); @@ -225,8 +238,8 @@ describe('Elasticsearch', function () { monitoring: { actions: [], watchers: [], - } - } + }, + }, }; const monitoringSetUpStub = sandbox.stub(Monitoring, 'setUp'); @@ -245,22 +258,21 @@ describe('Elasticsearch', function () { beforeEach(function () { es = new Elasticsearch(configFile); - // @ts-ignore es.client.indices = { - // @ts-ignore + // @ts-expect-error not assignable getAlias: () => Promise.resolve({body: [{[oldIndex]: {aliases: {[SCThingType.Book]: {}}}}]}), - // @ts-ignore + // @ts-expect-error not assignable putTemplate: () => Promise.resolve({}), - // @ts-ignore + // @ts-expect-error not assignable create: () => Promise.resolve({}), - // @ts-ignore + // @ts-expect-error not assignable delete: () => Promise.resolve({}), - // @ts-ignore + // @ts-expect-error not assignable exists: () => Promise.resolve({}), - // @ts-ignore + // @ts-expect-error not assignable refresh: () => Promise.resolve({}), - // @ts-ignore - updateAliases: () => Promise.resolve({}) + // @ts-expect-error not assignable + updateAliases: () => Promise.resolve({}), }; }); @@ -340,13 +352,13 @@ describe('Elasticsearch', function () { }, { remove: {index: oldIndex, alias: SCThingType.Book}, - } + }, ]; sandbox.stub(Elasticsearch, 'getIndex').returns(index); sandbox.stub(es, 'aliasMap').value({ [SCThingType.Book]: { [bulk.source]: oldIndex, - } + }, }); const refreshStub = sandbox.stub(es.client.indices, 'refresh'); const updateAliasesStub = sandbox.stub(es.client.indices, 'updateAliases'); @@ -357,11 +369,12 @@ describe('Elasticsearch', function () { await es.bulkUpdated(bulk); expect(refreshStub.calledWith({index})).to.be.true; - expect(updateAliasesStub.calledWith({ + expect( + updateAliasesStub.calledWith({ body: { - actions: expectedRefreshActions - } - }) + actions: expectedRefreshActions, + }, + }), ).to.be.true; expect(deleteStub.called).to.be.true; }); @@ -392,7 +405,7 @@ describe('Elasticsearch', function () { _index: '', _score: 0, _type: '', - _source: message as SCMessage + _source: message as SCMessage, }; sandbox.stub(es.client, 'search').resolves({body: {hits: {hits: [foundObject]}}}); @@ -420,7 +433,7 @@ describe('Elasticsearch', function () { _index: oldIndex, _score: 0, _type: '', - _source: message as SCMessage + _source: message as SCMessage, }; sandbox.stub(es.client, 'search').resolves({body: {hits: {hits: [object]}}}); sandbox.stub(Elasticsearch, 'getIndex').returns(index); @@ -434,7 +447,7 @@ describe('Elasticsearch', function () { _index: getIndex(), _score: 0, _type: '', - _source: message as SCMessage + _source: message as SCMessage, }; sandbox.stub(es.client, 'search').resolves({body: {hits: {hits: [object]}}}); // return index name with different generated UID (see getIndex method) @@ -451,18 +464,21 @@ describe('Elasticsearch', function () { }); it('should create a new object', async function () { - let caughtParam: any; + let caughtParameter: any; sandbox.stub(es.client, 'search').resolves({body: {hits: {hits: []}}}); - // @ts-ignore - let createStub = sandbox.stub(es.client, 'create').callsFake((param) => { - caughtParam = param; + // @ts-expect-error call + const createStub = sandbox.stub(es.client, 'create').callsFake(parameter => { + caughtParameter = parameter; return Promise.resolve({body: {created: true}}); }); await es.post(message as SCMessage, bulk); expect(createStub.called).to.be.true; - expect(caughtParam.body).to.be.eql({...message, creation_date: caughtParam.body.creation_date}); + expect(caughtParameter.body).to.be.eql({ + ...message, + creation_date: caughtParameter.body.creation_date, + }); }); }); @@ -482,32 +498,34 @@ describe('Elasticsearch', function () { _index: getIndex(), _score: 0, _type: '', - _source: message as SCMessage + _source: message as SCMessage, }; sandbox.stub(es.client, 'search').resolves({body: {hits: {hits: []}}}); return expect(es.put(object._source)).to.rejectedWith('exist'); }); + // noinspection JSUnusedLocalSymbols it('should update the object if it already exists', async function () { - let caughtParam: any; + let caughtParameter: any; const object: ElasticsearchObject = { _id: '', _index: getIndex(), _score: 0, _type: '', - _source: message as SCMessage + _source: message as SCMessage, }; sandbox.stub(es.client, 'search').resolves({body: {hits: {hits: [object]}}}); - // @ts-ignore - const stubUpdate = sandbox.stub(es.client, 'update').callsFake((params) => { - caughtParam = params; + // @ts-expect-error unused + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const stubUpdate = sandbox.stub(es.client, 'update').callsFake(parameters => { + caughtParameter = parameters; return Promise.resolve({body: {created: true}}); }); await es.put(object._source); - expect(caughtParam.body.doc).to.be.eql(object._source); + expect(caughtParameter.body.doc).to.be.eql(object._source); }); }); @@ -519,14 +537,14 @@ describe('Elasticsearch', function () { _index: getIndex(), _score: 0, _type: '', - _source: message as SCMessage + _source: message as SCMessage, }; const objectBook: ElasticsearchObject = { _id: '321', _index: getIndex(), _score: 0, _type: '', - _source: book as SCBook + _source: book as SCBook, }; const fakeEsAggregations = { '@all': { @@ -537,40 +555,36 @@ describe('Elasticsearch', function () { buckets: [ { key: 'person', - doc_count: 13 + doc_count: 13, }, { key: 'catalog', - doc_count: 4 - } - ] - } - } + doc_count: 4, + }, + ], + }, + }, }; const fakeSearchResponse: Partial>> = { - // @ts-ignore body: { took: 12, timed_out: false, - // @ts-ignore + // @ts-expect-error not assignable _shards: {}, - // @ts-ignore + // @ts-expect-error not assignable hits: { - hits: [ - objectMessage, - objectBook, - ], - total: 123 + hits: [objectMessage, objectBook], + total: 123, }, - aggregations: fakeEsAggregations + aggregations: fakeEsAggregations, }, headers: {}, - // @ts-ignore + // @ts-expect-error not assignable meta: {}, - // @ts-ignore + // @ts-expect-error not assignable statusCode: {}, - // @ts-ignore - warnings: {} + // @ts-expect-error not assignable + warnings: {}, }; let searchStub: sinon.SinonStub; before(function () { @@ -593,11 +607,11 @@ describe('Elasticsearch', function () { }, { count: 4, - key: 'catalog' - } + key: 'catalog', + }, ], field: 'type', - } + }, ]; const {data, facets} = await es.search({}); @@ -613,7 +627,7 @@ describe('Elasticsearch', function () { expect(pagination).to.be.eql({ count: fakeSearchResponse.body!.hits.hits.length, offset: from, - total: fakeSearchResponse.body!.hits.total + total: fakeSearchResponse.body!.hits.total, }); }); @@ -624,7 +638,7 @@ describe('Elasticsearch', function () { }); it('should build the search request properly', async function () { - const params: SCSearchQuery = { + const parameters: SCSearchQuery = { query: 'mathematics', from: 30, size: 5, @@ -632,42 +646,37 @@ describe('Elasticsearch', function () { { type: 'ducet', order: 'desc', - arguments: - { - field: 'name' - } - } + arguments: { + field: 'name', + }, + }, ], filter: { type: 'value', arguments: { field: 'type', - value: SCThingType.AcademicEvent - } - } + value: SCThingType.AcademicEvent, + }, + }, }; const fakeResponse = {foo: 'bar'}; const fakeBuildSortResponse = [fakeResponse]; - // @ts-ignore + // @ts-expect-error not assignable sandbox.stub(query, 'buildQuery').returns(fakeResponse); - // @ts-ignore sandbox.stub(query, 'buildSort').returns(fakeBuildSortResponse); - await es.search(params); + await es.search(parameters); - sandbox.assert - .calledWithMatch(searchStub, - { - body: { - aggs: aggregations, - query: fakeResponse, - sort: fakeBuildSortResponse - }, - from: params.from, - index: Elasticsearch.getListOfAllIndices(), - size: params.size, - } - ); + sandbox.assert.calledWithMatch(searchStub, { + body: { + aggs: aggregations, + query: fakeResponse, + sort: fakeBuildSortResponse, + }, + from: parameters.from, + index: Elasticsearch.getListOfAllIndices(), + size: parameters.size, + }); }); }); }); diff --git a/test/storage/elasticsearch/monitoring.spec.ts b/test/storage/elasticsearch/monitoring.spec.ts index 29ad6734..52ccc35f 100644 --- a/test/storage/elasticsearch/monitoring.spec.ts +++ b/test/storage/elasticsearch/monitoring.spec.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ /* * Copyright (C) 2020 StApps * This program is free software: you can redistribute it and/or modify @@ -18,7 +19,8 @@ import { SCMonitoringConfiguration, SCMonitoringLogAction, SCMonitoringMailAction, - SCMonitoringWatcher, SCThings + SCMonitoringWatcher, + SCThings, } from '@openstapps/core'; import {Logger} from '@openstapps/logger'; import {SearchResponse} from 'elasticsearch'; @@ -26,7 +28,7 @@ import {MailQueue} from '../../../src/notification/mail-queue'; import {setUp} from '../../../src/storage/elasticsearch/monitoring'; import {getTransport} from '../../common'; -import { expect } from 'chai'; +import {expect} from 'chai'; import sinon from 'sinon'; import cron from 'node-cron'; @@ -35,16 +37,15 @@ describe('Monitoring', async function () { const logAction: SCMonitoringLogAction = { message: 'Foo monitoring message', prefix: 'Backend Monitoring', - type: 'log' + type: 'log', }; const mailAction: SCMonitoringMailAction = { message: 'Bar monitoring message', recipients: ['xyz@xyz.com'], subject: 'Backend Monitoring', - type: 'mail' + type: 'mail', }; let transport: any; - // @ts-ignore let mailQueue: any; beforeEach(async function () { transport = getTransport(true); @@ -55,52 +56,52 @@ describe('Monitoring', async function () { sandbox.restore(); }); // const sandbox = sinon.createSandbox(); - let cronScheduleStub: sinon.SinonStub + let cronScheduleStub: sinon.SinonStub; const minLengthWatcher: SCMonitoringWatcher = { actions: [logAction, mailAction], conditions: [ { length: 10, - type: 'MinimumLength' - } + type: 'MinimumLength', + }, ], name: 'foo watcher', query: {foo: 'bar'}, triggers: [ { executionTime: 'monthly', - name: 'beginning of month' + name: 'beginning of month', }, { executionTime: 'daily', - name: 'every night' - } - ] + name: 'every night', + }, + ], }; const maxLengthWatcher: SCMonitoringWatcher = { actions: [logAction, mailAction], conditions: [ { length: 30, - type: 'MaximumLength' - } + type: 'MaximumLength', + }, ], name: 'foo watcher', query: {bar: 'foo'}, triggers: [ { executionTime: 'hourly', - name: 'every hour' + name: 'every hour', }, { executionTime: 'weekly', - name: 'every week' + name: 'every week', }, - ] + ], }; const monitoringConfig: SCMonitoringConfiguration = { actions: [logAction, mailAction], - watchers: [minLengthWatcher, maxLengthWatcher] + watchers: [minLengthWatcher, maxLengthWatcher], }; it('should create a schedule for each trigger', async function () { @@ -111,19 +112,18 @@ describe('Monitoring', async function () { it('should log errors where conditions failed', async function () { const fakeSearchResponse: Partial>> = { - // @ts-ignore body: { - took: 12, - timed_out: false, - // @ts-ignore - _shards: {}, - // @ts-ignore - hits: { - total: 123 - }, + took: 12, + timed_out: false, + // @ts-expect-error not assignable + _shards: {}, + // @ts-expect-error not assignable + hits: { + total: 123, + }, }, }; - let fakeClient = new Client({node: 'http://foohost:9200'}); + const fakeClient = new Client({node: 'http://foohost:9200'}); const loggerErrorStub = sandbox.stub(Logger, 'error'); const mailQueueSpy = sinon.spy(mailQueue, 'push'); cronScheduleStub.yields(); diff --git a/test/storage/elasticsearch/query.spec.ts b/test/storage/elasticsearch/query.spec.ts index 276b8edd..7b4a108f 100644 --- a/test/storage/elasticsearch/query.spec.ts +++ b/test/storage/elasticsearch/query.spec.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any,unicorn/no-null */ /* * Copyright (C) 2020 StApps * This program is free software: you can redistribute it and/or modify @@ -15,11 +16,13 @@ */ import { SCConfigFile, - SCSearchBooleanFilter, SCSearchDateRangeFilter, - SCSearchFilter, SCSearchNumericRangeFilter, + SCSearchBooleanFilter, + SCSearchDateRangeFilter, + SCSearchFilter, + SCSearchNumericRangeFilter, SCSearchQuery, SCSearchSort, - SCThingType + SCThingType, } from '@openstapps/core'; import {expect} from 'chai'; import { @@ -35,7 +38,12 @@ import { ScriptSort, } from '../../../src/storage/elasticsearch/types/elasticsearch'; import {configFile} from '../../../src/common'; -import {buildBooleanFilter, buildFilter, buildQuery, buildSort} from '../../../src/storage/elasticsearch/query'; +import { + buildBooleanFilter, + buildFilter, + buildQuery, + buildSort, +} from '../../../src/storage/elasticsearch/query'; describe('Query', function () { describe('buildBooleanFilter', function () { @@ -47,21 +55,21 @@ describe('Query', function () { type: 'value', arguments: { field: 'type', - value: SCThingType.Catalog - } + value: SCThingType.Catalog, + }, }, { type: 'value', arguments: { field: 'type', - value: SCThingType.Building - } - } - ] + value: SCThingType.Building, + }, + }, + ], }, - type: 'boolean' + type: 'boolean', }; - const booleanFilters: { [key: string]: SCSearchBooleanFilter } = { + const booleanFilters: {[key: string]: SCSearchBooleanFilter} = { and: booleanFilter, or: {...booleanFilter, arguments: {...booleanFilter.arguments, operation: 'or'}}, not: {...booleanFilter, arguments: {...booleanFilter.arguments, operation: 'not'}}, @@ -69,14 +77,14 @@ describe('Query', function () { const expectedEsFilters: Array = [ { term: { - 'type.raw': 'catalog' - } + 'type.raw': 'catalog', + }, }, { term: { - 'type.raw': 'building' - } - } + 'type.raw': 'building', + }, + }, ]; it('should create appropriate elasticsearch "and" filter argument', function () { @@ -100,7 +108,7 @@ describe('Query', function () { }); describe('buildQuery', function () { - const params: SCSearchQuery = { + const parameters: SCSearchQuery = { query: 'mathematics', from: 30, size: 5, @@ -108,27 +116,25 @@ describe('Query', function () { { type: 'ducet', order: 'desc', - arguments: - { - field: 'name' - } + arguments: { + field: 'name', + }, }, { type: 'ducet', order: 'desc', - arguments: - { - field: 'categories' - } + arguments: { + field: 'categories', + }, }, ], filter: { type: 'value', arguments: { field: 'type', - value: SCThingType.AcademicEvent - } - } + value: SCThingType.AcademicEvent, + }, + }, }; let esConfig: ElasticsearchConfig = { name: 'elasticsearch', @@ -138,7 +144,7 @@ describe('Query', function () { queryType: 'dis_max', matchBoosting: 1.3, fuzziness: 'AUTO', - cutoffFrequency: 0.0, + cutoffFrequency: 0, tieBreaker: 0, }, }; @@ -147,59 +153,59 @@ describe('Query', function () { queryType: 'dis_max', matchBoosting: 1.3, fuzziness: 'AUTO', - cutoffFrequency: 0.0, + cutoffFrequency: 0, tieBreaker: 0, }; const config: SCConfigFile = { - ...configFile + ...configFile, }; beforeEach(function () { esConfig = { name: 'elasticsearch', - version: '123' + version: '123', }; }); // TODO: check parts of received elasticsearch query for each test case it('should build query that includes sorting when query is undefined', function () { - expect(buildQuery(params, config, esConfig)).to.be.an('object'); + expect(buildQuery(parameters, config, esConfig)).to.be.an('object'); }); it('should build query that includes sorting when query type is query_string', function () { esConfig.query = {...query, queryType: 'query_string'}; - expect(buildQuery(params, config, esConfig)).to.be.an('object'); + expect(buildQuery(parameters, config, esConfig)).to.be.an('object'); }); it('should build query that includes sorting when query type is dis_max', function () { esConfig.query = {...query, queryType: 'dis_max'}; - expect(buildQuery(params, config, esConfig)).to.be.an('object'); + expect(buildQuery(parameters, config, esConfig)).to.be.an('object'); }); it('should build query that includes sorting when query type is dis_max', function () { esConfig.query = {...query, queryType: 'dis_max'}; - expect(buildQuery(params, config, esConfig)).to.be.an('object'); + expect(buildQuery(parameters, config, esConfig)).to.be.an('object'); }); it('should reject (throw an error) if provided query type is not supported', function () { - // @ts-ignore + // @ts-expect-error not assignable esConfig.query = {...query, queryType: 'invalid_query_type'}; - expect(() => buildQuery(params, config, esConfig)).to.throw('query type'); + expect(() => buildQuery(parameters, config, esConfig)).to.throw('query type'); }); }); describe('buildFilter', function () { - const searchFilters: { [key: string]: SCSearchFilter } = { + const searchFilters: {[key: string]: SCSearchFilter} = { value: { type: 'value', arguments: { field: 'type', - value: SCThingType.Dish - } + value: SCThingType.Dish, + }, }, distance: { type: 'distance', @@ -207,7 +213,7 @@ describe('Query', function () { distance: 1000, field: 'geo', position: [50.123, 8.123], - } + }, }, geoPoint: { type: 'geo', @@ -218,9 +224,9 @@ describe('Query', function () { coordinates: [ [50.123, 8.123], [50.123, 8.123], - ] - } - } + ], + }, + }, }, geoShape: { type: 'geo', @@ -232,9 +238,9 @@ describe('Query', function () { coordinates: [ [50.123, 8.123], [50.123, 8.123], - ] - } - } + ], + }, + }, }, boolean: { type: 'boolean', @@ -246,16 +252,16 @@ describe('Query', function () { arguments: { field: 'type', value: SCThingType.Dish, - } + }, }, { type: 'availability', arguments: { - field: 'offers.availabilityRange' - } - } - ] - } + field: 'offers.availabilityRange', + }, + }, + ], + }, }, }; @@ -263,8 +269,8 @@ describe('Query', function () { const filter = buildFilter(searchFilters.value); const expectedFilter: ESTermFilter = { term: { - 'type.raw': SCThingType.Dish - } + 'type.raw': SCThingType.Dish, + }, }; expect(filter).to.be.eql(expectedFilter); @@ -277,28 +283,30 @@ describe('Query', function () { range: { price: { relation: undefined, - } - } + }, + }, }; const rawFilter: SCSearchNumericRangeFilter = { type: 'numeric range', arguments: { bounds: {}, - field: 'price' - } + field: 'price', + }, }; + // eslint-disable-next-line unicorn/consistent-function-scoping const setBound = (location: 'upperBound' | 'lowerBound', bound: string | null) => { let out: number | null = null; - if (bound != null) { + if (bound != undefined) { out = Math.random(); rawFilter.arguments.bounds[location] = { mode: bound as 'inclusive' | 'exclusive', limit: out, }; - // @ts-ignore implicit any - expectedFilter.range.price[`${location === 'lowerBound' ? 'g' : 'l'}${bound === 'inclusive' ? 'te' : 't'}`] = out; + expectedFilter.range.price[ + `${location === 'lowerBound' ? 'g' : 'l'}${bound === 'inclusive' ? 'te' : 't'}` + ] = out; } }; setBound('upperBound', upperMode); @@ -307,9 +315,9 @@ describe('Query', function () { const filter = buildFilter(rawFilter) as ESNumericRangeFilter; expect(filter).to.deep.equal(expectedFilter); for (const bound of ['g', 'l']) { - // @ts-ignore implicit any + // @ts-expect-error implicit any const inclusiveExists = typeof filter.range.price[`${bound}t`] !== 'undefined'; - // @ts-ignore implicit any + // @ts-expect-error implicit any const exclusiveExists = typeof filter.range.price[`${bound}te`] !== 'undefined'; // only one should exist at the same time @@ -328,8 +336,8 @@ describe('Query', function () { format: 'thisIsADummyFormat', time_zone: 'thisIsADummyTimeZone', relation: 'testRelation' as any, - } - } + }, + }, }; const rawFilter: SCSearchDateRangeFilter = { @@ -340,19 +348,20 @@ describe('Query', function () { relation: 'testRelation' as any, format: 'thisIsADummyFormat', timeZone: 'thisIsADummyTimeZone', - } + }, }; const setBound = (location: 'upperBound' | 'lowerBound', bound: string | null) => { let out: string | null = null; - if (bound != null) { + if (bound != undefined) { out = `${location} ${bound} ${upperMode} ${lowerMode}`; rawFilter.arguments.bounds[location] = { mode: bound as 'inclusive' | 'exclusive', limit: out, }; - // @ts-ignore implicit any - expectedFilter.range.price[`${location === 'lowerBound' ? 'g' : 'l'}${bound === 'inclusive' ? 'te' : 't'}`] = out; + expectedFilter.range.price[ + `${location === 'lowerBound' ? 'g' : 'l'}${bound === 'inclusive' ? 'te' : 't'}` + ] = out; } }; setBound('upperBound', upperMode); @@ -361,9 +370,9 @@ describe('Query', function () { const filter = buildFilter(rawFilter) as ESNumericRangeFilter; expect(filter).to.deep.equal(expectedFilter); for (const bound of ['g', 'l']) { - // @ts-ignore implicit any + // @ts-expect-error implicit any const inclusiveExists = typeof filter.range.price[`${bound}t`] !== 'undefined'; - // @ts-ignore implicit any + // @ts-expect-error implicit any const exclusiveExists = typeof filter.range.price[`${bound}te`] !== 'undefined'; // only one should exist at the same time @@ -390,7 +399,7 @@ describe('Query', function () { 'offers.availabilityRange': { gte: `test||/${scope}`, lt: `test||+1${scope}/${scope}`, - } + }, }, }; expect(filter).to.be.eql(expectedFilter); @@ -411,7 +420,7 @@ describe('Query', function () { 'offers.availabilityRange': { gte: 'test||/s', lt: 'test||+1s/s', - } + }, }, }; expect(filter).to.be.eql(expectedFilter); @@ -432,7 +441,7 @@ describe('Query', function () { 'offers.availabilityRange': { gte: `test||/d`, lt: `test||+1d/d`, - } + }, }, }; expect(filter).to.be.eql(expectedFilter); @@ -452,7 +461,7 @@ describe('Query', function () { 'offers.availabilityRange': { gte: `now/d`, lt: `now+1d/d`, - } + }, }, }; expect(filter).to.be.eql(expectedFilter); @@ -463,12 +472,12 @@ describe('Query', function () { const filter = buildFilter(searchFilters.distance); const expectedFilter: ESGeoDistanceFilter = { geo_distance: { - distance: '1000m', + 'distance': '1000m', 'geo.point.coordinates': { lat: 8.123, - lon: 50.123 - } - } + lon: 50.123, + }, + }, }; expect(filter).to.be.eql(expectedFilter); @@ -488,24 +497,24 @@ describe('Query', function () { type: 'envelope', coordinates: [ [50.123, 8.123], - [50.123, 8.123] - ] + [50.123, 8.123], + ], }, }, - ignore_unmapped: true, - } + 'ignore_unmapped': true, + }, }, { geo_bounding_box: { 'geo.point.coordinates': { bottom_right: [50.123, 8.123], - top_left: [50.123, 8.123] + top_left: [50.123, 8.123], }, - ignore_unmapped: true, + 'ignore_unmapped': true, }, }, - ] - } + ], + }, }; expect(filter).to.be.eql(expectedFilter); @@ -521,12 +530,12 @@ describe('Query', function () { type: 'envelope', coordinates: [ [50.123, 8.123], - [50.123, 8.123] - ] + [50.123, 8.123], + ], }, }, - ignore_unmapped: true, - } + 'ignore_unmapped': true, + }, }; expect(filter).to.be.eql(expectedFilter); @@ -540,8 +549,8 @@ describe('Query', function () { must: [ { term: { - 'type.raw': 'dish' - } + 'type.raw': 'dish', + }, }, { range: { @@ -549,13 +558,13 @@ describe('Query', function () { gte: 'now/s', lt: 'now+1s/s', relation: 'intersects', - } - } - } + }, + }, + }, ], must_not: [], - should: [] - } + should: [], + }, }; expect(filter).to.be.eql(expectedFilter); @@ -568,7 +577,7 @@ describe('Query', function () { type: 'ducet', order: 'desc', arguments: { - field: 'name' + field: 'name', }, }, { @@ -576,14 +585,14 @@ describe('Query', function () { order: 'desc', arguments: { field: 'name', - } + }, }, { type: 'distance', order: 'desc', arguments: { field: 'geo', - position: [8.123, 50.123] + position: [8.123, 50.123], }, }, { @@ -592,35 +601,35 @@ describe('Query', function () { arguments: { universityRole: 'student', field: 'offers.prices', - } + }, }, ]; let sorts: Array = []; - const expectedSorts: { [key: string]: ESGenericSort | ESGeoDistanceSort | ScriptSort } = { + const expectedSorts: {[key: string]: ESGenericSort | ESGeoDistanceSort | ScriptSort} = { ducet: { - 'name.sort': 'desc' + 'name.sort': 'desc', }, generic: { - 'name': 'desc' + name: 'desc', }, distance: { _geo_distance: { - mode: 'avg', - order: 'desc', - unit: 'm', + 'mode': 'avg', + 'order': 'desc', + 'unit': 'm', 'geo.point.coordinates': { lat: 50.123, - lon: 8.123 - } - } + lon: 8.123, + }, + }, }, price: { _script: { order: 'asc', script: '\n // foo price sort script', - type: 'number' - } - } + type: 'number', + }, + }, }; before(function () { sorts = buildSort(searchSCSearchSort); @@ -641,7 +650,10 @@ describe('Query', function () { it('should build price sort', function () { const priceSortNoScript = { ...sorts[3], - _script: {...(sorts[3] as ScriptSort)._script, script: (expectedSorts.price as ScriptSort)._script.script} + _script: { + ...(sorts[3] as ScriptSort)._script, + script: (expectedSorts.price as ScriptSort)._script.script, + }, }; expect(priceSortNoScript).to.be.eql(expectedSorts.price); }); diff --git a/tsconfig.json b/tsconfig.json index 3b711172..4dbcef9c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,6 +6,6 @@ }, "exclude": [ "./config/", - "./test/" + "./test" ] } diff --git a/tslint.json b/tslint.json deleted file mode 100644 index f125abb0..00000000 --- a/tslint.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": "./node_modules/@openstapps/configuration/tslint.json" -}