diff --git a/.github/ISSUE_TEMPLATE/issue-template.md b/.github/ISSUE_TEMPLATE/issue-template.md index 6223758bd..8eb32396e 100644 --- a/.github/ISSUE_TEMPLATE/issue-template.md +++ b/.github/ISSUE_TEMPLATE/issue-template.md @@ -4,16 +4,22 @@ about: Describe this issue purpose here. --- -## Issue Name +## Issue Name (title) +Please enter the title for this github issue ### Summary +Description of the issue ### Steps to Reproduce +Describe how to reproduce the issue ### Current Behaviour +Describe the current behavior if it is relevant ### Expected Behaviour +Describe the expected behavior if it is relevant -### Extra Details +### Details +Provide all the details related to this issue. Also include screenshots, wireframes or mockups if they help. -Here you should include details about the system (if it is unique) and possible information about a fix (feel free to link to code where relevant). Screenshots/GIFs are also fine here. +__PS__: make sure to add the proper tags to the issue diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index d9b535cf5..2e89d4490 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -7,17 +7,25 @@ Short description of the pull request Background on use case, changes needed ## Fixes: +Please provide a list of the fixes implemented by this PR * Items added ## Changes: +Please provide a list of the changes implemented by this PR * changes made -## Tests included/Docs Updated? +## Tests included - [ ] Included for each change/fix? - [ ] Passing? (Merge will not be approved unless this is checked) -- [ ] Docs updated? -- [ ] New packages used/requires npm install? -- [ ] Toggle added for new features? + +## Documentation +- [ ] swagger documentation updated \[required\] +- [ ] official documentation updated \[nice-to-have] + +### official documentation info +If you have updated the official documentation, please provide PR # and URL of the pages where the updates are included + + diff --git a/.github/workflows/auto-merge-dependabot.yaml b/.github/workflows/auto-merge-dependabot.yaml index f080ac373..5ceef930d 100644 --- a/.github/workflows/auto-merge-dependabot.yaml +++ b/.github/workflows/auto-merge-dependabot.yaml @@ -15,7 +15,7 @@ jobs: ## Extract information about the dependencies being updated by a Dependabot-generated PR - name: Dependabot metadata id: dependabot-metadata - uses: dependabot/fetch-metadata@v2.0.0 + uses: dependabot/fetch-metadata@v2.1.0 with: github-token: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 58225c363..018ee476f 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -2,8 +2,8 @@ name: Deploy on: push: - branches: - - master + branches: + - master jobs: deploy: @@ -12,7 +12,7 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 - + - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 @@ -22,7 +22,7 @@ jobs: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - + - name: Create image tags id: meta uses: docker/metadata-action@v5 @@ -30,14 +30,15 @@ jobs: images: ghcr.io/scicatproject/backend-next flavor: latest=true # adds :latest tag to outputs.tags tags: type=sha,format=long,prefix= # adds : tag to outputs.tags - + - name: Build and push uses: docker/build-push-action@v5 with: context: . + platforms: linux/amd64,linux/arm64/v8 push: true tags: ${{ steps.meta.outputs.tags }} - + - name: Trigger ESS pipeline uses: swapActions/trigger-swap-deployment@v1 with: diff --git a/.github/workflows/github-tag-and-release.yml b/.github/workflows/github-tag-and-release.yml index 8bb15ac4a..8512df323 100644 --- a/.github/workflows/github-tag-and-release.yml +++ b/.github/workflows/github-tag-and-release.yml @@ -59,7 +59,7 @@ jobs: ## https://github.com/docker/metadata-action - name: Docker meta id: meta - uses: docker/metadata-action@v4 + uses: docker/metadata-action@v5 with: images: ghcr.io/scicatproject/backend-next tags: | diff --git a/README.md b/README.md index 2b6cbfd28..1a150b78f 100644 --- a/README.md +++ b/README.md @@ -88,88 +88,83 @@ The `loggers.json.example` file in the root directory showcases the example of c ## Environment variables Valid environment variables for the .env file. See [.env.example](/.env.example) for examples value formats. - -- `ADMIN_GROUPS` [string] _Optional_ Comma separated list of admin groups with admin permission assigned to the listed users. Example: "admin, ingestor". For more details check: [Scicat Documentation](https://scicatproject.github.io/documentation/Development/v4.x/backend/authorization.html) -- `CREATE_DATASET_GROUPS` [string] _Optional_ Comma seperated list of create dataset groups. Users belong to the listed groups can create dataset with/without PID. Example: "group1, group2". For more details check: [Scicat Documentation](https://scicatproject.github.io/documentation/Development/v4.x/backend/authorization.html) -- `CREATE_DATASET_WITH_PID_GROUPS` [string] _Optional_ Comma seperated list of create dataset with pid groups. Users belong to the listed groups can create dataset with PID. Example: "group1, group2". For more details check: [Scicat Documentation](https://scicatproject.github.io/documentation/Development/v4.x/backend/authorization.html) -- `DELETE_GROUPS` [string] _Optional_ Comma seperated list of delete groups. Users belong to the listed groups can delete any dataset, origDatablocks, datablocks etc. For more details check: [Scicat Documentation](https://scicatproject.github.io/documentation/Development/v4.x/backend/authorization.html) -- `DATASET_CREATION_VALIDATION_ENABLED` [boolean] Flag to enable/disable dataset validation to validate if requested new dataset is valid with given regular expression. Preconfigure **DATASET_CREATION_VALIDATION_REGEX** variable is required. Default value: false -- `DATASET_CREATION_VALIDATION_REGEX` [string] Regular expression validation for new dataset request. Default value: "" -- `PROPOSAL_GROUPS` [string] _Optional_ Comma separated list of proposal groups with permission to create any proposals. Example: "proposaladmin, proposalingestor". For more details check: [Scicat Documentation](https://scicatproject.github.io/documentation/Development/v4.x/backend/authorization.html) -- `SAMPLE_GROUPS` [string] _Optional_ Comma separated list of sample groups with permission to create any samples. Example: "sampleadmin, sampleingestor". For more details check: [Scicat Documentation](https://scicatproject.github.io/documentation/Development/v4.x/backend/authorization.html) - -- `ACCESS_GROUPS_GRAPHQL_ENABLED` [string] _Optional_ Flag to enable/disable the graphql service get access groups. In order to use this service following variables needs to be configured: `ACCESS_GROUP_SERVICE_TOKEN`, `ACCESS_GROUP_SERVICE_API_URL` and `ACCESS_GROUP_SERVICE_HANDLER` respectively. Values true or false. Defaults to true. -- `ACCESS_GROUPS_SERVICE_TOKEN` [string] _Optional_ Authentication token used if access groups are obtained from a third party service. This value is not used by the vanilla installation, but only if the instance is customized to use an external service to provide user groups, like the ESS example -- `ACCESS_GROUP_SERVICE_API_URL` [string] _Optional_ URL of the service providing the users' access groups. This value is not used by the vanilla installation, but only if the instance is customized to use an external service to provide user groups, like the ESS example -- `ACCESS_GROUP_SERVICE_HANDLER` [string] _Optional_ Configuration property that points to the source of a module. This module provides a specific responseProcessor function for handling GraphQL responses and a query template for making GraphQL requests -- `ACCESS_GROUPS_STATIC_ENABLED` [string] _Optional_ Flag to enable/disable automatic assignment of predefined access groups to all users. Values true or false. Defaults to true. -- `ACCESS_GROUPS_STATIC_VALUES` [string] _Optional_ Comma separated list of access groups automatically assigned to all users. Example: "scicat, user" -- `ACCESS_GROUPS_OIDCPAYLOAD_ENABLED` [string] _Optional_ Flag to enable/disable fetching access groups directly from OIDC response. Requires specifying a field via `OIDC_ACCESS_GROUPS_PROPERTY` to extract access groups. Defaults to false - -- `DOI_PREFIX` [string] The facility DOI prefix, with trailing slash. -- `EXPRESS_SESSION_SECRET` [string] _Optional_ Secret used to set up express session. -- `HTTP_MAX_REDIRECTS` [number] _Optional_ Max redirects for http requests. Defaults to 5. -- `HTTP_TIMEOUT` [number] _Optional_ Timeout from http requests in ms. Defaults to 5000. -- `JWT_SECRET` [string] The secret for your JWT token, used for authorization. -- `JWT_EXPIRES_IN` [number] _Optional_ How long, in seconds, the JWT token is valid. Defaults to `3600`. -- `LDAP_URL` [string] _Optional_ The URL to your LDAP server. -- `LDAP_BIND_DN` [string] _Optional_ Bind_DN for your LDAP server. -- `LDAP_BIND_CREDENTIALS` [string] _Optional_ Credentials for your LDAP server. -- `LDAP_SEARCH_BASE` [string] _Optional_ Search base for your LDAP server. -- `LDAP_SEARCH_FILTER` [string] _Optional_ Search filter for you LDAP server. -- `OIDC_ISSUER` [string] _Optional_ URL of the oidc server providing the authentication service. Example: https://identity.esss.dk/realm/ess. -- `OIDC_CLIENT_ID` [string] _Optional_ Identity of the client that we want to use to obtain the user token. Example: scicat -- `OIDC_CLIENT_SECRET` [string] _Optional_ Secret to provide to the oidc service to obtain the user token. Example: Aa1JIw3kv3mQlGFWhRrE3gOdkH6xreAwro -- `OIDC_CALLBACK_URL` [string] _Optional_ SciCat callback URL that we want th eoidc service to redirect to, in case of successful login. Example: http://myscicat/api/v3/oidc/callback -- `OIDC_SCOPE` [string] _Optional_ Space separated list of the info returned by the oidc service. Example: "openid profile email" -- `OIDC_SUCCESS_URL` [string] _Optional_ SciCat Frontend auth-callback URL. Required in order to pass user credentials to SciCat Frontend after OIDC login. Example: https://myscicatfrontend/auth-callback -- `OIDC_ACCESS_GROUPS` [string] _Optional_ Functionality is still unclear. -- `OIDC_ACCESS_GROUPS_PROPERTY` [string] _Optional_ Target field to get the access groups value from OIDC response. -- `OIDC_USERINFO_MAPPING_FIELD_USERNAME` [string] _Optional_ comma-separated list. Specifies the fields from the OIDC response to concatenate and use as the user's profile username. For example, setting `OIDC_USERINFO_MAPPING_FIELD_USERNAME="iss, sub"` combines the iss (issuer) and sub (subject) values from the OIDC response, resulting in a username like `myIssuer_myUserName`. This allows for customizable username definitions based on OIDC response attributes. Defaults to "preferred_username" || "name" -- `OIDC_USERINFO_MAPPING_FIELD_DISPLAYNAME` [string] _Optional_ Specifies the fields from the OIDC response and use as the user's profile displayname. For example, setting `OIDC_USERINFO_MAPPING_FIELD_DISPLAYNAME="preferred_username"` use displayName value from the OIDC response, resulting in a displayname like `myPreferredName`. This allows for customizable displayname definitions based on OIDC response attributes. Defaults to "name" -- `OIDC_USERINFO_MAPPING_FIELD_EMAIL` [string] _Optional_ Same as `OIDC_USERINFO_MAPPING_FIELD_DISPLAYNAME`. Defaults to "email" -- `OIDC_USERINFO_MAPPING_FIELD_FAMILYNAME` [string] _Optional_ Same as `OIDC_USERINFO_MAPPING_FIELD_DISPLAYNAME`. Defaults to "family_name" -- `OIDC_USERINFO_MAPPING_FIELD_ID` [string] _Optional_ Same as `OIDC_USERINFO_MAPPING_FIELD_DISPLAYNAME`. Defaults to "sub" || "user_id" -- `OIDC_USERINFO_MAPPING_FIELD_THUMBNAILPHOTO` [string] _Optional_ Same as `OIDC_USERINFO_MAPPING_FIELD_DISPLAYNAME`. Defaults to "thumbnailPhoto" -- `OIDC_USERINFO_MAPPING_FIELD_PROVIDER` [string] _Optional_ Same as `OIDC_USERINFO_MAPPING_FIELD_DISPLAYNAME`. Defaults to "iss" -- `OIDC_USERINFO_MAPPING_FIELD_GROUP` [string] _Optional_ Same as `OIDC_USERINFO_MAPPING_FIELD_DISPLAYNAME`. Defaults to "groups" -- `OIDC_USERQUERY_OPERATOR` [string] _Optional_ Specifies the operator ("or" or "and") for UserModel.findOne queries, determining the logic used to match fields like "username" or "email". Example: `UserModel.findOne({$or: {"username":"testUser", "email":"test@test.com"}})`. Defaults to "or" -- `OIDC_USERQUERY_FILTER` [string] _Optional_ Defines key-value pairs for UserModel.findOne queries, using a "key:value" format. Values should correspond to fields in the userProfile object. For instance,` OIDC_USERQUERY_FILTER="username:sub, email:email"` maps to `userProfile.sub` and `userProfile.email` respectively. Defaults to "username:username, email:email" - -- `LOGBOOK_ENABLED` [string] _Optional_ Flag to enable/disable the Logbook endpoints. Values "yes" or "no". Defaults to "no". -- `LOGBOOK_BASE_URL` [string] _Optional_ The base URL to the Logbook API. Only required if Logbook is enabled. - -- `METADATA_KEYS_RETURN_LIMIT` [number] _Optional_ The return limit for the `/Datasets/metadataKeys` endpoint. -- `METADATA_PARENT_INSTANCES_RETURN_LIMIT` _Optional_ The return limit of Datasets to extract metadata keys from for the `/Datasets/metadataKeys` endpoint. -- `MONGODB_URI` [string] The URI for your MongoDB instance. -- `OAI_PROVIDER_ROUTE` [string] _Optional_ URI to OAI provider, used for the `/publisheddata/:id/resync` endpoint. -- `PID_PREFIX` [string] The facility PID prefix, with trailing slash. -- `PUBLIC_URL_PREFIX` [string] The base URL to the facility Landing Page. -- `PORT` [number] _Optional_ The port on which you want to access the app. Defaults to `3000`. -- `RABBITMQ_ENABLED` [string] _Optional_ Flag to enable/disable RabbitMQ consumer. Values "yes" or "no". Defaults to "no". -- `RABBITMQ_HOSTNAME` [string] _Optional_ The hostname of the RabbitMQ message broker. Only required if RabbitMQ is enabled. -- `RABBITMQ_USERNAME` [string] _Optional_ The username used to authenticate to the RabbitMQ message broker. Only required if RabbitMQ is enabled. -- `RABBITMQ_PASSWORD` [string] _Optional_ The password used to authenticate to the RabbitMQ message broker. Only required if RabbitMQ is enabled. -- `REGISTER_DOI_URI` [string] URI to the organization that registers the facilities DOI's. -- `REGISTER_METADATA_URI` [string] URI to the organization that registers the facilities published data metadata. -- `SITE` [string] The name of your site. -- `SMTP_HOST` [string] _Optional_ Host of SMTP server. -- `SMTP_MESSAGE_FROM` [string] _Optional_ Email address that emails should be sent from. -- `SMTP_PORT` [string] _Optional_ Port of SMTP server. -- `SMTP_SECURE` [string] _Optional_ Secure of SMTP server. -- `POLICY_PUBLICATION_SHIFT` [integer] _Optional_ Embargo period expressed in years. Default value: 3 years -- `POLICY_RETENTION_SHIFT` [integer] _Optional_ Retention period (aka how long the facility will hold on to data) expressed in years. Default value: -1 (data will be hold indefinitely) - -- `ELASTICSEARCH_ENABLED` [string] Flag to enable/disable the Elasticsearch endpoints. Values "yes" or "no". Defaults to "no" -- `ES_HOST` [string] Host of Elasticsearch server instance -- `ES_USERNAME` [string] _Optional_ Elasticsearch username that can be customized when loads Elasticsearch server. Default value: 'elastic' -- `ES_PASSWORD` [string] Elasticsearch password that can be customized when loads Elasticsearch server. -- `MONGODB_COLLECTION` [string] Collection name to be mapped into specified Elasticsearch index. Used for data synchronization between mongoDB and Elasticsearch index. -- `ES_MAX_RESULT` [number] Maximum records can be indexed into Elasticsearch. Default value: 10000 -- `ES_FIELDS_LIMIT` [number] The total number of fields in an index. Default value: 1000 -- `ES_REFRESH` [string] If set to `wait_for` Elasticsearch will wait till data is insereted to specificied index then return response. Unless you have a good reason to wait for the change to become visible, always use `false` (the default setting). - -- `LOGGERS_CONFIG_FILE` [string] The file name for loggers configuration which needs to be located in the project root directory. Default value: "loggers.json" +| Environment Variable | Type | Optional | Description | Default Value | +|---------------------------------------------|---------|----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------| +| `ADMIN_GROUPS` | string | Yes | Comma-separated list of admin groups with admin permission assigned to the listed users. Example: "admin, ingestor". For more details check: [Scicat Documentation](https://scicatproject.github.io/documentation/Development/v4.x/backend/authorization.html) | | +| `CREATE_DATASET_GROUPS` | string | Yes | Comma-separated list of create dataset groups. Users belong to the listed groups can create dataset with/without PID. Example: "group1, group2". For more details check: [Scicat Documentation](https://scicatproject.github.io/documentation/Development/v4.x/backend/authorization.html) | | +| `CREATE_DATASET_WITH_PID_GROUPS` | string | Yes | Comma-separated list of create dataset with pid groups. Users belong to the listed groups can create dataset with PID. Example: "group1, group2". For more details check: [Scicat Documentation](https://scicatproject.github.io/documentation/Development/v4.x/backend/authorization.html) | | +| `DELETE_GROUPS` | string | Yes | Comma-separated list of delete groups. Users belong to the listed groups can delete any dataset, origDatablocks, datablocks, etc. For more details check: [Scicat Documentation](https://scicatproject.github.io/documentation/Development/v4.x/backend/authorization.html) | | +| `DATASET_CREATION_VALIDATION_ENABLED` | boolean | | Flag to enable/disable dataset validation to validate if requested new dataset is valid with given regular expression. Preconfigure **DATASET_CREATION_VALIDATION_REGEX** variable is required. | false | +| `DATASET_CREATION_VALIDATION_REGEX` | string | | Regular expression validation for new dataset request. | "" | +| `PROPOSAL_GROUPS` | string | Yes | Comma-separated list of proposal groups with permission to create any proposals. Example: "proposaladmin, proposalingestor". For more details check: [Scicat Documentation](https://scicatproject.github.io/documentation/Development/v4.x/backend/authorization.html) | | +| `SAMPLE_GROUPS` | string | Yes | Comma-separated list of sample groups with permission to create any samples. Example: "sampleadmin, sampleingestor". For more details check: [Scicat Documentation](https://scicatproject.github.io/documentation/Development/v4.x/backend/authorization.html) | | +| `ACCESS_GROUPS_GRAPHQL_ENABLED` | string | Yes | Flag to enable/disable the GraphQL service to get access groups. Requires configuration of `ACCESS_GROUP_SERVICE_TOKEN`, `ACCESS_GROUP_SERVICE_API_URL`, and `ACCESS_GROUP_SERVICE_HANDLER`. | true | +| `ACCESS_GROUPS_SERVICE_TOKEN` | string | Yes | Authentication token used if access groups are obtained from a third-party service. Not used by the vanilla installation, but only if the instance is customized to use an external service to provide user groups, like the ESS example. | | +| `ACCESS_GROUP_SERVICE_API_URL` | string | Yes | URL of the service providing the users' access groups. Not used by the vanilla installation, but only if the instance is customized to use an external service to provide user groups, like the ESS example. | | +| `ACCESS_GROUP_SERVICE_HANDLER` | string | Yes | Configuration property that points to the source of a module. This module provides a specific responseProcessor function for handling GraphQL responses and a query template for making GraphQL requests. | | +| `ACCESS_GROUPS_STATIC_ENABLED` | string | Yes | Flag to enable/disable automatic assignment of predefined access groups to all users. | true | +| `ACCESS_GROUPS_STATIC_VALUES` | string | Yes | Comma-separated list of access groups automatically assigned to all users. Example: "scicat, user". | | +| `ACCESS_GROUPS_OIDCPAYLOAD_ENABLED` | string | Yes | Flag to enable/disable fetching access groups directly from OIDC response. Requires specifying a field via `OIDC_ACCESS_GROUPS_PROPERTY` to extract access groups. | false | +| `DOI_PREFIX` | string | | The facility DOI prefix, with trailing slash. | | +| `EXPRESS_SESSION_SECRET` | string | Yes | Secret used to set up express session. | | +| `HTTP_MAX_REDIRECTS` | number | Yes | Max redirects for HTTP requests. | 5 | +| `HTTP_TIMEOUT` | number | Yes | Timeout for HTTP requests in ms. | 5000 | +| `JWT_SECRET` | string | | The secret for your JWT token, used for authorization. | | +| `JWT_EXPIRES_IN` | number | Yes | How long, in seconds, the JWT token is valid. | 3600 | +| `LDAP_URL` | string | Yes | The URL to your LDAP server. | | +| `LDAP_BIND_DN` | string | Yes | Bind_DN for your LDAP server. | | +| `LDAP_BIND_CREDENTIALS` | string | Yes | Credentials for your LDAP server. | | +| `LDAP_SEARCH_BASE` | string | Yes | Search base for your LDAP server. | | +| `LDAP_SEARCH_FILTER` | string | Yes | Search filter for your LDAP server. | | +| `OIDC_ISSUER` | string | Yes | URL of the OIDC server providing the authentication service. Example: https://identity.esss.dk/realm/ess. | | +| `OIDC_CLIENT_ID` | string | Yes | Identity of the client used to obtain the user token. Example: scicat. | | +| `OIDC_CLIENT_SECRET` | string | Yes | Secret to provide to the OIDC service to obtain the user token. Example: Aa1JIw3kv3mQlGFWhRrE3gOdkH6xreAwro. | | +| `OIDC_CALLBACK_URL` | string | Yes | SciCat callback URL to redirect to after a successful login. Example: http://myscicat/api/v3/oidc/callback. | | +| `OIDC_SCOPE` | string | Yes | Space-separated list of info returned by the OIDC service. Example: "openid profile email". | | +| `OIDC_SUCCESS_URL` | string | Yes | SciCat Frontend auth-callback URL. Required to pass user credentials to SciCat Frontend after OIDC login. Example: https://myscicatfrontend/auth-callback. | | +| `OIDC_ACCESS_GROUPS` | string | Yes | Functionality is still unclear. | | +| `OIDC_ACCESS_GROUPS_PROPERTY` | string | Yes | Target field to get the access groups value from OIDC response. | | +| `OIDC_USERINFO_MAPPING_FIELD_USERNAME` | string | Yes | Comma-separated list of fields from the OIDC response to use as the user's profile username. Example: `OIDC_USERINFO_MAPPING_FIELD_USERNAME="iss, sub"`. | "preferred_username" \|\| "name" | +| `OIDC_USERINFO_MAPPING_FIELD_DISPLAYNAME` | string | Yes | Field from the OIDC response to use as the user's profile display name. Example: `OIDC_USERINFO_MAPPING_FIELD_DISPLAYNAME="preferred_username"`. | "name" | +| `OIDC_USERINFO_MAPPING_FIELD_EMAIL` | string | Yes | Field from the OIDC response to use as the user's profile email. | "email" | +| `OIDC_USERINFO_MAPPING_FIELD_FAMILYNAME` | string | Yes | Field from the OIDC response to use as the user's profile family name. | "family_name" | +| `OIDC_USERINFO_MAPPING_FIELD_ID` | string | Yes | Field from the OIDC response to use as the user's profile ID. | "sub" \|\| "user_id" | +| `OIDC_USERINFO_MAPPING_FIELD_THUMBNAILPHOTO`| string | Yes | Field from the OIDC response to use as the user's profile thumbnail photo. | "thumbnailPhoto" | +| `OIDC_USERINFO_MAPPING_FIELD_PROVIDER` | string | Yes | Field from the OIDC response to use as the user's profile provider. | "iss" | +| `OIDC_USERINFO_MAPPING_FIELD_GROUP` | string | Yes | Field from the OIDC response to use as the user's profile group. | "groups" | +| `OIDC_USERQUERY_OPERATOR` | string | Yes | Specifies the operator ("or" or "and") for UserModel.findOne queries, determining the logic used to match fields like "username" or "email". Example: `UserModel.findOne({$or: {"username":"testUser", "email":"test@test.com"}})`. | "or" | +| `OIDC_USERQUERY_FILTER` | string | Yes | Defines key-value pairs for UserModel.findOne queries, using a "key:value" format. Example: `OIDC_USERQUERY_FILTER="username:sub, email:email"`. | "username:username, email:email" | +| `LOGBOOK_ENABLED` | string | Yes | Flag to enable/disable the Logbook endpoints. Values "yes" or "no". | "no" | +| `LOGBOOK_BASE_URL` | string | Yes | The base URL to the Logbook API. Only required if Logbook is enabled. | | +| `METADATA_KEYS_RETURN_LIMIT` | number | Yes | The return limit for the `/Datasets/metadataKeys` endpoint. | | +| `METADATA_PARENT_INSTANCES_RETURN_LIMIT` | number | Yes | The return limit of Datasets to extract metadata keys from for the `/Datasets/metadataKeys` endpoint. | | +| `MONGODB_URI` | string | | The URI for your MongoDB instance. | | +| `OAI_PROVIDER_ROUTE` | string | Yes | URI to OAI provider, used for the `/publisheddata/:id/resync` endpoint. | | +| `PID_PREFIX` | string | | The facility PID prefix, with trailing slash. | | +| `PUBLIC_URL_PREFIX` | string | | The base URL to the facility Landing Page. | | +| `PORT` | number | Yes | The port on which you want to access the app. | 3000 | +| `RABBITMQ_ENABLED` | string | Yes | Flag to enable/disable RabbitMQ consumer. Values "yes" or "no". | "no" | +| `RABBITMQ_HOSTNAME` | string | Yes | The hostname of the RabbitMQ message broker. Only required if RabbitMQ is enabled. | | +| `RABBITMQ_USERNAME` | string | Yes | The username used to authenticate to the RabbitMQ message broker. Only required if RabbitMQ is enabled. | | +| `RABBITMQ_PASSWORD` | string | Yes | The password used to authenticate to the RabbitMQ message broker. Only required if RabbitMQ is enabled. | | +| `REGISTER_DOI_URI` | string | | URI to the organization that registers the facility's DOIs. | | +| `REGISTER_METADATA_URI` | string | | URI to the organization that registers the facility's published data metadata. | | +| `SITE` | string | | The name of your site. | | +| `SMTP_HOST` | string | Yes | Host of SMTP server. | | +| `SMTP_MESSAGE_FROM` | string | Yes | Email address that emails should be sent from. | | +| `SMTP_PORT` | string | Yes | Port of SMTP server. | | +| `SMTP_SECURE` | string | Yes | Secure of SMTP server. | | +| `POLICY_PUBLICATION_SHIFT` | integer | Yes | Embargo period expressed in years. | 3 years | +| `POLICY_RETENTION_SHIFT` | integer | Yes | Retention period (how long the facility will hold on to data) expressed in years. | -1 (indefinitely) | +| `ELASTICSEARCH_ENABLED` | string | | Flag to enable/disable the Elasticsearch endpoints. Values "yes" or "no". | "no" | +| `ES_HOST` | string | | Host of Elasticsearch server instance. | | +| `ES_USERNAME` | string | Yes | Elasticsearch username. | "elastic" | +| `ES_PASSWORD` | string | | Elasticsearch password. | | +| `MONGODB_COLLECTION` | string | | Collection name to be mapped into specified Elasticsearch index. Used for data synchronization between MongoDB and Elasticsearch index. | | +| `ES_MAX_RESULT` | number | | Maximum records that can be indexed into Elasticsearch. | 10000 | +| `ES_FIELDS_LIMIT` | number | | The total number of fields in an index. | 1000 | +| `ES_REFRESH` | string | | If set to `wait_for`, Elasticsearch will wait till data is inserted into the specified index before returning a response. | false | +| `LOGGERS_CONFIG_FILE` | string | | The file name for loggers configuration, located in the project root directory. | "loggers.json" | ## Migrating from the old SciCat Backend @@ -213,6 +208,45 @@ Following are the post that I found useful working on the migration: - https://docs.nestjs.com/openapi/types-and-parameters - https://docs.nestjs.com/openapi/decorators +## New Release Version Bump Workflow + +### Workflow Overview + +Scicat Backend controls new releases with the `GitHub-tag-and-release` GitHub Action. This workflow is triggered by push events to the release branch. It automates the version bumping and release processes based on semantic commit messages. Full documentation of the action package can be found on [github-tag-action](https://github.com/marketplace/actions/github-tag) + +The image below shows visualized workflow. +![image](https://github.com/SciCatProject/scicat-backend-next/assets/78078898/0f3c5386-4a16-4ed1-a2ee-d71ef6f34e99) + +### Workflow Trigger Condition + +> [!Caution] +> Any push to the `release` branch initiates the workflow. + +### Versioning and Release Strategy + +**Semantic Versioning:** + +- The version is automatically bumped according to the semantic PR titles, using the [semantic-release](https://github.com/semantic-release/semantic-release) conventions: + + - `fix:` prefixed titles generate a patch release. + - `feat:` prefixed titles generate a minor release. + - `BREAKING CHANGE:` in the commit message triggers a major release. + +**Auto-generated Release Notes:** + +The release log is automatically populated with all commit messages since the last tag, providing a detailed changelog for the release. By default semantic-release uses [Angular Commit Message Conventions](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#-git-commit-guidelines). + +In order to generate detailed changelog for the release, the following type for the `commit message`/`PR title` should be used: + +- feat: message - A new feature +- fix: message - A bug fix +- docs: message - Documentation only changes +- style: message - Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc) +- refactor: message - A code change that neither fixes a bug nor adds a feature +- perf: message - A code change that improves performance +- test: message - Adding missing or correcting existing tests +- chore: message - Changes to the build process or auxiliary tools and libraries such as documentation generation + ## License This project is licensed under the GPL License - see the [LICENSE](LICENSE) file for details diff --git a/package-lock.json b/package-lock.json index f026cbf08..9c26d183b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,17 +11,17 @@ "dependencies": { "@casl/ability": "^6.3.2", "@elastic/elasticsearch": "^8.9.0", - "@nestjs-modules/mailer": "^1.8.1", + "@nestjs-modules/mailer": "^2.0.2", "@nestjs/axios": "^3.0.0", - "@nestjs/common": "^9.0.0", + "@nestjs/common": "^10.3.8", "@nestjs/config": "^3.0.0", - "@nestjs/core": "^9.0.0", + "@nestjs/core": "^10.3.8", "@nestjs/elasticsearch": "^10.0.1", "@nestjs/event-emitter": "^2.0.1", "@nestjs/jwt": "^10.0.1", "@nestjs/mongoose": "^10.0.0", "@nestjs/passport": "^10.0.0", - "@nestjs/platform-express": "^9.0.0", + "@nestjs/platform-express": "^10.3.8", "@nestjs/swagger": "^7.1.7", "@nestjs/terminus": "^10.1.1", "@user-office-software/duo-logger": "^2.1.1", @@ -36,7 +36,7 @@ "luxon": "^3.2.1", "mathjs": "^12.0.0", "migrate-mongo": "^11.0.0", - "mongoose": "^8.3.1", + "mongoose": "^8.4.0", "node-fetch": "^3.3.0", "nodemailer": "^6.7.8", "openid-client": "^5.1.8", @@ -44,7 +44,7 @@ "passport-jwt": "^4.0.0", "passport-ldapauth": "^3.0.1", "passport-local": "^1.0.0", - "reflect-metadata": "^0.1.13", + "reflect-metadata": "^0.2.2", "rimraf": "^5.0.0", "rxjs": "^7.5.7", "swagger-ui-express": "^5.0.0", @@ -54,7 +54,7 @@ "@faker-js/faker": "^8.0.1", "@nestjs/cli": "^10.0.5", "@nestjs/schematics": "^10.0.1", - "@nestjs/testing": "^9.0.0", + "@nestjs/testing": "^10.3.8", "@types/bcrypt": "^5.0.0", "@types/chai": "^4.3.6", "@types/express": "^4.17.13", @@ -82,8 +82,8 @@ "jest": "27.0.6", "mocha": "^10.0.0", "prettier": "^3.0.3", - "sinon": "^17.0.0", - "supertest": "^6.1.3", + "sinon": "^18.0.0", + "supertest": "^7.0.0", "ts-jest": "^27.0.3", "ts-loader": "^9.2.3", "ts-node": "^10.9.1", @@ -585,6 +585,7 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "devOptional": true, "engines": { "node": ">=6.9.0" } @@ -593,6 +594,7 @@ "version": "7.22.20", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "devOptional": true, "engines": { "node": ">=6.9.0" } @@ -709,6 +711,7 @@ "version": "7.23.0", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", + "devOptional": true, "bin": { "parser": "bin/babel-parser.js" }, @@ -879,9 +882,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.0.tgz", - "integrity": "sha512-Chk32uHMg6TnQdvw2e9IlqPpFX/6NLuK0Ys2PqLb7/gL5uFn9mXvK715FGLlOLQrcO4qIkNHkvPGktzzXexsFw==", + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.4.tgz", + "integrity": "sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -937,6 +940,7 @@ "version": "7.23.0", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", + "devOptional": true, "dependencies": { "@babel/helper-string-parser": "^7.22.5", "@babel/helper-validator-identifier": "^7.22.20", @@ -995,27 +999,59 @@ } }, "node_modules/@css-inline/css-inline": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@css-inline/css-inline/-/css-inline-0.13.0.tgz", - "integrity": "sha512-ZozAXBiW1I8hf6eW5eTNqhxUdNOBxrNNxxUnQRiKQpWcs5ORuGaiWwV5focMBTJ5WXGN+Z8VLP93BOwWFPzCJw==", + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/@css-inline/css-inline/-/css-inline-0.14.1.tgz", + "integrity": "sha512-u4eku+hnPqqHIGq/ZUQcaP0TrCbYeLIYBaK7qClNRGZbnh8RC4gVxLEIo8Pceo1nOK9E5G4Lxzlw5KnXcvflfA==", "engines": { "node": ">= 10" }, "optionalDependencies": { - "@css-inline/css-inline-darwin-arm64": "0.13.0", - "@css-inline/css-inline-darwin-x64": "0.13.0", - "@css-inline/css-inline-linux-arm-gnueabihf": "0.13.0", - "@css-inline/css-inline-linux-arm64-gnu": "0.13.0", - "@css-inline/css-inline-linux-arm64-musl": "0.13.0", - "@css-inline/css-inline-linux-x64-gnu": "0.13.0", - "@css-inline/css-inline-linux-x64-musl": "0.13.0", - "@css-inline/css-inline-win32-x64-msvc": "0.13.0" + "@css-inline/css-inline-android-arm-eabi": "0.14.1", + "@css-inline/css-inline-android-arm64": "0.14.1", + "@css-inline/css-inline-darwin-arm64": "0.14.1", + "@css-inline/css-inline-darwin-x64": "0.14.1", + "@css-inline/css-inline-linux-arm-gnueabihf": "0.14.1", + "@css-inline/css-inline-linux-arm64-gnu": "0.14.1", + "@css-inline/css-inline-linux-arm64-musl": "0.14.1", + "@css-inline/css-inline-linux-x64-gnu": "0.14.1", + "@css-inline/css-inline-linux-x64-musl": "0.14.1", + "@css-inline/css-inline-win32-x64-msvc": "0.14.1" + } + }, + "node_modules/@css-inline/css-inline-android-arm-eabi": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/@css-inline/css-inline-android-arm-eabi/-/css-inline-android-arm-eabi-0.14.1.tgz", + "integrity": "sha512-LNUR8TY4ldfYi0mi/d4UNuHJ+3o8yLQH9r2Nt6i4qeg1i7xswfL3n/LDLRXvGjBYqeEYNlhlBQzbPwMX1qrU6A==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@css-inline/css-inline-android-arm64": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/@css-inline/css-inline-android-arm64/-/css-inline-android-arm64-0.14.1.tgz", + "integrity": "sha512-tH5us0NYGoTNBHOUHVV7j9KfJ4DtFOeTLA3cM0XNoMtArNu2pmaaBMFJPqECzavfXkLc7x5Z22UPZYjoyHfvCA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" } }, "node_modules/@css-inline/css-inline-darwin-arm64": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@css-inline/css-inline-darwin-arm64/-/css-inline-darwin-arm64-0.13.0.tgz", - "integrity": "sha512-A4QvlZdhp8v+3IHKF/UftRf5GrAVUMEHCGRuk2Dx594xn/UR4ieh+B70aMm5rfONh2hv5mlR9UcoYAkVpEQ99g==", + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/@css-inline/css-inline-darwin-arm64/-/css-inline-darwin-arm64-0.14.1.tgz", + "integrity": "sha512-QE5W1YRIfRayFrtrcK/wqEaxNaqLULPI0gZB4ArbFRd3d56IycvgBasDTHPre5qL2cXCO3VyPx+80XyHOaVkag==", "cpu": [ "arm64" ], @@ -1028,9 +1064,9 @@ } }, "node_modules/@css-inline/css-inline-darwin-x64": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@css-inline/css-inline-darwin-x64/-/css-inline-darwin-x64-0.13.0.tgz", - "integrity": "sha512-px9z4ypzeECMyBEtlrNzTMpA1tnw5MmMIiMkBRhb8UGRr2pOBZY3yd/eEIxWzVVSPt0aIjVDwUOJ3+d0Z+BskA==", + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/@css-inline/css-inline-darwin-x64/-/css-inline-darwin-x64-0.14.1.tgz", + "integrity": "sha512-mAvv2sN8awNFsbvBzlFkZPbCNZ6GCWY5/YcIz7V5dPYw+bHHRbjnlkNTEZq5BsDxErVrMIGvz05PGgzuNvZvdQ==", "cpu": [ "x64" ], @@ -1043,9 +1079,9 @@ } }, "node_modules/@css-inline/css-inline-linux-arm-gnueabihf": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@css-inline/css-inline-linux-arm-gnueabihf/-/css-inline-linux-arm-gnueabihf-0.13.0.tgz", - "integrity": "sha512-+uo0coLQNgk/AKeOB8mXSRd8VIlUg38zRSB9B9q0ior9oBCDPtEdn1HuCSvWxHoOSJ8QNNk+uwbz0zW4CETzFw==", + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/@css-inline/css-inline-linux-arm-gnueabihf/-/css-inline-linux-arm-gnueabihf-0.14.1.tgz", + "integrity": "sha512-AWC44xL0X7BgKvrWEqfSqkT2tJA5kwSGrAGT+m0gt11wnTYySvQ6YpX0fTY9i3ppYGu4bEdXFjyK2uY1DTQMHA==", "cpu": [ "arm" ], @@ -1058,9 +1094,9 @@ } }, "node_modules/@css-inline/css-inline-linux-arm64-gnu": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@css-inline/css-inline-linux-arm64-gnu/-/css-inline-linux-arm64-gnu-0.13.0.tgz", - "integrity": "sha512-GVrsFbY5l0Hxyzxsm5S5JPGObvHm/Ybf2wZgnWBsQigxqGtr1FL535HaTwEnq6aHOpH3f08gR5Vx33gB7jG4pw==", + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/@css-inline/css-inline-linux-arm64-gnu/-/css-inline-linux-arm64-gnu-0.14.1.tgz", + "integrity": "sha512-drj0ciiJgdP3xKXvNAt4W+FH4KKMs8vB5iKLJ3HcH07sNZj58Sx++2GxFRS1el3p+GFp9OoYA6dgouJsGEqt0Q==", "cpu": [ "arm64" ], @@ -1073,9 +1109,9 @@ } }, "node_modules/@css-inline/css-inline-linux-arm64-musl": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@css-inline/css-inline-linux-arm64-musl/-/css-inline-linux-arm64-musl-0.13.0.tgz", - "integrity": "sha512-V5h5+CRnE01EgoafI/kyjEcM8zvN+sKLnp17Aq9LqQfsut7mO3i72d8g/xeVC37DCLoGQFLvDCzbze2NbF2dIQ==", + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/@css-inline/css-inline-linux-arm64-musl/-/css-inline-linux-arm64-musl-0.14.1.tgz", + "integrity": "sha512-FzknI+st8eA8YQSdEJU9ykcM0LZjjigBuynVF5/p7hiMm9OMP8aNhWbhZ8LKJpKbZrQsxSGS4g9Vnr6n6FiSdQ==", "cpu": [ "arm64" ], @@ -1088,9 +1124,9 @@ } }, "node_modules/@css-inline/css-inline-linux-x64-gnu": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@css-inline/css-inline-linux-x64-gnu/-/css-inline-linux-x64-gnu-0.13.0.tgz", - "integrity": "sha512-vbRV++73MW7dvz/AIbozkv4R68/k/sEp57hno/L6lx034VYxpCwdfqtGN4D0W1TOTzdr2b6qBOGNZ1oLKQZOQQ==", + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/@css-inline/css-inline-linux-x64-gnu/-/css-inline-linux-x64-gnu-0.14.1.tgz", + "integrity": "sha512-yubbEye+daDY/4vXnyASAxH88s256pPati1DfVoZpU1V0+KP0BZ1dByZOU1ktExurbPH3gZOWisAnBE9xon0Uw==", "cpu": [ "x64" ], @@ -1103,9 +1139,9 @@ } }, "node_modules/@css-inline/css-inline-linux-x64-musl": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@css-inline/css-inline-linux-x64-musl/-/css-inline-linux-x64-musl-0.13.0.tgz", - "integrity": "sha512-2tCnwU23W/yMs9cGc2/i2jd9y2pjuntx0a5OytqX7s9fvUtmI3nc0Od6wuf51LnmdU+XAU8HLT9pZppsQiwPfQ==", + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/@css-inline/css-inline-linux-x64-musl/-/css-inline-linux-x64-musl-0.14.1.tgz", + "integrity": "sha512-6CRAZzoy1dMLPC/tns2rTt1ZwPo0nL/jYBEIAsYTCWhfAnNnpoLKVh5Nm+fSU3OOwTTqU87UkGrFJhObD/wobQ==", "cpu": [ "x64" ], @@ -1118,9 +1154,9 @@ } }, "node_modules/@css-inline/css-inline-win32-x64-msvc": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@css-inline/css-inline-win32-x64-msvc/-/css-inline-win32-x64-msvc-0.13.0.tgz", - "integrity": "sha512-6VFhFSXp4FH+NzJhLd6fFi7jKCPvIRW+vq0tV+CPuiQ3zPzMfC9nIk8sB/1VJR8EcvBAjMV53YnacuDjRFRT9g==", + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/@css-inline/css-inline-win32-x64-msvc/-/css-inline-win32-x64-msvc-0.14.1.tgz", + "integrity": "sha512-nzotGiaiuiQW78EzsiwsHZXbxEt6DiMUFcDJ6dhiliomXxnlaPyBfZb6/FMBgRJOf6sknDt/5695OttNmbMYzg==", "cpu": [ "x64" ], @@ -2016,33 +2052,82 @@ } }, "node_modules/@nestjs-modules/mailer": { - "version": "1.11.2", - "resolved": "https://registry.npmjs.org/@nestjs-modules/mailer/-/mailer-1.11.2.tgz", - "integrity": "sha512-k07wyKbtCzxWMm6IqGwcGIisnXD/6sneGvUR8rBBZbxtLn1HE1FLGyiaXBrPui/0K7W41aS9x9jAIhfTawtlUg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@nestjs-modules/mailer/-/mailer-2.0.2.tgz", + "integrity": "sha512-+z4mADQasg0H1ZaGu4zZTuKv2pu+XdErqx99PLFPzCDNTN/q9U59WPgkxVaHnsvKHNopLj5Xap7G4ZpptduoYw==", "dependencies": { - "@css-inline/css-inline": "0.13.0", - "glob": "10.3.10", - "mjml": "4.15.3", - "preview-email": "3.0.19" + "@css-inline/css-inline": "0.14.1", + "glob": "10.3.12" }, "optionalDependencies": { "@types/ejs": "^3.1.5", + "@types/mjml": "^4.7.4", "@types/pug": "^2.0.10", - "ejs": "^3.1.9", + "ejs": "^3.1.10", "handlebars": "^4.7.8", + "liquidjs": "^10.11.1", + "mjml": "^4.15.3", + "preview-email": "^3.0.19", "pug": "^3.0.2" }, "peerDependencies": { "@nestjs/common": ">=7.0.9", "@nestjs/core": ">=7.0.9", "@types/ejs": ">=3.0.3", + "@types/mjml": ">=4.7.4", "@types/pug": ">=2.0.6", "ejs": ">=3.1.2", "handlebars": ">=4.7.6", + "liquidjs": ">=10.8.2", + "mjml": ">=4.15.3", "nodemailer": ">=6.4.6", + "preview-email": ">=3.0.19", "pug": ">=3.0.1" } }, + "node_modules/@nestjs-modules/mailer/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@nestjs-modules/mailer/node_modules/glob": { + "version": "10.3.12", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.12.tgz", + "integrity": "sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.6", + "minimatch": "^9.0.1", + "minipass": "^7.0.4", + "path-scurry": "^1.10.2" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@nestjs-modules/mailer/node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@nestjs/axios": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@nestjs/axios/-/axios-3.0.2.tgz", @@ -2208,12 +2293,12 @@ } }, "node_modules/@nestjs/common": { - "version": "9.4.3", - "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-9.4.3.tgz", - "integrity": "sha512-Gd6D4IaYj01o14Bwv81ukidn4w3bPHCblMUq+SmUmWLyosK+XQmInCS09SbDDZyL8jy86PngtBLTdhJ2bXSUig==", + "version": "10.3.8", + "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-10.3.8.tgz", + "integrity": "sha512-P+vPEIvqx2e+fonsYVlFXKvoChyJ8Tq+lfpqdVFqblovHbFr3kZ/nYX0cPs+XuW6bnRT8tz0SSR9XBGU43kJhw==", "dependencies": { "iterare": "1.2.1", - "tslib": "2.5.3", + "tslib": "2.6.2", "uid": "2.0.2" }, "funding": { @@ -2221,16 +2306,12 @@ "url": "https://opencollective.com/nest" }, "peerDependencies": { - "cache-manager": "<=5", "class-transformer": "*", "class-validator": "*", - "reflect-metadata": "^0.1.12", + "reflect-metadata": "^0.1.12 || ^0.2.0", "rxjs": "^7.1.0" }, "peerDependenciesMeta": { - "cache-manager": { - "optional": true - }, "class-transformer": { "optional": true }, @@ -2255,16 +2336,16 @@ } }, "node_modules/@nestjs/core": { - "version": "9.4.3", - "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-9.4.3.tgz", - "integrity": "sha512-Qi63+wi55Jh4sDyaj5Hhx2jOpKqT386aeo+VOKsxnd+Ql9VvkO/FjmuwBGUyzkJt29ENYc+P0Sx/k5LtstNpPQ==", + "version": "10.3.8", + "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-10.3.8.tgz", + "integrity": "sha512-AxF4tpYLDNn5Wfb3C4bNaaHJ4pREH5FJrSisR2A5zkYpQFORFs0Tc36lOFPMwBTy8Iv2wUwWLUVc5ftBnxEv4w==", "hasInstallScript": true, "dependencies": { "@nuxtjs/opencollective": "0.3.2", "fast-safe-stringify": "2.1.1", "iterare": "1.2.1", "path-to-regexp": "3.2.0", - "tslib": "2.5.3", + "tslib": "2.6.2", "uid": "2.0.2" }, "funding": { @@ -2272,11 +2353,11 @@ "url": "https://opencollective.com/nest" }, "peerDependencies": { - "@nestjs/common": "^9.0.0", - "@nestjs/microservices": "^9.0.0", - "@nestjs/platform-express": "^9.0.0", - "@nestjs/websockets": "^9.0.0", - "reflect-metadata": "^0.1.12", + "@nestjs/common": "^10.0.0", + "@nestjs/microservices": "^10.0.0", + "@nestjs/platform-express": "^10.0.0", + "@nestjs/websockets": "^10.0.0", + "reflect-metadata": "^0.1.12 || ^0.2.0", "rxjs": "^7.1.0" }, "peerDependenciesMeta": { @@ -2365,23 +2446,23 @@ } }, "node_modules/@nestjs/platform-express": { - "version": "9.4.3", - "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-9.4.3.tgz", - "integrity": "sha512-FpdczWoRSC0zz2dNL9u2AQLXKXRVtq4HgHklAhbL59X0uy+mcxhlSThG7DHzDMkoSnuuHY8ojDVf7mDxk+GtCw==", + "version": "10.3.8", + "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-10.3.8.tgz", + "integrity": "sha512-sifLoxgEJvAgbim1UuW6wyScMfkS9SVQRH+lN33N/9ZvZSjO6NSDLOe+wxqsnZkia+QrjFC0qy0ITRAsggfqbg==", "dependencies": { "body-parser": "1.20.2", "cors": "2.8.5", - "express": "4.18.2", + "express": "4.19.2", "multer": "1.4.4-lts.1", - "tslib": "2.5.3" + "tslib": "2.6.2" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/nest" }, "peerDependencies": { - "@nestjs/common": "^9.0.0", - "@nestjs/core": "^9.0.0" + "@nestjs/common": "^10.0.0", + "@nestjs/core": "^10.0.0" } }, "node_modules/@nestjs/schematics": { @@ -2508,22 +2589,22 @@ } }, "node_modules/@nestjs/testing": { - "version": "9.4.3", - "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-9.4.3.tgz", - "integrity": "sha512-LDT8Ai2eKnTzvnPaJwWOK03qTaFap5uHHsJCv6dL0uKWk6hyF9jms8DjyVaGsaujCaXDG8izl1mDEER0OmxaZA==", + "version": "10.3.8", + "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-10.3.8.tgz", + "integrity": "sha512-hpX9das2TdFTKQ4/2ojhjI6YgXtCfXRKui3A4Qaj54VVzc5+mtK502Jj18Vzji98o9MVS6skmYu+S/UvW3U6Fw==", "dev": true, "dependencies": { - "tslib": "2.5.3" + "tslib": "2.6.2" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/nest" }, "peerDependencies": { - "@nestjs/common": "^9.0.0", - "@nestjs/core": "^9.0.0", - "@nestjs/microservices": "^9.0.0", - "@nestjs/platform-express": "^9.0.0" + "@nestjs/common": "^10.0.0", + "@nestjs/core": "^10.0.0", + "@nestjs/microservices": "^10.0.0", + "@nestjs/platform-express": "^10.0.0" }, "peerDependenciesMeta": { "@nestjs/microservices": { @@ -2627,7 +2708,8 @@ "node_modules/@one-ini/wasm": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/@one-ini/wasm/-/wasm-0.1.1.tgz", - "integrity": "sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==" + "integrity": "sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==", + "optional": true }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", @@ -2676,16 +2758,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@pkgr/utils/node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", - "dev": true - }, "node_modules/@selderee/plugin-htmlparser2": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@selderee/plugin-htmlparser2/-/plugin-htmlparser2-0.11.0.tgz", "integrity": "sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ==", + "optional": true, "dependencies": { "domhandler": "^5.0.3", "selderee": "^0.11.0" @@ -2861,9 +2938,9 @@ } }, "node_modules/@types/chai": { - "version": "4.3.14", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.14.tgz", - "integrity": "sha512-Wj71sXE4Q4AkGdG9Tvq1u/fquNz9EdG4LIJMwVVII7ashjD/8cf8fyIfJAjRr6YcsXnSE8cOGQPq1gqeR8z+3w==", + "version": "4.3.16", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.16.tgz", + "integrity": "sha512-PatH4iOdyh3MyWtmHVFXLWCCIhUbopaltqddG9BzB+gMIzee2MJrvd+jouii9Z3wzQJruGWAm7WOMjgfG8hQlQ==", "dev": true }, "node_modules/@types/connect": { @@ -3018,9 +3095,9 @@ } }, "node_modules/@types/lodash": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.0.tgz", - "integrity": "sha512-t7dhREVv6dbNj0q17X12j7yDG4bD/DHYX7o5/DbDxobP0HnGPgpRz2Ej77aL7TZT3DSw13fqUTj8J4mMnqa7WA==", + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha512-wYCP26ZLxaT3R39kiN2+HcJ4kTd3U1waI/cY7ivWYqFP6pW3ZNpvi6Wd6PHZx7T/t8z0vlkXMg3QYLa7DZ/IJQ==", "dev": true }, "node_modules/@types/luxon": { @@ -3041,6 +3118,21 @@ "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", "dev": true }, + "node_modules/@types/mjml": { + "version": "4.7.4", + "resolved": "https://registry.npmjs.org/@types/mjml/-/mjml-4.7.4.tgz", + "integrity": "sha512-vyi1vzWgMzFMwZY7GSZYX0GU0dmtC8vLHwpgk+NWmwbwRSrlieVyJ9sn5elodwUfklJM7yGl0zQeet1brKTWaQ==", + "optional": true, + "dependencies": { + "@types/mjml-core": "*" + } + }, + "node_modules/@types/mjml-core": { + "version": "4.7.4", + "resolved": "https://registry.npmjs.org/@types/mjml-core/-/mjml-core-4.7.4.tgz", + "integrity": "sha512-hajbYITLm/wJU99Of50Dmn/k4ok+mrhJs4qDdnveJsINdiNJhQd+03C6Kt09vF9biB23cEI4pPeLrJNYfIZf7g==", + "optional": true + }, "node_modules/@types/mocha": { "version": "10.0.6", "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.6.tgz", @@ -3048,9 +3140,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.12.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz", - "integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==", + "version": "20.12.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz", + "integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==", "dependencies": { "undici-types": "~5.26.4" } @@ -3080,9 +3172,9 @@ } }, "node_modules/@types/nodemailer": { - "version": "6.4.14", - "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-6.4.14.tgz", - "integrity": "sha512-fUWthHO9k9DSdPCSPRqcu6TWhYyxTBg382vlNIttSe9M7XfsT06y0f24KHXtbnijPGGRIcVvdKHTNikOI6qiHA==", + "version": "6.4.15", + "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-6.4.15.tgz", + "integrity": "sha512-0EBJxawVNjPkng1zm2vopRctuWVCxk34JcIlRuXSf54habUWdz1FB7wHDqOqvDa8Mtpt0Q3LTXQkAs2LNyK5jQ==", "dev": true, "dependencies": { "@types/node": "*" @@ -3152,12 +3244,6 @@ "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", "dev": true }, - "node_modules/@types/semver": { - "version": "7.5.8", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", - "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", - "dev": true - }, "node_modules/@types/send": { "version": "0.17.1", "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.1.tgz", @@ -3246,21 +3332,19 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.7.0.tgz", - "integrity": "sha512-GJWR0YnfrKnsRoluVO3PRb9r5aMZriiMMM/RHj5nnTrBy1/wIgk76XCtCKcnXGjpZQJQRFtGV9/0JJ6n30uwpQ==", + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.10.0.tgz", + "integrity": "sha512-PzCr+a/KAef5ZawX7nbyNwBDtM1HdLIT53aSA2DDlxmxMngZ43O8SIePOeX8H5S+FHXeI6t97mTt/dDdzY4Fyw==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.7.0", - "@typescript-eslint/type-utils": "7.7.0", - "@typescript-eslint/utils": "7.7.0", - "@typescript-eslint/visitor-keys": "7.7.0", - "debug": "^4.3.4", + "@typescript-eslint/scope-manager": "7.10.0", + "@typescript-eslint/type-utils": "7.10.0", + "@typescript-eslint/utils": "7.10.0", + "@typescript-eslint/visitor-keys": "7.10.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", - "semver": "^7.6.0", "ts-api-utils": "^1.3.0" }, "engines": { @@ -3281,15 +3365,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.7.0.tgz", - "integrity": "sha512-fNcDm3wSwVM8QYL4HKVBggdIPAy9Q41vcvC/GtDobw3c4ndVT3K6cqudUmjHPw8EAp4ufax0o58/xvWaP2FmTg==", + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.10.0.tgz", + "integrity": "sha512-2EjZMA0LUW5V5tGQiaa2Gys+nKdfrn2xiTIBLR4fxmPmVSvgPcKNW+AE/ln9k0A4zDUti0J/GZXMDupQoI+e1w==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.7.0", - "@typescript-eslint/types": "7.7.0", - "@typescript-eslint/typescript-estree": "7.7.0", - "@typescript-eslint/visitor-keys": "7.7.0", + "@typescript-eslint/scope-manager": "7.10.0", + "@typescript-eslint/types": "7.10.0", + "@typescript-eslint/typescript-estree": "7.10.0", + "@typescript-eslint/visitor-keys": "7.10.0", "debug": "^4.3.4" }, "engines": { @@ -3309,13 +3393,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.7.0.tgz", - "integrity": "sha512-/8INDn0YLInbe9Wt7dK4cXLDYp0fNHP5xKLHvZl3mOT5X17rK/YShXaiNmorl+/U4VKCVIjJnx4Ri5b0y+HClw==", + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.10.0.tgz", + "integrity": "sha512-7L01/K8W/VGl7noe2mgH0K7BE29Sq6KAbVmxurj8GGaPDZXPr8EEQ2seOeAS+mEV9DnzxBQB6ax6qQQ5C6P4xg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.7.0", - "@typescript-eslint/visitor-keys": "7.7.0" + "@typescript-eslint/types": "7.10.0", + "@typescript-eslint/visitor-keys": "7.10.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3326,13 +3410,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.7.0.tgz", - "integrity": "sha512-bOp3ejoRYrhAlnT/bozNQi3nio9tIgv3U5C0mVDdZC7cpcQEDZXvq8inrHYghLVwuNABRqrMW5tzAv88Vy77Sg==", + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.10.0.tgz", + "integrity": "sha512-D7tS4WDkJWrVkuzgm90qYw9RdgBcrWmbbRkrLA4d7Pg3w0ttVGDsvYGV19SH8gPR5L7OtcN5J1hTtyenO9xE9g==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.7.0", - "@typescript-eslint/utils": "7.7.0", + "@typescript-eslint/typescript-estree": "7.10.0", + "@typescript-eslint/utils": "7.10.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -3353,9 +3437,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.7.0.tgz", - "integrity": "sha512-G01YPZ1Bd2hn+KPpIbrAhEWOn5lQBrjxkzHkWvP6NucMXFtfXoevK82hzQdpfuQYuhkvFDeQYbzXCjR1z9Z03w==", + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.10.0.tgz", + "integrity": "sha512-7fNj+Ya35aNyhuqrA1E/VayQX9Elwr8NKZ4WueClR3KwJ7Xx9jcCdOrLW04h51de/+gNbyFMs+IDxh5xIwfbNg==", "dev": true, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3366,13 +3450,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.7.0.tgz", - "integrity": "sha512-8p71HQPE6CbxIBy2kWHqM1KGrC07pk6RJn40n0DSc6bMOBBREZxSDJ+BmRzc8B5OdaMh1ty3mkuWRg4sCFiDQQ==", + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.10.0.tgz", + "integrity": "sha512-LXFnQJjL9XIcxeVfqmNj60YhatpRLt6UhdlFwAkjNc6jSUlK8zQOl1oktAP8PlWFzPQC1jny/8Bai3/HPuvN5g==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.7.0", - "@typescript-eslint/visitor-keys": "7.7.0", + "@typescript-eslint/types": "7.10.0", + "@typescript-eslint/visitor-keys": "7.10.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -3418,18 +3502,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.7.0.tgz", - "integrity": "sha512-LKGAXMPQs8U/zMRFXDZOzmMKgFv3COlxUQ+2NMPhbqgVm6R1w+nU1i4836Pmxu9jZAuIeyySNrN/6Rc657ggig==", + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.10.0.tgz", + "integrity": "sha512-olzif1Fuo8R8m/qKkzJqT7qwy16CzPRWBvERS0uvyc+DHd8AKbO4Jb7kpAvVzMmZm8TrHnI7hvjN4I05zow+tg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.15", - "@types/semver": "^7.5.8", - "@typescript-eslint/scope-manager": "7.7.0", - "@typescript-eslint/types": "7.7.0", - "@typescript-eslint/typescript-estree": "7.7.0", - "semver": "^7.6.0" + "@typescript-eslint/scope-manager": "7.10.0", + "@typescript-eslint/types": "7.10.0", + "@typescript-eslint/typescript-estree": "7.10.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3443,12 +3524,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.7.0.tgz", - "integrity": "sha512-h0WHOj8MhdhY8YWkzIF30R379y0NqyOHExI9N9KCzvmu05EgG4FumeYa3ccfKUSphyWkWQE1ybVrgz/Pbam6YA==", + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.10.0.tgz", + "integrity": "sha512-9ntIVgsi6gg6FIq9xjEO4VQJvwOqA3jaBFQJ/6TK5AvEup2+cECI6Fh7QiBxmfMHXU0V0J4RyPeOU1VDNzl9cg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.7.0", + "@typescript-eslint/types": "7.10.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { @@ -3818,6 +3899,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/alce/-/alce-1.2.0.tgz", "integrity": "sha512-XppPf2S42nO2WhvKzlwzlfcApcXHzjlod30pKmcWjRgLOtqoe5DMuqdiYoM6AgyXksc6A6pV4v1L/WW217e57w==", + "optional": true, "dependencies": { "esprima": "^1.2.0", "estraverse": "^1.5.0" @@ -3830,6 +3912,7 @@ "version": "1.2.5", "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.2.5.tgz", "integrity": "sha512-S9VbPDU0adFErpDai3qDkjq8+G05ONtKzcyNrPKg/ZKa+tf879nX2KexNU95b31UoTJjRLInNBHHHjFPoCd7lQ==", + "optional": true, "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -3842,6 +3925,7 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", "integrity": "sha512-25w1fMXQrGdoquWnScXZGckOv+Wes+JDnuN/+7ex3SauFRS72r2lFDec0EKPt2YD1wUJ/IrfEex+9yp4hfSOJA==", + "optional": true, "engines": { "node": ">=0.10.0" } @@ -3872,6 +3956,7 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "devOptional": true, "engines": { "node": ">=6" } @@ -3929,6 +4014,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "devOptional": true, "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -4033,7 +4119,8 @@ "node_modules/asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "devOptional": true }, "node_modules/asn1": { "version": "0.2.6", @@ -4046,7 +4133,8 @@ "node_modules/assert-never": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/assert-never/-/assert-never-1.2.1.tgz", - "integrity": "sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw==" + "integrity": "sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw==", + "optional": true }, "node_modules/assert-plus": { "version": "1.0.0", @@ -4066,9 +4154,9 @@ } }, "node_modules/async": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", - "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==", + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", "optional": true }, "node_modules/asynckit": { @@ -4195,6 +4283,7 @@ "version": "3.0.0-canary-5", "resolved": "https://registry.npmjs.org/babel-walk/-/babel-walk-3.0.0-canary-5.tgz", "integrity": "sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==", + "optional": true, "dependencies": { "@babel/types": "^7.9.6" }, @@ -4269,6 +4358,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "devOptional": true, "engines": { "node": ">=8" } @@ -4366,7 +4456,8 @@ "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "optional": true }, "node_modules/boxen": { "version": "5.1.2", @@ -4441,6 +4532,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "devOptional": true, "dependencies": { "fill-range": "^7.0.1" }, @@ -4514,9 +4606,9 @@ } }, "node_modules/bson": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/bson/-/bson-6.6.0.tgz", - "integrity": "sha512-BVINv2SgcMjL4oYbBuCQTpE3/VKOSxrOA8Cj/wQP7izSzlBGVomdm+TcUd0Pzy0ytLSSDweCKQ6X3f5veM5LQA==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-6.7.0.tgz", + "integrity": "sha512-w2IquM5mYzYZv6rs3uN2DZTOBe2a0zXLj53TGDqwF4l6Sz/XsISrisXOJihArF9+BZ6Cq/GjVht7Sjfmri7ytQ==", "engines": { "node": ">=16.20.1" } @@ -4635,6 +4727,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", "integrity": "sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==", + "optional": true, "dependencies": { "no-case": "^2.2.0", "upper-case": "^1.1.1" @@ -4670,13 +4763,13 @@ ] }, "node_modules/chai": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.0.tgz", - "integrity": "sha512-kDZ7MZyM6Q1DhR9jy7dalKohXQ2yrlXkk59CR52aRKxJrobmlBNqnFQxX9xOX8w+4mz8SYlKJa/7D7ddltFXCw==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.1.tgz", + "integrity": "sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==", "dev": true, "dependencies": { "assertion-error": "^2.0.1", - "check-error": "^2.0.0", + "check-error": "^2.1.1", "deep-eql": "^5.0.1", "loupe": "^3.1.0", "pathval": "^2.0.0" @@ -4757,6 +4850,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz", "integrity": "sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw==", + "optional": true, "dependencies": { "is-regex": "^1.0.3" } @@ -4785,9 +4879,9 @@ } }, "node_modules/check-error": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.0.0.tgz", - "integrity": "sha512-tjLAOBHKVxtPoHe/SA7kNOMvhCRdCJ3vETdeY0RuAc9popf+hyaSV6ZEg9hr4cpWF7jmo/JSWEnLDrnijS9Tog==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", "dev": true, "engines": { "node": ">= 16" @@ -4797,6 +4891,7 @@ "version": "1.0.0-rc.12", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", + "optional": true, "dependencies": { "cheerio-select": "^2.1.0", "dom-serializer": "^2.0.0", @@ -4817,6 +4912,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "optional": true, "dependencies": { "boolbase": "^1.0.0", "css-select": "^5.1.0", @@ -4833,6 +4929,7 @@ "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "devOptional": true, "funding": [ { "type": "individual", @@ -4876,6 +4973,7 @@ "version": "3.8.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", + "devOptional": true, "funding": [ { "type": "github", @@ -4911,6 +5009,7 @@ "version": "4.2.4", "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.4.tgz", "integrity": "sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==", + "optional": true, "dependencies": { "source-map": "~0.6.0" }, @@ -4922,6 +5021,7 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "optional": true, "engines": { "node": ">=0.10.0" } @@ -4988,6 +5088,7 @@ "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "devOptional": true, "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", @@ -5001,6 +5102,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "devOptional": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -5208,6 +5310,7 @@ "version": "1.1.13", "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "optional": true, "dependencies": { "ini": "^1.3.4", "proto-list": "~1.2.1" @@ -5227,6 +5330,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz", "integrity": "sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==", + "optional": true, "dependencies": { "@babel/parser": "^7.6.0", "@babel/types": "^7.6.1" @@ -5277,9 +5381,9 @@ "dev": true }, "node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", "engines": { "node": ">= 0.6" } @@ -5361,6 +5465,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "optional": true, "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", @@ -5376,6 +5481,7 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "optional": true, "engines": { "node": ">= 6" }, @@ -5490,6 +5596,7 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "optional": true, "engines": { "node": ">=4.0.0" } @@ -5504,6 +5611,7 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "devOptional": true, "engines": { "node": ">=0.10.0" } @@ -5729,6 +5837,7 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", + "optional": true, "engines": { "node": ">=8" } @@ -5745,6 +5854,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "devOptional": true, "engines": { "node": ">=8" } @@ -5752,7 +5862,8 @@ "node_modules/detect-node": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "optional": true }, "node_modules/dezalgo": { "version": "1.0.4", @@ -5798,6 +5909,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/display-notification/-/display-notification-2.0.0.tgz", "integrity": "sha512-TdmtlAcdqy1NU+j7zlkDdMnCL878zriLaBmoD9quOoq1ySSSGv03l0hXK5CvIFZlIfFI/hizqdQuW+Num7xuhw==", + "optional": true, "dependencies": { "escape-string-applescript": "^1.0.0", "run-applescript": "^3.0.0" @@ -5821,12 +5933,14 @@ "node_modules/doctypes": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", - "integrity": "sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==" + "integrity": "sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==", + "optional": true }, "node_modules/dom-serializer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "optional": true, "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", @@ -5845,7 +5959,8 @@ "type": "github", "url": "https://github.com/sponsors/fb55" } - ] + ], + "optional": true }, "node_modules/domexception": { "version": "2.0.1", @@ -5872,6 +5987,7 @@ "version": "5.0.3", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "optional": true, "dependencies": { "domelementtype": "^2.3.0" }, @@ -5886,6 +6002,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "optional": true, "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", @@ -5931,6 +6048,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-1.0.4.tgz", "integrity": "sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==", + "optional": true, "dependencies": { "@one-ini/wasm": "0.1.1", "commander": "^10.0.0", @@ -5948,6 +6066,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "optional": true, "dependencies": { "balanced-match": "^1.0.0" } @@ -5956,6 +6075,7 @@ "version": "10.0.1", "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "optional": true, "engines": { "node": ">=14" } @@ -5964,6 +6084,7 @@ "version": "9.0.1", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz", "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==", + "optional": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -5980,9 +6101,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/ejs": { - "version": "3.1.9", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", - "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==", + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", "optional": true, "dependencies": { "jake": "^10.8.5" @@ -6029,6 +6150,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/encoding-japanese/-/encoding-japanese-2.0.0.tgz", "integrity": "sha512-++P0RhebUC8MJAwJOsT93dT+5oc5oPImp1HubZpAuCZ5kTLnhuuBhKHj2jJeO/Gj93idPBWmIuQ9QWMe5rX3pQ==", + "optional": true, "engines": { "node": ">=8.10.0" } @@ -6050,6 +6172,7 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "optional": true, "engines": { "node": ">=0.12" }, @@ -6084,6 +6207,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "devOptional": true, "engines": { "node": ">=6" } @@ -6092,6 +6216,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-3.0.0.tgz", "integrity": "sha512-w3PwNZJwRxlp47QGzhuEBldEqVHHhh8/tIPcl6ecf2Bou99cdAt0knihBV0Ecc7CGxYduXVBDheH1K2oADRlvw==", + "optional": true, "engines": { "node": ">=10" }, @@ -6113,6 +6238,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/escape-string-applescript/-/escape-string-applescript-1.0.0.tgz", "integrity": "sha512-4/hFwoYaC6TkpDn9A3pTC52zQPArFeXuIfhUtCGYdauTzXVP9H3BDr3oO/QzQehMpLDC7srvYgfwvImPFGfvBA==", + "optional": true, "engines": { "node": ">=0.10.0" } @@ -6491,16 +6617,16 @@ } }, "node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.1", + "body-parser": "1.20.2", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.5.0", + "cookie": "0.6.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", @@ -6549,14 +6675,6 @@ "node": ">= 0.8.0" } }, - "node_modules/express-session/node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/express-session/node_modules/cookie-signature": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz", @@ -6594,29 +6712,6 @@ } ] }, - "node_modules/express/node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, "node_modules/express/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -6635,20 +6730,6 @@ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, - "node_modules/express/node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/express/node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -6671,7 +6752,8 @@ "node_modules/extend-object": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/extend-object/-/extend-object-1.0.0.tgz", - "integrity": "sha512-0dHDIXC7y7LDmCh/lp1oYkmv73K25AMugQI07r8eFopkW6f7Ufn1q+ETMsJjnV9Am14SlElkqy3O92r6xEaxPw==" + "integrity": "sha512-0dHDIXC7y7LDmCh/lp1oYkmv73K25AMugQI07r8eFopkW6f7Ufn1q+ETMsJjnV9Am14SlElkqy3O92r6xEaxPw==", + "optional": true }, "node_modules/external-editor": { "version": "3.1.0", @@ -6850,6 +6932,7 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "devOptional": true, "dependencies": { "to-regex-range": "^5.0.1" }, @@ -6907,6 +6990,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/fixpack/-/fixpack-4.0.0.tgz", "integrity": "sha512-5SM1+H2CcuJ3gGEwTiVo/+nd/hYpNj9Ch3iMDOQ58ndY+VGQ2QdvaUTkd3otjZvYnd/8LF/HkJ5cx7PBq0orCQ==", + "optional": true, "dependencies": { "alce": "1.2.0", "chalk": "^3.0.0", @@ -6923,6 +7007,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "optional": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -7188,6 +7273,7 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -7250,6 +7336,7 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "devOptional": true, "engines": { "node": "6.* || 8.* || >= 10.*" } @@ -7294,6 +7381,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/get-port/-/get-port-5.1.1.tgz", "integrity": "sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==", + "optional": true, "engines": { "node": ">=8" }, @@ -7338,6 +7426,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "devOptional": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -7462,6 +7551,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "devOptional": true, "dependencies": { "function-bind": "^1.1.1" }, @@ -7523,6 +7613,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "optional": true, "dependencies": { "has-symbols": "^1.0.2" }, @@ -7553,6 +7644,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "devOptional": true, "bin": { "he": "bin/he" } @@ -7596,6 +7688,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-4.0.0.tgz", "integrity": "sha512-aoGxanpFPLg7MkIl/DDFYtb0iWz7jMFGqFhvEDZga6/4QTjneiD8I/NXL1x5aaoCp7FSIT6h/OhykDdPsbtMig==", + "optional": true, "dependencies": { "camel-case": "^3.0.0", "clean-css": "^4.2.1", @@ -7615,12 +7708,14 @@ "node_modules/html-minifier/node_modules/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==" + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "optional": true }, "node_modules/html-to-text": { "version": "9.0.5", "resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-9.0.5.tgz", "integrity": "sha512-qY60FjREgVZL03vJU6IfMV4GDjGBIoOyvuFdpBDIX9yTlDw0TjxVBQp+P8NvpdIXNJvfWBTNul7fsAQJq2FNpg==", + "optional": true, "dependencies": { "@selderee/plugin-htmlparser2": "^0.11.0", "deepmerge": "^4.3.1", @@ -7643,6 +7738,7 @@ "url": "https://github.com/sponsors/fb55" } ], + "optional": true, "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", @@ -7801,7 +7897,8 @@ "node_modules/ini": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "optional": true }, "node_modules/inquirer": { "version": "8.2.6", @@ -7872,6 +7969,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "devOptional": true, "dependencies": { "binary-extensions": "^2.0.0" }, @@ -7883,6 +7981,7 @@ "version": "2.13.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", + "devOptional": true, "dependencies": { "has": "^1.0.3" }, @@ -7894,6 +7993,7 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "devOptional": true, "bin": { "is-docker": "cli.js" }, @@ -7908,6 +8008,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-4.0.0.tgz", "integrity": "sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==", + "optional": true, "dependencies": { "acorn": "^7.1.1", "object-assign": "^4.1.1" @@ -7917,6 +8018,7 @@ "version": "7.4.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "optional": true, "bin": { "acorn": "bin/acorn" }, @@ -7928,6 +8030,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "devOptional": true, "engines": { "node": ">=0.10.0" } @@ -7953,6 +8056,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "devOptional": true, "dependencies": { "is-extglob": "^2.1.1" }, @@ -8018,6 +8122,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "devOptional": true, "engines": { "node": ">=0.12.0" } @@ -8049,12 +8154,14 @@ "node_modules/is-promise": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", - "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", + "optional": true }, "node_modules/is-regex": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "optional": true, "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -8100,6 +8207,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "devOptional": true, "dependencies": { "is-docker": "^2.0.0" }, @@ -8997,6 +9105,7 @@ "version": "1.15.1", "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.15.1.tgz", "integrity": "sha512-ESjNzSlt/sWE8sciZH8kBF8BPlwXPwhR6pWKAw8bw4Bwj+iZcnKW6ONWUutJ7eObuBZQpiIb8S7OYspWrKt7rA==", + "optional": true, "dependencies": { "config-chain": "^1.1.13", "editorconfig": "^1.0.4", @@ -9017,6 +9126,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==", + "optional": true, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -9025,6 +9135,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.0.tgz", "integrity": "sha512-CVDtwCdhYIvnAzFoJ6NJ6dX3oga9/HyciQDnG1vQDjSLMeKLJ4A93ZqYKDrgYSr1FBY5/hMYC+2VCi24pgpkGA==", + "optional": true, "dependencies": { "abbrev": "^2.0.0" }, @@ -9039,6 +9150,7 @@ "version": "3.0.5", "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz", "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==", + "optional": true, "engines": { "node": ">=14" } @@ -9046,7 +9158,8 @@ "node_modules/js-stringify": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", - "integrity": "sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==" + "integrity": "sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==", + "optional": true }, "node_modules/js-tokens": { "version": "4.0.0", @@ -9213,6 +9326,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", "integrity": "sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==", + "optional": true, "dependencies": { "is-promise": "^2.0.0", "promise": "^7.0.1" @@ -9222,6 +9336,7 @@ "version": "10.0.0", "resolved": "https://registry.npmjs.org/juice/-/juice-10.0.0.tgz", "integrity": "sha512-9f68xmhGrnIi6DBkiiP3rUrQN33SEuaKu1+njX6VgMP+jwZAsnT33WIzlrWICL9matkhYu3OyrqSUP55YTIdGg==", + "optional": true, "dependencies": { "cheerio": "^1.0.0-rc.12", "commander": "^6.1.0", @@ -9240,14 +9355,15 @@ "version": "6.2.1", "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "optional": true, "engines": { "node": ">= 6" } }, "node_modules/just-extend": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", - "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz", + "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==", "dev": true }, "node_modules/jwa": { @@ -9350,6 +9466,7 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/leac/-/leac-0.6.0.tgz", "integrity": "sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg==", + "optional": true, "funding": { "url": "https://ko-fi.com/killymxi" } @@ -9379,12 +9496,14 @@ "node_modules/libbase64": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/libbase64/-/libbase64-1.2.1.tgz", - "integrity": "sha512-l+nePcPbIG1fNlqMzrh68MLkX/gTxk/+vdvAb388Ssi7UuUN31MI44w4Yf33mM3Cm4xDfw48mdf3rkdHszLNew==" + "integrity": "sha512-l+nePcPbIG1fNlqMzrh68MLkX/gTxk/+vdvAb388Ssi7UuUN31MI44w4Yf33mM3Cm4xDfw48mdf3rkdHszLNew==", + "optional": true }, "node_modules/libmime": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/libmime/-/libmime-5.2.1.tgz", "integrity": "sha512-A0z9O4+5q+ZTj7QwNe/Juy1KARNb4WaviO4mYeFC4b8dBT2EEqK2pkM+GC8MVnkOjqhl5nYQxRgnPYRRTNmuSQ==", + "optional": true, "dependencies": { "encoding-japanese": "2.0.0", "iconv-lite": "0.6.3", @@ -9396,6 +9515,7 @@ "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "optional": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, @@ -9411,7 +9531,8 @@ "node_modules/libqp": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/libqp/-/libqp-2.0.1.tgz", - "integrity": "sha512-Ka0eC5LkF3IPNQHJmYBWljJsw0UvM6j+QdKRbWyCdTmYwvIDE6a7bCm0UkTAL/K+3KXK5qXT/ClcInU01OpdLg==" + "integrity": "sha512-Ka0eC5LkF3IPNQHJmYBWljJsw0UvM6j+QdKRbWyCdTmYwvIDE6a7bCm0UkTAL/K+3KXK5qXT/ClcInU01OpdLg==", + "optional": true }, "node_modules/lines-and-columns": { "version": "1.2.4", @@ -9423,10 +9544,40 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz", "integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==", + "optional": true, "dependencies": { "uc.micro": "^1.0.1" } }, + "node_modules/liquidjs": { + "version": "10.12.0", + "resolved": "https://registry.npmjs.org/liquidjs/-/liquidjs-10.12.0.tgz", + "integrity": "sha512-ZpT27WEqUu8IeddXoLbdeBTbRfV5r7oUKDjJMthuQKQTScgI8pbLGbSWiiAktQVpPG7mHMGsJ0JVbZYn1w9Gtg==", + "optional": true, + "dependencies": { + "commander": "^10.0.0" + }, + "bin": { + "liquid": "bin/liquid.js", + "liquidjs": "bin/liquid.js" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/liquidjs" + } + }, + "node_modules/liquidjs/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/loader-runner": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", @@ -9537,7 +9688,8 @@ "node_modules/lower-case": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", - "integrity": "sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==" + "integrity": "sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==", + "optional": true }, "node_modules/lru-cache": { "version": "5.1.1", @@ -9572,6 +9724,7 @@ "version": "3.6.5", "resolved": "https://registry.npmjs.org/mailparser/-/mailparser-3.6.5.tgz", "integrity": "sha512-nteTpF0Khm5JLOnt4sigmzNdUH/6mO7PZ4KEnvxf4mckyXYFFhrtAWZzbq/V5aQMH+049gA7ZjfLdh+QiX2Uqg==", + "optional": true, "dependencies": { "encoding-japanese": "2.0.0", "he": "1.2.0", @@ -9588,6 +9741,7 @@ "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "optional": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, @@ -9599,6 +9753,7 @@ "version": "6.9.3", "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.3.tgz", "integrity": "sha512-fy9v3NgTzBngrMFkDsKEj0r02U7jm6XfC3b52eoNV+GCrGj+s8pt5OqhiJdWKuw51zCTdiNR/IUD1z33LIIGpg==", + "optional": true, "engines": { "node": ">=6.0.0" } @@ -9607,6 +9762,7 @@ "version": "5.4.0", "resolved": "https://registry.npmjs.org/mailsplit/-/mailsplit-5.4.0.tgz", "integrity": "sha512-wnYxX5D5qymGIPYLwnp6h8n1+6P6vz/MJn5AzGjZ8pwICWssL+CCQjWBIToOVHASmATot4ktvlLo6CyLfOXWYA==", + "optional": true, "dependencies": { "libbase64": "1.2.1", "libmime": "5.2.0", @@ -9617,6 +9773,7 @@ "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "optional": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, @@ -9628,6 +9785,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/libmime/-/libmime-5.2.0.tgz", "integrity": "sha512-X2U5Wx0YmK0rXFbk67ASMeqYIkZ6E5vY7pNWRKtnNzqjvdYYG8xtPDpCnuUEnPU9vlgNev+JoSrcaKSUaNvfsw==", + "optional": true, "dependencies": { "encoding-japanese": "2.0.0", "iconv-lite": "0.6.3", @@ -9673,11 +9831,11 @@ } }, "node_modules/mathjs": { - "version": "12.4.1", - "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-12.4.1.tgz", - "integrity": "sha512-welnW3khgwYjPYvECFHO+xkCxAx9IKIIPDDWPi8B5rKAvmgoEHnQX9slEmHKZTNaJiE+OS4qrJJcB4sfDn/4sw==", + "version": "12.4.2", + "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-12.4.2.tgz", + "integrity": "sha512-lW14EzwAFgbNN7AZikxplmhs7wiXDhMphBOGCA3KS6T29ECEkHJsBtbEW5cnCz7sXtl4nDyvTdR+DqVsZyiiEw==", "dependencies": { - "@babel/runtime": "^7.24.0", + "@babel/runtime": "^7.24.4", "complex.js": "^2.1.1", "decimal.js": "^10.4.3", "escape-latex": "^1.2.0", @@ -9722,7 +9880,8 @@ "node_modules/mensch": { "version": "0.3.4", "resolved": "https://registry.npmjs.org/mensch/-/mensch-0.3.4.tgz", - "integrity": "sha512-IAeFvcOnV9V0Yk+bFhYR07O3yNina9ANIN5MoXBKYJ/RLYPurd2d0yw14MDhpr9/momp0WofT1bPUh3hkzdi/g==" + "integrity": "sha512-IAeFvcOnV9V0Yk+bFhYR07O3yNina9ANIN5MoXBKYJ/RLYPurd2d0yw14MDhpr9/momp0WofT1bPUh3hkzdi/g==", + "optional": true }, "node_modules/merge-descriptors": { "version": "1.0.1", @@ -9855,9 +10014,9 @@ } }, "node_modules/minipass": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.3.tgz", - "integrity": "sha512-LhbbwCfz3vsb12j/WkWQPZfKTsgqIe1Nf/ti1pKjYESGLHIVjWU96G9/ljLH4F9mWNVhlQOm0VySdAWzf05dpg==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", "engines": { "node": ">=16 || 14 >=14.17" } @@ -9894,6 +10053,7 @@ "version": "4.15.3", "resolved": "https://registry.npmjs.org/mjml/-/mjml-4.15.3.tgz", "integrity": "sha512-bW2WpJxm6HS+S3Yu6tq1DUPFoTxU9sPviUSmnL7Ua+oVO3WA5ILFWqvujUlz+oeuM+HCwEyMiP5xvKNPENVjYA==", + "optional": true, "dependencies": { "@babel/runtime": "^7.23.9", "mjml-cli": "4.15.3", @@ -9910,6 +10070,7 @@ "version": "4.15.3", "resolved": "https://registry.npmjs.org/mjml-accordion/-/mjml-accordion-4.15.3.tgz", "integrity": "sha512-LPNVSj1LyUVYT9G1gWwSw3GSuDzDsQCu0tPB2uDsq4VesYNnU6v3iLCQidMiR6azmIt13OEozG700ygAUuA6Ng==", + "optional": true, "dependencies": { "@babel/runtime": "^7.23.9", "lodash": "^4.17.21", @@ -9920,6 +10081,7 @@ "version": "4.15.3", "resolved": "https://registry.npmjs.org/mjml-body/-/mjml-body-4.15.3.tgz", "integrity": "sha512-7pfUOVPtmb0wC+oUOn4xBsAw4eT5DyD6xqaxj/kssu6RrFXOXgJaVnDPAI9AzIvXJ/5as9QrqRGYAddehwWpHQ==", + "optional": true, "dependencies": { "@babel/runtime": "^7.23.9", "lodash": "^4.17.21", @@ -9930,6 +10092,7 @@ "version": "4.15.3", "resolved": "https://registry.npmjs.org/mjml-button/-/mjml-button-4.15.3.tgz", "integrity": "sha512-79qwn9AgdGjJR1vLnrcm2rq2AsAZkKC5JPwffTMG+Nja6zGYpTDZFZ56ekHWr/r1b5WxkukcPj2PdevUug8c+Q==", + "optional": true, "dependencies": { "@babel/runtime": "^7.23.9", "lodash": "^4.17.21", @@ -9940,6 +10103,7 @@ "version": "4.15.3", "resolved": "https://registry.npmjs.org/mjml-carousel/-/mjml-carousel-4.15.3.tgz", "integrity": "sha512-3ju6I4l7uUhPRrJfN3yK9AMsfHvrYbRkcJ1GRphFHzUj37B2J6qJOQUpzA547Y4aeh69TSb7HFVf1t12ejQxVw==", + "optional": true, "dependencies": { "@babel/runtime": "^7.23.9", "lodash": "^4.17.21", @@ -9950,6 +10114,7 @@ "version": "4.15.3", "resolved": "https://registry.npmjs.org/mjml-cli/-/mjml-cli-4.15.3.tgz", "integrity": "sha512-+V2TDw3tXUVEptFvLSerz125C2ogYl8klIBRY1m5BHd4JvGVf3yhx8N3PngByCzA6PGcv/eydGQN+wy34SHf0Q==", + "optional": true, "dependencies": { "@babel/runtime": "^7.23.9", "chokidar": "^3.0.0", @@ -9972,6 +10137,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "optional": true, "dependencies": { "balanced-match": "^1.0.0" } @@ -9980,6 +10146,7 @@ "version": "9.0.3", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "optional": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -9994,6 +10161,7 @@ "version": "4.15.3", "resolved": "https://registry.npmjs.org/mjml-column/-/mjml-column-4.15.3.tgz", "integrity": "sha512-hYdEFdJGHPbZJSEysykrevEbB07yhJGSwfDZEYDSbhQQFjV2tXrEgYcFD5EneMaowjb55e3divSJxU4c5q4Qgw==", + "optional": true, "dependencies": { "@babel/runtime": "^7.23.9", "lodash": "^4.17.21", @@ -10004,6 +10172,7 @@ "version": "4.15.3", "resolved": "https://registry.npmjs.org/mjml-core/-/mjml-core-4.15.3.tgz", "integrity": "sha512-Dmwk+2cgSD9L9GmTbEUNd8QxkTZtW9P7FN/ROZW/fGZD6Hq6/4TB0zEspg2Ow9eYjZXO2ofOJ3PaQEEShKV0kQ==", + "optional": true, "dependencies": { "@babel/runtime": "^7.23.9", "cheerio": "1.0.0-rc.12", @@ -10021,6 +10190,7 @@ "version": "4.15.3", "resolved": "https://registry.npmjs.org/mjml-divider/-/mjml-divider-4.15.3.tgz", "integrity": "sha512-vh27LQ9FG/01y0b9ntfqm+GT5AjJnDSDY9hilss2ixIUh0FemvfGRfsGVeV5UBVPBKK7Ffhvfqc7Rciob9Spzw==", + "optional": true, "dependencies": { "@babel/runtime": "^7.23.9", "lodash": "^4.17.21", @@ -10031,6 +10201,7 @@ "version": "4.15.3", "resolved": "https://registry.npmjs.org/mjml-group/-/mjml-group-4.15.3.tgz", "integrity": "sha512-HSu/rKnGZVKFq3ciT46vi1EOy+9mkB0HewO4+P6dP/Y0UerWkN6S3UK11Cxsj0cAp0vFwkPDCdOeEzRdpFEkzA==", + "optional": true, "dependencies": { "@babel/runtime": "^7.23.9", "lodash": "^4.17.21", @@ -10041,6 +10212,7 @@ "version": "4.15.3", "resolved": "https://registry.npmjs.org/mjml-head/-/mjml-head-4.15.3.tgz", "integrity": "sha512-o3mRuuP/MB5fZycjD3KH/uXsnaPl7Oo8GtdbJTKtH1+O/3pz8GzGMkscTKa97l03DAG2EhGrzzLcU2A6eshwFw==", + "optional": true, "dependencies": { "@babel/runtime": "^7.23.9", "lodash": "^4.17.21", @@ -10051,6 +10223,7 @@ "version": "4.15.3", "resolved": "https://registry.npmjs.org/mjml-head-attributes/-/mjml-head-attributes-4.15.3.tgz", "integrity": "sha512-2ISo0r5ZKwkrvJgDou9xVPxxtXMaETe2AsAA02L89LnbB2KC0N5myNsHV0sEysTw9+CfCmgjAb0GAI5QGpxKkQ==", + "optional": true, "dependencies": { "@babel/runtime": "^7.23.9", "lodash": "^4.17.21", @@ -10061,6 +10234,7 @@ "version": "4.15.3", "resolved": "https://registry.npmjs.org/mjml-head-breakpoint/-/mjml-head-breakpoint-4.15.3.tgz", "integrity": "sha512-Eo56FA5C2v6ucmWQL/JBJ2z641pLOom4k0wP6CMZI2utfyiJ+e2Uuinj1KTrgDcEvW4EtU9HrfAqLK9UosLZlg==", + "optional": true, "dependencies": { "@babel/runtime": "^7.23.9", "lodash": "^4.17.21", @@ -10071,6 +10245,7 @@ "version": "4.15.3", "resolved": "https://registry.npmjs.org/mjml-head-font/-/mjml-head-font-4.15.3.tgz", "integrity": "sha512-CzV2aDPpiNIIgGPHNcBhgyedKY4SX3BJoTwOobSwZVIlEA6TAWB4Z9WwFUmQqZOgo1AkkiTHPZQvGcEhFFXH6g==", + "optional": true, "dependencies": { "@babel/runtime": "^7.23.9", "lodash": "^4.17.21", @@ -10081,6 +10256,7 @@ "version": "4.15.3", "resolved": "https://registry.npmjs.org/mjml-head-html-attributes/-/mjml-head-html-attributes-4.15.3.tgz", "integrity": "sha512-MDNDPMBOgXUZYdxhosyrA2kudiGO8aogT0/cODyi2Ed9o/1S7W+je11JUYskQbncqhWKGxNyaP4VWa+6+vUC/g==", + "optional": true, "dependencies": { "@babel/runtime": "^7.23.9", "lodash": "^4.17.21", @@ -10091,6 +10267,7 @@ "version": "4.15.3", "resolved": "https://registry.npmjs.org/mjml-head-preview/-/mjml-head-preview-4.15.3.tgz", "integrity": "sha512-J2PxCefUVeFwsAExhrKo4lwxDevc5aKj888HBl/wN4EuWOoOg06iOGCxz4Omd8dqyFsrqvbBuPqRzQ+VycGmaA==", + "optional": true, "dependencies": { "@babel/runtime": "^7.23.9", "lodash": "^4.17.21", @@ -10101,6 +10278,7 @@ "version": "4.15.3", "resolved": "https://registry.npmjs.org/mjml-head-style/-/mjml-head-style-4.15.3.tgz", "integrity": "sha512-9J+JuH+mKrQU65CaJ4KZegACUgNIlYmWQYx3VOBR/tyz+8kDYX7xBhKJCjQ1I4wj2Tvga3bykd89Oc2kFZ5WOw==", + "optional": true, "dependencies": { "@babel/runtime": "^7.23.9", "lodash": "^4.17.21", @@ -10111,6 +10289,7 @@ "version": "4.15.3", "resolved": "https://registry.npmjs.org/mjml-head-title/-/mjml-head-title-4.15.3.tgz", "integrity": "sha512-IM59xRtsxID4DubQ0iLmoCGXguEe+9BFG4z6y2xQDrscIa4QY3KlfqgKGT69ojW+AVbXXJPEVqrAi4/eCsLItQ==", + "optional": true, "dependencies": { "@babel/runtime": "^7.23.9", "lodash": "^4.17.21", @@ -10121,6 +10300,7 @@ "version": "4.15.3", "resolved": "https://registry.npmjs.org/mjml-hero/-/mjml-hero-4.15.3.tgz", "integrity": "sha512-9cLAPuc69yiuzNrMZIN58j+HMK1UWPaq2i3/Fg2ZpimfcGFKRcPGCbEVh0v+Pb6/J0+kf8yIO0leH20opu3AyQ==", + "optional": true, "dependencies": { "@babel/runtime": "^7.23.9", "lodash": "^4.17.21", @@ -10131,6 +10311,7 @@ "version": "4.15.3", "resolved": "https://registry.npmjs.org/mjml-image/-/mjml-image-4.15.3.tgz", "integrity": "sha512-g1OhSdofIytE9qaOGdTPmRIp7JsCtgO0zbsn1Fk6wQh2gEL55Z40j/VoghslWAWTgT2OHFdBKnMvWtN6U5+d2Q==", + "optional": true, "dependencies": { "@babel/runtime": "^7.23.9", "lodash": "^4.17.21", @@ -10141,6 +10322,7 @@ "version": "4.15.3", "resolved": "https://registry.npmjs.org/mjml-migrate/-/mjml-migrate-4.15.3.tgz", "integrity": "sha512-sr/+35RdxZroNQVegjpfRHJ5hda9XCgaS4mK2FGO+Mb1IUevKfeEPII3F/cHDpNwFeYH3kAgyqQ22ClhGLWNBA==", + "optional": true, "dependencies": { "@babel/runtime": "^7.23.9", "js-beautify": "^1.6.14", @@ -10157,6 +10339,7 @@ "version": "4.15.3", "resolved": "https://registry.npmjs.org/mjml-navbar/-/mjml-navbar-4.15.3.tgz", "integrity": "sha512-VsKH/Jdlf8Yu3y7GpzQV5n7JMdpqvZvTSpF6UQXL0PWOm7k6+LX+sCZimOfpHJ+wCaaybpxokjWZ71mxOoCWoA==", + "optional": true, "dependencies": { "@babel/runtime": "^7.23.9", "lodash": "^4.17.21", @@ -10167,6 +10350,7 @@ "version": "4.15.3", "resolved": "https://registry.npmjs.org/mjml-parser-xml/-/mjml-parser-xml-4.15.3.tgz", "integrity": "sha512-Tz0UX8/JVYICLjT+U8J1f/TFxIYVYjzZHeh4/Oyta0pLpRLeZlxEd71f3u3kdnulCKMP4i37pFRDmyLXAlEuLw==", + "optional": true, "dependencies": { "@babel/runtime": "^7.23.9", "detect-node": "2.1.0", @@ -10185,6 +10369,7 @@ "url": "https://github.com/sponsors/fb55" } ], + "optional": true, "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", @@ -10196,6 +10381,7 @@ "version": "4.15.3", "resolved": "https://registry.npmjs.org/mjml-preset-core/-/mjml-preset-core-4.15.3.tgz", "integrity": "sha512-1zZS8P4O0KweWUqNS655+oNnVMPQ1Rq1GaZq5S9JfwT1Vh/m516lSmiTW9oko6gGHytt5s6Yj6oOeu5Zm8FoLw==", + "optional": true, "dependencies": { "@babel/runtime": "^7.23.9", "mjml-accordion": "4.15.3", @@ -10229,6 +10415,7 @@ "version": "4.15.3", "resolved": "https://registry.npmjs.org/mjml-raw/-/mjml-raw-4.15.3.tgz", "integrity": "sha512-IGyHheOYyRchBLiAEgw3UM11kFNmBSMupu2BDdejC6ZiDhEAdG+tyERlsCwDPYtXanvFpGWULIu3XlsUPc+RZw==", + "optional": true, "dependencies": { "@babel/runtime": "^7.23.9", "lodash": "^4.17.21", @@ -10239,6 +10426,7 @@ "version": "4.15.3", "resolved": "https://registry.npmjs.org/mjml-section/-/mjml-section-4.15.3.tgz", "integrity": "sha512-JfVPRXH++Hd933gmQfG8JXXCBCR6fIzC3DwiYycvanL/aW1cEQ2EnebUfQkt5QzlYjOkJEH+JpccAsq3ln6FZQ==", + "optional": true, "dependencies": { "@babel/runtime": "^7.23.9", "lodash": "^4.17.21", @@ -10249,6 +10437,7 @@ "version": "4.15.3", "resolved": "https://registry.npmjs.org/mjml-social/-/mjml-social-4.15.3.tgz", "integrity": "sha512-7sD5FXrESOxpT9Z4Oh36bS6u/geuUrMP1aCg2sjyAwbPcF1aWa2k9OcatQfpRf6pJEhUZ18y6/WBBXmMVmSzXg==", + "optional": true, "dependencies": { "@babel/runtime": "^7.23.9", "lodash": "^4.17.21", @@ -10259,6 +10448,7 @@ "version": "4.15.3", "resolved": "https://registry.npmjs.org/mjml-spacer/-/mjml-spacer-4.15.3.tgz", "integrity": "sha512-3B7Qj+17EgDdAtZ3NAdMyOwLTX1jfmJuY7gjyhS2HtcZAmppW+cxqHUBwCKfvSRgTQiccmEvtNxaQK+tfyrZqA==", + "optional": true, "dependencies": { "@babel/runtime": "^7.23.9", "lodash": "^4.17.21", @@ -10269,6 +10459,7 @@ "version": "4.15.3", "resolved": "https://registry.npmjs.org/mjml-table/-/mjml-table-4.15.3.tgz", "integrity": "sha512-FLx7DcRKTdKdcOCbMyBaeudeHaHpwPveRrBm6WyQe3LXx6FfdmOh59i71/16LFQMgBOD3N4/UJkzxLzlTJzMqQ==", + "optional": true, "dependencies": { "@babel/runtime": "^7.23.9", "lodash": "^4.17.21", @@ -10279,6 +10470,7 @@ "version": "4.15.3", "resolved": "https://registry.npmjs.org/mjml-text/-/mjml-text-4.15.3.tgz", "integrity": "sha512-+C0hxCmw9kg0XzT6vhE5mFkK6y225nC8UEQcN94K0fBCjPKkM+HqZMwGX205fzdGRi+Bxa55b/VhrIVwdv+8vw==", + "optional": true, "dependencies": { "@babel/runtime": "^7.23.9", "lodash": "^4.17.21", @@ -10289,6 +10481,7 @@ "version": "4.15.3", "resolved": "https://registry.npmjs.org/mjml-validator/-/mjml-validator-4.15.3.tgz", "integrity": "sha512-Xb72KdqRwjv/qM2rJpV22syyP2N3cRQ9VVDrN6u2FSzLq02buFNxmSPJ7CKhat3PrUNdVHU75KZwOf/tz4UEhA==", + "optional": true, "dependencies": { "@babel/runtime": "^7.23.9" } @@ -10297,6 +10490,7 @@ "version": "4.15.3", "resolved": "https://registry.npmjs.org/mjml-wrapper/-/mjml-wrapper-4.15.3.tgz", "integrity": "sha512-ditsCijeHJrmBmObtJmQ18ddLxv5oPyMTdPU8Di8APOnD2zPk7Z4UAuJSl7HXB45oFiivr3MJf4koFzMUSZ6Gg==", + "optional": true, "dependencies": { "@babel/runtime": "^7.23.9", "lodash": "^4.17.21", @@ -10476,12 +10670,12 @@ } }, "node_modules/mongodb": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.5.0.tgz", - "integrity": "sha512-Fozq68InT+JKABGLqctgtb8P56pRrJFkbhW0ux+x1mdHeyinor8oNzJqwLjV/t5X5nJGfTlluxfyMnOXNggIUA==", + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.6.2.tgz", + "integrity": "sha512-ZF9Ugo2JCG/GfR7DEb4ypfyJJyiKbg5qBYKRintebj8+DNS33CyGMkWbrS9lara+u+h+yEOGSRiLhFO/g1s1aw==", "dependencies": { "@mongodb-js/saslprep": "^1.1.5", - "bson": "^6.4.0", + "bson": "^6.7.0", "mongodb-connection-string-url": "^3.0.0" }, "engines": { @@ -10561,17 +10755,17 @@ } }, "node_modules/mongoose": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.3.1.tgz", - "integrity": "sha512-D78C+s7QI4+pJQhs3XbOxzrHFEti4x+BDhaH94QrdV1/cmMA7fHc50LgLSXjzA/5q89TBK8DAXyf3VwDZbQJlA==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.4.0.tgz", + "integrity": "sha512-fgqRMwVEP1qgRYfh+tUe2YBBFnPO35FIg2lfFH+w9IhRGg1/ataWGIqvf/MjwM29cZ60D5vSnqtN2b8Qp0sOZA==", "dependencies": { - "bson": "^6.5.0", + "bson": "^6.7.0", "kareem": "2.6.3", - "mongodb": "6.5.0", + "mongodb": "6.6.2", "mpath": "0.9.0", "mquery": "5.0.0", "ms": "2.1.3", - "sift": "16.0.1" + "sift": "17.1.3" }, "engines": { "node": ">=16.20.1" @@ -10655,61 +10849,51 @@ "node_modules/nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "optional": true }, "node_modules/nise": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.5.tgz", - "integrity": "sha512-VJuPIfUFaXNRzETTQEEItTOP8Y171ijr+JLq42wHes3DiryR8vT+1TXQW/Rx8JNUhyYYWyIvjXTU6dOhJcs9Nw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/nise/-/nise-6.0.0.tgz", + "integrity": "sha512-K8ePqo9BFvN31HXwEtTNGzgrPpmvgciDsFz8aztFjt4LqKO/JeFD8tBOeuDiCMXrIl/m1YvfH8auSpxfaD09wg==", "dev": true, "dependencies": { - "@sinonjs/commons": "^2.0.0", - "@sinonjs/fake-timers": "^10.0.2", - "@sinonjs/text-encoding": "^0.7.1", - "just-extend": "^4.0.2", - "path-to-regexp": "^1.7.0" + "@sinonjs/commons": "^3.0.0", + "@sinonjs/fake-timers": "^11.2.2", + "@sinonjs/text-encoding": "^0.7.2", + "just-extend": "^6.2.0", + "path-to-regexp": "^6.2.1" } }, "node_modules/nise/node_modules/@sinonjs/commons": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", - "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", "dev": true, "dependencies": { "type-detect": "4.0.8" } }, "node_modules/nise/node_modules/@sinonjs/fake-timers": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", - "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "version": "11.2.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", + "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", "dev": true, "dependencies": { "@sinonjs/commons": "^3.0.0" } }, - "node_modules/nise/node_modules/@sinonjs/fake-timers/node_modules/@sinonjs/commons": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", - "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", - "dev": true, - "dependencies": { - "type-detect": "4.0.8" - } - }, "node_modules/nise/node_modules/path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", - "dev": true, - "dependencies": { - "isarray": "0.0.1" - } + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.2.tgz", + "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==", + "dev": true }, "node_modules/no-case": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", + "optional": true, "dependencies": { "lower-case": "^1.1.1" } @@ -10807,6 +10991,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "devOptional": true, "engines": { "node": ">=0.10.0" } @@ -10838,6 +11023,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "optional": true, "dependencies": { "boolbase": "^1.0.0" }, @@ -10929,6 +11115,7 @@ "version": "7.4.2", "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", + "optional": true, "dependencies": { "is-docker": "^2.0.0", "is-wsl": "^2.1.1" @@ -11034,6 +11221,7 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz", "integrity": "sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==", + "optional": true, "dependencies": { "p-timeout": "^3.1.0" }, @@ -11048,6 +11236,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "optional": true, "engines": { "node": ">=4" } @@ -11086,6 +11275,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "optional": true, "dependencies": { "p-finally": "^1.0.0" }, @@ -11106,6 +11296,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/p-wait-for/-/p-wait-for-3.2.0.tgz", "integrity": "sha512-wpgERjNkLrBiFmkMEjuZJEWKKDrNfHCKA1OhyN1wg1FrLkULbviEy6py1AyJUgZ72YWFbZ38FIpnqvVqAlDUwA==", + "optional": true, "dependencies": { "p-timeout": "^3.0.0" }, @@ -11120,6 +11311,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", "integrity": "sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==", + "optional": true, "dependencies": { "no-case": "^2.2.0" } @@ -11158,6 +11350,7 @@ "version": "7.1.2", "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "optional": true, "dependencies": { "entities": "^4.4.0" }, @@ -11169,6 +11362,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", + "optional": true, "dependencies": { "domhandler": "^5.0.2", "parse5": "^7.0.0" @@ -11181,6 +11375,7 @@ "version": "0.12.1", "resolved": "https://registry.npmjs.org/parseley/-/parseley-0.12.1.tgz", "integrity": "sha512-e6qHKe3a9HWr0oMRVDTRhKce+bRO8VGQR3NyVwcjwrbhMmFCX9KszEV35+rn4AdilFAq9VPxP/Fe1wC9Qjd2lw==", + "optional": true, "dependencies": { "leac": "^0.6.0", "peberminta": "^0.9.0" @@ -11282,14 +11477,15 @@ "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "devOptional": true }, "node_modules/path-scurry": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", - "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.2.tgz", + "integrity": "sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==", "dependencies": { - "lru-cache": "^9.1.1 || ^10.0.0", + "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { @@ -11300,9 +11496,9 @@ } }, "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", - "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==", + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", + "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==", "engines": { "node": "14 || >=16.14" } @@ -11339,6 +11535,7 @@ "version": "0.9.0", "resolved": "https://registry.npmjs.org/peberminta/-/peberminta-0.9.0.tgz", "integrity": "sha512-XIxfHpEuSJbITd1H3EeQwpcZbTLHc+VVr8ANI9t5sit565tsI4/xK3KWTUFE2e6QiangUkh3B0jihzmGnNrRsQ==", + "optional": true, "funding": { "url": "https://ko-fi.com/killymxi" } @@ -11353,6 +11550,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "devOptional": true, "engines": { "node": ">=8.6" }, @@ -11516,6 +11714,7 @@ "version": "3.0.19", "resolved": "https://registry.npmjs.org/preview-email/-/preview-email-3.0.19.tgz", "integrity": "sha512-DBS3Nir18YtKc8loYCCOGitmiaQ0vTdahPoiXxwNweJDpmVZo+w3tppufOhoK0m8skpRxT56llYLs3VrORnmNQ==", + "optional": true, "dependencies": { "ci-info": "^3.8.0", "display-notification": "2.0.0", @@ -11542,6 +11741,7 @@ "version": "7.3.1", "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "optional": true, "dependencies": { "asap": "~2.0.3" } @@ -11562,7 +11762,8 @@ "node_modules/proto-list": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", - "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==" + "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", + "optional": true }, "node_modules/proxy-addr": { "version": "2.0.7", @@ -11588,11 +11789,12 @@ "dev": true }, "node_modules/pug": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/pug/-/pug-3.0.2.tgz", - "integrity": "sha512-bp0I/hiK1D1vChHh6EfDxtndHji55XP/ZJKwsRqrz6lRia6ZC2OZbdAymlxdVFwd1L70ebrVJw4/eZ79skrIaw==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/pug/-/pug-3.0.3.tgz", + "integrity": "sha512-uBi6kmc9f3SZ3PXxqcHiUZLmIXgfgWooKWXcwSGwQd2Zi5Rb0bT14+8CJjJgI8AB+nndLaNgHGrcc6bPIB665g==", + "optional": true, "dependencies": { - "pug-code-gen": "^3.0.2", + "pug-code-gen": "^3.0.3", "pug-filters": "^4.0.0", "pug-lexer": "^5.0.1", "pug-linker": "^4.0.0", @@ -11606,6 +11808,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-3.0.0.tgz", "integrity": "sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==", + "optional": true, "dependencies": { "constantinople": "^4.0.1", "js-stringify": "^1.0.2", @@ -11613,29 +11816,32 @@ } }, "node_modules/pug-code-gen": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-3.0.2.tgz", - "integrity": "sha512-nJMhW16MbiGRiyR4miDTQMRWDgKplnHyeLvioEJYbk1RsPI3FuA3saEP8uwnTb2nTJEKBU90NFVWJBk4OU5qyg==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-3.0.3.tgz", + "integrity": "sha512-cYQg0JW0w32Ux+XTeZnBEeuWrAY7/HNE6TWnhiHGnnRYlCgyAUPoyh9KzCMa9WhcJlJ1AtQqpEYHc+vbCzA+Aw==", + "optional": true, "dependencies": { "constantinople": "^4.0.1", "doctypes": "^1.1.0", "js-stringify": "^1.0.2", "pug-attrs": "^3.0.0", - "pug-error": "^2.0.0", - "pug-runtime": "^3.0.0", + "pug-error": "^2.1.0", + "pug-runtime": "^3.0.1", "void-elements": "^3.1.0", "with": "^7.0.0" } }, "node_modules/pug-error": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-2.0.0.tgz", - "integrity": "sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ==" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-2.1.0.tgz", + "integrity": "sha512-lv7sU9e5Jk8IeUheHata6/UThZ7RK2jnaaNztxfPYUY+VxZyk/ePVaNZ/vwmH8WqGvDz3LrNYt/+gA55NDg6Pg==", + "optional": true }, "node_modules/pug-filters": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-4.0.0.tgz", "integrity": "sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==", + "optional": true, "dependencies": { "constantinople": "^4.0.1", "jstransformer": "1.0.0", @@ -11648,6 +11854,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-5.0.1.tgz", "integrity": "sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w==", + "optional": true, "dependencies": { "character-parser": "^2.2.0", "is-expression": "^4.0.0", @@ -11658,6 +11865,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-4.0.0.tgz", "integrity": "sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==", + "optional": true, "dependencies": { "pug-error": "^2.0.0", "pug-walk": "^2.0.0" @@ -11667,6 +11875,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-3.0.0.tgz", "integrity": "sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==", + "optional": true, "dependencies": { "object-assign": "^4.1.1", "pug-walk": "^2.0.0" @@ -11676,6 +11885,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-6.0.0.tgz", "integrity": "sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw==", + "optional": true, "dependencies": { "pug-error": "^2.0.0", "token-stream": "1.0.0" @@ -11684,12 +11894,14 @@ "node_modules/pug-runtime": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-3.0.1.tgz", - "integrity": "sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==" + "integrity": "sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==", + "optional": true }, "node_modules/pug-strip-comments": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-2.0.0.tgz", "integrity": "sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==", + "optional": true, "dependencies": { "pug-error": "^2.0.0" } @@ -11697,7 +11909,8 @@ "node_modules/pug-walk": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-2.0.0.tgz", - "integrity": "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==" + "integrity": "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==", + "optional": true }, "node_modules/punycode": { "version": "2.3.0", @@ -11795,6 +12008,7 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "optional": true, "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", @@ -11809,6 +12023,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "optional": true, "engines": { "node": ">=0.10.0" } @@ -11834,6 +12049,7 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "devOptional": true, "dependencies": { "picomatch": "^2.2.1" }, @@ -11854,9 +12070,9 @@ } }, "node_modules/reflect-metadata": { - "version": "0.1.14", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.14.tgz", - "integrity": "sha512-ZhYeb6nRaXCfhnndflDK8qI6ZQ/YcWZCISRAWICW9XYqMUwjZM9Z0DveWX/ABN01oxSHwVxKQmxeYZSsm0jh5A==" + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", + "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==" }, "node_modules/regenerator-runtime": { "version": "0.14.0", @@ -11867,6 +12083,7 @@ "version": "0.2.7", "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", + "optional": true, "engines": { "node": ">= 0.10" } @@ -11884,6 +12101,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "devOptional": true, "engines": { "node": ">=0.10.0" } @@ -11906,6 +12124,7 @@ "version": "1.22.4", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz", "integrity": "sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==", + "devOptional": true, "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -11987,9 +12206,9 @@ } }, "node_modules/rimraf": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz", - "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==", + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.7.tgz", + "integrity": "sha512-nV6YcJo5wbLW77m+8KjH8aB/7/rxQy9SZ0HY5shnwULfS+9nmTtVXAJET5NdZmCzA4fPI/Hm1wo/Po/4mopOdg==", "dependencies": { "glob": "^10.3.7" }, @@ -11997,7 +12216,7 @@ "rimraf": "dist/esm/bin.mjs" }, "engines": { - "node": ">=14" + "node": ">=14.18" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -12007,6 +12226,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-3.2.0.tgz", "integrity": "sha512-Ep0RsvAjnRcBX1p5vogbaBdAGu/8j/ewpvGqnQYunnLd9SM0vWcPJewPKNnWFggf0hF0pwIgwV5XK7qQ7UZ8Qg==", + "optional": true, "dependencies": { "execa": "^0.10.0" }, @@ -12018,6 +12238,7 @@ "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "optional": true, "dependencies": { "nice-try": "^1.0.4", "path-key": "^2.0.1", @@ -12033,6 +12254,7 @@ "version": "0.10.0", "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz", "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==", + "optional": true, "dependencies": { "cross-spawn": "^6.0.0", "get-stream": "^3.0.0", @@ -12050,6 +12272,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==", + "optional": true, "engines": { "node": ">=4" } @@ -12058,6 +12281,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "optional": true, "engines": { "node": ">=0.10.0" } @@ -12066,6 +12290,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", + "optional": true, "dependencies": { "path-key": "^2.0.0" }, @@ -12077,6 +12302,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "optional": true, "engines": { "node": ">=4" } @@ -12085,6 +12311,7 @@ "version": "5.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "optional": true, "bin": { "semver": "bin/semver" } @@ -12093,6 +12320,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "optional": true, "dependencies": { "shebang-regex": "^1.0.0" }, @@ -12104,6 +12332,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "optional": true, "engines": { "node": ">=0.10.0" } @@ -12111,12 +12340,14 @@ "node_modules/run-applescript/node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "optional": true }, "node_modules/run-applescript/node_modules/which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "optional": true, "dependencies": { "isexe": "^2.0.0" }, @@ -12249,6 +12480,7 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/selderee/-/selderee-0.11.0.tgz", "integrity": "sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA==", + "optional": true, "dependencies": { "parseley": "^0.12.0" }, @@ -12454,9 +12686,9 @@ } }, "node_modules/sift": { - "version": "16.0.1", - "resolved": "https://registry.npmjs.org/sift/-/sift-16.0.1.tgz", - "integrity": "sha512-Wv6BjQ5zbhW7VFefWusVP33T/EM0vYikCaQ2qR8yULbsilAT8/wQaXvuQ3ptGLpoKx+lihJE3y2UTgKDyyNHZQ==" + "version": "17.1.3", + "resolved": "https://registry.npmjs.org/sift/-/sift-17.1.3.tgz", + "integrity": "sha512-Rtlj66/b0ICeFzYTuNvX/EF1igRbbnGSvEyT79McoZa/DeGhMyC5pWKOEsZKnpkqtSeovd5FL/bjHWC3CIIvCQ==" }, "node_modules/signal-exit": { "version": "4.1.0", @@ -12470,17 +12702,17 @@ } }, "node_modules/sinon": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-17.0.1.tgz", - "integrity": "sha512-wmwE19Lie0MLT+ZYNpDymasPHUKTaZHUH/pKEubRXIzySv9Atnlw+BUMGCzWgV7b7wO+Hw6f1TEOr0IUnmU8/g==", + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-18.0.0.tgz", + "integrity": "sha512-+dXDXzD1sBO6HlmZDd7mXZCR/y5ECiEiGCBSGuFD/kZ0bDTofPYc6JaeGmPSF+1j1MejGUWkORbYOLDyvqCWpA==", "dev": true, "dependencies": { - "@sinonjs/commons": "^3.0.0", + "@sinonjs/commons": "^3.0.1", "@sinonjs/fake-timers": "^11.2.2", "@sinonjs/samsam": "^8.0.0", - "diff": "^5.1.0", - "nise": "^5.1.5", - "supports-color": "^7.2.0" + "diff": "^5.2.0", + "nise": "^6.0.0", + "supports-color": "^7" }, "funding": { "type": "opencollective", @@ -12488,9 +12720,9 @@ } }, "node_modules/sinon/node_modules/@sinonjs/commons": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", - "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", "dev": true, "dependencies": { "type-detect": "4.0.8" @@ -12506,9 +12738,9 @@ } }, "node_modules/sinon/node_modules/diff": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", - "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", "dev": true, "engines": { "node": ">=0.3.1" @@ -12533,6 +12765,7 @@ "version": "1.12.2", "resolved": "https://registry.npmjs.org/slick/-/slick-1.12.2.tgz", "integrity": "sha512-4qdtOGcBjral6YIBCWJ0ljFSKNLz9KkhbWtuGvUyRowl1kxfuE1x/Z/aJcaiilpb3do9bl5K7/1h9XC5wWpY/A==", + "optional": true, "engines": { "node": "*" } @@ -12729,6 +12962,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==", + "optional": true, "engines": { "node": ">=0.10.0" } @@ -12802,16 +13036,77 @@ } }, "node_modules/supertest": { - "version": "6.3.4", - "resolved": "https://registry.npmjs.org/supertest/-/supertest-6.3.4.tgz", - "integrity": "sha512-erY3HFDG0dPnhw4U+udPfrzXa4xhSG+n4rxfRuZWCUvjFWwKl+OxWf/7zk50s84/fAAs7vf5QAb9uRa0cCykxw==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/supertest/-/supertest-7.0.0.tgz", + "integrity": "sha512-qlsr7fIC0lSddmA3tzojvzubYxvlGtzumcdHgPwbFWMISQwL22MhM2Y3LNt+6w9Yyx7559VW5ab70dgphm8qQA==", "dev": true, "dependencies": { "methods": "^1.1.2", - "superagent": "^8.1.2" + "superagent": "^9.0.1" }, "engines": { - "node": ">=6.4.0" + "node": ">=14.18.0" + } + }, + "node_modules/supertest/node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/supertest/node_modules/formidable": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-3.5.1.tgz", + "integrity": "sha512-WJWKelbRHN41m5dumb0/k8TeAx7Id/y3a+Z7QfhxP/htI9Js5zYaEDtG8uMgG0vM0lOlqnmjE99/kfpOYi/0Og==", + "dev": true, + "dependencies": { + "dezalgo": "^1.0.4", + "hexoid": "^1.0.0", + "once": "^1.4.0" + }, + "funding": { + "url": "https://ko-fi.com/tunnckoCore/commissions" + } + }, + "node_modules/supertest/node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/supertest/node_modules/superagent": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-9.0.1.tgz", + "integrity": "sha512-CcRSdb/P2oUVaEpQ87w9Obsl+E9FruRd6b2b7LdiBtJoyMr2DQt7a89anAfiX/EL59j9b2CbRFvf2S91DhuCww==", + "dev": true, + "dependencies": { + "component-emitter": "^1.3.0", + "cookiejar": "^2.1.4", + "debug": "^4.3.4", + "fast-safe-stringify": "^2.1.1", + "form-data": "^4.0.0", + "formidable": "^3.5.1", + "methods": "^1.1.2", + "mime": "2.6.0", + "qs": "^6.11.0", + "semver": "^7.3.8" + }, + "engines": { + "node": ">=14.18.0" } }, "node_modules/supports-color": { @@ -12842,6 +13137,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "devOptional": true, "engines": { "node": ">= 0.4" }, @@ -12899,12 +13195,6 @@ "url": "https://opencollective.com/unts" } }, - "node_modules/synckit/node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", - "dev": true - }, "node_modules/tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", @@ -13110,6 +13400,7 @@ "version": "1.240.0", "resolved": "https://registry.npmjs.org/tlds/-/tlds-1.240.0.tgz", "integrity": "sha512-1OYJQenswGZSOdRw7Bql5Qu7uf75b+F3HFBXbqnG/ifHa0fev1XcG+3pJf3pA/KC6RtHQzfKgIf1vkMlMG7mtQ==", + "optional": true, "bin": { "tlds": "bin.js" } @@ -13136,6 +13427,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "devOptional": true, "engines": { "node": ">=4" } @@ -13144,6 +13436,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "devOptional": true, "dependencies": { "is-number": "^7.0.0" }, @@ -13162,7 +13455,8 @@ "node_modules/token-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-1.0.0.tgz", - "integrity": "sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg==" + "integrity": "sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg==", + "optional": true }, "node_modules/tough-cookie": { "version": "4.1.3", @@ -13392,9 +13686,9 @@ } }, "node_modules/tslib": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", - "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==" + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, "node_modules/type-check": { "version": "0.4.0", @@ -13478,12 +13772,14 @@ "node_modules/uc.micro": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", - "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==" + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "optional": true }, "node_modules/uglify-js": { "version": "3.17.4", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", + "optional": true, "bin": { "uglifyjs": "bin/uglifyjs" }, @@ -13587,7 +13883,8 @@ "node_modules/upper-case": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", - "integrity": "sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA==" + "integrity": "sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA==", + "optional": true }, "node_modules/uri-js": { "version": "4.4.1", @@ -13656,6 +13953,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/valid-data-url/-/valid-data-url-3.0.1.tgz", "integrity": "sha512-jOWVmzVceKlVVdwjNSenT4PbGghU0SBIizAev8ofZVgivk/TVHXSbNL8LP6M3spZvkR9/QolkyJavGSX5Cs0UA==", + "optional": true, "engines": { "node": ">=10" } @@ -13727,6 +14025,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==", + "optional": true, "engines": { "node": ">=0.10.0" } @@ -13807,6 +14106,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/web-resource-inliner/-/web-resource-inliner-6.0.1.tgz", "integrity": "sha512-kfqDxt5dTB1JhqsCUQVFDj0rmY+4HLwGQIsLPbyrsN9y9WV/1oFDSx3BQ4GfCv9X+jVeQ7rouTqwK53rA/7t8A==", + "optional": true, "dependencies": { "ansi-colors": "^4.1.1", "escape-goat": "^3.0.0", @@ -13823,6 +14123,7 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "optional": true, "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^4.2.0", @@ -13836,6 +14137,7 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "optional": true, "dependencies": { "domelementtype": "^2.2.0" }, @@ -13850,6 +14152,7 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-3.3.0.tgz", "integrity": "sha512-J1C5rIANUbuYK+FuFL98650rihynUOEzRLxW+90bKZRWB6A1X1Tf82GxR1qAWLyfNPRvjqfip3Q5tdYlmAa9lA==", + "optional": true, "dependencies": { "domelementtype": "^2.0.1" }, @@ -13864,6 +14167,7 @@ "version": "2.8.0", "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "optional": true, "dependencies": { "dom-serializer": "^1.0.1", "domelementtype": "^2.2.0", @@ -13877,6 +14181,7 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "optional": true, "dependencies": { "domelementtype": "^2.2.0" }, @@ -13891,6 +14196,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "optional": true, "funding": { "url": "https://github.com/fb55/entities?sponsor=1" } @@ -13899,6 +14205,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-5.0.1.tgz", "integrity": "sha512-vKZZra6CSe9qsJzh0BjBGXo8dvzNsq/oGvsjfRdOrrryfeD9UOBEEQdeoqCRmKZchF5h2zOBMQ6YuQ0uRUmdbQ==", + "optional": true, "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^3.3.0", @@ -13913,6 +14220,7 @@ "version": "2.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "optional": true, "bin": { "mime": "cli.js" }, @@ -13924,6 +14232,7 @@ "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "optional": true, "dependencies": { "whatwg-url": "^5.0.0" }, @@ -13942,17 +14251,20 @@ "node_modules/web-resource-inliner/node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "optional": true }, "node_modules/web-resource-inliner/node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "optional": true }, "node_modules/web-resource-inliner/node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "optional": true, "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" @@ -14128,6 +14440,7 @@ "version": "7.0.2", "resolved": "https://registry.npmjs.org/with/-/with-7.0.2.tgz", "integrity": "sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==", + "optional": true, "dependencies": { "@babel/parser": "^7.9.6", "@babel/types": "^7.9.6", @@ -14248,6 +14561,7 @@ "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "devOptional": true, "engines": { "node": ">=10" } @@ -14262,6 +14576,7 @@ "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "devOptional": true, "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -14279,6 +14594,7 @@ "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "devOptional": true, "engines": { "node": ">=12" } diff --git a/package.json b/package.json index 119e20e94..65b1ff50f 100644 --- a/package.json +++ b/package.json @@ -32,17 +32,17 @@ "dependencies": { "@casl/ability": "^6.3.2", "@elastic/elasticsearch": "^8.9.0", - "@nestjs-modules/mailer": "^1.8.1", + "@nestjs-modules/mailer": "^2.0.2", "@nestjs/axios": "^3.0.0", - "@nestjs/common": "^9.0.0", + "@nestjs/common": "^10.3.8", "@nestjs/config": "^3.0.0", - "@nestjs/core": "^9.0.0", + "@nestjs/core": "^10.3.8", "@nestjs/elasticsearch": "^10.0.1", "@nestjs/event-emitter": "^2.0.1", "@nestjs/jwt": "^10.0.1", "@nestjs/mongoose": "^10.0.0", "@nestjs/passport": "^10.0.0", - "@nestjs/platform-express": "^9.0.0", + "@nestjs/platform-express": "^10.3.8", "@nestjs/swagger": "^7.1.7", "@nestjs/terminus": "^10.1.1", "@user-office-software/duo-logger": "^2.1.1", @@ -57,7 +57,7 @@ "luxon": "^3.2.1", "mathjs": "^12.0.0", "migrate-mongo": "^11.0.0", - "mongoose": "^8.3.1", + "mongoose": "^8.4.0", "node-fetch": "^3.3.0", "nodemailer": "^6.7.8", "openid-client": "^5.1.8", @@ -65,7 +65,7 @@ "passport-jwt": "^4.0.0", "passport-ldapauth": "^3.0.1", "passport-local": "^1.0.0", - "reflect-metadata": "^0.1.13", + "reflect-metadata": "^0.2.2", "rimraf": "^5.0.0", "rxjs": "^7.5.7", "swagger-ui-express": "^5.0.0", @@ -80,7 +80,7 @@ "@faker-js/faker": "^8.0.1", "@nestjs/cli": "^10.0.5", "@nestjs/schematics": "^10.0.1", - "@nestjs/testing": "^9.0.0", + "@nestjs/testing": "^10.3.8", "@types/bcrypt": "^5.0.0", "@types/chai": "^4.3.6", "@types/express": "^4.17.13", @@ -108,8 +108,8 @@ "jest": "27.0.6", "mocha": "^10.0.0", "prettier": "^3.0.3", - "sinon": "^17.0.0", - "supertest": "^6.1.3", + "sinon": "^18.0.0", + "supertest": "^7.0.0", "ts-jest": "^27.0.3", "ts-loader": "^9.2.3", "ts-node": "^10.9.1", diff --git a/src/auth/access-group-provider/access-group-from-multiple-providers.service.ts b/src/auth/access-group-provider/access-group-from-multiple-providers.service.ts index 1107f2b72..60cf7f289 100644 --- a/src/auth/access-group-provider/access-group-from-multiple-providers.service.ts +++ b/src/auth/access-group-provider/access-group-from-multiple-providers.service.ts @@ -17,8 +17,12 @@ export class AccessGroupFromMultipleProvidersService extends AccessGroupService for (const accessGroupProvider of this.accessGroupProviders) { const accessGroupsFromProvider = await accessGroupProvider.getAccessGroups(userPayload); - accessGroups.push(...accessGroupsFromProvider); + + accessGroups.push( + ...accessGroupsFromProvider.filter((group) => group.trim() !== ""), + ); } + return accessGroups; } } diff --git a/src/casl/casl-ability.factory.ts b/src/casl/casl-ability.factory.ts index 8bf7f4743..0861325c3 100644 --- a/src/casl/casl-ability.factory.ts +++ b/src/casl/casl-ability.factory.ts @@ -1302,37 +1302,38 @@ export class CaslAbilityFactory { cannot(Action.InstrumentCreate, Instrument); cannot(Action.InstrumentUpdate, Instrument); cannot(Action.InstrumentDelete, Instrument); - } else if ( - user.currentGroups.some((g) => configuration().deleteGroups.includes(g)) - ) { - /* - / user that belongs to any of the group listed in DELETE_GROUPS - */ + } else { + if ( + user.currentGroups.some((g) => configuration().deleteGroups.includes(g)) + ) { + /* + * user that belongs to any of the group listed in DELETE_GROUPS + */ - // ------------------------------------- - // instrument - // ------------------------------------- - // endpoint authorization - can(Action.InstrumentDelete, Instrument); - } else if ( - user.currentGroups.some((g) => configuration().adminGroups.includes(g)) - ) { - /** - * authenticated users belonging to any of the group listed in ADMIN_GROUPS - */ - // ------------------------------------- - // instrument - // ------------------------------------- - // endpoint authorization - can(Action.InstrumentRead, Instrument); - can(Action.InstrumentCreate, Instrument); - can(Action.InstrumentUpdate, Instrument); - cannot(Action.InstrumentDelete, Instrument); - } else if (user) { - can(Action.InstrumentRead, Instrument); - cannot(Action.InstrumentCreate, Instrument); - cannot(Action.InstrumentUpdate, Instrument); - cannot(Action.InstrumentDelete, Instrument); + // ------------------------------------- + // endpoint authorization + can(Action.InstrumentDelete, Instrument); + } else { + cannot(Action.InstrumentDelete, Instrument); + } + + if ( + user.currentGroups.some((g) => configuration().adminGroups.includes(g)) + ) { + /** + * authenticated users belonging to any of the group listed in ADMIN_GROUPS + */ + + // ------------------------------------- + // endpoint authorization + can(Action.InstrumentRead, Instrument); + can(Action.InstrumentCreate, Instrument); + can(Action.InstrumentUpdate, Instrument); + } else { + can(Action.InstrumentRead, Instrument); + cannot(Action.InstrumentCreate, Instrument); + cannot(Action.InstrumentUpdate, Instrument); + } } // Instrument permissions diff --git a/src/datasets/datasets.service.ts b/src/datasets/datasets.service.ts index c13edd355..c78974c1e 100644 --- a/src/datasets/datasets.service.ts +++ b/src/datasets/datasets.service.ts @@ -64,10 +64,8 @@ export class DatasetsService { // insert created and updated fields addCreatedByFields(createDatasetDto, username), ); - if (this.ESClient) { - await this.ESClient.updateInsertDocument( - createdDataset.toObject() as DatasetDocument, - ); + if (this.ESClient && createdDataset) { + await this.ESClient.updateInsertDocument(createdDataset.toObject()); } return createdDataset.save(); } @@ -242,10 +240,8 @@ export class DatasetsService { throw new NotFoundException(`Dataset #${id} not found`); } - if (this.ESClient) { - await this.ESClient.updateInsertDocument( - updatedDataset.toObject() as DatasetDocument, - ); + if (this.ESClient && updatedDataset) { + await this.ESClient.updateInsertDocument(updatedDataset.toObject()); } // we were able to find the dataset and update it return updatedDataset; @@ -283,10 +279,8 @@ export class DatasetsService { ) .exec(); - if (this.ESClient) { - await this.ESClient.updateInsertDocument( - patchedDataset?.toObject() as DatasetDocument, - ); + if (this.ESClient && patchedDataset) { + await this.ESClient.updateInsertDocument(patchedDataset.toObject()); } // we were able to find the dataset and update it diff --git a/src/elastic-search/configuration/datasetFieldMapping.ts b/src/elastic-search/configuration/datasetFieldMapping.ts index 24c78ec15..988bb5b7e 100644 --- a/src/elastic-search/configuration/datasetFieldMapping.ts +++ b/src/elastic-search/configuration/datasetFieldMapping.ts @@ -25,6 +25,7 @@ export const datasetMappings: MappingObject = { }, pid: { type: "keyword", + ignore_above: 256, }, creationTime: { type: "date", @@ -48,29 +49,48 @@ export const datasetMappings: MappingObject = { }, proposalId: { type: "keyword", + ignore_above: 256, + }, + sampleId: { + type: "keyword", + ignore_above: 256, }, sourceFolder: { type: "keyword", + ignore_above: 256, }, isPublished: { type: "boolean", }, type: { type: "keyword", + ignore_above: 256, }, keywords: { type: "keyword", + ignore_above: 256, }, creationLocation: { type: "keyword", + ignore_above: 256, }, ownerGroup: { type: "keyword", + ignore_above: 256, }, accessGroups: { type: "keyword", + ignore_above: 256, }, sharedWith: { type: "keyword", + ignore_above: 256, + }, + ownerEmail: { + type: "keyword", + ignore_above: 256, + }, + size: { + type: "long", }, }; diff --git a/src/elastic-search/elastic-search.service.ts b/src/elastic-search/elastic-search.service.ts index 59d9b4244..69782558b 100644 --- a/src/elastic-search/elastic-search.service.ts +++ b/src/elastic-search/elastic-search.service.ts @@ -359,7 +359,7 @@ export class ElasticSearchService implements OnModuleInit { ); } } - async updateInsertDocument(data: DatasetDocument) { + async updateInsertDocument(data: Partial) { //NOTE: Replace all keys with lower case, also replace spaces and dot with underscore delete data._id; const transformedScientificMetadata = transformKeysInObject( @@ -428,7 +428,7 @@ export class ElasticSearchService implements OnModuleInit { ]; }, onDrop(doc) { - console.debug(`${doc.document._id}`, doc.error?.reason); + console.debug(`${doc.document.pid}`, doc.error?.reason); }, }); } diff --git a/src/elastic-search/providers/fields.enum.ts b/src/elastic-search/providers/fields.enum.ts index 13718e921..8030407ab 100644 --- a/src/elastic-search/providers/fields.enum.ts +++ b/src/elastic-search/providers/fields.enum.ts @@ -12,15 +12,7 @@ export enum FilterFields { Mode = "mode", } -export enum FacetFields { - Type = "type", - CreationLocation = "creationLocation", - OwnerGroup = "ownerGroup", - AccessGroups = "accessGroups", - Keywords = "keywords", -} - -export enum QueryFields { +export enum MustFields { DatasetName = "datasetName", Description = "description", } @@ -30,6 +22,14 @@ export enum ShouldFields { UserGroups = "userGroups", } +export enum FacetFields { + Type = "type", + CreationLocation = "creationLocation", + OwnerGroup = "ownerGroup", + AccessGroups = "accessGroups", + Keywords = "keywords", +} + export enum SortFields { DatasetName = "datasetName", DatasetNameKeyword = "datasetName.keyword", diff --git a/src/elastic-search/providers/query-builder.service.ts b/src/elastic-search/providers/query-builder.service.ts index 08070f3e1..930f877f9 100644 --- a/src/elastic-search/providers/query-builder.service.ts +++ b/src/elastic-search/providers/query-builder.service.ts @@ -10,7 +10,7 @@ import { } from "../interfaces/es-common.type"; import { FilterFields, - QueryFields, + MustFields, FacetFields, ShouldFields, } from "./fields.enum"; @@ -22,7 +22,7 @@ import { convertToElasticSearchQuery } from "../helpers/utils"; @Injectable() export class SearchQueryService { readonly filterFields = [...Object.values(FilterFields)]; - readonly queryFields = [...Object.values(QueryFields)]; + readonly mustFields = [...Object.values(MustFields)]; readonly shouldFields = [...Object.values(ShouldFields)]; readonly facetFields = [...Object.values(FacetFields)]; readonly textQuerySplitMethod = /[ ,]+/; @@ -33,9 +33,13 @@ export class SearchQueryService { const filter = this.buildFilterFields(fields); const should = this.buildShouldFields(fields); - const query = this.buildTextQuery(fields); + const must = this.buildTextQuery(fields); - return this.constructFinalQuery(filter, should, query); + // NOTE: The final query flow is as follows: + // step 1. Build filter fields conditions must match all filter fields + // step 2. Build should fields conditions must match at least one should field + // step 3. Build text query conditions must match all text query fields + return this.constructFinalQuery(filter, should, must); } catch (err) { Logger.error("Elastic search build search query failed"); throw err; @@ -44,15 +48,14 @@ export class SearchQueryService { private buildFilterFields(fields: Partial): IFilter[] { const filter: IFilter[] = []; - for (const fieldName of this.filterFields) { - if (fields[fieldName]) { - const filterQueries = this.buildTermsFilter( - fieldName, - fields[fieldName], - ); - filter.push(...filterQueries); + Object.entries(fields).forEach(([key, value]) => { + if (this.shouldFields.includes(key as ShouldFields) || key === "text") { + return; } - } + + const filterQueries = this.buildTermsFilter(key, value); + filter.push(...filterQueries); + }); return filter; } @@ -101,7 +104,7 @@ export class SearchQueryService { private buildWildcardQueries(text: string): QueryDslQueryContainer[] { const terms = this.splitSearchText(text); return terms.flatMap((term) => - this.queryFields.map((fieldName) => ({ + this.mustFields.map((fieldName) => ({ wildcard: { [fieldName]: { value: `*${term}*` } }, })), ); @@ -170,10 +173,10 @@ export class SearchQueryService { }, }); } - if (typeof values === "string") { + if (typeof values === "string" || typeof values === "number") { filterArray.push({ match: { - [`${fieldName}.keyword`]: values as string, + [fieldName]: values as string | number, }, }); } diff --git a/src/proposals/dto/update-proposal.dto.ts b/src/proposals/dto/update-proposal.dto.ts index 788fa89c0..1ce6ce0f8 100644 --- a/src/proposals/dto/update-proposal.dto.ts +++ b/src/proposals/dto/update-proposal.dto.ts @@ -4,6 +4,7 @@ import { IsArray, IsDateString, IsEmail, + IsObject, IsOptional, IsString, ValidateNested, @@ -113,6 +114,16 @@ export class UpdateProposalDto extends OwnableDto { @ValidateNested({ each: true }) @Type(() => CreateMeasurementPeriodDto) readonly MeasurementPeriodList?: CreateMeasurementPeriodDto[]; + + @ApiProperty({ + type: Object, + required: false, + default: {}, + description: "JSON object containing the proposal metadata.", + }) + @IsOptional() + @IsObject() + readonly metadata?: Record; } export class PartialUpdateProposalDto extends PartialType(UpdateProposalDto) {} diff --git a/src/proposals/schemas/proposal.schema.ts b/src/proposals/schemas/proposal.schema.ts index 8ebbe4baa..8e26a1692 100644 --- a/src/proposals/schemas/proposal.schema.ts +++ b/src/proposals/schemas/proposal.schema.ts @@ -158,6 +158,15 @@ export class ProposalClass extends OwnableClass { required: false, }) MeasurementPeriodList?: MeasurementPeriodClass[]; + + @ApiProperty({ + type: Object, + required: false, + default: {}, + description: "JSON object containing the proposal metadata.", + }) + @Prop({ type: Object, required: false, default: {} }) + metadata?: Record; } export const ProposalSchema = SchemaFactory.createForClass(ProposalClass); diff --git a/src/published-data/published-data.controller.ts b/src/published-data/published-data.controller.ts index 364c03c29..c8030b6ca 100644 --- a/src/published-data/published-data.controller.ts +++ b/src/published-data/published-data.controller.ts @@ -48,7 +48,6 @@ import { FilterQuery, QueryOptions } from "mongoose"; import { DatasetsService } from "src/datasets/datasets.service"; import { ProposalsService } from "src/proposals/proposals.service"; import { AttachmentsService } from "src/attachments/attachments.service"; -import { existsSync, readFileSync } from "fs"; import { HttpService } from "@nestjs/axios"; import { ConfigService } from "@nestjs/config"; import { firstValueFrom } from "rxjs"; @@ -59,8 +58,6 @@ import { DatasetClass } from "src/datasets/schemas/dataset.schema"; @ApiTags("published data") @Controller("publisheddata") export class PublishedDataController { - private doiConfigPath = "./src/config/doiconfig.local.json"; - constructor( private readonly attachmentsService: AttachmentsService, private readonly configService: ConfigService, @@ -434,6 +431,28 @@ export class PublishedDataController { @CheckPolicies((ability: AppAbility) => ability.can(Action.Update, PublishedData), ) + @ApiOperation({ + summary: "Edits published data.", + description: + "It edits published data and resyncs with OAI Provider if it is defined.", + }) + @ApiParam({ + name: "id", + description: "The DOI of the published data.", + type: String, + }) + @ApiParam({ + name: "data", + description: + "The edited data that will be updated in the database and with OAI Provider if defined.", + type: UpdatePublishedDataDto, + }) + @ApiResponse({ + status: HttpStatus.OK, + isArray: false, + description: + "Return the result of resync with OAI Provider if defined, or null.", + }) @Post("/:id/resync") async resync( @Param("id") id: string, @@ -443,47 +462,25 @@ export class PublishedDataController { const OAIServerUri = this.configService.get("oaiProviderRoute"); - let doiProviderCredentials = { - username: "removed", - password: "removed", - }; - - if (existsSync(this.doiConfigPath)) { - doiProviderCredentials = JSON.parse( - readFileSync(this.doiConfigPath).toString(), + let returnValue = null; + if (OAIServerUri) { + returnValue = await this.publishedDataService.resyncOAIPublication( + id, + publishedData, + OAIServerUri, ); } - const resyncOAIPublication = { - method: "PUT", - body: publishedData, - json: true, - uri: OAIServerUri + "/" + encodeURIComponent(encodeURIComponent(id)), - headers: { - "content-type": "application/json;charset=UTF-8", - }, - auth: doiProviderCredentials, - }; - - let res; - try { - res = await firstValueFrom( - this.httpService.request({ - ...resyncOAIPublication, - method: "PUT", - }), - ); - } catch (error) { - handleAxiosRequestError(error, "PublishedDataController.resync"); - } - try { await this.publishedDataService.update({ doi: id }, publishedData); - } catch (error) { - console.error(error); + } catch (error: any) { + throw new HttpException( + `Error occurred: ${error}`, + error.response?.status || HttpStatus.FAILED_DEPENDENCY, + ); } - return res ? res.data : null; + return returnValue; } } diff --git a/src/published-data/published-data.service.spec.ts b/src/published-data/published-data.service.spec.ts index 12a9937ec..60d74ed5e 100644 --- a/src/published-data/published-data.service.spec.ts +++ b/src/published-data/published-data.service.spec.ts @@ -1,8 +1,14 @@ +import { HttpException, Logger } from "@nestjs/common"; import { getModelToken } from "@nestjs/mongoose"; import { Test, TestingModule } from "@nestjs/testing"; import { Model } from "mongoose"; import { PublishedDataService } from "./published-data.service"; import { PublishedData } from "./schemas/published-data.schema"; +import { HttpModule, HttpService } from "@nestjs/axios"; +import { AxiosInstance } from "axios"; +import fs from "fs"; +import { of } from "rxjs"; +import { AxiosResponse } from "axios"; const mockPublishedData: PublishedData = { doi: "100.10/random-test-uuid-string", @@ -30,13 +36,21 @@ const mockPublishedData: PublishedData = { updatedAt: new Date("2022-02-15T13:00:00"), }; +const mockAxiosResponse: Partial = { + data: "success", + status: 200, + statusText: "OK", +}; + describe("PublishedDataService", () => { let service: PublishedDataService; // eslint-disable-next-line @typescript-eslint/no-unused-vars let model: Model; + let httpService: HttpService; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ + imports: [HttpModule], providers: [ PublishedDataService, { @@ -49,14 +63,80 @@ describe("PublishedDataService", () => { exec: jest.fn(), }, }, + { + provide: "AXIOS_INSTANCE_TOKEN", + useValue: {} as AxiosInstance, + }, ], }).compile(); service = await module.resolve(PublishedDataService); model = module.get>(getModelToken("PublishedData")); + httpService = module.get(HttpService); + Logger.error = jest.fn(); }); it("should be defined", () => { expect(service).toBeDefined(); }); + + describe("resyncOAIPublication", () => { + const id = "test-id"; + const OAIServerUri = "https://oaimockserver.com"; + const doiCredentials = { + username: "the_username", + password: "the_password", + }; + + it("should throw HttpException if doiConfigPath file does not exist", async () => { + jest.mock("fs"); + jest.spyOn(fs, "existsSync").mockReturnValue(false); + + await expect( + service.resyncOAIPublication(id, mockPublishedData, OAIServerUri), + ).rejects.toThrowError(HttpException); + }); + + it("should call httpService.request with correct payload", async () => { + jest.mock("fs"); + jest.spyOn(fs, "existsSync").mockReturnValueOnce(true); + jest + .spyOn(fs, "readFileSync") + .mockReturnValueOnce(JSON.stringify(doiCredentials)); + jest + .spyOn(httpService, "request") + .mockReturnValueOnce(of(mockAxiosResponse as AxiosResponse)); + await service.resyncOAIPublication(id, mockPublishedData, OAIServerUri); + + expect(httpService.request).toHaveBeenCalledTimes(1); + + expect(httpService.request).toHaveBeenCalledWith({ + method: "PUT", + json: true, + body: mockPublishedData, + auth: doiCredentials, + uri: OAIServerUri + "/" + id, + headers: { + "content-type": "application/json;charset=UTF-8", + }, + }); + }); + + it("should throw HttpException if request to oaiProvider raise exception", async () => { + jest.mock("fs"); + jest.spyOn(fs, "existsSync").mockReturnValueOnce(true); + jest + .spyOn(fs, "readFileSync") + .mockReturnValueOnce(JSON.stringify(doiCredentials)); + jest.spyOn(httpService, "request").mockImplementation(() => { + throw new Error(); + }); + + await expect( + service.resyncOAIPublication(id, mockPublishedData, OAIServerUri), + ).rejects.toThrowError(HttpException); + + expect(Logger.error).toBeCalled(); + }); + }); }); diff --git a/src/published-data/published-data.service.ts b/src/published-data/published-data.service.ts index 97cbed44b..8da73c442 100644 --- a/src/published-data/published-data.service.ts +++ b/src/published-data/published-data.service.ts @@ -1,4 +1,11 @@ -import { Inject, Injectable, Scope } from "@nestjs/common"; +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { + Inject, + Injectable, + Scope, + HttpException, + HttpStatus, +} from "@nestjs/common"; import { REQUEST } from "@nestjs/core"; import { Request } from "express"; import { InjectModel } from "@nestjs/mongoose"; @@ -20,12 +27,21 @@ import { PublishedDataDocument, } from "./schemas/published-data.schema"; import { JWTUser } from "src/auth/interfaces/jwt-user.interface"; +import { HttpService } from "@nestjs/axios"; +import { UpdatePublishedDataDto } from "./dto/update-published-data.dto"; +import { IRegister } from "./interfaces/published-data.interface"; +import { existsSync, readFileSync } from "fs"; +import { firstValueFrom } from "rxjs"; +import { handleAxiosRequestError } from "src/common/utils"; @Injectable({ scope: Scope.REQUEST }) export class PublishedDataService { + private doiConfigPath = "./src/config/doiconfig.local.json"; + constructor( @InjectModel(PublishedData.name) private publishedDataModel: Model, + private readonly httpService: HttpService, @Inject(REQUEST) private request: Request, ) {} @@ -101,4 +117,51 @@ export class PublishedDataService { async remove(filter: FilterQuery): Promise { return this.publishedDataModel.findOneAndDelete(filter).exec(); } + + async resyncOAIPublication( + id: string, + publishedData: UpdatePublishedDataDto, + OAIServerUri: string, + ): Promise { + let doiProviderCredentials; + + // this can be improved on by validating doiProviderCredentials + if (existsSync(this.doiConfigPath)) { + doiProviderCredentials = JSON.parse( + readFileSync(this.doiConfigPath).toString(), + ); + } else { + throw new HttpException( + "doiConfigPath file not found", + HttpStatus.INTERNAL_SERVER_ERROR, + ); + } + + const resyncOAIPublication = { + method: "PUT", + body: publishedData, + json: true, + uri: OAIServerUri + "/" + encodeURIComponent(encodeURIComponent(id)), + headers: { + "content-type": "application/json;charset=UTF-8", + }, + auth: doiProviderCredentials, + }; + + try { + const res = await firstValueFrom( + this.httpService.request({ + ...resyncOAIPublication, + method: "PUT", + }), + ); + return res ? res.data : null; + } catch (error: any) { + handleAxiosRequestError(error, "PublishedDataController.resync"); + throw new HttpException( + `Error occurred: ${error}`, + error.response?.status || HttpStatus.FAILED_DEPENDENCY, + ); + } + } } diff --git a/src/published-data/schemas/published-data.schema.ts b/src/published-data/schemas/published-data.schema.ts index bb68c3c88..d9e73a30c 100644 --- a/src/published-data/schemas/published-data.schema.ts +++ b/src/published-data/schemas/published-data.schema.ts @@ -27,7 +27,12 @@ export class PublishedData { }) _id: string; - @ApiProperty({ type: String, description: "Digital Object Identifier" }) + @ApiProperty({ + type: String, + description: + "Digital Object Identifier; e.g.," + + ' "10.xxx/9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d".', + }) @Prop({ type: String, unique: true, @@ -47,7 +52,9 @@ export class PublishedData { @ApiProperty({ type: String, required: false, - description: "Creator Affiliation", + description: + "Creator Affiliation. This field has the semantics of" + + " [DataCite Creator/affiliation](https://datacite-metadata-schema.readthedocs.io/en/4.5/properties/creator/#affiliation).", }) @Prop({ type: String, required: false }) affiliation: string; @@ -55,7 +62,10 @@ export class PublishedData { @ApiProperty({ type: [String], required: true, - description: "Creator of dataset/dataset collection", + description: + "Creator of dataset/dataset collection. This field has the semantics" + + " of Dublin Core [dcmi:creator](https://www.dublincore.org/specifications/dublin-core/dcmi-terms/terms/creator/)" + + " and [DataCite Creator/creatorName](https://datacite-metadata-schema.readthedocs.io/en/4.5/properties/creator/#creatorname).", }) @Prop({ type: [String], required: true }) creator: string[]; @@ -63,7 +73,10 @@ export class PublishedData { @ApiProperty({ type: String, required: true, - description: "Dataset publisher", + description: + "Dataset publisher. This field has the semantics of Dublin Core" + + " [dcmi:publisher](https://www.dublincore.org/specifications/dublin-core/dcmi-terms/terms/publisher/)" + + " and [DataCite publisher](https://datacite-metadata-schema.readthedocs.io/en/4.5/properties/publisher).", }) @Prop({ type: String, required: true }) publisher: string; @@ -71,12 +84,22 @@ export class PublishedData { @ApiProperty({ type: Number, required: true, - description: "Year of publication ", + description: + "Year of publication. This field has the semantics of Dublin Core" + + " [dcmi:date](https://www.dublincore.org/specifications/dublin-core/dcmi-terms/terms/date/)" + + " and [DataCite publicationYear](https://datacite-metadata-schema.readthedocs.io/en/4.5/properties/publicationyear/).", }) @Prop({ type: Number, required: true }) publicationYear: number; - @ApiProperty({ type: String, required: true, description: "Title" }) + @ApiProperty({ + type: String, + required: true, + description: + "The title of the data. This field has the semantics of Dublin Core" + + " [dcmi:title](https://www.dublincore.org/specifications/dublin-core/dcmi-terms/terms/title/)" + + " and [DataCite title](https://datacite-metadata-schema.readthedocs.io/en/4.5/properties/title/).", + }) @Prop({ type: String, required: true }) title: string; @@ -91,7 +114,10 @@ export class PublishedData { @ApiProperty({ type: String, required: true, - description: "Abstract text for published datasets", + description: + "Abstract text for published datasets. This field has the semantics" + + " of [DataCite description](https://datacite-metadata-schema.readthedocs.io/en/4.5/properties/description/)" + + " with [Abstract descriptionType](https://datacite-metadata-schema.readthedocs.io/en/4.5/appendices/appendix-1/descriptionType/#abstract).", }) @Prop({ type: String, required: true }) abstract: string; @@ -99,7 +125,11 @@ export class PublishedData { @ApiProperty({ type: String, required: true, - description: "Link to description of how to re-use data", + description: + "Link to description of how to re-use data. This field has the" + + " semantics of Dublic Core [dcmi:description](https://www.dublincore.org/specifications/dublin-core/dcmi-terms/terms/description/)" + + " and [DataCite description](https://datacite-metadata-schema.readthedocs.io/en/4.5/properties/description/)" + + " with [Abstract descriptionType](https://datacite-metadata-schema.readthedocs.io/en/4.5/appendices/appendix-1/descriptionType/#abstract).", }) @Prop({ type: String, required: true }) dataDescription: string; @@ -131,7 +161,9 @@ export class PublishedData { @ApiProperty({ type: [String], required: true, - description: "Array of one or more PIDS which make up the published data", + description: + "Array of one or more Dataset persistent identifier (pid) values that" + + " make up the published data.", }) @Prop({ type: [String], required: true }) pidArray: string[]; diff --git a/test/ElasticSearch.js b/test/ElasticSearch.js index a34551ab1..221a57043 100644 --- a/test/ElasticSearch.js +++ b/test/ElasticSearch.js @@ -1,6 +1,7 @@ /* eslint-disable @typescript-eslint/no-var-requires */ "use strict"; +const { faker } = require("@faker-js/faker"); const utils = require("./LoginUtils"); const { TestData } = require("./TestData"); require("dotenv").config(); @@ -23,21 +24,18 @@ const scientificMetadataFieldName = { string: "with_string", }; -const scientificMetadata = ({ - lhs = "", - relation = "", - rhs = "", - unit = "", -}) => { +const scientificMetadata = (values) => { + const scientificQuery = values.map((value) => { + return { + lhs: value.lhs, + relation: value.relation, + rhs: value.rhs, + unit: value.unit, + }; + }); + return { - scientific: [ - { - lhs, - relation, - rhs, - unit, - }, - ], + scientific: scientificQuery, }; }; @@ -71,7 +69,7 @@ const scientificMetadata = ({ ); }); - it("0010: adds a new raw dataset with scientificMetadata", function () { + it("0010: adds a new raw dataset with scientificMetadata", async () => { return request(appUrl) .post("/api/v3/Datasets") .send(TestData.ScientificMetadataForElasticSearch) @@ -92,42 +90,74 @@ const scientificMetadata = ({ }); }); - it("0020: should fetch dataset with unitSI and ValueSI condition filter", function () { - request(appUrl) + it("0020: should fetch dataset with correct unitSI and ValueSI condition for scientific filter", async () => { + return request(appUrl) .post("/api/v3/elastic-search/search") .send( - scientificMetadata({ - lhs: scientificMetadataFieldName.unitAndValue, - relation: Relation.GREATER_THAN, - rhs: 99, - unit: "m", - }), + scientificMetadata([ + { + lhs: scientificMetadataFieldName.unitAndValue, + relation: Relation.GREATER_THAN, + rhs: 99, + unit: "m", + }, + { + lhs: scientificMetadataFieldName.unitAndValue, + relation: Relation.EQUAL_TO_NUMERIC, + rhs: 100, + unit: "m", + }, + { + lhs: scientificMetadataFieldName.unitAndValue, + relation: Relation.LESS_THAN, + rhs: 101, + unit: "m", + }, + ]), ) .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }); + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect(TestData.SuccessfulPostStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.data.should.include(decodeURIComponent(pid)); + }); + }); - request(appUrl) + it("0021: should fetch dataset with correct numeric value for scientific filter", async () => { + return request(appUrl) .post("/api/v3/elastic-search/search") .send( - scientificMetadata({ - lhs: scientificMetadataFieldName.unitAndValue, - relation: Relation.LESS_THAN, - rhs: 101, - unit: "m", - }), + scientificMetadata([ + { + lhs: scientificMetadataFieldName.number, + relation: Relation.EQUAL_TO_NUMERIC, + rhs: 111, + unit: "", + }, + ]), ) .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }); + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect(TestData.SuccessfulPostStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.data.should.include(decodeURIComponent(pid)); + }); + }); + it("0022: should fetch dataset with correct string value for the scientific filter", async () => { return request(appUrl) .post("/api/v3/elastic-search/search") .send( - scientificMetadata({ - lhs: scientificMetadataFieldName.unitAndValue, - relation: Relation.EQUAL_TO_NUMERIC, - rhs: 100, - unit: "m", - }), + scientificMetadata([ + { + lhs: scientificMetadataFieldName.string, + relation: Relation.EQUAL_TO_STRING, + rhs: "222", + unit: "", + }, + ]), ) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) @@ -137,37 +167,36 @@ const scientificMetadata = ({ res.body.data.should.include(decodeURIComponent(pid)); }); }); - it("0030: should fetch dataset with numeric value filter", async () => { + + it("0023: should fail when fetching dataset with incorrect relation type and value type for the scientific filter", async () => { return request(appUrl) .post("/api/v3/elastic-search/search") .send( - scientificMetadata({ - lhs: scientificMetadataFieldName.number, - relation: Relation.EQUAL_TO_NUMERIC, - rhs: 111, - unit: "", - }), + scientificMetadata([ + { + lhs: scientificMetadataFieldName.number, + relation: Relation.EQUAL_TO_NUMERIC, + rhs: "111", + unit: "", + }, + ]), ) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) .expect(TestData.SuccessfulPostStatusCode) .expect("Content-Type", /json/) .then((res) => { - res.body.data.should.include(decodeURIComponent(pid)); + res.body.data.should.be.length(0); }); }); - it("0040: should fetch dataset with string value filter", async () => { + it("0030: should fetching dataset with correct proposalId and size", async () => { return request(appUrl) .post("/api/v3/elastic-search/search") - .send( - scientificMetadata({ - lhs: scientificMetadataFieldName.string, - relation: Relation.EQUAL_TO_STRING, - rhs: "222", - unit: "", - }), - ) + .send({ + proposalId: TestData.ScientificMetadataForElasticSearch.proposalId, + size: TestData.ScientificMetadataForElasticSearch.size, + }) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) .expect(TestData.SuccessfulPostStatusCode) @@ -177,30 +206,54 @@ const scientificMetadata = ({ }); }); - it("0050: should fail when fetching dataset with incorrect relation type and value type", async () => { + it("0031: should fail fetching dataset with correct proposalId but wrong size", async () => { return request(appUrl) .post("/api/v3/elastic-search/search") - .send( - scientificMetadata({ - lhs: scientificMetadataFieldName.number, - relation: Relation.EQUAL_TO_NUMERIC, - rhs: "111", - unit: "", - }), - ) + .send({ + proposalId: TestData.ScientificMetadataForElasticSearch.proposalId, + size: faker.number.int({ min: 100000001, max: 100400000 }), + }) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) .expect(TestData.SuccessfulPostStatusCode) .expect("Content-Type", /json/) .then((res) => { - res.body.should.have - .property("data") - .which.is.an("array") - .that.has.lengthOf(0); + res.body.data.should.be.length(0); + }); + }); + it("0032: should fail fetching dataset with wrong proposalId but correct size", async () => { + return request(appUrl) + .post("/api/v3/elastic-search/search") + .send({ + proposalId: "wrongProposalId", + size: TestData.ScientificMetadataForElasticSearch.size, + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect(TestData.SuccessfulPostStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.data.should.be.length(0); + }); + }); + + it("0033: should fail fetching dataset with incorrect proposalId and size", async () => { + return request(appUrl) + .post("/api/v3/elastic-search/search") + .send({ + proposalId: "wrongProposalId", + size: faker.number.int({ min: 100000001, max: 100400000 }), + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect(TestData.SuccessfulPostStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.data.should.be.length(0); }); }); - it("0060: should delete this raw dataset", async () => { + it("0034: should delete this raw dataset", async () => { return request(appUrl) .delete("/api/v3/datasets/" + pid) .set("Accept", "application/json") diff --git a/test/TestData.js b/test/TestData.js index 5a3a5310b..f5ca82fbd 100644 --- a/test/TestData.js +++ b/test/TestData.js @@ -809,6 +809,8 @@ const TestData = { creationTime: faker.date.past(), sourceFolder: faker.system.directoryPath(), owner: faker.internet.userName(), + size: faker.number.int({ min: 0, max: 100000000 }), + proposalId: faker.string.numeric(6), contactEmail: faker.internet.email(), scientificMetadata: { with_unit_and_value_si: {